mirror of
https://github.com/actions/setup-go.git
synced 2026-03-16 18:15:19 +00:00
feat: add go-download-base-url input for custom Go distributions (#721)
Some checks failed
Validate Microsoft build of Go / Microsoft build of Go 1.24 on macos-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go 1.24 on windows-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go 1.25 on macos-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go 1.25 on windows-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go via env var on macos-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go via env var on windows-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go arch arm64 on macos-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go arch x64 on macos-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go with caching on macos-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go with caching on windows-latest (push) Waiting to run
Validate 'setup-go' / stable (macos-latest) (push) Waiting to run
Validate 'setup-go' / stable (macos-latest-large) (push) Waiting to run
Validate 'setup-go' / stable (windows-latest) (push) Waiting to run
Validate 'setup-go' / oldstable (macos-latest) (push) Waiting to run
Validate 'setup-go' / oldstable (macos-latest-large) (push) Waiting to run
Validate 'setup-go' / oldstable (windows-latest) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x32, windows-latest, oldstable) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x32, windows-latest, stable) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x64, macos-latest, oldstable) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x64, macos-latest, stable) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x64, macos-latest-large, oldstable) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x64, macos-latest-large, stable) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x64, windows-latest, oldstable) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x64, windows-latest, stable) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.20.14, windows-latest) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.21.13, macos-latest) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.21.13, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.21.13, windows-latest) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.22.8, macos-latest) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.22.8, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.22.8, windows-latest) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.23.2, macos-latest) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.23.2, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / check-latest (1.20, macos-latest) (push) Waiting to run
Validate 'setup-go' / check-latest (1.20, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / check-latest (1.20, windows-latest) (push) Waiting to run
Validate 'setup-go' / check-latest (1.21, macos-latest) (push) Waiting to run
Validate 'setup-go' / check-latest (1.21, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / check-latest (1.21, windows-latest) (push) Waiting to run
Validate 'setup-go' / check-latest (1.22, macos-latest) (push) Waiting to run
Validate 'setup-go' / check-latest (1.22, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / check-latest (1.22, windows-latest) (push) Waiting to run
Validate 'setup-go' / check-latest (1.23, macos-latest) (push) Waiting to run
Validate 'setup-go' / check-latest (1.23, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / check-latest (1.23, windows-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file (macos-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file (macos-latest-large) (push) Waiting to run
Validate 'setup-go' / go-version-file (windows-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-gowork (macos-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-gowork (macos-latest-large) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-gowork (windows-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-tool-versions (macos-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-tool-versions (macos-latest-large) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-tool-versions (windows-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-go-version (macos-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-go-version (macos-latest-large) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-go-version (windows-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.20.14, macos-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.20.14, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.20.14, windows-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.21.10, macos-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.21.10, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.21.10, windows-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.22.8, macos-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.22.8, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.22.8, windows-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.23.2, macos-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.23.2, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.23.2, windows-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-dist (1.11.12, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-dist (1.11.12, windows-latest) (push) Waiting to run
Validate 'setup-go' / architecture (arm64, 1.20.14, macos-latest) (push) Waiting to run
Validate 'setup-go' / architecture (arm64, 1.21, macos-latest) (push) Waiting to run
Validate 'setup-go' / architecture (arm64, 1.22, macos-latest) (push) Waiting to run
Validate 'setup-go' / architecture (arm64, 1.23, macos-latest) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.20.14, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.20.14, windows-latest) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.21, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.21, windows-latest) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.22, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.22, windows-latest) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.23, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.23, windows-latest) (push) Waiting to run
Validate Windows installation / Validate if symlink is created (false, 1.20.1) (push) Waiting to run
Validate Windows installation / Validate if symlink is created (true, 1.20.1) (push) Waiting to run
Validate Windows installation / Find default go version (push) Waiting to run
Validate Windows installation / Validate if symlink is not created for default go (false) (push) Blocked by required conditions
Validate Windows installation / Validate if symlink is not created for default go (true) (push) Blocked by required conditions
Validate Windows installation / Validate if hostedtoolcache works as expected (false, 1.20.1) (push) Waiting to run
Basic validation / Basic validation (push) Failing after 37s
Validate Microsoft build of Go / Microsoft build of Go 1.24 on ubuntu-latest (push) Failing after 39s
Validate Microsoft build of Go / Microsoft build of Go 1.25 on ubuntu-latest (push) Failing after 40s
Validate Microsoft build of Go / Microsoft build of Go via env var on ubuntu-latest (push) Failing after 40s
Validate Microsoft build of Go / Microsoft build of Go arch x64 on ubuntu-latest (push) Failing after 40s
Validate Microsoft build of Go / Microsoft build of Go with caching on ubuntu-latest (push) Failing after 40s
Validate 'setup-go' / stable (ubuntu-latest) (push) Failing after 41s
Validate 'setup-go' / oldstable (ubuntu-latest) (push) Failing after 41s
Validate 'setup-go' / aliases-arch (x32, ubuntu-latest, oldstable) (push) Failing after 41s
Validate 'setup-go' / aliases-arch (x32, ubuntu-latest, stable) (push) Failing after 41s
Validate 'setup-go' / aliases-arch (x64, ubuntu-latest, oldstable) (push) Failing after 41s
Validate 'setup-go' / aliases-arch (x64, ubuntu-latest, stable) (push) Failing after 41s
Validate 'setup-go' / Setup local-cache version (1.21.13, ubuntu-latest) (push) Failing after 42s
Validate 'setup-go' / Setup local-cache version (1.22.8, ubuntu-latest) (push) Failing after 42s
Validate 'setup-go' / Setup local-cache version (1.23.2, ubuntu-latest) (push) Failing after 42s
Validate 'setup-go' / check-latest (1.20, ubuntu-latest) (push) Failing after 42s
Validate 'setup-go' / check-latest (1.21, ubuntu-latest) (push) Failing after 43s
Validate 'setup-go' / check-latest (1.22, ubuntu-latest) (push) Failing after 44s
Validate 'setup-go' / check-latest (1.23, ubuntu-latest) (push) Failing after 44s
Validate 'setup-go' / go-version-file (ubuntu-latest) (push) Failing after 44s
Validate 'setup-go' / go-version-file-with-gowork (ubuntu-latest) (push) Failing after 45s
Validate 'setup-go' / go-version-file-with-tool-versions (ubuntu-latest) (push) Failing after 46s
Validate 'setup-go' / go-version-file-with-go-version (ubuntu-latest) (push) Failing after 46s
Validate 'setup-go' / setup-versions-from-manifest (1.20.14, ubuntu-latest) (push) Failing after 46s
Validate 'setup-go' / setup-versions-from-manifest (1.21.10, ubuntu-latest) (push) Failing after 47s
Validate 'setup-go' / setup-versions-from-manifest (1.22.8, ubuntu-latest) (push) Failing after 48s
Validate 'setup-go' / setup-versions-from-manifest (1.23.2, ubuntu-latest) (push) Failing after 48s
Validate 'setup-go' / setup-versions-from-dist (1.11.12, ubuntu-latest) (push) Failing after 49s
Validate 'setup-go' / architecture (x64, 1.20.14, ubuntu-latest) (push) Failing after 49s
Check dist/ / Check dist/ (push) Failing after 1m20s
Validate 'setup-go' / architecture (x64, 1.21, ubuntu-latest) (push) Failing after 49s
CodeQL analysis / CodeQL analysis (push) Failing after 1m20s
Licensed / Licensed (push) Failing after 1m19s
Validate 'setup-go' / architecture (x64, 1.22, ubuntu-latest) (push) Failing after 49s
Validate 'setup-go' / architecture (x64, 1.23, ubuntu-latest) (push) Failing after 49s
Some checks failed
Validate Microsoft build of Go / Microsoft build of Go 1.24 on macos-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go 1.24 on windows-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go 1.25 on macos-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go 1.25 on windows-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go via env var on macos-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go via env var on windows-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go arch arm64 on macos-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go arch x64 on macos-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go with caching on macos-latest (push) Waiting to run
Validate Microsoft build of Go / Microsoft build of Go with caching on windows-latest (push) Waiting to run
Validate 'setup-go' / stable (macos-latest) (push) Waiting to run
Validate 'setup-go' / stable (macos-latest-large) (push) Waiting to run
Validate 'setup-go' / stable (windows-latest) (push) Waiting to run
Validate 'setup-go' / oldstable (macos-latest) (push) Waiting to run
Validate 'setup-go' / oldstable (macos-latest-large) (push) Waiting to run
Validate 'setup-go' / oldstable (windows-latest) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x32, windows-latest, oldstable) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x32, windows-latest, stable) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x64, macos-latest, oldstable) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x64, macos-latest, stable) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x64, macos-latest-large, oldstable) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x64, macos-latest-large, stable) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x64, windows-latest, oldstable) (push) Waiting to run
Validate 'setup-go' / aliases-arch (x64, windows-latest, stable) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.20.14, windows-latest) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.21.13, macos-latest) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.21.13, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.21.13, windows-latest) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.22.8, macos-latest) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.22.8, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.22.8, windows-latest) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.23.2, macos-latest) (push) Waiting to run
Validate 'setup-go' / Setup local-cache version (1.23.2, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / check-latest (1.20, macos-latest) (push) Waiting to run
Validate 'setup-go' / check-latest (1.20, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / check-latest (1.20, windows-latest) (push) Waiting to run
Validate 'setup-go' / check-latest (1.21, macos-latest) (push) Waiting to run
Validate 'setup-go' / check-latest (1.21, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / check-latest (1.21, windows-latest) (push) Waiting to run
Validate 'setup-go' / check-latest (1.22, macos-latest) (push) Waiting to run
Validate 'setup-go' / check-latest (1.22, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / check-latest (1.22, windows-latest) (push) Waiting to run
Validate 'setup-go' / check-latest (1.23, macos-latest) (push) Waiting to run
Validate 'setup-go' / check-latest (1.23, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / check-latest (1.23, windows-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file (macos-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file (macos-latest-large) (push) Waiting to run
Validate 'setup-go' / go-version-file (windows-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-gowork (macos-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-gowork (macos-latest-large) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-gowork (windows-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-tool-versions (macos-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-tool-versions (macos-latest-large) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-tool-versions (windows-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-go-version (macos-latest) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-go-version (macos-latest-large) (push) Waiting to run
Validate 'setup-go' / go-version-file-with-go-version (windows-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.20.14, macos-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.20.14, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.20.14, windows-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.21.10, macos-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.21.10, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.21.10, windows-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.22.8, macos-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.22.8, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.22.8, windows-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.23.2, macos-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.23.2, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-manifest (1.23.2, windows-latest) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-dist (1.11.12, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / setup-versions-from-dist (1.11.12, windows-latest) (push) Waiting to run
Validate 'setup-go' / architecture (arm64, 1.20.14, macos-latest) (push) Waiting to run
Validate 'setup-go' / architecture (arm64, 1.21, macos-latest) (push) Waiting to run
Validate 'setup-go' / architecture (arm64, 1.22, macos-latest) (push) Waiting to run
Validate 'setup-go' / architecture (arm64, 1.23, macos-latest) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.20.14, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.20.14, windows-latest) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.21, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.21, windows-latest) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.22, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.22, windows-latest) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.23, macos-latest-large) (push) Waiting to run
Validate 'setup-go' / architecture (x64, 1.23, windows-latest) (push) Waiting to run
Validate Windows installation / Validate if symlink is created (false, 1.20.1) (push) Waiting to run
Validate Windows installation / Validate if symlink is created (true, 1.20.1) (push) Waiting to run
Validate Windows installation / Find default go version (push) Waiting to run
Validate Windows installation / Validate if symlink is not created for default go (false) (push) Blocked by required conditions
Validate Windows installation / Validate if symlink is not created for default go (true) (push) Blocked by required conditions
Validate Windows installation / Validate if hostedtoolcache works as expected (false, 1.20.1) (push) Waiting to run
Basic validation / Basic validation (push) Failing after 37s
Validate Microsoft build of Go / Microsoft build of Go 1.24 on ubuntu-latest (push) Failing after 39s
Validate Microsoft build of Go / Microsoft build of Go 1.25 on ubuntu-latest (push) Failing after 40s
Validate Microsoft build of Go / Microsoft build of Go via env var on ubuntu-latest (push) Failing after 40s
Validate Microsoft build of Go / Microsoft build of Go arch x64 on ubuntu-latest (push) Failing after 40s
Validate Microsoft build of Go / Microsoft build of Go with caching on ubuntu-latest (push) Failing after 40s
Validate 'setup-go' / stable (ubuntu-latest) (push) Failing after 41s
Validate 'setup-go' / oldstable (ubuntu-latest) (push) Failing after 41s
Validate 'setup-go' / aliases-arch (x32, ubuntu-latest, oldstable) (push) Failing after 41s
Validate 'setup-go' / aliases-arch (x32, ubuntu-latest, stable) (push) Failing after 41s
Validate 'setup-go' / aliases-arch (x64, ubuntu-latest, oldstable) (push) Failing after 41s
Validate 'setup-go' / aliases-arch (x64, ubuntu-latest, stable) (push) Failing after 41s
Validate 'setup-go' / Setup local-cache version (1.21.13, ubuntu-latest) (push) Failing after 42s
Validate 'setup-go' / Setup local-cache version (1.22.8, ubuntu-latest) (push) Failing after 42s
Validate 'setup-go' / Setup local-cache version (1.23.2, ubuntu-latest) (push) Failing after 42s
Validate 'setup-go' / check-latest (1.20, ubuntu-latest) (push) Failing after 42s
Validate 'setup-go' / check-latest (1.21, ubuntu-latest) (push) Failing after 43s
Validate 'setup-go' / check-latest (1.22, ubuntu-latest) (push) Failing after 44s
Validate 'setup-go' / check-latest (1.23, ubuntu-latest) (push) Failing after 44s
Validate 'setup-go' / go-version-file (ubuntu-latest) (push) Failing after 44s
Validate 'setup-go' / go-version-file-with-gowork (ubuntu-latest) (push) Failing after 45s
Validate 'setup-go' / go-version-file-with-tool-versions (ubuntu-latest) (push) Failing after 46s
Validate 'setup-go' / go-version-file-with-go-version (ubuntu-latest) (push) Failing after 46s
Validate 'setup-go' / setup-versions-from-manifest (1.20.14, ubuntu-latest) (push) Failing after 46s
Validate 'setup-go' / setup-versions-from-manifest (1.21.10, ubuntu-latest) (push) Failing after 47s
Validate 'setup-go' / setup-versions-from-manifest (1.22.8, ubuntu-latest) (push) Failing after 48s
Validate 'setup-go' / setup-versions-from-manifest (1.23.2, ubuntu-latest) (push) Failing after 48s
Validate 'setup-go' / setup-versions-from-dist (1.11.12, ubuntu-latest) (push) Failing after 49s
Validate 'setup-go' / architecture (x64, 1.20.14, ubuntu-latest) (push) Failing after 49s
Check dist/ / Check dist/ (push) Failing after 1m20s
Validate 'setup-go' / architecture (x64, 1.21, ubuntu-latest) (push) Failing after 49s
CodeQL analysis / CodeQL analysis (push) Failing after 1m20s
Licensed / Licensed (push) Failing after 1m19s
Validate 'setup-go' / architecture (x64, 1.22, ubuntu-latest) (push) Failing after 49s
Validate 'setup-go' / architecture (x64, 1.23, ubuntu-latest) (push) Failing after 49s
* feat: add go-download-base-url input for custom Go distributions
Add support for downloading Go from custom sources such as Microsoft Go
(aka.ms). Users can specify a custom download base URL via the
`go-download-base-url` input or the `GO_DOWNLOAD_BASE_URL` environment
variable (input takes precedence).
When a custom URL is provided, the action skips the GitHub-hosted
manifest and attempts to resolve versions from the custom URL's JSON
listing. If the listing is unavailable (as with aka.ms redirect links),
it falls back to constructing the download URL directly from the
version, platform, and architecture.
Usage:
- uses: actions/setup-go@v6
with:
go-version: '1.25'
go-download-base-url: 'https://aka.ms/golang/release/latest'
Changes:
- action.yml: add go-download-base-url optional input
- installer.ts: add getInfoFromDirectDownload() for URL construction
fallback, thread custom URL through getGo/getInfoFromDist/findMatch
- main.ts: read new input and GO_DOWNLOAD_BASE_URL env var
- setup-go.test.ts: add 12 unit tests for custom URL behavior
- microsoft-validation.yml: add E2E workflow testing Microsoft build of Go
across ubuntu/windows/macos with versions 1.24 and 1.25
- README.md: document new input with Microsoft build of Go examples
* run prettier
* fixup PR review
* revert cache-save
* fixup
* handle distinct cache
* skip json for known URL
* fix bug in JSON with custom URL
This commit is contained in:
143
.github/workflows/microsoft-validation.yml
vendored
Normal file
143
.github/workflows/microsoft-validation.yml
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
name: Validate Microsoft build of Go
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
|
||||
jobs:
|
||||
microsoft-basic:
|
||||
name: 'Microsoft build of Go ${{ matrix.go-version }} on ${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
go-version: ['1.25', '1.24']
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Microsoft build of Go ${{ matrix.go-version }}
|
||||
uses: ./
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
go-download-base-url: 'https://aka.ms/golang/release/latest'
|
||||
cache: false
|
||||
|
||||
- name: Verify Go installation
|
||||
run: go version
|
||||
|
||||
- name: Verify Go env
|
||||
run: go env
|
||||
|
||||
- name: Verify Go is functional
|
||||
shell: bash
|
||||
run: |
|
||||
# Create a simple Go program and run it
|
||||
mkdir -p /tmp/test-go && cd /tmp/test-go
|
||||
cat > main.go << 'EOF'
|
||||
package main
|
||||
import "fmt"
|
||||
func main() {
|
||||
fmt.Println("Hello from Microsoft build of Go!")
|
||||
}
|
||||
EOF
|
||||
go run main.go
|
||||
|
||||
microsoft-env-var:
|
||||
name: 'Microsoft build of Go via env var on ${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
env:
|
||||
GO_DOWNLOAD_BASE_URL: 'https://aka.ms/golang/release/latest'
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Microsoft build of Go via environment variable
|
||||
uses: ./
|
||||
with:
|
||||
go-version: '1.25'
|
||||
cache: false
|
||||
|
||||
- name: Verify Go installation
|
||||
run: go version
|
||||
|
||||
- name: Verify Go is functional
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p /tmp/test-go && cd /tmp/test-go
|
||||
cat > main.go << 'EOF'
|
||||
package main
|
||||
import "fmt"
|
||||
func main() {
|
||||
fmt.Println("Hello from Microsoft build of Go via env var!")
|
||||
}
|
||||
EOF
|
||||
go run main.go
|
||||
|
||||
microsoft-architecture:
|
||||
name: 'Microsoft build of Go arch ${{ matrix.architecture }} on ${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
architecture: [x64]
|
||||
include:
|
||||
- os: macos-latest
|
||||
architecture: arm64
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Microsoft build of Go with architecture
|
||||
uses: ./
|
||||
with:
|
||||
go-version: '1.25'
|
||||
go-download-base-url: 'https://aka.ms/golang/release/latest'
|
||||
architecture: ${{ matrix.architecture }}
|
||||
cache: false
|
||||
|
||||
- name: Verify Go installation
|
||||
run: go version
|
||||
|
||||
microsoft-with-cache:
|
||||
name: 'Microsoft build of Go with caching on ${{ matrix.os }}'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Microsoft build of Go with caching
|
||||
uses: ./
|
||||
with:
|
||||
go-version: '1.25'
|
||||
go-download-base-url: 'https://aka.ms/golang/release/latest'
|
||||
cache: true
|
||||
|
||||
- name: Verify Go installation
|
||||
run: go version
|
||||
|
||||
- name: Verify Go is functional
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p /tmp/test-go && cd /tmp/test-go
|
||||
go mod init test
|
||||
cat > main.go << 'EOF'
|
||||
package main
|
||||
import "fmt"
|
||||
func main() {
|
||||
fmt.Println("Hello from cached Microsoft build of Go!")
|
||||
}
|
||||
EOF
|
||||
go run main.go
|
||||
@@ -54,6 +54,9 @@ See [action.yml](action.yml).
|
||||
|
||||
# Architecture to install (auto-detected if not specified)
|
||||
architecture: 'x64'
|
||||
|
||||
# Custom base URL for Go downloads (e.g., for mirrors)
|
||||
go-download-base-url: ''
|
||||
```
|
||||
<!-- end usage -->
|
||||
|
||||
@@ -130,6 +133,7 @@ For examples of using `cache-dependency-path`, see the [Caching](docs/advanced-u
|
||||
- [Check latest version](docs/advanced-usage.md#check-latest-version)
|
||||
- [Caching](docs/advanced-usage.md#caching)
|
||||
- [Outputs](docs/advanced-usage.md#outputs)
|
||||
- [Custom download URL](docs/advanced-usage.md#custom-download-url)
|
||||
- [Using `setup-go` on GHES](docs/advanced-usage.md#using-setup-go-on-ghes)
|
||||
|
||||
## License
|
||||
|
||||
@@ -45,6 +45,7 @@ describe('setup-go', () => {
|
||||
let mkdirSpy: jest.SpyInstance;
|
||||
let symlinkSpy: jest.SpyInstance;
|
||||
let execSpy: jest.SpyInstance;
|
||||
let execFileSpy: jest.SpyInstance;
|
||||
let getManifestSpy: jest.SpyInstance;
|
||||
let getAllVersionsSpy: jest.SpyInstance;
|
||||
let httpmGetJsonSpy: jest.SpyInstance;
|
||||
@@ -71,6 +72,10 @@ describe('setup-go', () => {
|
||||
archSpy = jest.spyOn(osm, 'arch');
|
||||
archSpy.mockImplementation(() => os['arch']);
|
||||
execSpy = jest.spyOn(cp, 'execSync');
|
||||
execFileSpy = jest.spyOn(cp, 'execFileSync');
|
||||
execFileSpy.mockImplementation(() => {
|
||||
throw new Error('ENOENT');
|
||||
});
|
||||
|
||||
// switch path join behaviour based on set os.platform
|
||||
joinSpy = jest.spyOn(path, 'join');
|
||||
@@ -129,8 +134,9 @@ describe('setup-go', () => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// clear out env var set during 'run'
|
||||
// clear out env vars set during 'run'
|
||||
delete process.env[im.GOTOOLCHAIN_ENV_VAR];
|
||||
delete process.env['GO_DOWNLOAD_BASE_URL'];
|
||||
|
||||
//jest.resetAllMocks();
|
||||
jest.clearAllMocks();
|
||||
@@ -1105,4 +1111,456 @@ use .
|
||||
expect(vars).toStrictEqual({GOTOOLCHAIN: 'local'});
|
||||
expect(process.env).toHaveProperty('GOTOOLCHAIN', 'local');
|
||||
});
|
||||
|
||||
describe('go-download-base-url', () => {
|
||||
it('downloads a version from custom base URL using version listing', async () => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'x64';
|
||||
|
||||
const versionSpec = '1.13.1';
|
||||
const customBaseUrl = 'https://example.com/golang';
|
||||
|
||||
inputs['go-version'] = versionSpec;
|
||||
inputs['go-download-base-url'] = customBaseUrl;
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||
const toolPath = path.normalize('/cache/go/1.13.1/x64');
|
||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
||||
cacheSpy.mockImplementation(async () => toolPath);
|
||||
|
||||
await main.run();
|
||||
|
||||
const expPath = path.join(toolPath, 'bin');
|
||||
expect(logSpy).toHaveBeenCalledWith(
|
||||
`Using custom Go download base URL: ${customBaseUrl}`
|
||||
);
|
||||
expect(logSpy).toHaveBeenCalledWith('Install from custom download URL');
|
||||
// Version listing should use custom base URL, not go.dev
|
||||
expect(getSpy).toHaveBeenCalledWith(
|
||||
`${customBaseUrl}/?mode=json&include=all`
|
||||
);
|
||||
expect(dlSpy).toHaveBeenCalled();
|
||||
expect(extractTarSpy).toHaveBeenCalled();
|
||||
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
|
||||
});
|
||||
|
||||
it('skips version listing for known direct-download URL (aka.ms)', async () => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'x64';
|
||||
|
||||
const versionSpec = '1.25.0';
|
||||
const customBaseUrl = 'https://aka.ms/golang/release/latest';
|
||||
|
||||
inputs['go-version'] = versionSpec;
|
||||
inputs['go-download-base-url'] = customBaseUrl;
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||
const toolPath = path.normalize('/cache/go/1.25.0/x64');
|
||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
||||
cacheSpy.mockImplementation(async () => toolPath);
|
||||
|
||||
await main.run();
|
||||
|
||||
const expPath = path.join(toolPath, 'bin');
|
||||
expect(logSpy).toHaveBeenCalledWith(
|
||||
'Skipping version listing for known direct-download URL. Constructing download URL directly.'
|
||||
);
|
||||
expect(logSpy).toHaveBeenCalledWith(
|
||||
`Constructed direct download URL: ${customBaseUrl}/go1.25.0.linux-amd64.tar.gz`
|
||||
);
|
||||
expect(logSpy).toHaveBeenCalledWith('Install from custom download URL');
|
||||
expect(getSpy).not.toHaveBeenCalled();
|
||||
expect(dlSpy).toHaveBeenCalled();
|
||||
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
|
||||
});
|
||||
|
||||
it('constructs correct direct download URL for windows (aka.ms)', async () => {
|
||||
os.platform = 'win32';
|
||||
os.arch = 'x64';
|
||||
|
||||
const versionSpec = '1.25.0';
|
||||
const customBaseUrl = 'https://aka.ms/golang/release/latest';
|
||||
|
||||
inputs['go-version'] = versionSpec;
|
||||
inputs['go-download-base-url'] = customBaseUrl;
|
||||
process.env['RUNNER_TEMP'] = 'C:\\temp\\';
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
dlSpy.mockImplementation(async () => 'C:\\temp\\some\\path');
|
||||
extractZipSpy.mockImplementation(() => 'C:\\temp\\some\\other\\path');
|
||||
const toolPath = path.normalize('C:\\cache\\go\\1.25.0\\x64');
|
||||
cacheSpy.mockImplementation(async () => toolPath);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(getSpy).not.toHaveBeenCalled();
|
||||
expect(dlSpy).toHaveBeenCalledWith(
|
||||
`${customBaseUrl}/go1.25.0.windows-amd64.zip`,
|
||||
'C:\\temp\\go1.25.0.windows-amd64.zip',
|
||||
undefined
|
||||
);
|
||||
});
|
||||
|
||||
it('skips manifest and downloads directly from custom URL', async () => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'x64';
|
||||
|
||||
const versionSpec = '1.12.16';
|
||||
const customBaseUrl = 'https://example.com/golang';
|
||||
|
||||
inputs['go-version'] = versionSpec;
|
||||
inputs['go-download-base-url'] = customBaseUrl;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||
const toolPath = path.normalize('/cache/go/1.12.16/x64');
|
||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
||||
cacheSpy.mockImplementation(async () => toolPath);
|
||||
|
||||
await main.run();
|
||||
|
||||
// Should not try to use the manifest at all
|
||||
expect(logSpy).not.toHaveBeenCalledWith(
|
||||
expect.stringContaining('Not found in manifest')
|
||||
);
|
||||
expect(logSpy).toHaveBeenCalledWith('Install from custom download URL');
|
||||
});
|
||||
|
||||
it('strips trailing slashes from custom base URL', async () => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'x64';
|
||||
|
||||
const versionSpec = '1.13.1';
|
||||
const customBaseUrl = 'https://example.com/golang/';
|
||||
|
||||
inputs['go-version'] = versionSpec;
|
||||
inputs['go-download-base-url'] = customBaseUrl;
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||
const toolPath = path.normalize('/cache/go/1.13.1/x64');
|
||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
||||
cacheSpy.mockImplementation(async () => toolPath);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(logSpy).toHaveBeenCalledWith(
|
||||
`Acquiring go1.13.1 from https://example.com/golang/go1.13.1.linux-amd64.tar.gz`
|
||||
);
|
||||
});
|
||||
|
||||
it('reads custom base URL from environment variable', async () => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'x64';
|
||||
|
||||
const versionSpec = '1.13.1';
|
||||
const customBaseUrl = 'https://example.com/golang';
|
||||
|
||||
inputs['go-version'] = versionSpec;
|
||||
process.env['GO_DOWNLOAD_BASE_URL'] = customBaseUrl;
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||
const toolPath = path.normalize('/cache/go/1.13.1/x64');
|
||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
||||
cacheSpy.mockImplementation(async () => toolPath);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(logSpy).toHaveBeenCalledWith(
|
||||
`Using custom Go download base URL: ${customBaseUrl}`
|
||||
);
|
||||
expect(logSpy).toHaveBeenCalledWith('Install from custom download URL');
|
||||
});
|
||||
|
||||
it('input takes precedence over environment variable', async () => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'x64';
|
||||
|
||||
const versionSpec = '1.13.1';
|
||||
const inputUrl = 'https://input.example.com/golang';
|
||||
const envUrl = 'https://env.example.com/golang';
|
||||
|
||||
inputs['go-version'] = versionSpec;
|
||||
inputs['go-download-base-url'] = inputUrl;
|
||||
process.env['GO_DOWNLOAD_BASE_URL'] = envUrl;
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||
const toolPath = path.normalize('/cache/go/1.13.1/x64');
|
||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
||||
cacheSpy.mockImplementation(async () => toolPath);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(logSpy).toHaveBeenCalledWith(
|
||||
`Using custom Go download base URL: ${inputUrl}`
|
||||
);
|
||||
expect(logSpy).toHaveBeenCalledWith(
|
||||
`Acquiring go1.13.1 from ${inputUrl}/go1.13.1.linux-amd64.tar.gz`
|
||||
);
|
||||
});
|
||||
|
||||
it('errors when stable alias is used with custom URL', async () => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'x64';
|
||||
|
||||
inputs['go-version'] = 'stable';
|
||||
inputs['go-download-base-url'] = 'https://example.com/golang';
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
await main.run();
|
||||
|
||||
expect(cnSpy).toHaveBeenCalledWith(
|
||||
`::error::Version aliases 'stable' are not supported with a custom download base URL. Please specify an exact Go version.${osm.EOL}`
|
||||
);
|
||||
});
|
||||
|
||||
it('logs info when check-latest is used with custom URL', async () => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'x64';
|
||||
|
||||
const versionSpec = '1.13.1';
|
||||
const customBaseUrl = 'https://example.com/golang';
|
||||
|
||||
inputs['go-version'] = versionSpec;
|
||||
inputs['go-download-base-url'] = customBaseUrl;
|
||||
inputs['check-latest'] = true;
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||
const toolPath = path.normalize('/cache/go/1.13.1/x64');
|
||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
||||
cacheSpy.mockImplementation(async () => toolPath);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(logSpy).toHaveBeenCalledWith(
|
||||
'check-latest is not supported with a custom download base URL. Using the provided version spec directly.'
|
||||
);
|
||||
});
|
||||
|
||||
it('constructs direct download info correctly', () => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'x64';
|
||||
|
||||
const info = im.getInfoFromDirectDownload(
|
||||
'1.25.0',
|
||||
'x64',
|
||||
'https://aka.ms/golang/release/latest'
|
||||
);
|
||||
|
||||
expect(info.type).toBe('dist');
|
||||
expect(info.downloadUrl).toBe(
|
||||
'https://aka.ms/golang/release/latest/go1.25.0.linux-amd64.tar.gz'
|
||||
);
|
||||
expect(info.fileName).toBe('go1.25.0.linux-amd64.tar.gz');
|
||||
expect(info.resolvedVersion).toBe('1.25.0');
|
||||
});
|
||||
|
||||
it('constructs direct download info for windows', () => {
|
||||
os.platform = 'win32';
|
||||
os.arch = 'x64';
|
||||
|
||||
const info = im.getInfoFromDirectDownload(
|
||||
'1.25.0',
|
||||
'x64',
|
||||
'https://aka.ms/golang/release/latest'
|
||||
);
|
||||
|
||||
expect(info.type).toBe('dist');
|
||||
expect(info.downloadUrl).toBe(
|
||||
'https://aka.ms/golang/release/latest/go1.25.0.windows-amd64.zip'
|
||||
);
|
||||
expect(info.fileName).toBe('go1.25.0.windows-amd64.zip');
|
||||
});
|
||||
|
||||
it('constructs direct download info for arm64', () => {
|
||||
os.platform = 'darwin';
|
||||
os.arch = 'arm64';
|
||||
|
||||
const info = im.getInfoFromDirectDownload(
|
||||
'1.25.0',
|
||||
'arm64',
|
||||
'https://aka.ms/golang/release/latest'
|
||||
);
|
||||
|
||||
expect(info.type).toBe('dist');
|
||||
expect(info.downloadUrl).toBe(
|
||||
'https://aka.ms/golang/release/latest/go1.25.0.darwin-arm64.tar.gz'
|
||||
);
|
||||
expect(info.fileName).toBe('go1.25.0.darwin-arm64.tar.gz');
|
||||
});
|
||||
|
||||
it('caches under actual installed version when it differs from input spec', async () => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'x64';
|
||||
|
||||
const versionSpec = '1.20';
|
||||
const customBaseUrl = 'https://aka.ms/golang/release/latest';
|
||||
|
||||
inputs['go-version'] = versionSpec;
|
||||
inputs['go-download-base-url'] = customBaseUrl;
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
||||
|
||||
// Mock the installed Go binary reporting a different patch version
|
||||
execFileSpy.mockImplementation(() => 'go version go1.20.14 linux/amd64');
|
||||
|
||||
const expectedToolName = im.customToolCacheName(customBaseUrl);
|
||||
const toolPath = path.normalize(`/cache/${expectedToolName}/1.20.14/x64`);
|
||||
cacheSpy.mockImplementation(async () => toolPath);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(logSpy).toHaveBeenCalledWith(
|
||||
"Requested version '1.20' resolved to installed version '1.20.14'"
|
||||
);
|
||||
// Cache key should use actual version, not the input spec
|
||||
expect(cacheSpy).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
expectedToolName,
|
||||
'1.20.14',
|
||||
'x64'
|
||||
);
|
||||
});
|
||||
|
||||
it('shows clear error with platform/arch and URL on 404', async () => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'arm64';
|
||||
|
||||
const versionSpec = '1.25.0';
|
||||
const customBaseUrl = 'https://example.com/golang';
|
||||
|
||||
inputs['go-version'] = versionSpec;
|
||||
inputs['go-download-base-url'] = customBaseUrl;
|
||||
|
||||
getSpy.mockImplementationOnce(() => {
|
||||
throw new Error('Not a JSON endpoint');
|
||||
});
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
const httpError = new tc.HTTPError(404);
|
||||
dlSpy.mockImplementation(() => {
|
||||
throw httpError;
|
||||
});
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(cnSpy).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'The requested Go version 1.25.0 is not available for platform linux/arm64'
|
||||
)
|
||||
);
|
||||
expect(cnSpy).toHaveBeenCalledWith(expect.stringContaining('HTTP 404'));
|
||||
});
|
||||
|
||||
it('shows clear error with platform/arch and URL on download failure', async () => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'x64';
|
||||
|
||||
const versionSpec = '1.25.0';
|
||||
const customBaseUrl = 'https://example.com/golang';
|
||||
|
||||
inputs['go-version'] = versionSpec;
|
||||
inputs['go-download-base-url'] = customBaseUrl;
|
||||
|
||||
getSpy.mockImplementationOnce(() => {
|
||||
throw new Error('Not a JSON endpoint');
|
||||
});
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
dlSpy.mockImplementation(() => {
|
||||
throw new Error('connection refused');
|
||||
});
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(cnSpy).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'Failed to download Go 1.25.0 for platform linux/x64'
|
||||
)
|
||||
);
|
||||
expect(cnSpy).toHaveBeenCalledWith(
|
||||
expect.stringContaining(customBaseUrl)
|
||||
);
|
||||
});
|
||||
|
||||
it.each(['^1.25.0', '~1.25', '>=1.25.0', '<1.26.0', '1.25.x', '1.x'])(
|
||||
'errors on version range "%s" when version listing is unavailable',
|
||||
async versionSpec => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'x64';
|
||||
|
||||
inputs['go-version'] = versionSpec;
|
||||
inputs['go-download-base-url'] = 'https://example.com/golang';
|
||||
|
||||
// Simulate version listing not available
|
||||
getSpy.mockImplementationOnce(() => {
|
||||
throw new Error('Not a JSON endpoint');
|
||||
});
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(cnSpy).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
`Version range '${versionSpec}' is not supported with a custom download base URL`
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
it('rejects version range in getInfoFromDirectDownload', () => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'x64';
|
||||
|
||||
expect(() =>
|
||||
im.getInfoFromDirectDownload(
|
||||
'^1.25.0',
|
||||
'x64',
|
||||
'https://example.com/golang'
|
||||
)
|
||||
).toThrow(
|
||||
"Version range '^1.25.0' is not supported with a custom download base URL"
|
||||
);
|
||||
});
|
||||
|
||||
it('passes token as auth header for custom URL downloads', async () => {
|
||||
os.platform = 'linux';
|
||||
os.arch = 'x64';
|
||||
|
||||
const versionSpec = '1.25.0';
|
||||
const customBaseUrl = 'https://private-mirror.example.com/golang';
|
||||
|
||||
inputs['go-version'] = versionSpec;
|
||||
inputs['go-download-base-url'] = customBaseUrl;
|
||||
inputs['token'] = 'ghp_testtoken123';
|
||||
|
||||
getSpy.mockImplementationOnce(() => {
|
||||
throw new Error('Not a JSON endpoint');
|
||||
});
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
||||
const expectedToolName = im.customToolCacheName(customBaseUrl);
|
||||
const toolPath = path.normalize(`/cache/${expectedToolName}/1.25.0/x64`);
|
||||
cacheSpy.mockImplementation(async () => toolPath);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(dlSpy).toHaveBeenCalledWith(
|
||||
`${customBaseUrl}/go1.25.0.linux-amd64.tar.gz`,
|
||||
undefined,
|
||||
'token ghp_testtoken123'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,6 +19,8 @@ inputs:
|
||||
description: 'Used to specify the path to a dependency file (e.g., go.mod, go.sum)'
|
||||
architecture:
|
||||
description: 'Target architecture for Go to use. Examples: x86, x64. Will use system architecture by default.'
|
||||
go-download-base-url:
|
||||
description: 'Custom base URL for downloading Go distributions. Use this to download Go from a mirror or custom source. Defaults to "https://go.dev/dl". Can also be set via the GO_DOWNLOAD_BASE_URL environment variable. The input takes precedence over the environment variable.'
|
||||
outputs:
|
||||
go-version:
|
||||
description: 'The installed Go version. Useful when given a version range as input.'
|
||||
|
||||
222
dist/setup/index.js
vendored
222
dist/setup/index.js
vendored
@@ -77034,9 +77034,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.GOTOOLCHAIN_LOCAL_VAL = exports.GOTOOLCHAIN_ENV_VAR = void 0;
|
||||
exports.getGo = getGo;
|
||||
exports.customToolCacheName = customToolCacheName;
|
||||
exports.extractGoArchive = extractGoArchive;
|
||||
exports.getManifest = getManifest;
|
||||
exports.getInfoFromManifest = getInfoFromManifest;
|
||||
exports.getInfoFromDirectDownload = getInfoFromDirectDownload;
|
||||
exports.findMatch = findMatch;
|
||||
exports.getVersionsDist = getVersionsDist;
|
||||
exports.makeSemver = makeSemver;
|
||||
@@ -77048,6 +77050,8 @@ const path = __importStar(__nccwpck_require__(16928));
|
||||
const semver = __importStar(__nccwpck_require__(62088));
|
||||
const httpm = __importStar(__nccwpck_require__(54844));
|
||||
const sys = __importStar(__nccwpck_require__(57666));
|
||||
const crypto_1 = __importDefault(__nccwpck_require__(76982));
|
||||
const child_process_1 = __importDefault(__nccwpck_require__(35317));
|
||||
const fs_1 = __importDefault(__nccwpck_require__(79896));
|
||||
const os_1 = __importDefault(__nccwpck_require__(70857));
|
||||
const utils_1 = __nccwpck_require__(71798);
|
||||
@@ -77057,14 +77061,23 @@ const MANIFEST_REPO_OWNER = 'actions';
|
||||
const MANIFEST_REPO_NAME = 'go-versions';
|
||||
const MANIFEST_REPO_BRANCH = 'main';
|
||||
const MANIFEST_URL = `https://raw.githubusercontent.com/${MANIFEST_REPO_OWNER}/${MANIFEST_REPO_NAME}/${MANIFEST_REPO_BRANCH}/versions-manifest.json`;
|
||||
const DEFAULT_GO_DOWNLOAD_BASE_URL = 'https://go.dev/dl';
|
||||
const GOLANG_DOWNLOAD_URL = 'https://go.dev/dl/?mode=json&include=all';
|
||||
// Base URLs known to not serve a version listing JSON endpoint.
|
||||
// For these URLs we skip the getInfoFromDist() call entirely and construct
|
||||
// the download URL directly, avoiding a guaranteed-404 HTTP request.
|
||||
const NO_VERSION_LISTING_BASE_URLS = ['https://aka.ms/golang/release/latest'];
|
||||
function getGo(versionSpec_1, checkLatest_1, auth_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (versionSpec, checkLatest, auth, arch = os_1.default.arch()) {
|
||||
return __awaiter(this, arguments, void 0, function* (versionSpec, checkLatest, auth, arch = os_1.default.arch(), goDownloadBaseUrl) {
|
||||
var _a;
|
||||
let manifest;
|
||||
const osPlat = os_1.default.platform();
|
||||
const customBaseUrl = goDownloadBaseUrl === null || goDownloadBaseUrl === void 0 ? void 0 : goDownloadBaseUrl.replace(/\/+$/, '');
|
||||
if (versionSpec === utils_1.StableReleaseAlias.Stable ||
|
||||
versionSpec === utils_1.StableReleaseAlias.OldStable) {
|
||||
if (customBaseUrl) {
|
||||
throw new Error(`Version aliases '${versionSpec}' are not supported with a custom download base URL. Please specify an exact Go version.`);
|
||||
}
|
||||
manifest = yield getManifest(auth);
|
||||
let stableVersion = yield resolveStableVersionInput(versionSpec, arch, osPlat, manifest);
|
||||
if (!stableVersion) {
|
||||
@@ -77077,18 +77090,28 @@ function getGo(versionSpec_1, checkLatest_1, auth_1) {
|
||||
versionSpec = stableVersion;
|
||||
}
|
||||
if (checkLatest) {
|
||||
core.info('Attempting to resolve the latest version from the manifest...');
|
||||
const resolvedVersion = yield resolveVersionFromManifest(versionSpec, true, auth, arch, manifest);
|
||||
if (resolvedVersion) {
|
||||
versionSpec = resolvedVersion;
|
||||
core.info(`Resolved as '${versionSpec}'`);
|
||||
if (customBaseUrl) {
|
||||
core.info('check-latest is not supported with a custom download base URL. Using the provided version spec directly.');
|
||||
}
|
||||
else {
|
||||
core.info(`Failed to resolve version ${versionSpec} from manifest`);
|
||||
core.info('Attempting to resolve the latest version from the manifest...');
|
||||
const resolvedVersion = yield resolveVersionFromManifest(versionSpec, true, auth, arch, manifest);
|
||||
if (resolvedVersion) {
|
||||
versionSpec = resolvedVersion;
|
||||
core.info(`Resolved as '${versionSpec}'`);
|
||||
}
|
||||
else {
|
||||
core.info(`Failed to resolve version ${versionSpec} from manifest`);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Use a distinct tool cache name for custom downloads to avoid
|
||||
// colliding with the runner's pre-installed Go
|
||||
const toolCacheName = customBaseUrl
|
||||
? customToolCacheName(customBaseUrl)
|
||||
: 'go';
|
||||
// check cache
|
||||
const toolPath = tc.find('go', versionSpec, arch);
|
||||
const toolPath = tc.find(toolCacheName, versionSpec, arch);
|
||||
// If not found in cache, download
|
||||
if (toolPath) {
|
||||
core.info(`Found in cache @ ${toolPath}`);
|
||||
@@ -77097,43 +77120,79 @@ function getGo(versionSpec_1, checkLatest_1, auth_1) {
|
||||
core.info(`Attempting to download ${versionSpec}...`);
|
||||
let downloadPath = '';
|
||||
let info = null;
|
||||
//
|
||||
// Try download from internal distribution (popular versions only)
|
||||
//
|
||||
try {
|
||||
info = yield getInfoFromManifest(versionSpec, true, auth, arch, manifest);
|
||||
if (info) {
|
||||
downloadPath = yield installGoVersion(info, auth, arch);
|
||||
if (customBaseUrl) {
|
||||
//
|
||||
// Download from custom base URL
|
||||
//
|
||||
const skipVersionListing = NO_VERSION_LISTING_BASE_URLS.some(url => customBaseUrl.toLowerCase() === url.toLowerCase());
|
||||
if (skipVersionListing) {
|
||||
core.info('Skipping version listing for known direct-download URL. Constructing download URL directly.');
|
||||
info = getInfoFromDirectDownload(versionSpec, arch, customBaseUrl);
|
||||
}
|
||||
else {
|
||||
core.info('Not found in manifest. Falling back to download directly from Go');
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
if (err instanceof tc.HTTPError &&
|
||||
(err.httpStatusCode === 403 || err.httpStatusCode === 429)) {
|
||||
core.info(`Received HTTP status code ${err.httpStatusCode}. This usually indicates the rate limit has been exceeded`);
|
||||
}
|
||||
else {
|
||||
core.info(err.message);
|
||||
}
|
||||
core.debug((_a = err.stack) !== null && _a !== void 0 ? _a : '');
|
||||
core.info('Falling back to download directly from Go');
|
||||
}
|
||||
//
|
||||
// Download from storage.googleapis.com
|
||||
//
|
||||
if (!downloadPath) {
|
||||
info = yield getInfoFromDist(versionSpec, arch);
|
||||
if (!info) {
|
||||
throw new Error(`Unable to find Go version '${versionSpec}' for platform ${osPlat} and architecture ${arch}.`);
|
||||
try {
|
||||
info = yield getInfoFromDist(versionSpec, arch, customBaseUrl);
|
||||
}
|
||||
catch (_b) {
|
||||
core.info('Version listing not available from custom URL. Constructing download URL directly.');
|
||||
}
|
||||
if (!info) {
|
||||
info = getInfoFromDirectDownload(versionSpec, arch, customBaseUrl);
|
||||
}
|
||||
}
|
||||
try {
|
||||
core.info('Install from dist');
|
||||
downloadPath = yield installGoVersion(info, undefined, arch);
|
||||
core.info('Install from custom download URL');
|
||||
downloadPath = yield installGoVersion(info, auth, arch, toolCacheName);
|
||||
}
|
||||
catch (err) {
|
||||
throw new Error(`Failed to download version ${versionSpec}: ${err}`);
|
||||
const downloadUrl = (info === null || info === void 0 ? void 0 : info.downloadUrl) || customBaseUrl;
|
||||
if (err instanceof tc.HTTPError && err.httpStatusCode === 404) {
|
||||
throw new Error(`The requested Go version ${versionSpec} is not available for platform ${osPlat}/${arch}. ` +
|
||||
`Download URL returned HTTP 404: ${downloadUrl}`);
|
||||
}
|
||||
throw new Error(`Failed to download Go ${versionSpec} for platform ${osPlat}/${arch} ` +
|
||||
`from ${downloadUrl}: ${err}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//
|
||||
// Try download from internal distribution (popular versions only)
|
||||
//
|
||||
try {
|
||||
info = yield getInfoFromManifest(versionSpec, true, auth, arch, manifest);
|
||||
if (info) {
|
||||
downloadPath = yield installGoVersion(info, auth, arch);
|
||||
}
|
||||
else {
|
||||
core.info('Not found in manifest. Falling back to download directly from Go');
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
if (err instanceof tc.HTTPError &&
|
||||
(err.httpStatusCode === 403 || err.httpStatusCode === 429)) {
|
||||
core.info(`Received HTTP status code ${err.httpStatusCode}. This usually indicates the rate limit has been exceeded`);
|
||||
}
|
||||
else {
|
||||
core.info(err.message);
|
||||
}
|
||||
core.debug((_a = err.stack) !== null && _a !== void 0 ? _a : '');
|
||||
core.info('Falling back to download directly from Go');
|
||||
}
|
||||
//
|
||||
// Download from storage.googleapis.com
|
||||
//
|
||||
if (!downloadPath) {
|
||||
info = yield getInfoFromDist(versionSpec, arch);
|
||||
if (!info) {
|
||||
throw new Error(`Unable to find Go version '${versionSpec}' for platform ${osPlat} and architecture ${arch}.`);
|
||||
}
|
||||
try {
|
||||
core.info('Install from dist');
|
||||
downloadPath = yield installGoVersion(info, undefined, arch);
|
||||
}
|
||||
catch (err) {
|
||||
throw new Error(`Failed to download version ${versionSpec}: ${err}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return downloadPath;
|
||||
@@ -77186,16 +77245,19 @@ function cacheWindowsDir(extPath, tool, version, arch) {
|
||||
return defaultToolCacheDir;
|
||||
});
|
||||
}
|
||||
function addExecutablesToToolCache(extPath, info, arch) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const tool = 'go';
|
||||
function addExecutablesToToolCache(extPath_1, info_1, arch_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (extPath, info, arch, toolName = 'go') {
|
||||
const version = makeSemver(info.resolvedVersion);
|
||||
return ((yield cacheWindowsDir(extPath, tool, version, arch)) ||
|
||||
(yield tc.cacheDir(extPath, tool, version, arch)));
|
||||
return ((yield cacheWindowsDir(extPath, toolName, version, arch)) ||
|
||||
(yield tc.cacheDir(extPath, toolName, version, arch)));
|
||||
});
|
||||
}
|
||||
function installGoVersion(info, auth, arch) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
function customToolCacheName(baseUrl) {
|
||||
const hash = crypto_1.default.createHash('sha256').update(baseUrl).digest('hex');
|
||||
return `go-${hash.substring(0, 8)}`;
|
||||
}
|
||||
function installGoVersion(info_1, auth_1, arch_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (info, auth, arch, toolName = 'go') {
|
||||
core.info(`Acquiring ${info.resolvedVersion} from ${info.downloadUrl}`);
|
||||
// Windows requires that we keep the extension (.zip) for extraction
|
||||
const isWindows = os_1.default.platform() === 'win32';
|
||||
@@ -77208,12 +77270,33 @@ function installGoVersion(info, auth, arch) {
|
||||
if (info.type === 'dist') {
|
||||
extPath = path.join(extPath, 'go');
|
||||
}
|
||||
// For custom downloads, detect the actual installed version so the cache
|
||||
// key reflects the real patch level (e.g. input "1.20" may install 1.20.14).
|
||||
if (toolName !== 'go') {
|
||||
const actualVersion = detectInstalledGoVersion(extPath);
|
||||
if (actualVersion && actualVersion !== info.resolvedVersion) {
|
||||
core.info(`Requested version '${info.resolvedVersion}' resolved to installed version '${actualVersion}'`);
|
||||
info.resolvedVersion = actualVersion;
|
||||
}
|
||||
}
|
||||
core.info('Adding to the cache ...');
|
||||
const toolCacheDir = yield addExecutablesToToolCache(extPath, info, arch);
|
||||
const toolCacheDir = yield addExecutablesToToolCache(extPath, info, arch, toolName);
|
||||
core.info(`Successfully cached go to ${toolCacheDir}`);
|
||||
return toolCacheDir;
|
||||
});
|
||||
}
|
||||
function detectInstalledGoVersion(goDir) {
|
||||
try {
|
||||
const goBin = path.join(goDir, 'bin', os_1.default.platform() === 'win32' ? 'go.exe' : 'go');
|
||||
const output = child_process_1.default.execFileSync(goBin, ['version'], { encoding: 'utf8' });
|
||||
const match = output.match(/go version go(\S+)/);
|
||||
return match ? match[1] : null;
|
||||
}
|
||||
catch (err) {
|
||||
core.debug(`Failed to detect installed Go version: ${err.message}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
function extractGoArchive(archivePath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const platform = os_1.default.platform();
|
||||
@@ -77298,13 +77381,17 @@ function getInfoFromManifest(versionSpec_1, stable_1, auth_1) {
|
||||
return info;
|
||||
});
|
||||
}
|
||||
function getInfoFromDist(versionSpec, arch) {
|
||||
function getInfoFromDist(versionSpec, arch, goDownloadBaseUrl) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const version = yield findMatch(versionSpec, arch);
|
||||
const dlUrl = goDownloadBaseUrl
|
||||
? `${goDownloadBaseUrl}/?mode=json&include=all`
|
||||
: GOLANG_DOWNLOAD_URL;
|
||||
const version = yield findMatch(versionSpec, arch, dlUrl);
|
||||
if (!version) {
|
||||
return null;
|
||||
}
|
||||
const downloadUrl = `https://go.dev/dl/${version.files[0].filename}`;
|
||||
const baseUrl = goDownloadBaseUrl || DEFAULT_GO_DOWNLOAD_BASE_URL;
|
||||
const downloadUrl = `${baseUrl}/${version.files[0].filename}`;
|
||||
return {
|
||||
type: 'dist',
|
||||
downloadUrl: downloadUrl,
|
||||
@@ -77313,13 +77400,36 @@ function getInfoFromDist(versionSpec, arch) {
|
||||
};
|
||||
});
|
||||
}
|
||||
function getInfoFromDirectDownload(versionSpec, arch, goDownloadBaseUrl) {
|
||||
// Reject version specs that can't map to an artifact filename
|
||||
if (/[~^>=<|*x]/.test(versionSpec)) {
|
||||
throw new Error(`Version range '${versionSpec}' is not supported with a custom download base URL ` +
|
||||
`when version listing is unavailable. Please specify an exact version (e.g., '1.25.0').`);
|
||||
}
|
||||
const archStr = sys.getArch(arch);
|
||||
const platStr = sys.getPlatform();
|
||||
const extension = platStr === 'windows' ? 'zip' : 'tar.gz';
|
||||
// Ensure version has the 'go' prefix for the filename
|
||||
const goVersion = versionSpec.startsWith('go')
|
||||
? versionSpec
|
||||
: `go${versionSpec}`;
|
||||
const fileName = `${goVersion}.${platStr}-${archStr}.${extension}`;
|
||||
const downloadUrl = `${goDownloadBaseUrl}/${fileName}`;
|
||||
core.info(`Constructed direct download URL: ${downloadUrl}`);
|
||||
return {
|
||||
type: 'dist',
|
||||
downloadUrl: downloadUrl,
|
||||
resolvedVersion: versionSpec.replace(/^go/, ''),
|
||||
fileName: fileName
|
||||
};
|
||||
}
|
||||
function findMatch(versionSpec_1) {
|
||||
return __awaiter(this, arguments, void 0, function* (versionSpec, arch = os_1.default.arch()) {
|
||||
return __awaiter(this, arguments, void 0, function* (versionSpec, arch = os_1.default.arch(), dlUrl = GOLANG_DOWNLOAD_URL) {
|
||||
const archFilter = sys.getArch(arch);
|
||||
const platFilter = sys.getPlatform();
|
||||
let result;
|
||||
let match;
|
||||
const candidates = yield module.exports.getVersionsDist(GOLANG_DOWNLOAD_URL);
|
||||
const candidates = yield module.exports.getVersionsDist(dlUrl);
|
||||
if (!candidates) {
|
||||
throw new Error(`golang download url did not return results`);
|
||||
}
|
||||
@@ -77529,7 +77639,13 @@ function run() {
|
||||
const token = core.getInput('token');
|
||||
const auth = !token ? undefined : `token ${token}`;
|
||||
const checkLatest = core.getBooleanInput('check-latest');
|
||||
const installDir = yield installer.getGo(versionSpec, checkLatest, auth, arch);
|
||||
const goDownloadBaseUrl = core.getInput('go-download-base-url') ||
|
||||
process.env['GO_DOWNLOAD_BASE_URL'] ||
|
||||
undefined;
|
||||
if (goDownloadBaseUrl) {
|
||||
core.info(`Using custom Go download base URL: ${goDownloadBaseUrl}`);
|
||||
}
|
||||
const installDir = yield installer.getGo(versionSpec, checkLatest, auth, arch, goDownloadBaseUrl);
|
||||
const installDirVersion = path_1.default.basename(path_1.default.dirname(installDir));
|
||||
core.addPath(path_1.default.join(installDir, 'bin'));
|
||||
core.info('Added go to the path');
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
- [Restore-only caches](advanced-usage.md#restore-only-caches)
|
||||
- [Parallel builds](advanced-usage.md#parallel-builds)
|
||||
- [Outputs](advanced-usage.md#outputs)
|
||||
- [Custom download URL](advanced-usage.md#custom-download-url)
|
||||
- [Using `setup-go` on GHES](advanced-usage.md#using-setup-go-on-ghes)
|
||||
|
||||
## Using the `go-version` input
|
||||
@@ -222,6 +223,8 @@ want the most up-to-date Go version to always be used. It supports major (e.g.,
|
||||
|
||||
> Setting `check-latest` to `true` has performance implications as downloading Go versions is slower than using cached
|
||||
> versions.
|
||||
>
|
||||
> `check-latest` is ignored when `go-download-base-url` is set. See [Custom download URL](#custom-download-url) for details.
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
@@ -417,6 +420,57 @@ jobs:
|
||||
- run: echo "Was the Go cache restored? ${{ steps.go124.outputs.cache-hit }}" # true if cache-hit occurred
|
||||
```
|
||||
|
||||
## Custom download URL
|
||||
|
||||
The `go-download-base-url` input lets you download Go from a mirror or alternative source instead of the default `https://go.dev/dl`. This can also be set via the `GO_DOWNLOAD_BASE_URL` environment variable; the input takes precedence over the environment variable.
|
||||
|
||||
When a custom base URL is provided, the action skips the `actions/go-versions` manifest lookup and downloads directly from the specified URL.
|
||||
|
||||
**Using the [Microsoft build of Go](https://github.com/nicholasgasior/microsoft-go):**
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.25'
|
||||
go-download-base-url: 'https://aka.ms/golang/release/latest'
|
||||
- run: go version
|
||||
```
|
||||
|
||||
**Using an environment variable:**
|
||||
|
||||
```yaml
|
||||
env:
|
||||
GO_DOWNLOAD_BASE_URL: 'https://aka.ms/golang/release/latest'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.25'
|
||||
- run: go version
|
||||
```
|
||||
|
||||
> **Note:** Version range syntax (`^1.25`, `~1.24`, `>=1.25.0`) and aliases (`stable`, `oldstable`) are not supported with custom download URLs. Use exact versions such as `1.25`, `1.25.0`, or `1.25.0-1` (for sources that use revision numbers). If the custom server provides a version listing endpoint (`/?mode=json&include=all`), semver ranges will work; otherwise only exact versions are accepted.
|
||||
|
||||
> **Note:** The `check-latest` option is ignored when a custom download base URL is set. The action cannot query the custom server for the latest version, so it uses the version you specify directly. If you provide a partial version like `1.25`, the server determines which patch release to serve.
|
||||
|
||||
**Authenticated downloads:**
|
||||
|
||||
If your custom download source requires authentication, the `token` input is forwarded as an `Authorization` header. For example, to download from a private mirror:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.25'
|
||||
go-download-base-url: 'https://private-mirror.example.com/golang'
|
||||
token: ${{ secrets.MIRROR_TOKEN }}
|
||||
- run: go version
|
||||
```
|
||||
|
||||
## Using `setup-go` on GHES
|
||||
|
||||
### Avoiding rate limit issues
|
||||
|
||||
282
src/installer.ts
282
src/installer.ts
@@ -4,6 +4,8 @@ import * as path from 'path';
|
||||
import * as semver from 'semver';
|
||||
import * as httpm from '@actions/http-client';
|
||||
import * as sys from './system';
|
||||
import crypto from 'crypto';
|
||||
import cp from 'child_process';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import {StableReleaseAlias, isSelfHosted} from './utils';
|
||||
@@ -15,11 +17,17 @@ const MANIFEST_REPO_OWNER = 'actions';
|
||||
const MANIFEST_REPO_NAME = 'go-versions';
|
||||
const MANIFEST_REPO_BRANCH = 'main';
|
||||
const MANIFEST_URL = `https://raw.githubusercontent.com/${MANIFEST_REPO_OWNER}/${MANIFEST_REPO_NAME}/${MANIFEST_REPO_BRANCH}/versions-manifest.json`;
|
||||
const DEFAULT_GO_DOWNLOAD_BASE_URL = 'https://go.dev/dl';
|
||||
|
||||
type InstallationType = 'dist' | 'manifest';
|
||||
|
||||
const GOLANG_DOWNLOAD_URL = 'https://go.dev/dl/?mode=json&include=all';
|
||||
|
||||
// Base URLs known to not serve a version listing JSON endpoint.
|
||||
// For these URLs we skip the getInfoFromDist() call entirely and construct
|
||||
// the download URL directly, avoiding a guaranteed-404 HTTP request.
|
||||
const NO_VERSION_LISTING_BASE_URLS = ['https://aka.ms/golang/release/latest'];
|
||||
|
||||
export interface IGoVersionFile {
|
||||
filename: string;
|
||||
// darwin, linux, windows
|
||||
@@ -44,15 +52,23 @@ export async function getGo(
|
||||
versionSpec: string,
|
||||
checkLatest: boolean,
|
||||
auth: string | undefined,
|
||||
arch: Architecture = os.arch() as Architecture
|
||||
arch: Architecture = os.arch() as Architecture,
|
||||
goDownloadBaseUrl?: string
|
||||
) {
|
||||
let manifest: tc.IToolRelease[] | undefined;
|
||||
const osPlat: string = os.platform();
|
||||
const customBaseUrl = goDownloadBaseUrl?.replace(/\/+$/, '');
|
||||
|
||||
if (
|
||||
versionSpec === StableReleaseAlias.Stable ||
|
||||
versionSpec === StableReleaseAlias.OldStable
|
||||
) {
|
||||
if (customBaseUrl) {
|
||||
throw new Error(
|
||||
`Version aliases '${versionSpec}' are not supported with a custom download base URL. Please specify an exact Go version.`
|
||||
);
|
||||
}
|
||||
|
||||
manifest = await getManifest(auth);
|
||||
let stableVersion = await resolveStableVersionInput(
|
||||
versionSpec,
|
||||
@@ -76,24 +92,38 @@ export async function getGo(
|
||||
}
|
||||
|
||||
if (checkLatest) {
|
||||
core.info('Attempting to resolve the latest version from the manifest...');
|
||||
const resolvedVersion = await resolveVersionFromManifest(
|
||||
versionSpec,
|
||||
true,
|
||||
auth,
|
||||
arch,
|
||||
manifest
|
||||
);
|
||||
if (resolvedVersion) {
|
||||
versionSpec = resolvedVersion;
|
||||
core.info(`Resolved as '${versionSpec}'`);
|
||||
if (customBaseUrl) {
|
||||
core.info(
|
||||
'check-latest is not supported with a custom download base URL. Using the provided version spec directly.'
|
||||
);
|
||||
} else {
|
||||
core.info(`Failed to resolve version ${versionSpec} from manifest`);
|
||||
core.info(
|
||||
'Attempting to resolve the latest version from the manifest...'
|
||||
);
|
||||
const resolvedVersion = await resolveVersionFromManifest(
|
||||
versionSpec,
|
||||
true,
|
||||
auth,
|
||||
arch,
|
||||
manifest
|
||||
);
|
||||
if (resolvedVersion) {
|
||||
versionSpec = resolvedVersion;
|
||||
core.info(`Resolved as '${versionSpec}'`);
|
||||
} else {
|
||||
core.info(`Failed to resolve version ${versionSpec} from manifest`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use a distinct tool cache name for custom downloads to avoid
|
||||
// colliding with the runner's pre-installed Go
|
||||
const toolCacheName = customBaseUrl
|
||||
? customToolCacheName(customBaseUrl)
|
||||
: 'go';
|
||||
|
||||
// check cache
|
||||
const toolPath = tc.find('go', versionSpec, arch);
|
||||
const toolPath = tc.find(toolCacheName, versionSpec, arch);
|
||||
// If not found in cache, download
|
||||
if (toolPath) {
|
||||
core.info(`Found in cache @ ${toolPath}`);
|
||||
@@ -103,49 +133,93 @@ export async function getGo(
|
||||
let downloadPath = '';
|
||||
let info: IGoVersionInfo | null = null;
|
||||
|
||||
//
|
||||
// Try download from internal distribution (popular versions only)
|
||||
//
|
||||
try {
|
||||
info = await getInfoFromManifest(versionSpec, true, auth, arch, manifest);
|
||||
if (info) {
|
||||
downloadPath = await installGoVersion(info, auth, arch);
|
||||
} else {
|
||||
core.info(
|
||||
'Not found in manifest. Falling back to download directly from Go'
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof tc.HTTPError &&
|
||||
(err.httpStatusCode === 403 || err.httpStatusCode === 429)
|
||||
) {
|
||||
core.info(
|
||||
`Received HTTP status code ${err.httpStatusCode}. This usually indicates the rate limit has been exceeded`
|
||||
);
|
||||
} else {
|
||||
core.info((err as Error).message);
|
||||
}
|
||||
core.debug((err as Error).stack ?? '');
|
||||
core.info('Falling back to download directly from Go');
|
||||
}
|
||||
if (customBaseUrl) {
|
||||
//
|
||||
// Download from custom base URL
|
||||
//
|
||||
const skipVersionListing = NO_VERSION_LISTING_BASE_URLS.some(
|
||||
url => customBaseUrl.toLowerCase() === url.toLowerCase()
|
||||
);
|
||||
|
||||
//
|
||||
// Download from storage.googleapis.com
|
||||
//
|
||||
if (!downloadPath) {
|
||||
info = await getInfoFromDist(versionSpec, arch);
|
||||
if (!info) {
|
||||
throw new Error(
|
||||
`Unable to find Go version '${versionSpec}' for platform ${osPlat} and architecture ${arch}.`
|
||||
if (skipVersionListing) {
|
||||
core.info(
|
||||
'Skipping version listing for known direct-download URL. Constructing download URL directly.'
|
||||
);
|
||||
info = getInfoFromDirectDownload(versionSpec, arch, customBaseUrl);
|
||||
} else {
|
||||
try {
|
||||
info = await getInfoFromDist(versionSpec, arch, customBaseUrl);
|
||||
} catch {
|
||||
core.info(
|
||||
'Version listing not available from custom URL. Constructing download URL directly.'
|
||||
);
|
||||
}
|
||||
if (!info) {
|
||||
info = getInfoFromDirectDownload(versionSpec, arch, customBaseUrl);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
core.info('Install from dist');
|
||||
downloadPath = await installGoVersion(info, undefined, arch);
|
||||
core.info('Install from custom download URL');
|
||||
downloadPath = await installGoVersion(info, auth, arch, toolCacheName);
|
||||
} catch (err) {
|
||||
throw new Error(`Failed to download version ${versionSpec}: ${err}`);
|
||||
const downloadUrl = info?.downloadUrl || customBaseUrl;
|
||||
if (err instanceof tc.HTTPError && err.httpStatusCode === 404) {
|
||||
throw new Error(
|
||||
`The requested Go version ${versionSpec} is not available for platform ${osPlat}/${arch}. ` +
|
||||
`Download URL returned HTTP 404: ${downloadUrl}`
|
||||
);
|
||||
}
|
||||
throw new Error(
|
||||
`Failed to download Go ${versionSpec} for platform ${osPlat}/${arch} ` +
|
||||
`from ${downloadUrl}: ${err}`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Try download from internal distribution (popular versions only)
|
||||
//
|
||||
try {
|
||||
info = await getInfoFromManifest(versionSpec, true, auth, arch, manifest);
|
||||
if (info) {
|
||||
downloadPath = await installGoVersion(info, auth, arch);
|
||||
} else {
|
||||
core.info(
|
||||
'Not found in manifest. Falling back to download directly from Go'
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof tc.HTTPError &&
|
||||
(err.httpStatusCode === 403 || err.httpStatusCode === 429)
|
||||
) {
|
||||
core.info(
|
||||
`Received HTTP status code ${err.httpStatusCode}. This usually indicates the rate limit has been exceeded`
|
||||
);
|
||||
} else {
|
||||
core.info((err as Error).message);
|
||||
}
|
||||
core.debug((err as Error).stack ?? '');
|
||||
core.info('Falling back to download directly from Go');
|
||||
}
|
||||
|
||||
//
|
||||
// Download from storage.googleapis.com
|
||||
//
|
||||
if (!downloadPath) {
|
||||
info = await getInfoFromDist(versionSpec, arch);
|
||||
if (!info) {
|
||||
throw new Error(
|
||||
`Unable to find Go version '${versionSpec}' for platform ${osPlat} and architecture ${arch}.`
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
core.info('Install from dist');
|
||||
downloadPath = await installGoVersion(info, undefined, arch);
|
||||
} catch (err) {
|
||||
throw new Error(`Failed to download version ${versionSpec}: ${err}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,20 +303,26 @@ async function cacheWindowsDir(
|
||||
async function addExecutablesToToolCache(
|
||||
extPath: string,
|
||||
info: IGoVersionInfo,
|
||||
arch: string
|
||||
arch: string,
|
||||
toolName: string = 'go'
|
||||
): Promise<string> {
|
||||
const tool = 'go';
|
||||
const version = makeSemver(info.resolvedVersion);
|
||||
return (
|
||||
(await cacheWindowsDir(extPath, tool, version, arch)) ||
|
||||
(await tc.cacheDir(extPath, tool, version, arch))
|
||||
(await cacheWindowsDir(extPath, toolName, version, arch)) ||
|
||||
(await tc.cacheDir(extPath, toolName, version, arch))
|
||||
);
|
||||
}
|
||||
|
||||
export function customToolCacheName(baseUrl: string): string {
|
||||
const hash = crypto.createHash('sha256').update(baseUrl).digest('hex');
|
||||
return `go-${hash.substring(0, 8)}`;
|
||||
}
|
||||
|
||||
async function installGoVersion(
|
||||
info: IGoVersionInfo,
|
||||
auth: string | undefined,
|
||||
arch: string
|
||||
arch: string,
|
||||
toolName: string = 'go'
|
||||
): Promise<string> {
|
||||
core.info(`Acquiring ${info.resolvedVersion} from ${info.downloadUrl}`);
|
||||
|
||||
@@ -260,13 +340,48 @@ async function installGoVersion(
|
||||
extPath = path.join(extPath, 'go');
|
||||
}
|
||||
|
||||
// For custom downloads, detect the actual installed version so the cache
|
||||
// key reflects the real patch level (e.g. input "1.20" may install 1.20.14).
|
||||
if (toolName !== 'go') {
|
||||
const actualVersion = detectInstalledGoVersion(extPath);
|
||||
if (actualVersion && actualVersion !== info.resolvedVersion) {
|
||||
core.info(
|
||||
`Requested version '${info.resolvedVersion}' resolved to installed version '${actualVersion}'`
|
||||
);
|
||||
info.resolvedVersion = actualVersion;
|
||||
}
|
||||
}
|
||||
|
||||
core.info('Adding to the cache ...');
|
||||
const toolCacheDir = await addExecutablesToToolCache(extPath, info, arch);
|
||||
const toolCacheDir = await addExecutablesToToolCache(
|
||||
extPath,
|
||||
info,
|
||||
arch,
|
||||
toolName
|
||||
);
|
||||
core.info(`Successfully cached go to ${toolCacheDir}`);
|
||||
|
||||
return toolCacheDir;
|
||||
}
|
||||
|
||||
function detectInstalledGoVersion(goDir: string): string | null {
|
||||
try {
|
||||
const goBin = path.join(
|
||||
goDir,
|
||||
'bin',
|
||||
os.platform() === 'win32' ? 'go.exe' : 'go'
|
||||
);
|
||||
const output = cp.execFileSync(goBin, ['version'], {encoding: 'utf8'});
|
||||
const match = output.match(/go version go(\S+)/);
|
||||
return match ? match[1] : null;
|
||||
} catch (err) {
|
||||
core.debug(
|
||||
`Failed to detect installed Go version: ${(err as Error).message}`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function extractGoArchive(archivePath: string): Promise<string> {
|
||||
const platform = os.platform();
|
||||
let extPath: string;
|
||||
@@ -384,14 +499,23 @@ export async function getInfoFromManifest(
|
||||
|
||||
async function getInfoFromDist(
|
||||
versionSpec: string,
|
||||
arch: Architecture
|
||||
arch: Architecture,
|
||||
goDownloadBaseUrl?: string
|
||||
): Promise<IGoVersionInfo | null> {
|
||||
const version: IGoVersion | undefined = await findMatch(versionSpec, arch);
|
||||
const dlUrl = goDownloadBaseUrl
|
||||
? `${goDownloadBaseUrl}/?mode=json&include=all`
|
||||
: GOLANG_DOWNLOAD_URL;
|
||||
const version: IGoVersion | undefined = await findMatch(
|
||||
versionSpec,
|
||||
arch,
|
||||
dlUrl
|
||||
);
|
||||
if (!version) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const downloadUrl = `https://go.dev/dl/${version.files[0].filename}`;
|
||||
const baseUrl = goDownloadBaseUrl || DEFAULT_GO_DOWNLOAD_BASE_URL;
|
||||
const downloadUrl = `${baseUrl}/${version.files[0].filename}`;
|
||||
|
||||
return <IGoVersionInfo>{
|
||||
type: 'dist',
|
||||
@@ -401,9 +525,43 @@ async function getInfoFromDist(
|
||||
};
|
||||
}
|
||||
|
||||
export function getInfoFromDirectDownload(
|
||||
versionSpec: string,
|
||||
arch: Architecture,
|
||||
goDownloadBaseUrl: string
|
||||
): IGoVersionInfo {
|
||||
// Reject version specs that can't map to an artifact filename
|
||||
if (/[~^>=<|*x]/.test(versionSpec)) {
|
||||
throw new Error(
|
||||
`Version range '${versionSpec}' is not supported with a custom download base URL ` +
|
||||
`when version listing is unavailable. Please specify an exact version (e.g., '1.25.0').`
|
||||
);
|
||||
}
|
||||
|
||||
const archStr = sys.getArch(arch);
|
||||
const platStr = sys.getPlatform();
|
||||
const extension = platStr === 'windows' ? 'zip' : 'tar.gz';
|
||||
// Ensure version has the 'go' prefix for the filename
|
||||
const goVersion = versionSpec.startsWith('go')
|
||||
? versionSpec
|
||||
: `go${versionSpec}`;
|
||||
const fileName = `${goVersion}.${platStr}-${archStr}.${extension}`;
|
||||
const downloadUrl = `${goDownloadBaseUrl}/${fileName}`;
|
||||
|
||||
core.info(`Constructed direct download URL: ${downloadUrl}`);
|
||||
|
||||
return <IGoVersionInfo>{
|
||||
type: 'dist',
|
||||
downloadUrl: downloadUrl,
|
||||
resolvedVersion: versionSpec.replace(/^go/, ''),
|
||||
fileName: fileName
|
||||
};
|
||||
}
|
||||
|
||||
export async function findMatch(
|
||||
versionSpec: string,
|
||||
arch: Architecture = os.arch() as Architecture
|
||||
arch: Architecture = os.arch() as Architecture,
|
||||
dlUrl: string = GOLANG_DOWNLOAD_URL
|
||||
): Promise<IGoVersion | undefined> {
|
||||
const archFilter = sys.getArch(arch);
|
||||
const platFilter = sys.getPlatform();
|
||||
@@ -412,7 +570,7 @@ export async function findMatch(
|
||||
let match: IGoVersion | undefined;
|
||||
|
||||
const candidates: IGoVersion[] | null = await module.exports.getVersionsDist(
|
||||
GOLANG_DOWNLOAD_URL
|
||||
dlUrl
|
||||
);
|
||||
if (!candidates) {
|
||||
throw new Error(`golang download url did not return results`);
|
||||
|
||||
12
src/main.ts
12
src/main.ts
@@ -34,11 +34,21 @@ export async function run() {
|
||||
|
||||
const checkLatest = core.getBooleanInput('check-latest');
|
||||
|
||||
const goDownloadBaseUrl =
|
||||
core.getInput('go-download-base-url') ||
|
||||
process.env['GO_DOWNLOAD_BASE_URL'] ||
|
||||
undefined;
|
||||
|
||||
if (goDownloadBaseUrl) {
|
||||
core.info(`Using custom Go download base URL: ${goDownloadBaseUrl}`);
|
||||
}
|
||||
|
||||
const installDir = await installer.getGo(
|
||||
versionSpec,
|
||||
checkLatest,
|
||||
auth,
|
||||
arch
|
||||
arch,
|
||||
goDownloadBaseUrl
|
||||
);
|
||||
|
||||
const installDirVersion = path.basename(path.dirname(installDir));
|
||||
|
||||
Reference in New Issue
Block a user