Compare commits

...

22 Commits

Author SHA1 Message Date
Alif Rachmawadi
b6f5cc2b39 bump version
Some checks failed
Main workflow / Run (macos-latest) (push) Failing after 4s
Main workflow / Run (ubuntu-latest) (push) Failing after 33s
Main workflow / Run (windows-latest) (push) Has been cancelled
2019-08-26 11:54:54 +07:00
Alif Rachmawadi
ad07e49913 removed unused file 2019-08-26 11:54:54 +07:00
Alif Rachmawadi
8f119fb49d Merge pull request #2 from subosito/tool-cache-110
tool-cache 1.1.0
2019-08-26 11:49:37 +07:00
Alif Rachmawadi
1dedc0776a remove unused hacks 2019-08-26 10:59:10 +07:00
Alif Rachmawadi
e4b52bc94d update tool-cache 1.1.0 2019-08-26 10:58:41 +07:00
Alif Rachmawadi
9267b2d4d1 updated user agent 2019-08-19 22:26:44 +07:00
Alif Rachmawadi
0fdcd6ee16 updated usage
Some checks failed
Main workflow / Run (macos-latest) (push) Failing after 2s
Main workflow / Run (ubuntu-latest) (push) Failing after 1m33s
Main workflow / Run (windows-latest) (push) Has been cancelled
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
21 changed files with 5584 additions and 801 deletions

View File

@@ -12,7 +12,40 @@ steps:
java-version: '12.x' java-version: '12.x'
- uses: subosito/flutter-action@v1 - uses: subosito/flutter-action@v1
with: 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 pub get
- run: flutter test - run: flutter test
- run: flutter build apk - run: flutter build apk
@@ -35,7 +68,8 @@ jobs:
java-version: '12.x' java-version: '12.x'
- uses: subosito/flutter-action@v1 - uses: subosito/flutter-action@v1
with: with:
version: '1.7.8+hotfix.4' flutter-version: '1.8.4'
channel: 'beta'
- run: flutter pub get - run: flutter pub get
- run: flutter test - run: flutter test
- run: flutter build apk - 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

View File

@@ -1,15 +1,28 @@
import io = require('@actions/io'); import io = require('@actions/io');
import fs = require('fs'); import fs = require('fs');
import path = require('path'); import path = require('path');
import nock = require('nock');
const toolDir = path.join(__dirname, 'runner', 'tools'); const toolDir = path.join(__dirname, 'runner', 'tools');
const tempDir = path.join(__dirname, 'runner', 'temp'); const tempDir = path.join(__dirname, 'runner', 'temp');
const dataDir = path.join(__dirname, 'data');
process.env['RUNNER_TOOL_CACHE'] = toolDir; process.env['RUNNER_TOOL_CACHE'] = toolDir;
process.env['RUNNER_TEMP'] = tempDir; process.env['RUNNER_TEMP'] = tempDir;
import * as installer from '../src/installer'; 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', () => { describe('installer tests', () => {
beforeAll(async () => { beforeAll(async () => {
await io.rmRF(toolDir); await io.rmRF(toolDir);
@@ -26,13 +39,8 @@ describe('installer tests', () => {
}, 100000); }, 100000);
it('Downloads flutter', async () => { it('Downloads flutter', async () => {
await installer.getFlutter('1.7.8+hotfix.4', 'stable'); await installer.getFlutter('1.0.0', 'stable');
const sdkDir = path.join( const sdkDir = path.join(toolDir, 'flutter', '1.0.0-stable', 'x64');
toolDir,
'flutter',
'1.7.8-hotfix.4-stable',
'x64'
);
expect(fs.existsSync(`${sdkDir}.complete`)).toBe(true); expect(fs.existsSync(`${sdkDir}.complete`)).toBe(true);
expect(fs.existsSync(path.join(sdkDir, 'bin'))).toBe(true); expect(fs.existsSync(path.join(sdkDir, 'bin'))).toBe(true);
@@ -46,6 +54,49 @@ describe('installer tests', () => {
expect(fs.existsSync(path.join(sdkDir, 'bin'))).toBe(true); expect(fs.existsSync(path.join(sdkDir, 'bin'))).toBe(true);
}, 100000); }, 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 () => { it('Throws if no location contains correct flutter version', async () => {
let thrown = false; let thrown = false;
try { try {

View File

@@ -1,14 +1,17 @@
name: 'Flutter Action' name: 'Flutter action'
description: 'Setup your runner with Flutter environment' description: 'Setup your runner with Flutter environment'
author: 'Alif Rachmawadi' author: 'Alif Rachmawadi'
inputs: inputs:
version: flutter-version:
description: 'The Flutter version to make available on the path' description: 'The Flutter version to make available on the path'
required: true required: false
channel: channel:
description: 'The Flutter build release channel' description: 'The Flutter build release channel'
required: false required: false
default: 'stable' 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: runs:
using: 'node12' using: 'node12'
main: 'lib/index.js' main: 'lib/index.js'

View File

@@ -20,8 +20,8 @@ const installer = __importStar(require("./installer"));
function run() { function run() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
try { try {
const version = core.getInput('version', { required: true }); const version = core.getInput('version') || core.getInput('flutter-version') || '';
const channel = core.getInput('channel', { required: false }) || 'stable'; const channel = core.getInput('channel') || 'stable';
yield installer.getFlutter(version, channel); yield installer.getFlutter(version, channel);
} }
catch (error) { catch (error) {

View File

@@ -14,20 +14,18 @@ var __importStar = (this && this.__importStar) || function (mod) {
result["default"] = mod; result["default"] = mod;
return result; return result;
}; };
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core")); const core = __importStar(require("@actions/core"));
const io = __importStar(require("@actions/io")); const io = __importStar(require("@actions/io"));
const tc = __importStar(require("@actions/tool-cache")); const tc = __importStar(require("@actions/tool-cache"));
const fs = __importStar(require("fs")); const fs = __importStar(require("fs"));
const path = __importStar(require("path")); const path = __importStar(require("path"));
const v4_1 = __importDefault(require("uuid/v4")); const restm = __importStar(require("typed-rest-client/RestClient"));
const exec_1 = require("@actions/exec/lib/exec"); const semver = __importStar(require("semver"));
const IS_WINDOWS = process.platform === 'win32'; const IS_WINDOWS = process.platform === 'win32';
const IS_DARWIN = process.platform === 'darwin'; const IS_DARWIN = process.platform === 'darwin';
const IS_LINUX = process.platform === 'linux'; const IS_LINUX = process.platform === 'linux';
const storageUrl = 'https://storage.googleapis.com/flutter_infra/releases';
let tempDirectory = process.env['RUNNER_TEMP'] || ''; let tempDirectory = process.env['RUNNER_TEMP'] || '';
if (!tempDirectory) { if (!tempDirectory) {
let baseLocation; let baseLocation;
@@ -46,9 +44,12 @@ if (!tempDirectory) {
} }
function getFlutter(version, channel) { function getFlutter(version, channel) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
// make semver compatible, eg: 1.7.8+hotfix.4 -> 1.7.8-hotfix.4 const versionPart = version.split('.');
const semver = version.replace('+', '-'); if (versionPart[1] == null || versionPart[2] == null) {
const cleanver = `${semver}-${channel}`; version = version.concat('.x');
}
version = yield determineVersion(version, channel);
let cleanver = `${version.replace('+', '-')}-${channel}`;
let toolPath = tc.find('flutter', cleanver); let toolPath = tc.find('flutter', cleanver);
if (toolPath) { if (toolPath) {
core.debug(`Tool found in cache ${toolPath}`); core.debug(`Tool found in cache ${toolPath}`);
@@ -82,7 +83,7 @@ function extName() {
function getDownloadInfo(version, channel) { function getDownloadInfo(version, channel) {
const os = osName(); const os = osName();
const ext = extName(); 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 { return {
version, version,
url url
@@ -116,49 +117,44 @@ function extractFile(file, destDir) {
throw new Error(`Failed to extract ${file} - it is a directory`); throw new Error(`Failed to extract ${file} - it is a directory`);
} }
if ('tar.xz' === extName()) { if ('tar.xz' === extName()) {
yield extractTarXz(file, destDir); yield tc.extractTar(file, destDir, 'x');
}
else {
if (IS_DARWIN) {
yield extractZipDarwin(file, destDir);
} }
else { else {
yield tc.extractZip(file, destDir); yield tc.extractZip(file, destDir);
} }
}
}); });
} }
/** function determineVersion(version, channel) {
* Extract a tar.xz
*
* @param file path to the tar.xz
* @param dest destination directory. Optional.
* @returns path to the destination directory
*/
function extractTarXz(file, dest) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
if (!file) { if (version.endsWith('.x') || version === '') {
throw new Error("parameter 'file' is required"); return yield getLatestVersion(version, channel);
} }
dest = dest || (yield _createExtractFolder(dest)); return version;
const tarPath = yield io.which('tar', true);
yield exec_1.exec(`"${tarPath}"`, ['xC', dest, '-f', file]);
return dest;
}); });
} }
exports.extractTarXz = extractTarXz; function getLatestVersion(version, channel) {
function _createExtractFolder(dest) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
if (!dest) { const releasesUrl = `${storageUrl}/releases_${osName()}.json`;
dest = path.join(tempDirectory, v4_1.default()); const rest = new restm.RestClient('flutter-action');
const storage = (yield rest.get(releasesUrl)).result;
if (!storage) {
throw new Error('unable to get latest version');
} }
yield io.mkdirP(dest); if (version.endsWith('.x')) {
return dest; 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));
function extractZipDarwin(file, dest) { const sortedVersions = versions.sort(semver.rcompare);
return __awaiter(this, void 0, void 0, function* () { core.debug(`latest version of ${version} from channel ${channel} is ${sortedVersions[0]}`);
const unzipPath = path.join(__dirname, '..', 'scripts', 'externals', 'unzip-darwin'); return sortedVersions[0];
yield exec_1.exec(`"${unzipPath}"`, [file], { cwd: dest }); }
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;
}); });
} }

View File

@@ -1,7 +0,0 @@
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -8,7 +8,7 @@
You can use this to download tools (or other files) from a download URL: You can use this to download tools (or other files) from a download URL:
``` ```js
const tc = require('@actions/tool-cache'); const tc = require('@actions/tool-cache');
const node12Path = await tc.downloadTool('http://nodejs.org/dist/v12.7.0/node-v12.7.0-linux-x64.tar.gz'); const node12Path = await tc.downloadTool('http://nodejs.org/dist/v12.7.0/node-v12.7.0-linux-x64.tar.gz');
@@ -18,7 +18,7 @@ const node12Path = await tc.downloadTool('http://nodejs.org/dist/v12.7.0/node-v1
These can then be extracted in platform specific ways: These can then be extracted in platform specific ways:
``` ```js
const tc = require('@actions/tool-cache'); const tc = require('@actions/tool-cache');
if (process.platform === 'win32') { if (process.platform === 'win32') {
@@ -41,7 +41,7 @@ Finally, you can cache these directories in our tool-cache. This is useful if yo
You'll often want to add it to the path as part of this step: You'll often want to add it to the path as part of this step:
``` ```js
const tc = require('@actions/tool-cache'); const tc = require('@actions/tool-cache');
const core = require('@actions/core'); const core = require('@actions/core');
@@ -54,7 +54,7 @@ core.addPath(cachedPath);
You can also cache files for reuse. You can also cache files for reuse.
``` ```js
const tc = require('@actions/tool-cache'); const tc = require('@actions/tool-cache');
tc.cacheFile('path/to/exe', 'destFileName.exe', 'myExeName', '1.1.0'); tc.cacheFile('path/to/exe', 'destFileName.exe', 'myExeName', '1.1.0');
@@ -64,7 +64,7 @@ tc.cacheFile('path/to/exe', 'destFileName.exe', 'myExeName', '1.1.0');
Finally, you can find directories and files you've previously cached: Finally, you can find directories and files you've previously cached:
``` ```js
const tc = require('@actions/tool-cache'); const tc = require('@actions/tool-cache');
const core = require('@actions/core'); const core = require('@actions/core');
@@ -74,7 +74,7 @@ core.addPath(nodeDirectory);
You can even find all cached versions of a tool: You can even find all cached versions of a tool:
``` ```js
const tc = require('@actions/tool-cache'); const tc = require('@actions/tool-cache');
const allNodeVersions = tc.findAllVersions('node'); const allNodeVersions = tc.findAllVersions('node');

View File

@@ -30,9 +30,10 @@ export declare function extract7z(file: string, dest?: string, _7zPath?: string)
* *
* @param file path to the tar * @param file path to the tar
* @param dest destination directory. Optional. * @param dest destination directory. Optional.
* @param flags flags for the tar. Optional.
* @returns path to the destination directory * @returns path to the destination directory
*/ */
export declare function extractTar(file: string, dest?: string): Promise<string>; export declare function extractTar(file: string, dest?: string, flags?: string): Promise<string>;
/** /**
* Extract a zip * Extract a zip
* *

View File

@@ -185,16 +185,17 @@ exports.extract7z = extract7z;
* *
* @param file path to the tar * @param file path to the tar
* @param dest destination directory. Optional. * @param dest destination directory. Optional.
* @param flags flags for the tar. Optional.
* @returns path to the destination directory * @returns path to the destination directory
*/ */
function extractTar(file, dest) { function extractTar(file, dest, flags = 'xz') {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
if (!file) { if (!file) {
throw new Error("parameter 'file' is required"); throw new Error("parameter 'file' is required");
} }
dest = dest || (yield _createExtractFolder(dest)); dest = dest || (yield _createExtractFolder(dest));
const tarPath = yield io.which('tar', true); const tarPath = yield io.which('tar', true);
yield exec_1.exec(`"${tarPath}"`, ['xzC', dest, '-f', file]); yield exec_1.exec(`"${tarPath}"`, [flags, '-C', dest, '-f', file]);
return dest; return dest;
}); });
} }
@@ -215,9 +216,14 @@ function extractZip(file, dest) {
if (IS_WINDOWS) { if (IS_WINDOWS) {
yield extractZipWin(file, dest); yield extractZipWin(file, dest);
} }
else {
if (process.platform === 'darwin') {
yield extractZipDarwin(file, dest);
}
else { else {
yield extractZipNix(file, dest); yield extractZipNix(file, dest);
} }
}
return dest; return dest;
}); });
} }
@@ -249,6 +255,12 @@ function extractZipNix(file, dest) {
yield exec_1.exec(`"${unzipPath}"`, [file], { cwd: dest }); yield exec_1.exec(`"${unzipPath}"`, [file], { cwd: dest });
}); });
} }
function extractZipDarwin(file, dest) {
return __awaiter(this, void 0, void 0, function* () {
const unzipPath = path.join(__dirname, '..', 'scripts', 'externals', 'unzip-darwin');
yield exec_1.exec(`"${unzipPath}"`, [file], { cwd: dest });
});
}
/** /**
* Caches a directory and installs it into the tool cacheDir * Caches a directory and installs it into the tool cacheDir
* *

File diff suppressed because one or more lines are too long

View File

@@ -1,36 +1,32 @@
{ {
"_args": [ "_from": "@actions/tool-cache@^1.1.0",
[ "_id": "@actions/tool-cache@1.1.0",
"@actions/tool-cache@1.0.0",
"/Users/subosito/Code/playground/flutter-actions"
]
],
"_from": "@actions/tool-cache@1.0.0",
"_id": "@actions/tool-cache@1.0.0",
"_inBundle": false, "_inBundle": false,
"_integrity": "sha512-l3zT0IfDfi5Ik5aMpnXqGHGATxN8xa9ls4ue+X/CBXpPhRMRZS4vcuh5Q9T98WAGbkysRCfhpbksTPHIcKnNwQ==", "_integrity": "sha512-Oe/R1Gxv0G699OUL9ypxk9cTwHf1uXHhpcK7kpZt8d/Sbw915ktMkfxXt9+awOfLDwyl54sLi86KGCuSvnRuIQ==",
"_location": "/@actions/tool-cache", "_location": "/@actions/tool-cache",
"_phantomChildren": {}, "_phantomChildren": {},
"_requested": { "_requested": {
"type": "version", "type": "range",
"registry": true, "registry": true,
"raw": "@actions/tool-cache@1.0.0", "raw": "@actions/tool-cache@^1.1.0",
"name": "@actions/tool-cache", "name": "@actions/tool-cache",
"escapedName": "@actions%2ftool-cache", "escapedName": "@actions%2ftool-cache",
"scope": "@actions", "scope": "@actions",
"rawSpec": "1.0.0", "rawSpec": "^1.1.0",
"saveSpec": null, "saveSpec": null,
"fetchSpec": "1.0.0" "fetchSpec": "^1.1.0"
}, },
"_requiredBy": [ "_requiredBy": [
"/" "/"
], ],
"_resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-1.0.0.tgz", "_resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-1.1.0.tgz",
"_spec": "1.0.0", "_shasum": "1a0e29f244f2b5c6989fc264581068689f9c219e",
"_where": "/Users/subosito/Code/playground/flutter-actions", "_spec": "@actions/tool-cache@^1.1.0",
"_where": "/Users/subosito/Code/subosito/flutter-action",
"bugs": { "bugs": {
"url": "https://github.com/actions/toolkit/issues" "url": "https://github.com/actions/toolkit/issues"
}, },
"bundleDependencies": false,
"dependencies": { "dependencies": {
"@actions/core": "^1.0.0", "@actions/core": "^1.0.0",
"@actions/exec": "^1.0.0", "@actions/exec": "^1.0.0",
@@ -39,6 +35,7 @@
"typed-rest-client": "^1.4.0", "typed-rest-client": "^1.4.0",
"uuid": "^3.3.2" "uuid": "^3.3.2"
}, },
"deprecated": false,
"description": "Actions tool-cache lib", "description": "Actions tool-cache lib",
"devDependencies": { "devDependencies": {
"@types/nock": "^10.0.3", "@types/nock": "^10.0.3",
@@ -54,7 +51,6 @@
"lib", "lib",
"scripts" "scripts"
], ],
"gitHead": "a40bce7c8d382aa3dbadaa327acbc696e9390e55",
"homepage": "https://github.com/actions/toolkit/tree/master/packages/exec", "homepage": "https://github.com/actions/toolkit/tree/master/packages/exec",
"keywords": [ "keywords": [
"exec", "exec",
@@ -74,5 +70,5 @@
"test": "echo \"Error: run tests from root\" && exit 1", "test": "echo \"Error: run tests from root\" && exit 1",
"tsc": "tsc" "tsc": "tsc"
}, },
"version": "1.0.0" "version": "1.1.0"
} }

25
node_modules/semver/package.json generated vendored
View File

@@ -1,39 +1,38 @@
{ {
"_args": [ "_from": "semver",
[
"semver@6.3.0",
"/Users/subosito/Code/playground/flutter-actions"
]
],
"_from": "semver@6.3.0",
"_id": "semver@6.3.0", "_id": "semver@6.3.0",
"_inBundle": false, "_inBundle": false,
"_integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "_integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"_location": "/semver", "_location": "/semver",
"_phantomChildren": {}, "_phantomChildren": {},
"_requested": { "_requested": {
"type": "version", "type": "tag",
"registry": true, "registry": true,
"raw": "semver@6.3.0", "raw": "semver",
"name": "semver", "name": "semver",
"escapedName": "semver", "escapedName": "semver",
"rawSpec": "6.3.0", "rawSpec": "",
"saveSpec": null, "saveSpec": null,
"fetchSpec": "6.3.0" "fetchSpec": "latest"
}, },
"_requiredBy": [ "_requiredBy": [
"#USER",
"/",
"/@actions/tool-cache", "/@actions/tool-cache",
"/istanbul-lib-instrument" "/istanbul-lib-instrument"
], ],
"_resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "_resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"_spec": "6.3.0", "_shasum": "ee0a64c8af5e8ceea67687b133761e1becbd1d3d",
"_where": "/Users/subosito/Code/playground/flutter-actions", "_spec": "semver",
"_where": "/Users/subosito/Code/subosito/flutter-action",
"bin": { "bin": {
"semver": "./bin/semver.js" "semver": "./bin/semver.js"
}, },
"bugs": { "bugs": {
"url": "https://github.com/npm/node-semver/issues" "url": "https://github.com/npm/node-semver/issues"
}, },
"bundleDependencies": false,
"deprecated": false,
"description": "The semantic version parser used by npm.", "description": "The semantic version parser used by npm.",
"devDependencies": { "devDependencies": {
"tap": "^14.3.1" "tap": "^14.3.1"

122
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{ {
"name": "flutter-action", "name": "flutter-action",
"version": "1.0.2", "version": "1.1.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@@ -20,9 +20,9 @@
"integrity": "sha512-ezrJSRdqtXtdx1WXlfYL85+40F7gB39jCK9P0jZVODW3W6xUYmu6ZOEc/UmmElUwhRyDRm1R4yNZu1Joq2kuQg==" "integrity": "sha512-ezrJSRdqtXtdx1WXlfYL85+40F7gB39jCK9P0jZVODW3W6xUYmu6ZOEc/UmmElUwhRyDRm1R4yNZu1Joq2kuQg=="
}, },
"@actions/tool-cache": { "@actions/tool-cache": {
"version": "1.0.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-1.0.0.tgz", "resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-1.1.0.tgz",
"integrity": "sha512-l3zT0IfDfi5Ik5aMpnXqGHGATxN8xa9ls4ue+X/CBXpPhRMRZS4vcuh5Q9T98WAGbkysRCfhpbksTPHIcKnNwQ==", "integrity": "sha512-Oe/R1Gxv0G699OUL9ypxk9cTwHf1uXHhpcK7kpZt8d/Sbw915ktMkfxXt9+awOfLDwyl54sLi86KGCuSvnRuIQ==",
"requires": { "requires": {
"@actions/core": "^1.0.0", "@actions/core": "^1.0.0",
"@actions/exec": "^1.0.0", "@actions/exec": "^1.0.0",
@@ -530,6 +530,15 @@
"integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==", "integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==",
"dev": true "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": { "@types/node": {
"version": "12.6.8", "version": "12.6.8",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz",
@@ -702,6 +711,12 @@
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
"dev": true "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": { "assign-symbols": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
@@ -1052,6 +1067,20 @@
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
"dev": true "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": { "chalk": {
"version": "2.4.2", "version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -1063,6 +1092,12 @@
"supports-color": "^5.3.0" "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": { "ci-info": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
@@ -1308,6 +1343,21 @@
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
"dev": true "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": { "deep-is": {
"version": "0.1.3", "version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
@@ -2321,6 +2371,12 @@
"integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
"dev": true "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": { "get-stdin": {
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz",
@@ -3817,6 +3873,46 @@
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true "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": { "node-int64": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@@ -4149,6 +4245,12 @@
"pify": "^3.0.0" "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": { "performance-now": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -4240,6 +4342,12 @@
"sisteransi": "^1.0.0" "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": { "psl": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz", "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz",
@@ -5177,6 +5285,12 @@
"prelude-ls": "~1.1.2" "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": { "type-fest": {
"version": "0.6.0", "version": "0.6.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",

View File

@@ -1,6 +1,6 @@
{ {
"name": "flutter-action", "name": "flutter-action",
"version": "1.0.2", "version": "1.1.1",
"private": true, "private": true,
"description": "Flutter environment for use in actions", "description": "Flutter environment for use in actions",
"main": "lib/index.js", "main": "lib/index.js",
@@ -26,17 +26,20 @@
"@actions/core": "^1.0.0", "@actions/core": "^1.0.0",
"@actions/exec": "^1.0.0", "@actions/exec": "^1.0.0",
"@actions/io": "^1.0.0", "@actions/io": "^1.0.0",
"@actions/tool-cache": "^1.0.0", "@actions/tool-cache": "^1.1.0",
"semver": "^6.3.0",
"uuid": "^3.3.2" "uuid": "^3.3.2"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^24.0.13", "@types/jest": "^24.0.13",
"@types/nock": "^10.0.3",
"@types/node": "^12.0.4", "@types/node": "^12.0.4",
"@types/semver": "^6.0.0", "@types/semver": "^6.0.1",
"@types/uuid": "^3.4.5", "@types/uuid": "^3.4.5",
"husky": "^3.0.0", "husky": "^3.0.0",
"jest": "^24.8.0", "jest": "^24.8.0",
"jest-circus": "^24.7.1", "jest-circus": "^24.7.1",
"nock": "^10.0.6",
"prettier": "^1.17.1", "prettier": "^1.17.1",
"ts-jest": "^24.0.2", "ts-jest": "^24.0.2",
"typescript": "^3.5.1" "typescript": "^3.5.1"

View File

@@ -3,8 +3,9 @@ import * as installer from './installer';
async function run() { async function run() {
try { try {
const version = core.getInput('version', {required: true}); const version =
const channel = core.getInput('channel', {required: false}) || 'stable'; core.getInput('version') || core.getInput('flutter-version') || '';
const channel = core.getInput('channel') || 'stable';
await installer.getFlutter(version, channel); await installer.getFlutter(version, channel);
} catch (error) { } catch (error) {

View File

@@ -3,13 +3,15 @@ import * as io from '@actions/io';
import * as tc from '@actions/tool-cache'; import * as tc from '@actions/tool-cache';
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import uuidV4 from 'uuid/v4'; import * as restm from 'typed-rest-client/RestClient';
import {exec} from '@actions/exec/lib/exec'; import * as semver from 'semver';
const IS_WINDOWS = process.platform === 'win32'; const IS_WINDOWS = process.platform === 'win32';
const IS_DARWIN = process.platform === 'darwin'; const IS_DARWIN = process.platform === 'darwin';
const IS_LINUX = process.platform === 'linux'; const IS_LINUX = process.platform === 'linux';
const storageUrl = 'https://storage.googleapis.com/flutter_infra/releases';
let tempDirectory = process.env['RUNNER_TEMP'] || ''; let tempDirectory = process.env['RUNNER_TEMP'] || '';
if (!tempDirectory) { if (!tempDirectory) {
@@ -32,9 +34,15 @@ export async function getFlutter(
version: string, version: string,
channel: string channel: string
): Promise<void> { ): Promise<void> {
// make semver compatible, eg: 1.7.8+hotfix.4 -> 1.7.8-hotfix.4 const versionPart = version.split('.');
const semver = version.replace('+', '-');
const cleanver = `${semver}-${channel}`; 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); let toolPath = tc.find('flutter', cleanver);
if (toolPath) { if (toolPath) {
@@ -75,7 +83,7 @@ function getDownloadInfo(
): {version: string; url: string} { ): {version: string; url: string} {
const os = osName(); const os = osName();
const ext = extName(); 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 { return {
version, version,
@@ -120,54 +128,84 @@ async function extractFile(file: string, destDir: string): Promise<void> {
} }
if ('tar.xz' === extName()) { if ('tar.xz' === extName()) {
await extractTarXz(file, destDir); await tc.extractTar(file, destDir, 'x');
} else {
if (IS_DARWIN) {
await extractZipDarwin(file, destDir);
} else { } else {
await tc.extractZip(file, destDir); await tc.extractZip(file, destDir);
} }
} }
}
/** async function determineVersion(
* Extract a tar.xz version: string,
* channel: string
* @param file path to the tar.xz
* @param dest destination directory. Optional.
* @returns path to the destination directory
*/
export async function extractTarXz(
file: string,
dest?: string
): Promise<string> { ): Promise<string> {
if (!file) { if (version.endsWith('.x') || version === '') {
throw new Error("parameter 'file' is required"); return await getLatestVersion(version, channel);
} }
dest = dest || (await _createExtractFolder(dest)); return version;
const tarPath: string = await io.which('tar', true);
await exec(`"${tarPath}"`, ['xC', dest, '-f', file]);
return dest;
} }
async function _createExtractFolder(dest?: string): Promise<string> { interface IFlutterChannel {
if (!dest) { [key: string]: string;
dest = path.join(tempDirectory, uuidV4()); beta: string;
dev: string;
stable: string;
} }
await io.mkdirP(dest); interface IFlutterRelease {
return dest; hash: string;
channel: string;
version: string;
} }
async function extractZipDarwin(file: string, dest: string): Promise<void> { interface IFlutterStorage {
const unzipPath = path.join( current_release: IFlutterChannel;
__dirname, releases: IFlutterRelease[];
'..', }
'scripts',
'externals', async function getLatestVersion(
'unzip-darwin' version: string,
channel: string
): Promise<string> {
const releasesUrl: string = `${storageUrl}/releases_${osName()}.json`;
const rest: restm.RestClient = new restm.RestClient('flutter-action');
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
); );
await exec(`"${unzipPath}"`, [file], {cwd: dest}); 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;
} }