setup-go/src/main.ts

113 lines
3.5 KiB
TypeScript
Raw Normal View History

2020-02-09 00:21:39 -05:00
import * as core from '@actions/core';
2020-03-26 12:40:41 -04:00
import * as io from '@actions/io';
2020-02-09 00:21:39 -05:00
import * as installer from './installer';
2020-03-27 00:55:12 -04:00
import path from 'path';
import cp from 'child_process';
import fs from 'fs';
import {URL} from 'url';
2020-02-09 00:21:39 -05:00
export async function run() {
try {
//
// versionSpec is optional. If supplied, install / use from the tool cache
// If not supplied then problem matchers will still be setup. Useful for self-hosted.
//
let versionSpec = core.getInput('go-version');
2020-02-09 08:47:38 -05:00
2020-02-09 08:44:32 -05:00
// stable will be true unless false is the exact input
// since getting unstable versions should be explicit
2020-02-10 15:21:04 -05:00
let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
2020-02-09 00:21:39 -05:00
core.info(`Setup go ${stable ? 'stable' : ''} version spec ${versionSpec}`);
2020-02-09 22:39:44 -05:00
2020-02-09 00:21:39 -05:00
if (versionSpec) {
let token = core.getInput('token');
let auth = !token || isGhes() ? undefined : `token ${token}`;
2020-02-09 00:21:39 -05:00
Add `version-resolver` input 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. Introduce an optional input, `version-resolver`. If defined, it tries to resolve the version spec against either GitHub local copy or Go's canonical source of version manifest. If the value of `version-resolver` is: - "manifest": the manifest file under @actions/go-version get used. - "dist": the manifest at https://golang.org/dl/?mode=json&include=all gets used. It can take values Example: -------- - Latest Go Version: 1.15.2 - tool-cache has go1.15 (1.15.0), latest. build.yml: ``` [...] - uses: actions/setup-go@v2 with: go-version: '>=1.5 <2' [...] ``` Although the intention of the user might be to get latest version between "oldest Go 1.15.0, newest--not inclusive--Go 2.0", the cache will match this range with Go 1.15.0. build.yml (v2): ``` [...] - uses: actions/setup-go@v2 with: go-version: '>=1.5 <2' version-resolver: 'manifest' [...] ``` With supplied version resolver, the semver range will be checked against the local GitHub version manifest from @actions/go-versions[1], and match 1.15.2. Cache will be queried with the resolved version, instead of the range. When the cache gets updated globally, next runs will use the tool from the cache, instead of downloading locally or in case of resolver 'dist', directly from Google. [1]: https://raw.githubusercontent.com/actions/go-versions/main/versions-manifest.json Closes #73
2020-09-13 18:59:29 -07:00
// 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
);
2020-02-09 00:29:21 -05:00
core.exportVariable('GOROOT', installDir);
core.addPath(path.join(installDir, 'bin'));
core.info('Added go to the path');
2020-03-26 12:02:52 -04:00
let added = await addBinToPath();
core.debug(`add bin ${added}`);
core.info(`Successfully setup go version ${versionSpec}`);
2020-02-09 00:21:39 -05:00
}
// add problem matchers
const matchersPath = path.join(__dirname, '..', 'matchers.json');
core.info(`##[add-matcher]${matchersPath}`);
2020-03-31 10:32:03 -04:00
// output the version actually being used
let goPath = await io.which('go');
2020-03-31 10:40:32 -04:00
let goVersion = (cp.execSync(`${goPath} version`) || '').toString();
core.info(goVersion);
2020-04-06 08:42:55 -04:00
core.startGroup('go env');
let goEnv = (cp.execSync(`${goPath} env`) || '').toString();
core.info(goEnv);
2020-04-06 08:42:55 -04:00
core.endGroup();
2020-02-09 00:21:39 -05:00
} catch (error) {
core.setFailed(error.message);
}
2020-02-09 00:29:21 -05:00
}
2020-03-26 12:02:52 -04:00
2020-03-27 00:55:12 -04:00
export async function addBinToPath(): Promise<boolean> {
2020-03-26 12:02:52 -04:00
let added = false;
2020-03-26 12:40:41 -04:00
let g = await io.which('go');
core.debug(`which go :${g}:`);
2020-03-26 12:40:41 -04:00
if (!g) {
core.debug('go not in the path');
2020-03-26 12:40:41 -04:00
return added;
}
2020-03-26 12:17:32 -04:00
2020-03-26 12:40:41 -04:00
let buf = cp.execSync('go env GOPATH');
2020-03-26 12:02:52 -04:00
if (buf) {
2020-03-26 12:40:41 -04:00
let gp = buf.toString().trim();
core.debug(`go env GOPATH :${gp}:`);
if (!fs.existsSync(gp)) {
// some of the hosted images have go install but not profile dir
core.debug(`creating ${gp}`);
io.mkdirP(gp);
}
2020-03-26 12:23:38 -04:00
let bp = path.join(gp, 'bin');
if (!fs.existsSync(bp)) {
core.debug(`creating ${bp}`);
io.mkdirP(bp);
2020-03-26 12:54:21 -04:00
}
core.addPath(bp);
added = true;
2020-03-26 12:02:52 -04:00
}
return added;
}
2020-03-27 00:55:12 -04:00
function isGhes(): boolean {
const ghUrl = new URL(
process.env['GITHUB_SERVER_URL'] || 'https://github.com'
);
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
2020-03-27 00:55:12 -04:00
}