diff --git a/lib/installer.js b/lib/installer.js index 4829000..6c44c91 100644 --- a/lib/installer.js +++ b/lib/installer.js @@ -22,6 +22,8 @@ const tc = __importStar(require("@actions/tool-cache")); const os = __importStar(require("os")); const path = __importStar(require("path")); const util = __importStar(require("util")); +const semver = __importStar(require("semver")); +const httpm = __importStar(require("typed-rest-client/HttpClient")); let osPlat = os.platform(); let osArch = os.arch(); if (!tempDirectory) { @@ -42,6 +44,7 @@ if (!tempDirectory) { } function getGo(version) { return __awaiter(this, void 0, void 0, function* () { + version = yield determineVersion(version); // check cache let toolPath; toolPath = tc.find('go', normalizeVersion(version)); @@ -127,8 +130,59 @@ function normalizeVersion(version) { return version.concat('.0.0'); } else if (versionPart[2] == null) { + // handle beta and rc: 1.10beta1 => 1.10.0-beta1, 1.10rc1 => 1.10.0-rc1 + if (versionPart[1].includes('beta') || versionPart[1].includes('rc')) { + versionPart[1] = versionPart[1] + .replace('beta', '.0-beta') + .replace('rc', '.0-rc'); + return versionPart.join('.'); + } //append patch version if not available return version.concat('.0'); } return version; } +function determineVersion(version) { + return __awaiter(this, void 0, void 0, function* () { + if (!version.endsWith('.x')) { + return version; + } + return yield getLatestVersion(version); + }); +} +function getLatestVersion(version) { + return __awaiter(this, void 0, void 0, function* () { + // clean .x syntax: 1.10.x -> 1.10 + const trimmedVersion = version.slice(0, version.length - 2); + const versions = yield getPossibleVersions(trimmedVersion); + if (version.length === 0) { + return trimmedVersion; + } + return versions[0]; + }); +} +function unique(value, index, self) { + return self.indexOf(value) === index; +} +function getAvailableVersions() { + return __awaiter(this, void 0, void 0, function* () { + let http = new httpm.HttpClient('setup-java'); + let contents = yield (yield http.get('https://api.github.com/repos/golang/go/git/refs/tags')).readBody(); + const matches = contents.match(/go\d+\.[\w\.]+/g) || []; + const versions = matches + .map(version => version.replace('go', '')) + .filter(unique); + return versions; + }); +} +function getPossibleVersions(version) { + return __awaiter(this, void 0, void 0, function* () { + const versions = yield getAvailableVersions(); + const possibleVersions = versions.filter(v => v.startsWith(version)); + const versionMap = new Map(); + possibleVersions.forEach(v => versionMap.set(normalizeVersion(v), v)); + return Array.from(versionMap.keys()) + .sort(semver.rcompare) + .map(v => versionMap.get(v)); + }); +} diff --git a/src/installer.ts b/src/installer.ts index cb33548..857e93f 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -5,6 +5,8 @@ import * as tc from '@actions/tool-cache'; import * as os from 'os'; import * as path from 'path'; import * as util from 'util'; +import * as semver from 'semver'; +import * as httpm from 'typed-rest-client/HttpClient'; let osPlat: string = os.platform(); let osArch: string = os.arch(); @@ -25,6 +27,8 @@ if (!tempDirectory) { } export async function getGo(version: string) { + version = await determineVersion(version); + // check cache let toolPath: string; toolPath = tc.find('go', normalizeVersion(version)); @@ -123,8 +127,67 @@ function normalizeVersion(version: string): string { //append minor and patch version if not available return version.concat('.0.0'); } else if (versionPart[2] == null) { + // handle beta and rc: 1.10beta1 => 1.10.0-beta1, 1.10rc1 => 1.10.0-rc1 + if (versionPart[1].includes('beta') || versionPart[1].includes('rc')) { + versionPart[1] = versionPart[1] + .replace('beta', '.0-beta') + .replace('rc', '.0-rc'); + return versionPart.join('.'); + } + //append patch version if not available return version.concat('.0'); } return version; } + +async function determineVersion(version: string): Promise { + if (!version.endsWith('.x')) { + return version; + } + + return await getLatestVersion(version); +} + +async function getLatestVersion(version: string): Promise { + // clean .x syntax: 1.10.x -> 1.10 + const trimmedVersion = version.slice(0, version.length - 2); + + const versions = await getPossibleVersions(trimmedVersion); + + if (version.length === 0) { + return trimmedVersion; + } + + return versions[0]; +} + +function unique(value: string, index: number, self: string[]) { + return self.indexOf(value) === index; +} + +async function getAvailableVersions(): Promise { + let http: httpm.HttpClient = new httpm.HttpClient('setup-java'); + let contents = await (await http.get( + 'https://api.github.com/repos/golang/go/git/refs/tags' + )).readBody(); + + const matches = contents.match(/go\d+\.[\w\.]+/g) || []; + const versions = matches + .map(version => version.replace('go', '')) + .filter(unique); + + return versions; +} + +async function getPossibleVersions(version: string): Promise { + const versions = await getAvailableVersions(); + const possibleVersions = versions.filter(v => v.startsWith(version)); + + const versionMap = new Map(); + possibleVersions.forEach(v => versionMap.set(normalizeVersion(v), v)); + + return Array.from(versionMap.keys()) + .sort(semver.rcompare) + .map(v => versionMap.get(v)); +}