diff --git a/action.yml b/action.yml index 4a32e12ba..17053a915 100644 --- a/action.yml +++ b/action.yml @@ -1,9 +1,11 @@ name: 'Setup Go environment' description: 'Setup a Go environment and add it to the PATH' author: 'GitHub' -inputs: +inputs: go-version: description: 'The Go version to download (if necessary) and use. Supports semver spec and ranges.' + version-resolver: + description: 'Version inventory for resolving semver ranges before checking tool cache. Use "manifest" for @actions/go-versions, or "dist" for golang.org/dl' stable: description: 'Whether to download only stable versions' default: 'true' diff --git a/dist/index.js b/dist/index.js index 8c713fa66..9be4fe37e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1440,7 +1440,21 @@ function run() { if (versionSpec) { let token = core.getInput('token'); let auth = !token || isGhes() ? undefined : `token ${token}`; - const installDir = yield installer.getGo(versionSpec, stable, auth); + // Tool cache can be stale in GitHub and self-hosted runners. If supplied + // `go-version` is a semver range--instead of an explicit version--it will + // be tried through the version inventory in cache, first. Even though + // the GitHub local copy or origin distribution may have newer versions + // matching the passed range, as long as the cache can satisfy the range, + // the latest version from cache will be used. + // + // Allow passing a prefered version inventory for resolving versionSpec. + // - "manifest": GitHub hosted (@actions/go-versions) + // - "dist": Origin (https://golang.org/dl/?mode=json&include=all) + let resolver = core.getInput('version-resolver'); + if (resolver && resolver != 'manifest' && resolver != 'dist') { + throw new Error(`Unknown version-resolver: '${resolver}'`); + } + const installDir = yield installer.getGo(versionSpec, resolver, stable, auth); core.exportVariable('GOROOT', installDir); core.addPath(path_1.default.join(installDir, 'bin')); core.info('Added go to the path'); @@ -4943,10 +4957,23 @@ const semver = __importStar(__webpack_require__(280)); const httpm = __importStar(__webpack_require__(539)); const sys = __importStar(__webpack_require__(737)); const os_1 = __importDefault(__webpack_require__(87)); -function getGo(versionSpec, stable, auth) { +function getGo(versionSpec, versionSpecResolver, stable, auth) { return __awaiter(this, void 0, void 0, function* () { - let osPlat = os_1.default.platform(); - let osArch = os_1.default.arch(); + let versionInfo = null; + if (versionSpecResolver) { + core.info(`Resolving versionSpec '${versionSpec}' from '${versionSpecResolver}'`); + switch (versionSpecResolver) { + case 'manifest': + versionInfo = yield getInfoFromManifest(versionSpec, stable, auth); + break; + case 'dist': + versionInfo = yield getInfoFromDist(versionSpec, stable); + break; + } + } + if (versionInfo && versionInfo.resolvedVersion.length > 0) { + versionSpec = versionInfo.resolvedVersion; + } // check cache let toolPath; toolPath = tc.find('go', versionSpec); @@ -4962,7 +4989,7 @@ function getGo(versionSpec, stable, auth) { // Try download from internal distribution (popular versions only) // try { - info = yield getInfoFromManifest(versionSpec, stable, auth); + info = versionInfo !== null && versionInfo !== void 0 ? versionInfo : (yield getInfoFromManifest(versionSpec, stable, auth)); if (info) { downloadPath = yield installGoVersion(info, auth); } @@ -4985,8 +5012,10 @@ function getGo(versionSpec, stable, auth) { // Download from storage.googleapis.com // if (!downloadPath) { - info = yield getInfoFromDist(versionSpec, stable); + info = versionInfo !== null && versionInfo !== void 0 ? versionInfo : (yield getInfoFromDist(versionSpec, stable)); if (!info) { + let osPlat = os_1.default.platform(); + let osArch = os_1.default.arch(); throw new Error(`Unable to find Go version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.`); } try { diff --git a/src/installer.ts b/src/installer.ts index 0e0d5d399..d229015e5 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -5,6 +5,7 @@ import * as semver from 'semver'; import * as httpm from '@actions/http-client'; import * as sys from './system'; import os from 'os'; +import {version} from 'process'; type InstallationType = 'dist' | 'manifest'; @@ -30,11 +31,29 @@ export interface IGoVersionInfo { export async function getGo( versionSpec: string, + versionSpecResolver: string | undefined, stable: boolean, auth: string | undefined -) { - let osPlat: string = os.platform(); - let osArch: string = os.arch(); +): Promise { + let versionInfo: IGoVersionInfo | null = null; + + if (versionSpecResolver) { + core.info( + `Resolving versionSpec '${versionSpec}' from '${versionSpecResolver}'` + ); + switch (versionSpecResolver) { + case 'manifest': + versionInfo = await getInfoFromManifest(versionSpec, stable, auth); + break; + case 'dist': + versionInfo = await getInfoFromDist(versionSpec, stable); + break; + } + } + + if (versionInfo && versionInfo.resolvedVersion.length > 0) { + versionSpec = versionInfo.resolvedVersion; + } // check cache let toolPath: string; @@ -52,7 +71,8 @@ export async function getGo( // Try download from internal distribution (popular versions only) // try { - info = await getInfoFromManifest(versionSpec, stable, auth); + info = + versionInfo ?? (await getInfoFromManifest(versionSpec, stable, auth)); if (info) { downloadPath = await installGoVersion(info, auth); } else { @@ -79,8 +99,10 @@ export async function getGo( // Download from storage.googleapis.com // if (!downloadPath) { - info = await getInfoFromDist(versionSpec, stable); + info = versionInfo ?? (await getInfoFromDist(versionSpec, stable)); if (!info) { + let osPlat: string = os.platform(); + let osArch: string = os.arch(); throw new Error( `Unable to find Go version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.` ); diff --git a/src/main.ts b/src/main.ts index 2d90b2fe7..616209cbf 100644 --- a/src/main.ts +++ b/src/main.ts @@ -24,7 +24,27 @@ export async function run() { let token = core.getInput('token'); let auth = !token || isGhes() ? undefined : `token ${token}`; - const installDir = await installer.getGo(versionSpec, stable, auth); + // Tool cache can be stale in GitHub and self-hosted runners. If supplied + // `go-version` is a semver range--instead of an explicit version--it will + // be tried through the version inventory in cache, first. Even though + // the GitHub local copy or origin distribution may have newer versions + // matching the passed range, as long as the cache can satisfy the range, + // the latest version from cache will be used. + // + // Allow passing a prefered version inventory for resolving versionSpec. + // - "manifest": GitHub hosted (@actions/go-versions) + // - "dist": Origin (https://golang.org/dl/?mode=json&include=all) + let resolver = core.getInput('version-resolver'); + if (resolver && resolver != 'manifest' && resolver != 'dist') { + throw new Error(`Unknown version-resolver: '${resolver}'`); + } + + const installDir = await installer.getGo( + versionSpec, + resolver, + stable, + auth + ); core.exportVariable('GOROOT', installDir); core.addPath(path.join(installDir, 'bin'));