From 39e54cc1e65f7e15f15d7436358728c8313ad635 Mon Sep 17 00:00:00 2001 From: Alif Rachmawadi Date: Fri, 16 Aug 2019 18:30:17 +0700 Subject: [PATCH] get latest release automatically --- lib/index.js | 2 +- lib/installer.js | 35 +++++++++++++++++++++--- src/index.ts | 2 +- src/installer.ts | 69 +++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 98 insertions(+), 10 deletions(-) diff --git a/lib/index.js b/lib/index.js index a4237f1..ba1d644 100644 --- a/lib/index.js +++ b/lib/index.js @@ -20,7 +20,7 @@ const installer = __importStar(require("./installer")); function run() { return __awaiter(this, void 0, void 0, function* () { try { - const version = core.getInput('version', { required: true }); + const version = core.getInput('version', { required: false }) || ''; const channel = core.getInput('channel', { required: false }) || 'stable'; yield installer.getFlutter(version, channel); } diff --git a/lib/installer.js b/lib/installer.js index c97322f..b8ad76e 100644 --- a/lib/installer.js +++ b/lib/installer.js @@ -23,11 +23,13 @@ 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 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,9 +48,8 @@ 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}`; + 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}`); @@ -82,7 +83,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 +163,29 @@ 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'); + } + 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; + }); +} diff --git a/src/index.ts b/src/index.ts index 38b79f9..0e6c991 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ import * as installer from './installer'; async function run() { try { - const version = core.getInput('version', {required: true}); + const version = core.getInput('version', {required: false}) || ''; const channel = core.getInput('channel', {required: false}) || 'stable'; await installer.getFlutter(version, channel); diff --git a/src/installer.ts b/src/installer.ts index aacbd59..286bf7c 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -3,6 +3,7 @@ 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 uuidV4 from 'uuid/v4'; import {exec} from '@actions/exec/lib/exec'; @@ -10,6 +11,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,9 +35,9 @@ export async function getFlutter( version: string, channel: string ): Promise { - // make semver compatible, eg: 1.7.8+hotfix.4 -> 1.7.8-hotfix.4 - const semver = version.replace('+', '-'); - const cleanver = `${semver}-${channel}`; + version = await determineVersion(version, channel); + + let cleanver = `${version.replace('+', '-')}-${channel}`; let toolPath = tc.find('flutter', cleanver); if (toolPath) { @@ -75,7 +78,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 +174,61 @@ async function extractZipDarwin(file: string, dest: string): Promise { ); await exec(`"${unzipPath}"`, [file], {cwd: dest}); } + +async function determineVersion( + version: string, + channel: string +): Promise { + 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 { + const releasesUrl: string = `${storageUrl}/releases_${osName()}.json`; + const rest: restm.RestClient = new restm.RestClient('setup-go'); + const storage: IFlutterStorage | null = (await rest.get( + releasesUrl + )).result; + + if (!storage) { + throw new Error('unable to get latest version'); + } + + 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; +}