Compare commits

..

36 Commits
v2 ... v3.1.0

Author SHA1 Message Date
fcdc43634a Update @zeit/ncc to @vercel/ncc (#229) 2022-05-12 12:04:41 +02:00
265edc1beb Add go-version-file option (#62) 2022-05-12 10:04:39 +02:00
193b404f8a Successfully set up (#231) 2022-05-03 08:43:40 -04:00
56a61c9834 Create ADR for integrating cache functionality to setup-go action (#217) 2022-04-26 11:38:01 +02:00
b46db954a1 Merge pull request #222 from vsafonkin/v-vsafonkin/add-readme-note
Add note about golang building process
2022-04-20 18:09:14 +03:00
3332358454 Add note about go building 2022-04-20 16:11:14 +02:00
46eabca1ab Merge pull request #221 from vsafonkin/v-vsafonkin/fix-gopath-condition
Fix condition for GOPATH output
2022-04-19 09:58:46 +03:00
07948221be Rename CONDUCT.md and change email inside (#218) 2022-04-18 10:45:36 +02:00
ad70bef2ef Fix condition for old go versions 2022-04-17 17:36:51 +02:00
4a4352b330 Add 'go-version' Output (#85)
* Add go-version to action outputs

This provides the semver version of Go that has been installed. This is useful
if only a major or minor version has been provided as the input go-version
value.

* Convert version extraction to a function

Simplify how the version is extracted and add a simple test at the same
time.

Co-authored-by: Peter Mescalchin <peter@magnetikonline.com>
Co-authored-by: Brian Cristante <33549821+brcrista@users.noreply.github.com>

Co-authored-by: Peter Mescalchin <peter@magnetikonline.com>
Co-authored-by: Brian Cristante <33549821+brcrista@users.noreply.github.com>
2022-04-08 12:23:10 -04:00
115d6e6004 Set LF for all files (#214)
* Set LF for all files

* Set gitattr text=auto
2022-04-07 11:31:36 -04:00
bf7ccf173e Correct some small README.md formatting typos (#213) 2022-04-01 09:27:16 -04:00
dcb4ec94ce Bump GitHub actions, README.md cleanups (#202)
* Bump `actions/checkout@v3`

* Bump `actions/setup-node@v3`

* Bump `actions/upload-artifact@v3`

* Bump `actions/setup-go@v3` in `README.md` examples

* Removed mention of `stable` action argument from `README.md`

* Add "new style" workflow build buttons to `README.md`
2022-03-31 15:29:52 -04:00
341b20ac36 Update usage examples on readme (#212)
* Fix action usage examples on readme

* Revert changes on package-lock

* Fix some checkout action version
2022-03-29 15:16:03 -04:00
a5865a93f2 Merge pull request #211 from Frassle/awaitmkdirp
await io.mkdirP
2022-03-28 09:47:39 -04:00
13df686579 Update dist 2022-03-28 14:23:54 +01:00
8e9a229830 Merge pull request #210 from vsafonkin/v-vsafonkin/update-readme-v3
Update README to v3
2022-03-28 09:19:11 -04:00
0b4fbc55f6 await io.mkdirP 2022-03-28 10:54:44 +01:00
acdbc5377c Remove stable input description from README 2022-03-28 10:24:34 +02:00
3e6475c089 Update README to v3 2022-03-25 09:53:28 +01:00
65771601ff Merge pull request #208 from actions/dependabot/npm_and_yarn/minimist-1.2.6
Bump minimist from 1.2.5 to 1.2.6
2022-03-24 09:32:50 -04:00
fcc0174ef2 Bump minimist from 1.2.5 to 1.2.6
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-24 11:54:47 +00:00
75726802f3 Merge pull request #175 from mmlb/do-not-export-GOROOT
Do not export GOROOT for Go versions >= 1.9
2022-03-17 16:02:21 -04:00
0c03929337 Remove duplicated spyOn 2022-03-14 12:32:36 -04:00
229eefa42b Update dist 2022-03-14 12:24:32 -04:00
802876f7c7 Fix formatting 2022-03-14 12:23:03 -04:00
2a34c33bd7 Export GOROOT for versions < 1.9 2022-03-14 12:21:30 -04:00
83124a14b6 Do not export GOROOT
This has not been necessary since [Go 1.9](https://go.dev/doc/go1.9#goroot) at
least (although clunky to do so then) but definitely not since
[Go 1.10](https://go.dev/doc/go1.10#goroot).

This is cargo culting code that is more than 2 years out of date and runs into
issues when multiple go versions are used in an action run.

Signed-off-by: Manuel Mendez <mmendez534@gmail.com>
2022-03-11 08:26:16 -05:00
9a1626044c Merge pull request #204 from actions/joshmgross/service-codeowners
Update CODEOWNERS to actions-service
2022-03-10 13:33:03 -05:00
24c791c06c Update CODEOWNERS to actions-service 2022-03-10 13:29:40 -05:00
ec07be593a Add test for export of GOROOT to env var
Signed-off-by: Manuel Mendez <mmendez534@gmail.com>
2022-03-09 08:56:55 -05:00
f6164bd8c8 Remove stable input and fix SemVer notation (#195) 2022-02-28 10:16:32 +03:00
2bb2aab2fd update types node (#194) 2022-02-24 15:07:22 +03:00
edcbc0c2cd update lockfileVersion (#193) 2022-02-24 14:47:08 +03:00
fb9a043dd8 Update default runtime to node16 (#192) 2022-02-22 18:25:23 +03:00
5b0ae0e97d Bump pathval from 1.1.0 to 1.1.1 (#188) 2022-02-16 16:47:18 +03:00
18 changed files with 8489 additions and 3758 deletions

1
.gitattributes vendored
View File

@ -1 +1,2 @@
* text=auto
.licenses/** -diff linguist-generated=true .licenses/** -diff linguist-generated=true

View File

@ -21,12 +21,12 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Set Node.js 12.x - name: Set Node.js 16.x
uses: actions/setup-node@v2 uses: actions/setup-node@v3
with: with:
node-version: 12.x node-version: 16.x
- name: Install dependencies - name: Install dependencies
run: npm ci run: npm ci
@ -44,7 +44,7 @@ jobs:
id: diff id: diff
# If index.js was different than expected, upload the expected version as an artifact # If index.js was different than expected, upload the expected version as an artifact
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
if: ${{ failure() && steps.diff.conclusion == 'failure' }} if: ${{ failure() && steps.diff.conclusion == 'failure' }}
with: with:
name: dist name: dist

View File

@ -13,12 +13,16 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: Check licenses name: Check licenses
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
- run: npm ci - run: npm ci
- name: Install licensed - name: Install licensed
run: | run: |
cd $RUNNER_TEMP cd $RUNNER_TEMP
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.3.1/licensed-3.3.1-linux-x64.tar.gz curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.4.4/licensed-3.4.4-linux-x64.tar.gz
sudo tar -xzf licensed.tar.gz sudo tar -xzf licensed.tar.gz
sudo mv licensed /usr/local/bin/licensed sudo mv licensed /usr/local/bin/licensed
- run: licensed status - run: licensed status

View File

@ -22,7 +22,7 @@ jobs:
go: [1.12, 1.13, 1.14] go: [1.12, 1.13, 1.14]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: setup-go ${{ matrix.go }} - name: setup-go ${{ matrix.go }}
uses: ./ uses: ./
@ -41,7 +41,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest] os: [ubuntu-latest, windows-latest, macos-latest]
go-version: [1.16, 1.17] go-version: [1.16, 1.17]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Setup Go and check latest - name: Setup Go and check latest
uses: ./ uses: ./
with: with:
@ -50,6 +50,22 @@ jobs:
- name: Verify Go - name: Verify Go
run: go version run: go version
go-version-file:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v3
- name: Setup Go and check latest
uses: ./
with:
go-version-file: __tests__/data/go.mod
- name: verify go
run: __tests__/verify-go.sh 1.14
shell: bash
setup-versions-from-manifest: setup-versions-from-manifest:
name: Setup ${{ matrix.go }} ${{ matrix.os }} name: Setup ${{ matrix.go }} ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@ -60,7 +76,7 @@ jobs:
go: [1.12.16, 1.13.11, 1.14.3] go: [1.12.16, 1.13.11, 1.14.3]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: setup-go ${{ matrix.go }} - name: setup-go ${{ matrix.go }}
uses: ./ uses: ./
@ -78,10 +94,10 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
os: [macos-latest, windows-latest, ubuntu-latest] os: [macos-latest, windows-latest, ubuntu-latest]
go: [1.7, 1.8.6] go: [1.9, 1.8.6]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: setup-go ${{ matrix.go }} - name: setup-go ${{ matrix.go }}
uses: ./ uses: ./

View File

@ -17,12 +17,12 @@ jobs:
operating-system: [ubuntu-latest, windows-latest] operating-system: [ubuntu-latest, windows-latest]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Setup node 12 - name: Setup node 16
uses: actions/setup-node@v2 uses: actions/setup-node@v3
with: with:
node-version: 12 node-version: 16
cache: npm cache: npm
- name: npm ci - name: npm ci

View File

@ -1 +1 @@
* @actions/spark * @actions/actions-service

View File

@ -55,7 +55,7 @@ a project may be further defined and clarified by project maintainers.
## Enforcement ## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at opensource@github.com. All reported by contacting the project team at opensource+actions/setup-go@github.com. All
complaints will be reviewed and investigated and will result in a response that complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident. obligated to maintain confidentiality with regard to the reporter of an incident.

101
README.md
View File

@ -1,45 +1,63 @@
# setup-go # setup-go
<p align="left"> [![build-test](https://github.com/actions/setup-go/actions/workflows/workflow.yml/badge.svg)](https://github.com/actions/setup-go/actions/workflows/workflow.yml)
<a href="https://github.com/actions/setup-go/actions"><img alt="GitHub Actions status" src="https://github.com/actions/setup-go/workflows/build-test/badge.svg"></a> [![Validate 'setup-go'](https://github.com/actions/setup-go/actions/workflows/versions.yml/badge.svg)](https://github.com/actions/setup-go/actions/workflows/versions.yml)
<a href="https://github.com/actions/setup-go/actions"><img alt="versions status" src="https://github.com/actions/setup-go/workflows/go-versions/badge.svg"></a>
</p>
This action sets up a go environment for use in actions by: This action sets up a go environment for use in actions by:
- optionally downloading and caching a version of Go by version and adding to PATH - Optionally downloading and caching a version of Go by version and adding to `PATH`.
- registering problem matchers for error output - Registering problem matchers for error output.
# V2 # V3
The V2 offers: The V3 edition of the action offers:
- Adds GOBIN to the PATH
- Proxy Support - Adds `GOBIN` to the `PATH`
- `stable` input - Proxy support
- Check latest version - Check latest version
- Bug Fixes (including issues around version matching and semver) - Bug fixes (including issues around version matching and semver)
The action will first check the local cache for a version match. If a version is not found locally, it will pull it from the `main` branch of the [go-versions](https://github.com/actions/go-versions/blob/main/versions-manifest.json) repository. On miss or failure, it will fall back to downloading directly from [go dist](https://storage.googleapis.com/golang). To change the default behavior, please use the [check-latest input](#check-latest-version). The action will first check the local cache for a version match. If a version is not found locally, it will pull it from the `main` branch of the [go-versions](https://github.com/actions/go-versions/blob/main/versions-manifest.json) repository. On miss or failure, it will fall back to downloading directly from [go dist](https://storage.googleapis.com/golang). To change the default behavior, please use the [check-latest input](#check-latest-version).
**Note:** The `setup-go` action uses executable binaries which are built by Golang side. The action does not build golang from source code.
Matching by [semver spec](https://github.com/npm/node-semver): Matching by [semver spec](https://github.com/npm/node-semver):
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: actions/setup-go@v2 - uses: actions/setup-go@v3
with: with:
go-version: '^1.13.1' # The Go version to download (if necessary) and use. go-version: '^1.13.1' # The Go version to download (if necessary) and use.
- run: go version - run: go version
``` ```
Matching an unstable pre-release:
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: actions/setup-go@v2 - uses: actions/setup-go@v3
with: with:
stable: 'false' go-version: '>=1.17.0'
go-version: '1.14.0-rc1' # The Go version to download (if necessary) and use. - run: go version
```
Matching an unstable pre-release:
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '1.18.0-rc.1' # The Go version to download (if necessary) and use.
- run: go version
```
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '1.16.0-beta.1' # The Go version to download (if necessary) and use.
- run: go version - run: go version
``` ```
@ -47,18 +65,19 @@ steps:
See [action.yml](action.yml) See [action.yml](action.yml)
## Basic: ## Basic
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: actions/setup-go@v2 - uses: actions/setup-go@v3
with: with:
go-version: '1.16.1' # The Go version to download (if necessary) and use. go-version: '1.16.1' # The Go version to download (if necessary) and use.
- run: go run hello.go - run: go run hello.go
``` ```
## Check latest version: ## Check latest version
The `check-latest` flag defaults to `false`. Use the default or set `check-latest` to `false` if you prefer stability and if you want to ensure a specific Go version is always used. The `check-latest` flag defaults to `false`. Use the default or set `check-latest` to `false` if you prefer stability and if you want to ensure a specific Go version is always used.
@ -68,15 +87,31 @@ If `check-latest` is set to `true`, the action first checks if the cached versio
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: actions/setup-go@v2 - uses: actions/setup-go@v3
with: with:
go-version: '1.14' go-version: '1.14'
check-latest: true check-latest: true
- run: go run hello.go - run: go run hello.go
``` ```
## Getting go version from the go.mod file
The `go-version-file` input accepts a path to a `go.mod` file containing the version of Go to be used by a project. As the `go.mod` file contains only major and minor (e.g. 1.18) tags, the action will search for the latest available patch version sequentially in the runner's directory with the cached tools, in the [version-manifest.json](https://github.com/actions/go-versions/blob/main/versions-manifest.json) file or at the go servers.
If both the `go-version` and the `go-version-file` inputs are provided then the `go-version` input is used.
> The action will search for the `go.mod` file relative to the repository root
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version-file: 'path/to/go.mod'
- run: go version
```
## Matrix testing
## Matrix Testing:
```yaml ```yaml
jobs: jobs:
build: build:
@ -86,20 +121,22 @@ jobs:
go: [ '1.14', '1.13' ] go: [ '1.14', '1.13' ]
name: Go ${{ matrix.go }} sample name: Go ${{ matrix.go }} sample
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Setup go - name: Setup go
uses: actions/setup-go@v2 uses: actions/setup-go@v3
with: with:
go-version: ${{ matrix.go }} go-version: ${{ matrix.go }}
- run: go run hello.go - run: go run hello.go
``` ```
### Supported version syntax ### Supported version syntax
The `go-version` input supports the following syntax: The `go-version` input supports the following syntax:
Specific versions: `1.15`, `1.16.1`, `1.17.0-rc2`, `1.16.0-beta1` - Specific versions: `1.15`, `1.16.1`, `1.17.0-rc.2`, `1.16.0-beta.1`
SemVer's version range syntax: `^1.13.1` - SemVer's version range syntax: `^1.13.1`, `>=1.18.0-rc.1`
For more information about semantic versioning please refer [semver](https://github.com/npm/node-semver) documentation
For more information about semantic versioning, please refer to [semver](https://github.com/npm/node-semver) documentation.
# License # License

12
__tests__/data/go.mod Normal file
View File

@ -0,0 +1,12 @@
module example.com/mymodule
go 1.14
require (
example.com/othermodule v1.2.3
example.com/thismodule v1.2.3
example.com/thatmodule v1.2.3
)
replace example.com/thatmodule => ../thatmodule
exclude example.com/thismodule v1.3.0

View File

@ -20,6 +20,7 @@ describe('setup-go', () => {
let inSpy: jest.SpyInstance; let inSpy: jest.SpyInstance;
let getBooleanInputSpy: jest.SpyInstance; let getBooleanInputSpy: jest.SpyInstance;
let exportVarSpy: jest.SpyInstance;
let findSpy: jest.SpyInstance; let findSpy: jest.SpyInstance;
let cnSpy: jest.SpyInstance; let cnSpy: jest.SpyInstance;
let logSpy: jest.SpyInstance; let logSpy: jest.SpyInstance;
@ -27,11 +28,12 @@ describe('setup-go', () => {
let platSpy: jest.SpyInstance; let platSpy: jest.SpyInstance;
let archSpy: jest.SpyInstance; let archSpy: jest.SpyInstance;
let dlSpy: jest.SpyInstance; let dlSpy: jest.SpyInstance;
let exSpy: jest.SpyInstance; let extractTarSpy: jest.SpyInstance;
let cacheSpy: jest.SpyInstance; let cacheSpy: jest.SpyInstance;
let dbgSpy: jest.SpyInstance; let dbgSpy: jest.SpyInstance;
let whichSpy: jest.SpyInstance; let whichSpy: jest.SpyInstance;
let existsSpy: jest.SpyInstance; let existsSpy: jest.SpyInstance;
let readFileSpy: jest.SpyInstance;
let mkdirpSpy: jest.SpyInstance; let mkdirpSpy: jest.SpyInstance;
let execSpy: jest.SpyInstance; let execSpy: jest.SpyInstance;
let getManifestSpy: jest.SpyInstance; let getManifestSpy: jest.SpyInstance;
@ -49,6 +51,7 @@ describe('setup-go', () => {
inSpy.mockImplementation(name => inputs[name]); inSpy.mockImplementation(name => inputs[name]);
getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput'); getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
getBooleanInputSpy.mockImplementation(name => inputs[name]); getBooleanInputSpy.mockImplementation(name => inputs[name]);
exportVarSpy = jest.spyOn(core, 'exportVariable');
// node // node
os = {}; os = {};
@ -61,7 +64,7 @@ describe('setup-go', () => {
// @actions/tool-cache // @actions/tool-cache
findSpy = jest.spyOn(tc, 'find'); findSpy = jest.spyOn(tc, 'find');
dlSpy = jest.spyOn(tc, 'downloadTool'); dlSpy = jest.spyOn(tc, 'downloadTool');
exSpy = jest.spyOn(tc, 'extractTar'); extractTarSpy = jest.spyOn(tc, 'extractTar');
cacheSpy = jest.spyOn(tc, 'cacheDir'); cacheSpy = jest.spyOn(tc, 'cacheDir');
getSpy = jest.spyOn(im, 'getVersionsDist'); getSpy = jest.spyOn(im, 'getVersionsDist');
getManifestSpy = jest.spyOn(tc, 'getManifestFromRepo'); getManifestSpy = jest.spyOn(tc, 'getManifestFromRepo');
@ -69,6 +72,7 @@ describe('setup-go', () => {
// io // io
whichSpy = jest.spyOn(io, 'which'); whichSpy = jest.spyOn(io, 'which');
existsSpy = jest.spyOn(fs, 'existsSync'); existsSpy = jest.spyOn(fs, 'existsSync');
readFileSpy = jest.spyOn(fs, 'readFileSync');
mkdirpSpy = jest.spyOn(io, 'mkdirP'); mkdirpSpy = jest.spyOn(io, 'mkdirP');
// gets // gets
@ -103,6 +107,11 @@ describe('setup-go', () => {
jest.restoreAllMocks(); jest.restoreAllMocks();
}, 100000); }, 100000);
it('can extract the major.minor.patch version from a given Go version string', async () => {
const goVersionOutput = 'go version go1.16.6 darwin/amd64';
expect(main.parseGoVersion(goVersionOutput)).toBe('1.16.6');
});
it('can find 1.9.7 from manifest on osx', async () => { it('can find 1.9.7 from manifest on osx', async () => {
os.platform = 'darwin'; os.platform = 'darwin';
os.arch = 'x64'; os.arch = 'x64';
@ -147,7 +156,7 @@ describe('setup-go', () => {
os.arch = 'x64'; os.arch = 'x64';
// spec: 1.13.0 => 1.13 // spec: 1.13.0 => 1.13
let match: im.IGoVersion | undefined = await im.findMatch('1.13.0', true); let match: im.IGoVersion | undefined = await im.findMatch('1.13.0');
expect(match).toBeDefined(); expect(match).toBeDefined();
let version: string = match ? match.version : ''; let version: string = match ? match.version : '';
expect(version).toBe('go1.13'); expect(version).toBe('go1.13');
@ -160,7 +169,7 @@ describe('setup-go', () => {
os.arch = 'x64'; os.arch = 'x64';
// spec: 1.13 => 1.13.7 (latest) // spec: 1.13 => 1.13.7 (latest)
let match: im.IGoVersion | undefined = await im.findMatch('1.13', true); let match: im.IGoVersion | undefined = await im.findMatch('1.13');
expect(match).toBeDefined(); expect(match).toBeDefined();
let version: string = match ? match.version : ''; let version: string = match ? match.version : '';
expect(version).toBe('go1.13.7'); expect(version).toBe('go1.13.7');
@ -173,7 +182,7 @@ describe('setup-go', () => {
os.arch = 'x64'; os.arch = 'x64';
// spec: ^1.13.6 => 1.13.7 // spec: ^1.13.6 => 1.13.7
let match: im.IGoVersion | undefined = await im.findMatch('^1.13.6', true); let match: im.IGoVersion | undefined = await im.findMatch('^1.13.6');
expect(match).toBeDefined(); expect(match).toBeDefined();
let version: string = match ? match.version : ''; let version: string = match ? match.version : '';
expect(version).toBe('go1.13.7'); expect(version).toBe('go1.13.7');
@ -186,7 +195,7 @@ describe('setup-go', () => {
os.arch = 'x32'; os.arch = 'x32';
// spec: 1 => 1.13.7 (latest) // spec: 1 => 1.13.7 (latest)
let match: im.IGoVersion | undefined = await im.findMatch('1', true); let match: im.IGoVersion | undefined = await im.findMatch('1');
expect(match).toBeDefined(); expect(match).toBeDefined();
let version: string = match ? match.version : ''; let version: string = match ? match.version : '';
expect(version).toBe('go1.13.7'); expect(version).toBe('go1.13.7');
@ -199,10 +208,7 @@ describe('setup-go', () => {
os.arch = 'x64'; os.arch = 'x64';
// spec: 1.14, stable=false => go1.14rc1 // spec: 1.14, stable=false => go1.14rc1
let match: im.IGoVersion | undefined = await im.findMatch( let match: im.IGoVersion | undefined = await im.findMatch('1.14.0-rc.1');
'1.14.0-rc1',
false
);
expect(match).toBeDefined(); expect(match).toBeDefined();
let version: string = match ? match.version : ''; let version: string = match ? match.version : '';
expect(version).toBe('go1.14rc1'); expect(version).toBe('go1.14rc1');
@ -218,7 +224,7 @@ describe('setup-go', () => {
findSpy.mockImplementation(() => toolPath); findSpy.mockImplementation(() => toolPath);
await main.run(); await main.run();
expect(logSpy).toHaveBeenCalledWith(`Setup go stable version spec 1.13.0`); expect(logSpy).toHaveBeenCalledWith(`Setup go version spec 1.13.0`);
}); });
it('evaluates to stable with no input', async () => { it('evaluates to stable with no input', async () => {
@ -230,7 +236,41 @@ describe('setup-go', () => {
findSpy.mockImplementation(() => toolPath); findSpy.mockImplementation(() => toolPath);
await main.run(); await main.run();
expect(logSpy).toHaveBeenCalledWith(`Setup go stable version spec 1.13.0`); expect(logSpy).toHaveBeenCalledWith(`Setup go version spec 1.13.0`);
});
it('does not export any variables for Go versions >=1.9', async () => {
inputs['go-version'] = '1.13.0';
inSpy.mockImplementation(name => inputs[name]);
let toolPath = path.normalize('/cache/go/1.13.0/x64');
findSpy.mockImplementation(() => toolPath);
let vars: {[key: string]: string} = {};
exportVarSpy.mockImplementation((name: string, val: string) => {
vars[name] = val;
});
await main.run();
expect(vars).toStrictEqual({});
});
it('exports GOROOT for Go versions <1.9', async () => {
inputs['go-version'] = '1.8';
inSpy.mockImplementation(name => inputs[name]);
let toolPath = path.normalize('/cache/go/1.8.0/x64');
findSpy.mockImplementation(() => toolPath);
let vars: {[key: string]: string} = {};
exportVarSpy.mockImplementation((name: string, val: string) => {
vars[name] = val;
});
await main.run();
expect(vars).toStrictEqual({
GOROOT: toolPath
});
}); });
it('finds a version of go already in the cache', async () => { it('finds a version of go already in the cache', async () => {
@ -274,14 +314,14 @@ describe('setup-go', () => {
findSpy.mockImplementation(() => ''); findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(() => '/some/temp/path'); dlSpy.mockImplementation(() => '/some/temp/path');
let toolPath = path.normalize('/cache/go/1.13.0/x64'); let toolPath = path.normalize('/cache/go/1.13.0/x64');
exSpy.mockImplementation(() => '/some/other/temp/path'); extractTarSpy.mockImplementation(() => '/some/other/temp/path');
cacheSpy.mockImplementation(() => toolPath); cacheSpy.mockImplementation(() => toolPath);
await main.run(); await main.run();
let expPath = path.join(toolPath, 'bin'); let expPath = path.join(toolPath, 'bin');
expect(dlSpy).toHaveBeenCalled(); expect(dlSpy).toHaveBeenCalled();
expect(exSpy).toHaveBeenCalled(); expect(extractTarSpy).toHaveBeenCalled();
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`); expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
}); });
@ -316,7 +356,7 @@ describe('setup-go', () => {
dlSpy.mockImplementation(async () => '/some/temp/path'); dlSpy.mockImplementation(async () => '/some/temp/path');
let toolPath = path.normalize('/cache/go/1.12.16/x64'); let toolPath = path.normalize('/cache/go/1.12.16/x64');
exSpy.mockImplementation(async () => '/some/other/temp/path'); extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath); cacheSpy.mockImplementation(async () => toolPath);
await main.run(); await main.run();
@ -324,7 +364,7 @@ describe('setup-go', () => {
let expPath = path.join(toolPath, 'bin'); let expPath = path.join(toolPath, 'bin');
expect(dlSpy).toHaveBeenCalled(); expect(dlSpy).toHaveBeenCalled();
expect(exSpy).toHaveBeenCalled(); expect(extractTarSpy).toHaveBeenCalled();
expect(logSpy).not.toHaveBeenCalledWith( expect(logSpy).not.toHaveBeenCalledWith(
'Not found in manifest. Falling back to download directly from Go' 'Not found in manifest. Falling back to download directly from Go'
); );
@ -353,7 +393,7 @@ describe('setup-go', () => {
dlSpy.mockImplementation(async () => '/some/temp/path'); dlSpy.mockImplementation(async () => '/some/temp/path');
let toolPath = path.normalize('/cache/go/1.12.17/x64'); let toolPath = path.normalize('/cache/go/1.12.17/x64');
exSpy.mockImplementation(async () => '/some/other/temp/path'); extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath); cacheSpy.mockImplementation(async () => toolPath);
await main.run(); await main.run();
@ -361,7 +401,7 @@ describe('setup-go', () => {
let expPath = path.join(toolPath, 'bin'); let expPath = path.join(toolPath, 'bin');
expect(dlSpy).toHaveBeenCalled(); expect(dlSpy).toHaveBeenCalled();
expect(exSpy).toHaveBeenCalled(); expect(extractTarSpy).toHaveBeenCalled();
expect(logSpy).not.toHaveBeenCalledWith( expect(logSpy).not.toHaveBeenCalledWith(
'Not found in manifest. Falling back to download directly from Go' 'Not found in manifest. Falling back to download directly from Go'
); );
@ -390,18 +430,18 @@ describe('setup-go', () => {
dlSpy.mockImplementation(async () => '/some/temp/path'); dlSpy.mockImplementation(async () => '/some/temp/path');
let toolPath = path.normalize('/cache/go/1.12.14/x64'); let toolPath = path.normalize('/cache/go/1.12.14/x64');
exSpy.mockImplementation(async () => '/some/other/temp/path'); extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath); cacheSpy.mockImplementation(async () => toolPath);
await main.run(); await main.run();
let expPath = path.join(toolPath, 'bin'); let expPath = path.join(toolPath, 'bin');
expect(logSpy).toHaveBeenCalledWith('Setup go stable version spec 1.12.14'); expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.12.14');
expect(findSpy).toHaveBeenCalled(); expect(findSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.12.14...'); expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.12.14...');
expect(dlSpy).toHaveBeenCalled(); expect(dlSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith('matching 1.12.14...'); expect(logSpy).toHaveBeenCalledWith('matching 1.12.14...');
expect(exSpy).toHaveBeenCalled(); expect(extractTarSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith( expect(logSpy).toHaveBeenCalledWith(
'Not found in manifest. Falling back to download directly from Go' 'Not found in manifest. Falling back to download directly from Go'
); );
@ -560,11 +600,11 @@ describe('setup-go', () => {
// 1.13.1 => 1.13.1 // 1.13.1 => 1.13.1
// 1.13 => 1.13.0 // 1.13 => 1.13.0
// 1.10beta1 => 1.10.0-beta1, 1.10rc1 => 1.10.0-rc1 // 1.10beta1 => 1.10.0-beta.1, 1.10rc1 => 1.10.0-rc.1
// 1.8.5beta1 => 1.8.5-beta1, 1.8.5rc1 => 1.8.5-rc1 // 1.8.5beta1 => 1.8.5-beta.1, 1.8.5rc1 => 1.8.5-rc.1
it('converts prerelease versions', async () => { it('converts prerelease versions', async () => {
expect(im.makeSemver('1.10beta1')).toBe('1.10.0-beta1'); expect(im.makeSemver('1.10beta1')).toBe('1.10.0-beta.1');
expect(im.makeSemver('1.10rc1')).toBe('1.10.0-rc1'); expect(im.makeSemver('1.10rc1')).toBe('1.10.0-rc.1');
}); });
it('converts dot zero versions', async () => { it('converts dot zero versions', async () => {
@ -603,12 +643,12 @@ describe('setup-go', () => {
const toolPath = path.normalize('/cache/go/1.16.1/x64'); const toolPath = path.normalize('/cache/go/1.16.1/x64');
findSpy.mockReturnValue(toolPath); findSpy.mockReturnValue(toolPath);
dlSpy.mockImplementation(async () => '/some/temp/path'); dlSpy.mockImplementation(async () => '/some/temp/path');
exSpy.mockImplementation(async () => '/some/other/temp/path'); extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath); cacheSpy.mockImplementation(async () => toolPath);
await main.run(); await main.run();
expect(logSpy).toHaveBeenCalledWith('Setup go stable version spec 1.16'); expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.16');
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
}); });
@ -625,7 +665,7 @@ describe('setup-go', () => {
findSpy.mockImplementation(() => ''); findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path'); dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize('/cache/go/1.17.5/x64'); const toolPath = path.normalize('/cache/go/1.17.5/x64');
exSpy.mockImplementation(async () => '/some/other/temp/path'); extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath); cacheSpy.mockImplementation(async () => toolPath);
const expectedUrl = const expectedUrl =
'https://github.com/actions/go-versions/releases/download/1.17.6-1668090892/go-1.17.6-darwin-x64.tar.gz'; 'https://github.com/actions/go-versions/releases/download/1.17.6-1668090892/go-1.17.6-darwin-x64.tar.gz';
@ -633,7 +673,7 @@ describe('setup-go', () => {
await main.run(); await main.run();
expect(logSpy).toHaveBeenCalledWith( expect(logSpy).toHaveBeenCalledWith(
`Setup go stable version spec ${versionSpec}` `Setup go version spec ${versionSpec}`
); );
expect(logSpy).toHaveBeenCalledWith( expect(logSpy).toHaveBeenCalledWith(
'Attempting to resolve the latest version from the manifest...' 'Attempting to resolve the latest version from the manifest...'
@ -646,7 +686,7 @@ describe('setup-go', () => {
expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...'); expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...');
expect(logSpy).toHaveBeenCalledWith('Added go to the path'); expect(logSpy).toHaveBeenCalledWith('Added go to the path');
expect(logSpy).toHaveBeenCalledWith( expect(logSpy).toHaveBeenCalledWith(
`Successfully setup go version ${versionSpec}` `Successfully set up Go version ${versionSpec}`
); );
}); });
@ -666,7 +706,7 @@ describe('setup-go', () => {
dlSpy.mockImplementation(async () => '/some/temp/path'); dlSpy.mockImplementation(async () => '/some/temp/path');
let toolPath = path.normalize('/cache/go/1.13.7/x64'); let toolPath = path.normalize('/cache/go/1.13.7/x64');
exSpy.mockImplementation(async () => '/some/other/temp/path'); extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath); cacheSpy.mockImplementation(async () => toolPath);
await main.run(); await main.run();
@ -674,7 +714,7 @@ describe('setup-go', () => {
let expPath = path.join(toolPath, 'bin'); let expPath = path.join(toolPath, 'bin');
expect(dlSpy).toHaveBeenCalled(); expect(dlSpy).toHaveBeenCalled();
expect(exSpy).toHaveBeenCalled(); expect(extractTarSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith( expect(logSpy).toHaveBeenCalledWith(
'Attempting to resolve the latest version from the manifest...' 'Attempting to resolve the latest version from the manifest...'
); );
@ -708,7 +748,7 @@ describe('setup-go', () => {
dlSpy.mockImplementation(async () => '/some/temp/path'); dlSpy.mockImplementation(async () => '/some/temp/path');
let toolPath = path.normalize('/cache/go/1.13.7/x64'); let toolPath = path.normalize('/cache/go/1.13.7/x64');
exSpy.mockImplementation(async () => '/some/other/temp/path'); extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath); cacheSpy.mockImplementation(async () => toolPath);
await main.run(); await main.run();
@ -719,7 +759,7 @@ describe('setup-go', () => {
`Failed to resolve version ${versionSpec} from manifest` `Failed to resolve version ${versionSpec} from manifest`
); );
expect(dlSpy).toHaveBeenCalled(); expect(dlSpy).toHaveBeenCalled();
expect(exSpy).toHaveBeenCalled(); expect(extractTarSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith( expect(logSpy).toHaveBeenCalledWith(
'Attempting to resolve the latest version from the manifest...' 'Attempting to resolve the latest version from the manifest...'
); );
@ -736,4 +776,68 @@ describe('setup-go', () => {
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`); expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
}); });
}); });
describe('go-version-file', () => {
const goModContents = `module example.com/mymodule
go 1.14
require (
example.com/othermodule v1.2.3
example.com/thismodule v1.2.3
example.com/thatmodule v1.2.3
)
replace example.com/thatmodule => ../thatmodule
exclude example.com/thismodule v1.3.0
`;
it('reads version from go.mod', async () => {
inputs['go-version-file'] = 'go.mod';
existsSpy.mockImplementation(path => true);
readFileSpy.mockImplementation(() => Buffer.from(goModContents));
await main.run();
expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.14');
expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.14...');
expect(logSpy).toHaveBeenCalledWith('matching 1.14...');
});
it('reads version from .go-version', async () => {
inputs['go-version-file'] = '.go-version';
existsSpy.mockImplementation(path => true);
readFileSpy.mockImplementation(() => Buffer.from(`1.13.0${osm.EOL}`));
await main.run();
expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.13.0');
expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.13.0...');
expect(logSpy).toHaveBeenCalledWith('matching 1.13.0...');
});
it('is overwritten by go-version', async () => {
inputs['go-version'] = '1.13.1';
inputs['go-version-file'] = 'go.mod';
existsSpy.mockImplementation(path => true);
readFileSpy.mockImplementation(() => Buffer.from(goModContents));
await main.run();
expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.13.1');
expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.13.1...');
expect(logSpy).toHaveBeenCalledWith('matching 1.13.1...');
});
it('reports a read failure', async () => {
inputs['go-version-file'] = 'go.mod';
existsSpy.mockImplementation(path => false);
await main.run();
expect(cnSpy).toHaveBeenCalledWith(
`::error::The specified go version file at: go.mod does not exist${osm.EOL}`
);
});
});
}); });

View File

@ -4,15 +4,17 @@ author: 'GitHub'
inputs: inputs:
go-version: go-version:
description: 'The Go version to download (if necessary) and use. Supports semver spec and ranges.' description: 'The Go version to download (if necessary) and use. Supports semver spec and ranges.'
go-version-file:
description: 'Path to the go.mod file.'
check-latest: check-latest:
description: 'Set this option to true if you want the action to always check for the latest available version that satisfies the version spec' description: 'Set this option to true if you want the action to always check for the latest available version that satisfies the version spec'
default: false default: false
stable:
description: 'Whether to download only stable versions'
default: 'true'
token: token:
description: Used to pull node distributions from go-versions. Since there's a default, this is typically not supplied by the user. description: Used to pull node distributions from go-versions. Since there's a default, this is typically not supplied by the user.
default: ${{ github.token }} default: ${{ github.token }}
outputs:
go-version:
description: 'The installed Go version. Useful when given a version range as input.'
runs: runs:
using: 'node12' using: 'node16'
main: 'dist/index.js' main: 'dist/index.js'

6970
dist/index.js vendored

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
# 0. Caching dependencies
Date: 2022-04-13
Status: Accepted
# Context
`actions/setup-go` is the one of the most popular action related to Golang in GitHub Actions. Many customers use it in conjunction with [actions/cache](https://github.com/actions/cache) to speed up dependency installation process.
See more examples on proper usage in [actions/cache documentation](https://github.com/actions/cache/blob/main/examples.md#go---modules).
# Goals & Anti-Goals
Integration of caching functionality into `actions/setup-go` action will bring the following benefits for action users:
- Decrease the entry threshold for using the cache for Go dependencies and simplify initial configuration
- Simplify YAML pipelines because there will be no need for additional steps to enable caching
- More users will use cache for Go so more customers will have fast builds!
We don't pursue the goal to provide wide customization of caching in scope of `actions/setup-go` action. The purpose of this integration is covering ~90% of basic use-cases. If user needs flexible customization, we should advice them to use `actions/cache` directly.
# Decision
- Add `cache` input parameter to `actions/setup-go`. For now, input will accept the following values:
- `true` - enable caching for go dependencies
- `false`- disable caching for go dependencies. This value will be set as default value
- Cache feature will be disabled by default to make sure that we don't break existing customers. We will consider enabling cache by default in next major releases
- Action will try to search a go.sum files in the repository and throw error in the scenario that it was not found
- The hash of found file will be used as cache key (the same approach like [actions/cache](https://github.com/actions/cache/blob/main/examples.md#go---modules) recommends)
- The following key cache will be used `${{ runner.os }}-go${{ go-version }}-${{ hashFiles('<go.sum-path>') }}`
- Action will cache global cache from the `go env GOMODCACHE` and `go env GOCACHE` commands.
- Add a `cache-dependency-path` input parameter to `actions/setup-go`. The new input will accept an array or regex of dependency files. The field will accept a path (relative to the repository root) to dependency files. If the provided path contains wildcards, the action will search all matching files and calculate a common hash like the ${{ hashFiles('**/go.sum') }} YAML construction does.
# Example of real use-cases
- With cache
```yml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '18'
cache: true
```
- With cache-dependency-path
```yml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '18'
cache: true
cache-dependency-path: **/go.sum
```
```yml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '18'
cache: true
cache-dependency-path: |
**/go.sum
**/go.mod
```
# Release process
As soon as functionality is implemented, we will release minor update of action. No need to bump major version since there are no breaking changes for existing users.
After that, we will update [starter-workflows](https://github.com/actions/starter-workflows/blob/main/ci/go.yml)

4667
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -31,9 +31,9 @@
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^27.0.2", "@types/jest": "^27.0.2",
"@types/node": "^12.0.4", "@types/node": "^16.11.25",
"@types/semver": "^6.0.0", "@types/semver": "^6.0.0",
"@zeit/ncc": "^0.21.0", "@vercel/ncc": "^0.33.4",
"jest": "^27.2.5", "jest": "^27.2.5",
"jest-circus": "^27.2.5", "jest-circus": "^27.2.5",
"nock": "^10.0.6", "nock": "^10.0.6",

View File

@ -4,6 +4,7 @@ import * as path from 'path';
import * as semver from 'semver'; import * as semver from 'semver';
import * as httpm from '@actions/http-client'; import * as httpm from '@actions/http-client';
import * as sys from './system'; import * as sys from './system';
import fs from 'fs';
import os from 'os'; import os from 'os';
type InstallationType = 'dist' | 'manifest'; type InstallationType = 'dist' | 'manifest';
@ -30,7 +31,6 @@ export interface IGoVersionInfo {
export async function getGo( export async function getGo(
versionSpec: string, versionSpec: string,
stable: boolean,
checkLatest: boolean, checkLatest: boolean,
auth: string | undefined auth: string | undefined
) { ) {
@ -41,7 +41,7 @@ export async function getGo(
core.info('Attempting to resolve the latest version from the manifest...'); core.info('Attempting to resolve the latest version from the manifest...');
const resolvedVersion = await resolveVersionFromManifest( const resolvedVersion = await resolveVersionFromManifest(
versionSpec, versionSpec,
stable, true,
auth auth
); );
if (resolvedVersion) { if (resolvedVersion) {
@ -68,7 +68,7 @@ export async function getGo(
// Try download from internal distribution (popular versions only) // Try download from internal distribution (popular versions only)
// //
try { try {
info = await getInfoFromManifest(versionSpec, stable, auth); info = await getInfoFromManifest(versionSpec, true, auth);
if (info) { if (info) {
downloadPath = await installGoVersion(info, auth); downloadPath = await installGoVersion(info, auth);
} else { } else {
@ -95,7 +95,7 @@ export async function getGo(
// Download from storage.googleapis.com // Download from storage.googleapis.com
// //
if (!downloadPath) { if (!downloadPath) {
info = await getInfoFromDist(versionSpec, stable); info = await getInfoFromDist(versionSpec);
if (!info) { if (!info) {
throw new Error( throw new Error(
`Unable to find Go version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.` `Unable to find Go version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.`
@ -191,11 +191,10 @@ export async function getInfoFromManifest(
} }
async function getInfoFromDist( async function getInfoFromDist(
versionSpec: string, versionSpec: string
stable: boolean
): Promise<IGoVersionInfo | null> { ): Promise<IGoVersionInfo | null> {
let version: IGoVersion | undefined; let version: IGoVersion | undefined;
version = await findMatch(versionSpec, stable); version = await findMatch(versionSpec);
if (!version) { if (!version) {
return null; return null;
} }
@ -211,8 +210,7 @@ async function getInfoFromDist(
} }
export async function findMatch( export async function findMatch(
versionSpec: string, versionSpec: string
stable: boolean
): Promise<IGoVersion | undefined> { ): Promise<IGoVersion | undefined> {
let archFilter = sys.getArch(); let archFilter = sys.getArch();
let platFilter = sys.getPlatform(); let platFilter = sys.getPlatform();
@ -233,18 +231,8 @@ export async function findMatch(
let candidate: IGoVersion = candidates[i]; let candidate: IGoVersion = candidates[i];
let version = makeSemver(candidate.version); let version = makeSemver(candidate.version);
// 1.13.0 is advertised as 1.13 preventing being able to match exactly 1.13.0
// since a semver of 1.13 would match latest 1.13
let parts: string[] = version.split('.');
if (parts.length == 2) {
version = version + '.0';
}
core.debug(`check ${version} satisfies ${versionSpec}`); core.debug(`check ${version} satisfies ${versionSpec}`);
if ( if (semver.satisfies(version, versionSpec)) {
semver.satisfies(version, versionSpec) &&
(!stable || candidate.stable === stable)
) {
goFile = candidate.files.find(file => { goFile = candidate.files.find(file => {
core.debug( core.debug(
`${file.arch}===${archFilter} && ${file.os}===${platFilter}` `${file.arch}===${archFilter} && ${file.os}===${platFilter}`
@ -284,20 +272,41 @@ export async function getVersionsDist(
// Convert the go version syntax into semver for semver matching // Convert the go version syntax into semver for semver matching
// 1.13.1 => 1.13.1 // 1.13.1 => 1.13.1
// 1.13 => 1.13.0 // 1.13 => 1.13.0
// 1.10beta1 => 1.10.0-beta1, 1.10rc1 => 1.10.0-rc1 // 1.10beta1 => 1.10.0-beta.1, 1.10rc1 => 1.10.0-rc.1
// 1.8.5beta1 => 1.8.5-beta1, 1.8.5rc1 => 1.8.5-rc1 // 1.8.5beta1 => 1.8.5-beta.1, 1.8.5rc1 => 1.8.5-rc.1
export function makeSemver(version: string): string { export function makeSemver(version: string): string {
version = version.replace('go', ''); version = version.replace('go', '');
version = version.replace('beta', '-beta').replace('rc', '-rc'); version = version.replace('beta', '-beta.').replace('rc', '-rc.');
let parts = version.split('-'); let parts = version.split('-');
let verPart: string = parts[0]; let semVersion = semver.coerce(parts[0])?.version;
let prereleasePart = parts.length > 1 ? `-${parts[1]}` : ''; if (!semVersion) {
throw new Error(
let verParts: string[] = verPart.split('.'); `The version: ${version} can't be changed to SemVer notation`
if (verParts.length == 2) { );
verPart += '.0';
} }
return `${verPart}${prereleasePart}`; if (!parts[1]) {
return semVersion;
}
const fullVersion = semver.valid(`${semVersion}-${parts[1]}`);
if (!fullVersion) {
throw new Error(
`The version: ${version} can't be changed to SemVer notation`
);
}
return fullVersion;
}
export function parseGoVersionFile(versionFilePath: string): string {
const contents = fs.readFileSync(versionFilePath).toString();
if (path.basename(versionFilePath) === 'go.mod') {
const match = contents.match(/^go (\d+(\.\d+)*)/m);
return match ? match[1] : '';
}
return contents.trim();
} }

View File

@ -1,6 +1,7 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as io from '@actions/io'; import * as io from '@actions/io';
import * as installer from './installer'; import * as installer from './installer';
import * as semver from 'semver';
import path from 'path'; import path from 'path';
import cp from 'child_process'; import cp from 'child_process';
import fs from 'fs'; import fs from 'fs';
@ -12,33 +13,30 @@ export async function run() {
// versionSpec is optional. If supplied, install / use from the tool cache // 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. // If not supplied then problem matchers will still be setup. Useful for self-hosted.
// //
let versionSpec = core.getInput('go-version'); const versionSpec = resolveVersionInput();
// stable will be true unless false is the exact input core.info(`Setup go version spec ${versionSpec}`);
// since getting unstable versions should be explicit
let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
core.info(`Setup go ${stable ? 'stable' : ''} version spec ${versionSpec}`);
if (versionSpec) { if (versionSpec) {
let token = core.getInput('token'); let token = core.getInput('token');
let auth = !token || isGhes() ? undefined : `token ${token}`; let auth = !token || isGhes() ? undefined : `token ${token}`;
const checkLatest = core.getBooleanInput('check-latest'); const checkLatest = core.getBooleanInput('check-latest');
const installDir = await installer.getGo( const installDir = await installer.getGo(versionSpec, checkLatest, auth);
versionSpec,
stable,
checkLatest,
auth
);
core.exportVariable('GOROOT', installDir);
core.addPath(path.join(installDir, 'bin')); core.addPath(path.join(installDir, 'bin'));
core.info('Added go to the path'); core.info('Added go to the path');
const version = installer.makeSemver(versionSpec);
// Go versions less than 1.9 require GOROOT to be set
if (semver.lt(version, '1.9.0')) {
core.info('Setting GOROOT for Go version < 1.9');
core.exportVariable('GOROOT', installDir);
}
let added = await addBinToPath(); let added = await addBinToPath();
core.debug(`add bin ${added}`); core.debug(`add bin ${added}`);
core.info(`Successfully setup go version ${versionSpec}`); core.info(`Successfully set up Go version ${versionSpec}`);
} }
// add problem matchers // add problem matchers
@ -50,6 +48,8 @@ export async function run() {
let goVersion = (cp.execSync(`${goPath} version`) || '').toString(); let goVersion = (cp.execSync(`${goPath} version`) || '').toString();
core.info(goVersion); core.info(goVersion);
core.setOutput('go-version', parseGoVersion(goVersion));
core.startGroup('go env'); core.startGroup('go env');
let goEnv = (cp.execSync(`${goPath} env`) || '').toString(); let goEnv = (cp.execSync(`${goPath} env`) || '').toString();
core.info(goEnv); core.info(goEnv);
@ -69,19 +69,19 @@ export async function addBinToPath(): Promise<boolean> {
} }
let buf = cp.execSync('go env GOPATH'); let buf = cp.execSync('go env GOPATH');
if (buf) { if (buf.length > 1) {
let gp = buf.toString().trim(); let gp = buf.toString().trim();
core.debug(`go env GOPATH :${gp}:`); core.debug(`go env GOPATH :${gp}:`);
if (!fs.existsSync(gp)) { if (!fs.existsSync(gp)) {
// some of the hosted images have go install but not profile dir // some of the hosted images have go install but not profile dir
core.debug(`creating ${gp}`); core.debug(`creating ${gp}`);
io.mkdirP(gp); await io.mkdirP(gp);
} }
let bp = path.join(gp, 'bin'); let bp = path.join(gp, 'bin');
if (!fs.existsSync(bp)) { if (!fs.existsSync(bp)) {
core.debug(`creating ${bp}`); core.debug(`creating ${bp}`);
io.mkdirP(bp); await io.mkdirP(bp);
} }
core.addPath(bp); core.addPath(bp);
@ -96,3 +96,37 @@ function isGhes(): boolean {
); );
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM'; return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
} }
export function parseGoVersion(versionString: string): string {
// get the installed version as an Action output
// based on go/src/cmd/go/internal/version/version.go:
// fmt.Printf("go version %s %s/%s\n", runtime.Version(), runtime.GOOS, runtime.GOARCH)
// expecting go<version> for runtime.Version()
return versionString.split(' ')[2].slice('go'.length);
}
function resolveVersionInput(): string {
let version = core.getInput('go-version');
const versionFilePath = core.getInput('go-version-file');
if (version && versionFilePath) {
core.warning(
'Both go-version and go-version-file inputs are specified, only go-version will be used'
);
}
if (version) {
return version;
}
if (versionFilePath) {
if (!fs.existsSync(versionFilePath)) {
throw new Error(
`The specified go version file at: ${versionFilePath} does not exist`
);
}
version = installer.parseGoVersionFile(versionFilePath);
}
return version;
}

View File

@ -1,4 +1,4 @@
let os = require('os'); const os = require('os');
export function getPlatform(): string { export function getPlatform(): string {
// darwin and linux match already // darwin and linux match already