mirror of
https://github.com/actions/setup-go.git
synced 2025-09-02 20:57:28 +08:00
Improve toolchain handling (#460)
* Configure environment to avoid toolchain installs
Force `go` to always use the local toolchain (i.e. the one the one that
shipped with the go command being run) via setting the `GOTOOLCHAIN`
environment variable to `local`[1]:
> When GOTOOLCHAIN is set to local, the go command always runs the
bundled Go toolchain.
This is how things are setup in the official Docker images (e.g.[2], see
also the discussion around that change[3]). The motivation behind this
is to:
* Reduce duplicate work: if the `toolchain` version in `go.mod` was
greated than the `go` version, the version from the `go` directive
would be installed, then Go would detect the `toolchain` version and
additionally install that
* Avoid Unexpected behaviour: if you specify this action runs with some Go
version (e.g. `1.21.0`) but your go.mod contains a `toolchain` or `go`
directive for a newer version (e.g. `1.22.0`) then, without any other
configuration/environment setup, any go commands will be run using go
`1.22.0`
This will be a **breaking change** for some workflows. Given a `go.mod`
like:
module proj
go 1.22.0
Then running any `go` command, e.g. `go mod tidy`, in an environment
where only go versions before `1.22.0` were installed would previously
trigger a toolchain download of Go `1.22.0` and that version being used
to execute the command. With this change the above would error out with
something like:
> go: go.mod requires go >= 1.22.0 (running go 1.21.7;
GOTOOLCHAIN=local)
[1] https://go.dev/doc/toolchain#select
[2] dae3405a32/Dockerfile-linux.template (L163)
[3] https://github.com/docker-library/golang/issues/472
* Prefer installing version from `toolchain` directive
Prefer this over the version from the `go` directive. Per the docs[1]
> The toolchain line declares a suggested toolchain to use with the
module or workspace
It seems reasonable to use this, since running this action in a
directory containing a `go.mod` (or `go.work`) suggests the user is
wishing to work _with the module or workspace_.
Link: https://go.dev/doc/toolchain#config [1]
Issue: https://github.com/actions/setup-go/issues/457
* squash! Configure environment to avoid toolchain installs
Only modify env if `GOTOOLCHAIN` is not set
* squash! Prefer installing version from `toolchain` directive
Avoid installing from `toolchain` if `GOTOOLCHAIN` is `local`, also
better regex for matching toolchain directive
This commit is contained in:
31
dist/setup/index.js
vendored
31
dist/setup/index.js
vendored
@@ -94312,6 +94312,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.GOTOOLCHAIN_LOCAL_VAL = exports.GOTOOLCHAIN_ENV_VAR = void 0;
|
||||
exports.getGo = getGo;
|
||||
exports.extractGoArchive = extractGoArchive;
|
||||
exports.getManifest = getManifest;
|
||||
@@ -94330,6 +94331,8 @@ const sys = __importStar(__nccwpck_require__(5632));
|
||||
const fs_1 = __importDefault(__nccwpck_require__(7147));
|
||||
const os_1 = __importDefault(__nccwpck_require__(2037));
|
||||
const utils_1 = __nccwpck_require__(1314);
|
||||
exports.GOTOOLCHAIN_ENV_VAR = 'GOTOOLCHAIN';
|
||||
exports.GOTOOLCHAIN_LOCAL_VAL = 'local';
|
||||
const MANIFEST_REPO_OWNER = 'actions';
|
||||
const MANIFEST_REPO_NAME = 'go-versions';
|
||||
const MANIFEST_REPO_BRANCH = 'main';
|
||||
@@ -94663,8 +94666,18 @@ function parseGoVersionFile(versionFilePath) {
|
||||
const contents = fs_1.default.readFileSync(versionFilePath).toString();
|
||||
if (path.basename(versionFilePath) === 'go.mod' ||
|
||||
path.basename(versionFilePath) === 'go.work') {
|
||||
const match = contents.match(/^go (\d+(\.\d+)*)/m);
|
||||
return match ? match[1] : '';
|
||||
// for backwards compatibility: use version from go directive if
|
||||
// 'GOTOOLCHAIN' has been explicitly set
|
||||
if (process.env[exports.GOTOOLCHAIN_ENV_VAR] !== exports.GOTOOLCHAIN_LOCAL_VAL) {
|
||||
// toolchain directive: https://go.dev/ref/mod#go-mod-file-toolchain
|
||||
const matchToolchain = contents.match(/^toolchain go(1\.\d+(?:\.\d+|rc\d+)?)/m);
|
||||
if (matchToolchain) {
|
||||
return matchToolchain[1];
|
||||
}
|
||||
}
|
||||
// go directive: https://go.dev/ref/mod#go-mod-file-go
|
||||
const matchGo = contents.match(/^go (\d+(\.\d+)*)/m);
|
||||
return matchGo ? matchGo[1] : '';
|
||||
}
|
||||
return contents.trim();
|
||||
}
|
||||
@@ -94782,6 +94795,7 @@ function run() {
|
||||
// If not supplied then problem matchers will still be setup. Useful for self-hosted.
|
||||
//
|
||||
const versionSpec = resolveVersionInput();
|
||||
setGoToolchain();
|
||||
const cache = core.getBooleanInput('cache');
|
||||
core.info(`Setup go version spec ${versionSpec}`);
|
||||
let arch = core.getInput('architecture');
|
||||
@@ -94890,6 +94904,19 @@ function resolveVersionInput() {
|
||||
}
|
||||
return version;
|
||||
}
|
||||
function setGoToolchain() {
|
||||
// docs: https://go.dev/doc/toolchain
|
||||
// "local indicates the bundled Go toolchain (the one that shipped with the go command being run)"
|
||||
// this is so any 'go' command is run with the selected Go version
|
||||
// and doesn't trigger a toolchain download and run commands with that
|
||||
// see e.g. issue #424
|
||||
// and a similar discussion: https://github.com/docker-library/golang/issues/472.
|
||||
// Set the value in process env so any `go` commands run as child-process
|
||||
// don't cause toolchain downloads
|
||||
process.env[installer.GOTOOLCHAIN_ENV_VAR] = installer.GOTOOLCHAIN_LOCAL_VAL;
|
||||
// and in the runner env so e.g. a user running `go mod tidy` won't cause it
|
||||
core.exportVariable(installer.GOTOOLCHAIN_ENV_VAR, installer.GOTOOLCHAIN_LOCAL_VAL);
|
||||
}
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
Reference in New Issue
Block a user