Compare commits

..
22 Commits
Author SHA1 Message Date
Alif Rachmawadi 0fdcd6ee16 updated usage 2019-08-18 21:25:10 +07:00
Alif Rachmawadi 828493a231 added more tests 2019-08-18 21:23:51 +07:00
Alif Rachmawadi a1e481922d handle 1.7 as 1.7.x 2019-08-18 21:23:37 +07:00
Alif Rachmawadi 5fe8a7cf47 rename 2019-08-16 19:33:37 +07:00
Alif Rachmawadi e0ee719d54 bump version 2019-08-16 19:18:34 +07:00
Alif Rachmawadi 9fcb2724bc use flutter-version 2019-08-16 19:15:18 +07:00
Alif Rachmawadi ad169ccdaa use flutter-version instead of version 2019-08-16 19:14:55 +07:00
Alif Rachmawadi 01ee38751a added semver 2019-08-16 19:04:23 +07:00
Alif Rachmawadi 1f3ea86f20 updated usage 2019-08-16 19:03:08 +07:00
Alif Rachmawadi 944fac1f62 added test fox .x version syntax 2019-08-16 19:03:08 +07:00
Alif Rachmawadi be0241570a handle .x version syntax 2019-08-16 18:59:11 +07:00
Alif Rachmawadi 9421912880 allow unmocked 2019-08-16 18:40:47 +07:00
Alif Rachmawadi 858e055b72 added test for fetching latest release 2019-08-16 18:31:13 +07:00
Alif Rachmawadi 62ca43375c set version as optional 2019-08-16 18:30:45 +07:00
Alif Rachmawadi fc54c01d84 added nock 2019-08-16 18:30:30 +07:00
Alif Rachmawadi 39e54cc1e6 get latest release automatically 2019-08-16 18:30:17 +07:00
Alif Rachmawadi b14481040a updated lib 2019-08-16 15:36:09 +07:00
Alif Rachmawadi 88fdaa7568 added test for invalid version 2019-08-16 15:34:20 +07:00
Alif Rachmawadi 9b82c25a31 use version; fixes #1 2019-08-16 09:28:18 +07:00
Alif Rachmawadi e15318b1da bump version 2019-08-16 09:16:46 +07:00
Alif Rachmawadi fc32c521f1 update cache path 2019-08-15 12:44:24 +07:00
Alif Rachmawadi 126ac36d04 updated usage 2019-08-14 08:13:02 +07:00
13 changed files with 4934 additions and 51 deletions
+41 -7
View File
@@ -6,13 +6,46 @@ This action sets up a flutter environment for use in actions. It works on Linux,
```yaml
steps:
- uses: actions/checkout@master
- uses: actions/checkout@v1
- uses: actions/setup-java@v1
with:
java-version: '12.x'
- uses: subosito/flutter-action@master
- uses: subosito/flutter-action@v1
with:
version: '1.7.8+hotfix.4'
flutter-version: '1.7.8+hotfix.4'
- run: flutter pub get
- run: flutter test
- run: flutter build apk
```
Use latest release for particular channel:
```yaml
steps:
- uses: actions/checkout@v1
- uses: actions/setup-java@v1
with:
java-version: '12.x'
- uses: subosito/flutter-action@v1
with:
channel: 'stable' # or: 'dev' or 'beta'
- run: flutter pub get
- run: flutter test
- run: flutter build apk
```
Use latest release for particular version and/or channel:
```yaml
steps:
- uses: actions/checkout@v1
- uses: actions/setup-java@v1
with:
java-version: '12.x'
- uses: subosito/flutter-action@v1
with:
flutter-version: '1.7.x' # you can use 1.7
channel: 'dev' # optional, default to: 'stable'
- run: flutter pub get
- run: flutter test
- run: flutter build apk
@@ -29,13 +62,14 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@master
- uses: actions/setup-java@v1.0.1
- uses: actions/checkout@v1
- uses: actions/setup-java@v1
with:
java-version: '12.x'
- uses: subosito/flutter-action@master
- uses: subosito/flutter-action@v1
with:
version: '1.7.8+hotfix.4'
flutter-version: '1.8.4'
channel: 'beta'
- run: flutter pub get
- run: flutter test
- run: flutter build apk
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+69 -8
View File
@@ -1,15 +1,28 @@
import io = require('@actions/io');
import fs = require('fs');
import path = require('path');
import nock = require('nock');
const toolDir = path.join(__dirname, 'runner', 'tools');
const tempDir = path.join(__dirname, 'runner', 'temp');
const dataDir = path.join(__dirname, 'data');
process.env['RUNNER_TOOL_CACHE'] = toolDir;
process.env['RUNNER_TEMP'] = tempDir;
import * as installer from '../src/installer';
function osName(): string {
switch (process.platform) {
case 'win32':
return 'windows';
case 'darwin':
return 'macos';
default:
return process.platform;
}
}
describe('installer tests', () => {
beforeAll(async () => {
await io.rmRF(toolDir);
@@ -26,13 +39,8 @@ describe('installer tests', () => {
}, 100000);
it('Downloads flutter', async () => {
await installer.getFlutter('1.7.8+hotfix.4', 'stable');
const sdkDir = path.join(
toolDir,
'Flutter',
'1.7.8-hotfix.4-stable',
'x64'
);
await installer.getFlutter('1.0.0', 'stable');
const sdkDir = path.join(toolDir, 'flutter', '1.0.0-stable', 'x64');
expect(fs.existsSync(`${sdkDir}.complete`)).toBe(true);
expect(fs.existsSync(path.join(sdkDir, 'bin'))).toBe(true);
@@ -40,9 +48,62 @@ describe('installer tests', () => {
it('Downloads flutter from beta channel', async () => {
await installer.getFlutter('1.8.3', 'beta');
const sdkDir = path.join(toolDir, 'Flutter', '1.8.3-beta', 'x64');
const sdkDir = path.join(toolDir, 'flutter', '1.8.3-beta', 'x64');
expect(fs.existsSync(`${sdkDir}.complete`)).toBe(true);
expect(fs.existsSync(path.join(sdkDir, 'bin'))).toBe(true);
}, 100000);
describe('get the latest release of a flutter version', () => {
beforeEach(() => {
const platform = osName();
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('Downloads latest flutter release from stable channel', async () => {
await installer.getFlutter('', 'stable');
const sdkDir = path.join(
toolDir,
'flutter',
'1.7.8-hotfix.4-stable',
'x64'
);
expect(fs.existsSync(`${sdkDir}.complete`)).toBe(true);
expect(fs.existsSync(path.join(sdkDir, 'bin'))).toBe(true);
}, 100000);
it('Downloads latest flutter release of 1.7 when using version 1.7 from dev channel', async () => {
await installer.getFlutter('1.7', 'dev');
const sdkDir = path.join(toolDir, 'flutter', '1.7.11-dev', 'x64');
expect(fs.existsSync(`${sdkDir}.complete`)).toBe(true);
expect(fs.existsSync(path.join(sdkDir, 'bin'))).toBe(true);
}, 100000);
it('Downloads latest flutter release of 1.7 when using version 1.7.x from dev channel', async () => {
await installer.getFlutter('1.7.x', 'dev');
const sdkDir = path.join(toolDir, 'flutter', '1.7.11-dev', 'x64');
expect(fs.existsSync(`${sdkDir}.complete`)).toBe(true);
expect(fs.existsSync(path.join(sdkDir, 'bin'))).toBe(true);
}, 100000);
});
it('Throws if no location contains correct flutter version', async () => {
let thrown = false;
try {
await installer.getFlutter('1000.0', 'dev');
} catch {
thrown = true;
}
expect(thrown).toBe(true);
});
});
+6 -3
View File
@@ -1,14 +1,17 @@
name: 'Flutter Action'
name: 'Flutter action'
description: 'Setup your runner with Flutter environment'
author: 'Alif Rachmawadi'
inputs:
version:
flutter-version:
description: 'The Flutter version to make available on the path'
required: true
required: false
channel:
description: 'The Flutter build release channel'
required: false
default: 'stable'
# Deprecated option, do not use. Will not be supported after October 1, 2019
version:
description: 'Deprecated. Use flutter-version instead. Will not be supported after October 1, 2019'
runs:
using: 'node12'
main: 'lib/index.js'
+2 -2
View File
@@ -20,8 +20,8 @@ const installer = __importStar(require("./installer"));
function run() {
return __awaiter(this, void 0, void 0, function* () {
try {
const version = core.getInput('version', { required: true });
const channel = core.getInput('channel', { required: false }) || 'stable';
const version = core.getInput('version') || core.getInput('flutter-version') || '';
const channel = core.getInput('channel') || 'stable';
yield installer.getFlutter(version, channel);
}
catch (error) {
+46 -6
View File
@@ -23,11 +23,14 @@ const io = __importStar(require("@actions/io"));
const tc = __importStar(require("@actions/tool-cache"));
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const restm = __importStar(require("typed-rest-client/RestClient"));
const semver = __importStar(require("semver"));
const v4_1 = __importDefault(require("uuid/v4"));
const exec_1 = require("@actions/exec/lib/exec");
const IS_WINDOWS = process.platform === 'win32';
const IS_DARWIN = process.platform === 'darwin';
const IS_LINUX = process.platform === 'linux';
const storageUrl = 'https://storage.googleapis.com/flutter_infra/releases';
let tempDirectory = process.env['RUNNER_TEMP'] || '';
if (!tempDirectory) {
let baseLocation;
@@ -46,10 +49,13 @@ if (!tempDirectory) {
}
function getFlutter(version, channel) {
return __awaiter(this, void 0, void 0, function* () {
// make semver compatible, eg: 1.7.8+hotfix.4 -> 1.7.8-hotfix.4
const semver = version.replace('+', '-');
const cleanver = `${semver}-${channel}`;
let toolPath = tc.find('Flutter', cleanver);
const versionPart = version.split('.');
if (versionPart[1] == null || versionPart[2] == null) {
version = version.concat('.x');
}
version = yield determineVersion(version, channel);
let cleanver = `${version.replace('+', '-')}-${channel}`;
let toolPath = tc.find('flutter', cleanver);
if (toolPath) {
core.debug(`Tool found in cache ${toolPath}`);
}
@@ -60,7 +66,7 @@ function getFlutter(version, channel) {
let tempDir = generateTempDir();
const sdkDir = yield extractDownload(sdkFile, tempDir);
core.debug(`Flutter sdk extracted to ${sdkDir}`);
toolPath = yield tc.cacheDir(sdkDir, 'Flutter', cleanver);
toolPath = yield tc.cacheDir(sdkDir, 'flutter', cleanver);
}
core.exportVariable('FLUTTER_HOME', toolPath);
core.addPath(path.join(toolPath, 'bin'));
@@ -82,7 +88,7 @@ function extName() {
function getDownloadInfo(version, channel) {
const os = osName();
const ext = extName();
const url = `https://storage.googleapis.com/flutter_infra/releases/${channel}/${os}/flutter_${os}_v${version}-${channel}.${ext}`;
const url = `${storageUrl}/${channel}/${os}/flutter_${os}_v${version}-${channel}.${ext}`;
return {
version,
url
@@ -162,3 +168,37 @@ function extractZipDarwin(file, dest) {
yield exec_1.exec(`"${unzipPath}"`, [file], { cwd: dest });
});
}
function determineVersion(version, channel) {
return __awaiter(this, void 0, void 0, function* () {
if (version.endsWith('.x') || version === '') {
return yield getLatestVersion(version, channel);
}
return version;
});
}
function getLatestVersion(version, channel) {
return __awaiter(this, void 0, void 0, function* () {
const releasesUrl = `${storageUrl}/releases_${osName()}.json`;
const rest = new restm.RestClient('setup-go');
const storage = (yield rest.get(releasesUrl)).result;
if (!storage) {
throw new Error('unable to get latest version');
}
if (version.endsWith('.x')) {
const sver = version.slice(0, version.length - 2);
const releases = storage.releases.filter(release => release.version.startsWith(`v${sver}`) && release.channel === channel);
const versions = releases.map(release => release.version.slice(1, release.version.length));
const sortedVersions = versions.sort(semver.rcompare);
core.debug(`latest version of ${version} from channel ${channel} is ${sortedVersions[0]}`);
return sortedVersions[0];
}
const channelVersion = storage.releases.find(release => release.hash === storage.current_release[channel]);
if (!channelVersion) {
throw new Error(`unable to get latest version from channel ${channel}`);
}
let cver = channelVersion.version;
cver = cver.slice(1, cver.length);
core.debug(`latest version from channel ${channel} is ${cver}`);
return cver;
});
}
+12 -13
View File
@@ -1,39 +1,38 @@
{
"_args": [
[
"semver@6.3.0",
"/Users/subosito/Code/playground/flutter-actions"
]
],
"_from": "semver@6.3.0",
"_from": "semver",
"_id": "semver@6.3.0",
"_inBundle": false,
"_integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"_location": "/semver",
"_phantomChildren": {},
"_requested": {
"type": "version",
"type": "tag",
"registry": true,
"raw": "semver@6.3.0",
"raw": "semver",
"name": "semver",
"escapedName": "semver",
"rawSpec": "6.3.0",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "6.3.0"
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/",
"/@actions/tool-cache",
"/istanbul-lib-instrument"
],
"_resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"_spec": "6.3.0",
"_where": "/Users/subosito/Code/playground/flutter-actions",
"_shasum": "ee0a64c8af5e8ceea67687b133761e1becbd1d3d",
"_spec": "semver",
"_where": "/Users/subosito/Code/subosito/flutter-action",
"bin": {
"semver": "./bin/semver.js"
},
"bugs": {
"url": "https://github.com/npm/node-semver/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "The semantic version parser used by npm.",
"devDependencies": {
"tap": "^14.3.1"
+115 -1
View File
@@ -1,6 +1,6 @@
{
"name": "flutter-action",
"version": "1.0.1",
"version": "1.1.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -530,6 +530,15 @@
"integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==",
"dev": true
},
"@types/nock": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/@types/nock/-/nock-10.0.3.tgz",
"integrity": "sha512-OthuN+2FuzfZO3yONJ/QVjKmLEuRagS9TV9lEId+WHL9KhftYG+/2z+pxlr0UgVVXSpVD8woie/3fzQn8ft/Ow==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/node": {
"version": "12.6.8",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz",
@@ -702,6 +711,12 @@
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
"dev": true
},
"assertion-error": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
"dev": true
},
"assign-symbols": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
@@ -1052,6 +1067,20 @@
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
"dev": true
},
"chai": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
"integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
"dev": true,
"requires": {
"assertion-error": "^1.1.0",
"check-error": "^1.0.2",
"deep-eql": "^3.0.1",
"get-func-name": "^2.0.0",
"pathval": "^1.1.0",
"type-detect": "^4.0.5"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -1063,6 +1092,12 @@
"supports-color": "^5.3.0"
}
},
"check-error": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
"dev": true
},
"ci-info": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
@@ -1308,6 +1343,21 @@
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
"dev": true
},
"deep-eql": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
"integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
"dev": true,
"requires": {
"type-detect": "^4.0.0"
}
},
"deep-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
"integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
"dev": true
},
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
@@ -2321,6 +2371,12 @@
"integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
"dev": true
},
"get-func-name": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
"integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
"dev": true
},
"get-stdin": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz",
@@ -3817,6 +3873,46 @@
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true
},
"nock": {
"version": "10.0.6",
"resolved": "https://registry.npmjs.org/nock/-/nock-10.0.6.tgz",
"integrity": "sha512-b47OWj1qf/LqSQYnmokNWM8D88KvUl2y7jT0567NB3ZBAZFz2bWp2PC81Xn7u8F2/vJxzkzNZybnemeFa7AZ2w==",
"dev": true,
"requires": {
"chai": "^4.1.2",
"debug": "^4.1.0",
"deep-equal": "^1.0.0",
"json-stringify-safe": "^5.0.1",
"lodash": "^4.17.5",
"mkdirp": "^0.5.0",
"propagate": "^1.0.0",
"qs": "^6.5.1",
"semver": "^5.5.0"
},
"dependencies": {
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
}
}
},
"node-int64": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@@ -4149,6 +4245,12 @@
"pify": "^3.0.0"
}
},
"pathval": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
"integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
"dev": true
},
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -4240,6 +4342,12 @@
"sisteransi": "^1.0.0"
}
},
"propagate": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz",
"integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=",
"dev": true
},
"psl": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz",
@@ -5177,6 +5285,12 @@
"prelude-ls": "~1.1.2"
}
},
"type-detect": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
"dev": true
},
"type-fest": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
+6 -3
View File
@@ -1,8 +1,8 @@
{
"name": "flutter-action",
"version": "1.0.1",
"version": "1.1.0",
"private": true,
"description": "flutter action",
"description": "Flutter environment for use in actions",
"main": "lib/index.js",
"scripts": {
"build": "tsc",
@@ -27,16 +27,19 @@
"@actions/exec": "^1.0.0",
"@actions/io": "^1.0.0",
"@actions/tool-cache": "^1.0.0",
"semver": "^6.3.0",
"uuid": "^3.3.2"
},
"devDependencies": {
"@types/jest": "^24.0.13",
"@types/nock": "^10.0.3",
"@types/node": "^12.0.4",
"@types/semver": "^6.0.0",
"@types/semver": "^6.0.1",
"@types/uuid": "^3.4.5",
"husky": "^3.0.0",
"jest": "^24.8.0",
"jest-circus": "^24.7.1",
"nock": "^10.0.6",
"prettier": "^1.17.1",
"ts-jest": "^24.0.2",
"typescript": "^3.5.1"
+3 -2
View File
@@ -3,8 +3,9 @@ import * as installer from './installer';
async function run() {
try {
const version = core.getInput('version', {required: true});
const channel = core.getInput('channel', {required: false}) || 'stable';
const version =
core.getInput('version') || core.getInput('flutter-version') || '';
const channel = core.getInput('channel') || 'stable';
await installer.getFlutter(version, channel);
} catch (error) {
+92 -6
View File
@@ -3,6 +3,8 @@ import * as io from '@actions/io';
import * as tc from '@actions/tool-cache';
import * as fs from 'fs';
import * as path from 'path';
import * as restm from 'typed-rest-client/RestClient';
import * as semver from 'semver';
import uuidV4 from 'uuid/v4';
import {exec} from '@actions/exec/lib/exec';
@@ -10,6 +12,8 @@ const IS_WINDOWS = process.platform === 'win32';
const IS_DARWIN = process.platform === 'darwin';
const IS_LINUX = process.platform === 'linux';
const storageUrl = 'https://storage.googleapis.com/flutter_infra/releases';
let tempDirectory = process.env['RUNNER_TEMP'] || '';
if (!tempDirectory) {
@@ -32,10 +36,16 @@ export async function getFlutter(
version: string,
channel: string
): Promise<void> {
// make semver compatible, eg: 1.7.8+hotfix.4 -> 1.7.8-hotfix.4
const semver = version.replace('+', '-');
const cleanver = `${semver}-${channel}`;
let toolPath = tc.find('Flutter', cleanver);
const versionPart = version.split('.');
if (versionPart[1] == null || versionPart[2] == null) {
version = version.concat('.x');
}
version = await determineVersion(version, channel);
let cleanver = `${version.replace('+', '-')}-${channel}`;
let toolPath = tc.find('flutter', cleanver);
if (toolPath) {
core.debug(`Tool found in cache ${toolPath}`);
@@ -49,7 +59,7 @@ export async function getFlutter(
const sdkDir = await extractDownload(sdkFile, tempDir);
core.debug(`Flutter sdk extracted to ${sdkDir}`);
toolPath = await tc.cacheDir(sdkDir, 'Flutter', cleanver);
toolPath = await tc.cacheDir(sdkDir, 'flutter', cleanver);
}
core.exportVariable('FLUTTER_HOME', toolPath);
@@ -75,7 +85,7 @@ function getDownloadInfo(
): {version: string; url: string} {
const os = osName();
const ext = extName();
const url = `https://storage.googleapis.com/flutter_infra/releases/${channel}/${os}/flutter_${os}_v${version}-${channel}.${ext}`;
const url = `${storageUrl}/${channel}/${os}/flutter_${os}_v${version}-${channel}.${ext}`;
return {
version,
@@ -171,3 +181,79 @@ async function extractZipDarwin(file: string, dest: string): Promise<void> {
);
await exec(`"${unzipPath}"`, [file], {cwd: dest});
}
async function determineVersion(
version: string,
channel: string
): Promise<string> {
if (version.endsWith('.x') || version === '') {
return await getLatestVersion(version, channel);
}
return version;
}
interface IFlutterChannel {
[key: string]: string;
beta: string;
dev: string;
stable: string;
}
interface IFlutterRelease {
hash: string;
channel: string;
version: string;
}
interface IFlutterStorage {
current_release: IFlutterChannel;
releases: IFlutterRelease[];
}
async function getLatestVersion(
version: string,
channel: string
): Promise<string> {
const releasesUrl: string = `${storageUrl}/releases_${osName()}.json`;
const rest: restm.RestClient = new restm.RestClient('setup-go');
const storage: IFlutterStorage | null = (await rest.get<IFlutterStorage | null>(
releasesUrl
)).result;
if (!storage) {
throw new Error('unable to get latest version');
}
if (version.endsWith('.x')) {
const sver = version.slice(0, version.length - 2);
const releases = storage.releases.filter(
release =>
release.version.startsWith(`v${sver}`) && release.channel === channel
);
const versions = releases.map(release =>
release.version.slice(1, release.version.length)
);
const sortedVersions = versions.sort(semver.rcompare);
core.debug(
`latest version of ${version} from channel ${channel} is ${sortedVersions[0]}`
);
return sortedVersions[0];
}
const channelVersion = storage.releases.find(
release => release.hash === storage.current_release[channel]
);
if (!channelVersion) {
throw new Error(`unable to get latest version from channel ${channel}`);
}
let cver = channelVersion.version;
cver = cver.slice(1, cver.length);
core.debug(`latest version from channel ${channel} is ${cver}`);
return cver;
}