mirror of
https://github.com/subosito/flutter-action.git
synced 2024-08-16 10:19:50 +02:00
add release version check function
This commit is contained in:
parent
1aaec8dd0f
commit
c7c0640db8
2 changed files with 292 additions and 0 deletions
117
__tests__/release.test.ts
Normal file
117
__tests__/release.test.ts
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
import fs = require('fs');
|
||||||
|
import path = require('path');
|
||||||
|
import nock = require('nock');
|
||||||
|
import * as release from '../src/release';
|
||||||
|
|
||||||
|
const platform = release.getPlatform();
|
||||||
|
|
||||||
|
describe('release tests', () => {
|
||||||
|
it('getPlatform', () => {
|
||||||
|
const platformMap: {[index: string]: string} = {
|
||||||
|
linux: 'linux',
|
||||||
|
macos: 'darwin',
|
||||||
|
windows: 'win32'
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(platform).toEqual(platformMap[process.platform]);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('determineVersion', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
const dataDir = path.join(__dirname, 'data');
|
||||||
|
|
||||||
|
nock('https://storage.googleapis.com', {allowUnmocked: true})
|
||||||
|
.get(`/flutter_infra/releases/releases_${platform}.json`)
|
||||||
|
.replyWithFile(200, path.join(dataDir, `releases_${platform}.json`));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
nock.cleanAll();
|
||||||
|
nock.enableNetConnect();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('channel: "stable", version: ""', async () => {
|
||||||
|
const result = await release.determineVersion('', 'stable', platform);
|
||||||
|
|
||||||
|
expect(result.version).toEqual('1.22.0');
|
||||||
|
expect(result.rawVersion).toEqual('1.22.0');
|
||||||
|
expect(result.downloadUrl).toContain('1.22.0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('channel: "beta", version: ""', async () => {
|
||||||
|
const result = await release.determineVersion('', 'beta', platform);
|
||||||
|
|
||||||
|
expect(result.version).toEqual('1.22.0-12.3.pre');
|
||||||
|
expect(result.rawVersion).toEqual('1.22.0-12.3.pre');
|
||||||
|
expect(result.downloadUrl).toContain('1.22.0-12.3.pre');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('channel: "dev", version: ""', async () => {
|
||||||
|
const result = await release.determineVersion('', 'dev', platform);
|
||||||
|
|
||||||
|
expect(result.version).toEqual('1.23.0-7.0.pre');
|
||||||
|
expect(result.rawVersion).toEqual('1.23.0-7.0.pre');
|
||||||
|
expect(result.downloadUrl).toContain('1.23.0-7.0.pre');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('channel: "dev", version: "1.17.x"', async () => {
|
||||||
|
const result = await release.determineVersion('1.17.x', 'dev', platform);
|
||||||
|
|
||||||
|
expect(result.version).toEqual('1.17.0-dev.5.0');
|
||||||
|
expect(result.rawVersion).toEqual('1.17.0-dev.5.0');
|
||||||
|
expect(result.downloadUrl).toContain('1.17.0-dev.5.0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('channel: "dev", version: "1.17"', async () => {
|
||||||
|
const result = await release.determineVersion('1.17', 'dev', platform);
|
||||||
|
|
||||||
|
expect(result.version).toEqual('1.17.0-dev.5.0');
|
||||||
|
expect(result.rawVersion).toEqual('1.17.0-dev.5.0');
|
||||||
|
expect(result.downloadUrl).toContain('1.17.0-dev.5.0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('channel: "dev", version: "1.7.x" (old format)', async () => {
|
||||||
|
const result = await release.determineVersion('1.7.x', 'dev', platform);
|
||||||
|
|
||||||
|
expect(result.version).toEqual('1.7.11');
|
||||||
|
expect(result.rawVersion).toEqual('v1.7.11');
|
||||||
|
expect(result.downloadUrl).toContain('v1.7.11');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('channel: "dev", version: "1.7" (old format)', async () => {
|
||||||
|
const result = await release.determineVersion('1.7', 'dev', platform);
|
||||||
|
|
||||||
|
expect(result.version).toEqual('1.7.11');
|
||||||
|
expect(result.rawVersion).toEqual('v1.7.11');
|
||||||
|
expect(result.downloadUrl).toContain('v1.7.11');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('channel: "dev", version: "0.12.x" (unknown)', async () => {
|
||||||
|
try {
|
||||||
|
await release.determineVersion('0.12.x', 'dev', platform);
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.message).toEqual('unable to find release for 0.12.x');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('channel: "dev", version: "0.12" (unknown)', async () => {
|
||||||
|
try {
|
||||||
|
await release.determineVersion('0.12', 'dev', platform);
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.message).toEqual('unable to find release for 0.12');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('channel: "dev", version: "1.17.0-dev.5.0"', async () => {
|
||||||
|
const result = await release.determineVersion(
|
||||||
|
'1.17.0-dev.5.0',
|
||||||
|
'dev',
|
||||||
|
platform
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.version).toEqual('1.17.0-dev.5.0');
|
||||||
|
expect(result.rawVersion).toEqual('1.17.0-dev.5.0');
|
||||||
|
expect(result.downloadUrl).toContain('1.17.0-dev.5.0');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
175
src/release.ts
Normal file
175
src/release.ts
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
import * as core from '@actions/core';
|
||||||
|
import * as httpm from '@actions/http-client';
|
||||||
|
import * as semver from 'semver';
|
||||||
|
|
||||||
|
export const storageUrl =
|
||||||
|
'https://storage.googleapis.com/flutter_infra/releases';
|
||||||
|
|
||||||
|
interface IFlutterChannel {
|
||||||
|
[key: string]: string;
|
||||||
|
beta: string;
|
||||||
|
dev: string;
|
||||||
|
stable: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IFlutterRelease {
|
||||||
|
hash: string;
|
||||||
|
channel: string;
|
||||||
|
version: string;
|
||||||
|
archive: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IFlutterStorage {
|
||||||
|
current_release: IFlutterChannel;
|
||||||
|
releases: IFlutterRelease[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPlatform(): string {
|
||||||
|
const platform = process.platform;
|
||||||
|
|
||||||
|
if (platform == 'win32') {
|
||||||
|
return 'windows';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (platform == 'darwin') {
|
||||||
|
return 'macos';
|
||||||
|
}
|
||||||
|
|
||||||
|
return platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function determineVersion(
|
||||||
|
version: string,
|
||||||
|
channel: string,
|
||||||
|
platform: string
|
||||||
|
): Promise<{version: string; rawVersion: string; downloadUrl: string}> {
|
||||||
|
const storage = await getReleases(platform);
|
||||||
|
|
||||||
|
if (version === '') {
|
||||||
|
return getLatestVersion(storage, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version.endsWith('.x')) {
|
||||||
|
return getWildcardVersion(storage, channel, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getVersion(storage, channel, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getReleases(platform: string): Promise<IFlutterStorage> {
|
||||||
|
const releasesUrl: string = `${storageUrl}/releases_${platform}.json`;
|
||||||
|
const http: httpm.HttpClient = new httpm.HttpClient('flutter-action');
|
||||||
|
const storage: IFlutterStorage | null = (
|
||||||
|
await http.getJson<IFlutterStorage | null>(releasesUrl)
|
||||||
|
).result;
|
||||||
|
|
||||||
|
if (!storage) {
|
||||||
|
throw new Error('unable to get flutter releases');
|
||||||
|
}
|
||||||
|
|
||||||
|
return storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getLatestVersion(
|
||||||
|
storage: IFlutterStorage,
|
||||||
|
channel: string
|
||||||
|
): Promise<{version: string; rawVersion: string; downloadUrl: string}> {
|
||||||
|
const channelVersion = storage.releases.find(release => {
|
||||||
|
return (
|
||||||
|
release.hash === storage.current_release[channel] &&
|
||||||
|
release.channel == channel
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!channelVersion) {
|
||||||
|
throw new Error(`unable to get latest version from channel ${channel}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let rver = channelVersion.version;
|
||||||
|
let cver = rver.startsWith('v') ? rver.slice(1, rver.length) : rver;
|
||||||
|
|
||||||
|
core.debug(`latest version from channel ${channel} is ${rver}`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
version: cver,
|
||||||
|
rawVersion: rver,
|
||||||
|
downloadUrl: `${storageUrl}/${channelVersion.archive}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getWildcardVersion(
|
||||||
|
storage: IFlutterStorage,
|
||||||
|
channel: string,
|
||||||
|
version: string
|
||||||
|
): Promise<{version: string; rawVersion: string; downloadUrl: string}> {
|
||||||
|
let sver = version.endsWith('.x')
|
||||||
|
? version.slice(0, version.length - 2)
|
||||||
|
: version;
|
||||||
|
|
||||||
|
const releases = storage.releases.filter(release => {
|
||||||
|
if (release.channel != channel) return false;
|
||||||
|
return prefixCompare(sver, release.version);
|
||||||
|
});
|
||||||
|
|
||||||
|
const versions = releases
|
||||||
|
.map(release => release.version)
|
||||||
|
.map(version =>
|
||||||
|
version.startsWith('v') ? version.slice(1, version.length) : version
|
||||||
|
);
|
||||||
|
|
||||||
|
const sortedVersions = versions.sort(semver.rcompare);
|
||||||
|
|
||||||
|
let cver = sortedVersions[0];
|
||||||
|
let release = releases.find(release => compare(cver, release.version));
|
||||||
|
|
||||||
|
if (!release) {
|
||||||
|
throw new Error(`unable to find release for ${version}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
core.debug(
|
||||||
|
`latest version of ${version} from channel ${channel} is ${release.version}`
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
version: cver,
|
||||||
|
rawVersion: release.version,
|
||||||
|
downloadUrl: `${storageUrl}/${release.archive}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getVersion(
|
||||||
|
storage: IFlutterStorage,
|
||||||
|
channel: string,
|
||||||
|
version: string
|
||||||
|
): Promise<{version: string; rawVersion: string; downloadUrl: string}> {
|
||||||
|
const release = storage.releases.find(release => {
|
||||||
|
if (release.channel != channel) return false;
|
||||||
|
return compare(version, release.version);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!release) {
|
||||||
|
return getWildcardVersion(storage, channel, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
version,
|
||||||
|
rawVersion: release.version,
|
||||||
|
downloadUrl: `${storageUrl}/${release.archive}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function compare(version: string, releaseVersion: string): boolean {
|
||||||
|
if (releaseVersion.startsWith('v')) {
|
||||||
|
return releaseVersion === `v${version}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return releaseVersion === version;
|
||||||
|
}
|
||||||
|
|
||||||
|
function prefixCompare(version: string, releaseVersion: string): boolean {
|
||||||
|
if (releaseVersion.startsWith('v')) {
|
||||||
|
return releaseVersion.startsWith(`v${version}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return releaseVersion.startsWith(version);
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue