mirror of
				https://github.com/actions/setup-go.git
				synced 2025-10-31 15:50:33 +00:00 
			
		
		
		
	Compare commits
	
		
			4 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 1616116e1b | ||
|   | 0f551ac199 | ||
|   | e1c0a1665b | ||
|   | 78bd24e01a | 
							
								
								
									
										105
									
								
								.github/workflows/versions.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										105
									
								
								.github/workflows/versions.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,51 +1,74 @@ | ||||
| name: go-versions | ||||
| name: Validate 'setup-go' | ||||
| on: | ||||
|     push: | ||||
|       branches: | ||||
|         - master | ||||
|       paths-ignore: | ||||
|         - '**.md' | ||||
|     pull_request: | ||||
|       paths-ignore: | ||||
|         - '**.md' | ||||
|   push: | ||||
|     branches: | ||||
|       - master | ||||
|     paths-ignore: | ||||
|       - '**.md' | ||||
|   pull_request: | ||||
|     paths-ignore: | ||||
|       - '**.md' | ||||
|   schedule: | ||||
|     - cron: 0 0 * * * | ||||
|  | ||||
| jobs: | ||||
|   run: | ||||
|     name: Go | ||||
|     runs-on: ${{ matrix.operating-system }} | ||||
|   local-cache: | ||||
|     name: Setup local-cache version | ||||
|     runs-on: ${{ matrix.os }} | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macos-latest] | ||||
|         os: [macos-latest, windows-latest, ubuntu-latest] | ||||
|         go: [1.12, 1.13, 1.14] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v2 | ||||
|  | ||||
|       - name: setup-go ${{ matrix.go }} | ||||
|         uses: ./ | ||||
|         with: | ||||
|           go-version: ${{ matrix.go }} | ||||
|  | ||||
|       - name: verify go | ||||
|         run: __tests__/verify-go.sh ${{ matrix.go }} | ||||
|         shell: bash | ||||
|  | ||||
|   setup-versions-from-manifest: | ||||
|     name: Setup ${{ matrix.go }} ${{ matrix.os }} | ||||
|     runs-on: ${{ matrix.os }} | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         os: [macos-latest, windows-latest, ubuntu-latest] | ||||
|         go: [1.12.16, 1.13.11, 1.14.3] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v2 | ||||
|        | ||||
|       - name: setup-go ${{ matrix.go }} | ||||
|         uses: ./ | ||||
|         with: | ||||
|           go-version: ${{ matrix.go }} | ||||
|        | ||||
|       - name: verify go | ||||
|         run: __tests__/verify-go.sh ${{ matrix.go }} | ||||
|         shell: bash | ||||
|  | ||||
|   setup-versions-from-dist: | ||||
|     name: Setup ${{ matrix.go }} ${{ matrix.os }} | ||||
|     runs-on: ${{ matrix.os }} | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         os: [macos-latest, windows-latest, ubuntu-latest] | ||||
|         go: [1.7, 1.8.6] | ||||
|     steps: | ||||
|     - name: Checkout | ||||
|       uses: actions/checkout@v2 | ||||
|  | ||||
|     - name: setup-go ^1.13.6 | ||||
|     - name: setup-go ${{ matrix.go }} | ||||
|       uses: ./ | ||||
|       with: | ||||
|         go-version: ^1.13.6 | ||||
|  | ||||
|     - name: validate version  | ||||
|       run: go version | grep "go1." | ||||
|  | ||||
|     - name: setup-go 1.13 | ||||
|       uses: ./ | ||||
|       with: | ||||
|         go-version: 1.13 | ||||
|  | ||||
|     - name: validate version  | ||||
|       run: go version | grep "go1.13."       | ||||
|  | ||||
|     - name: setup-go 1.12.9 | ||||
|       uses: ./ | ||||
|       with: | ||||
|         go-version: 1.12.9 | ||||
|  | ||||
|     - name: validate version  | ||||
|       run: go version | grep "go1.12.9" | ||||
|  | ||||
|     - name: dump env | ||||
|         go-version: ${{ matrix.go }} | ||||
|     - name: verify go | ||||
|       run: __tests__/verify-go.sh ${{ matrix.go }} | ||||
|       shell: bash | ||||
|       run: | | ||||
|         echo $PATH | ||||
|         echo go versions in tool cache:  | ||||
|         echo $(ls $RUNNER_TOOL_CACHE/go)        | ||||
|   | ||||
| @@ -11,9 +11,10 @@ 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 | ||||
| - registering problem matchers for error output | ||||
|  | ||||
| # V2 Beta | ||||
| # V2 | ||||
|  | ||||
| The V2 beta offers: | ||||
| The V2 offers: | ||||
| - Adds GOBIN to the PATH | ||||
| - Proxy Support | ||||
| - stable input  | ||||
| - Bug Fixes (including issues around version matching and semver) | ||||
| @@ -22,7 +23,7 @@ Matching by semver spec: | ||||
| ```yaml | ||||
| steps: | ||||
| - uses: actions/checkout@v2 | ||||
| - uses: actions/setup-go@v2-beta | ||||
| - uses: actions/setup-go@v2 | ||||
|   with: | ||||
|     go-version: '^1.13.1' # The Go version to download (if necessary) and use. | ||||
| - run: go version | ||||
| @@ -32,7 +33,7 @@ Matching an unstable pre-release: | ||||
| ```yaml | ||||
| steps: | ||||
| - uses: actions/checkout@v2 | ||||
| - uses: actions/setup-go@v2-beta | ||||
| - uses: actions/setup-go@v2 | ||||
|   with: | ||||
|     stable: 'false' | ||||
|     go-version: '1.14.0-rc1' # The Go version to download (if necessary) and use. | ||||
|   | ||||
							
								
								
									
										77
									
								
								__tests__/data/versions-manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								__tests__/data/versions-manifest.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| [ | ||||
|     { | ||||
|       "version": "1.12.17", | ||||
|       "stable": true, | ||||
|       "release_url": "https://github.com/actions/go-versions/releases/tag/1.12.17-20200616.21", | ||||
|       "files": [ | ||||
|         { | ||||
|           "filename": "go-1.12.17-darwin-x64.tar.gz", | ||||
|           "arch": "x64", | ||||
|           "platform": "darwin", | ||||
|           "download_url": "https://github.com/actions/go-versions/releases/download/1.12.17-20200616.21/go-1.12.17-darwin-x64.tar.gz" | ||||
|         }, | ||||
|         { | ||||
|           "filename": "go-1.12.17-linux-x64.tar.gz", | ||||
|           "arch": "x64", | ||||
|           "platform": "linux", | ||||
|           "download_url": "https://github.com/actions/go-versions/releases/download/1.12.17-20200616.21/go-1.12.17-linux-x64.tar.gz" | ||||
|         }, | ||||
|         { | ||||
|           "filename": "go-1.12.17-win32-x64.zip", | ||||
|           "arch": "x64", | ||||
|           "platform": "win32", | ||||
|           "download_url": "https://github.com/actions/go-versions/releases/download/1.12.17-20200616.21/go-1.12.17-win32-x64.zip" | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "version": "1.12.16", | ||||
|       "stable": true, | ||||
|       "release_url": "https://github.com/actions/go-versions/releases/tag/1.12.16-20200616.20", | ||||
|       "files": [ | ||||
|         { | ||||
|           "filename": "go-1.12.16-darwin-x64.tar.gz", | ||||
|           "arch": "x64", | ||||
|           "platform": "darwin", | ||||
|           "download_url": "https://github.com/actions/go-versions/releases/download/1.12.16-20200616.20/go-1.12.16-darwin-x64.tar.gz" | ||||
|         }, | ||||
|         { | ||||
|           "filename": "go-1.12.16-linux-x64.tar.gz", | ||||
|           "arch": "x64", | ||||
|           "platform": "linux", | ||||
|           "download_url": "https://github.com/actions/go-versions/releases/download/1.12.16-20200616.20/go-1.12.16-linux-x64.tar.gz" | ||||
|         }, | ||||
|         { | ||||
|           "filename": "go-1.12.16-win32-x64.zip", | ||||
|           "arch": "x64", | ||||
|           "platform": "win32", | ||||
|           "download_url": "https://github.com/actions/go-versions/releases/download/1.12.16-20200616.20/go-1.12.16-win32-x64.zip" | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "version": "1.9.7", | ||||
|       "stable": true, | ||||
|       "release_url": "https://github.com/actions/go-versions/releases/tag/1.9.7-20200616.1", | ||||
|       "files": [ | ||||
|         { | ||||
|           "filename": "go-1.9.7-darwin-x64.tar.gz", | ||||
|           "arch": "x64", | ||||
|           "platform": "darwin", | ||||
|           "download_url": "https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-darwin-x64.tar.gz" | ||||
|         }, | ||||
|         { | ||||
|           "filename": "go-1.9.7-linux-x64.tar.gz", | ||||
|           "arch": "x64", | ||||
|           "platform": "linux", | ||||
|           "download_url": "https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-linux-x64.tar.gz" | ||||
|         }, | ||||
|         { | ||||
|           "filename": "go-1.9.7-win32-x64.zip", | ||||
|           "arch": "x64", | ||||
|           "platform": "win32", | ||||
|           "download_url": "https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-win32-x64.zip" | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
|   ] | ||||
| @@ -3,13 +3,14 @@ import * as io from '@actions/io'; | ||||
| import * as tc from '@actions/tool-cache'; | ||||
| import fs from 'fs'; | ||||
| import cp from 'child_process'; | ||||
| import osm = require('os'); | ||||
| import osm from 'os'; | ||||
| import path from 'path'; | ||||
| import * as main from '../src/main'; | ||||
| import * as im from '../src/installer'; | ||||
|  | ||||
| let goJsonData = require('./data/golang-dl.json'); | ||||
| let matchers = require('../matchers.json'); | ||||
| let goTestManifest = require('./data/versions-manifest.json'); | ||||
| let matcherPattern = matchers.problemMatcher[0].pattern[0]; | ||||
| let matcherRegExp = new RegExp(matcherPattern.regexp); | ||||
|  | ||||
| @@ -32,6 +33,7 @@ describe('setup-go', () => { | ||||
|   let existsSpy: jest.SpyInstance; | ||||
|   let mkdirpSpy: jest.SpyInstance; | ||||
|   let execSpy: jest.SpyInstance; | ||||
|   let getManifestSpy: jest.SpyInstance; | ||||
|  | ||||
|   beforeEach(() => { | ||||
|     // @actions/core | ||||
| @@ -52,18 +54,22 @@ describe('setup-go', () => { | ||||
|     dlSpy = jest.spyOn(tc, 'downloadTool'); | ||||
|     exSpy = jest.spyOn(tc, 'extractTar'); | ||||
|     cacheSpy = jest.spyOn(tc, 'cacheDir'); | ||||
|     getSpy = jest.spyOn(im, 'getVersions'); | ||||
|     getSpy = jest.spyOn(im, 'getVersionsDist'); | ||||
|     getManifestSpy = jest.spyOn(tc, 'getManifestFromRepo'); | ||||
|  | ||||
|     // io | ||||
|     whichSpy = jest.spyOn(io, 'which'); | ||||
|     existsSpy = jest.spyOn(fs, 'existsSync'); | ||||
|     mkdirpSpy = jest.spyOn(io, 'mkdirP'); | ||||
|  | ||||
|     // gets | ||||
|     getManifestSpy.mockImplementation(() => <tc.IToolRelease[]>goTestManifest); | ||||
|  | ||||
|     // writes | ||||
|     cnSpy = jest.spyOn(process.stdout, 'write'); | ||||
|     logSpy = jest.spyOn(console, 'log'); | ||||
|     dbgSpy = jest.spyOn(main, '_debug'); | ||||
|     getSpy.mockImplementation(() => <im.IGoVersion[]>goJsonData); | ||||
|     logSpy = jest.spyOn(core, 'info'); | ||||
|     dbgSpy = jest.spyOn(core, 'debug'); | ||||
|     getSpy.mockImplementation(() => <im.IGoVersion[] | null>goJsonData); | ||||
|     cnSpy.mockImplementation(line => { | ||||
|       // uncomment to debug | ||||
|       // process.stderr.write('write:' + line + '\n'); | ||||
| @@ -86,27 +92,43 @@ describe('setup-go', () => { | ||||
|  | ||||
|   afterAll(async () => {}, 100000); | ||||
|  | ||||
|   it('can query versions', async () => { | ||||
|     let versions: im.IGoVersion[] | null = await im.getVersions( | ||||
|       'https://non.existant.com/path' | ||||
|   it('can find 1.9.7 from manifest on osx', async () => { | ||||
|     os.platform = 'darwin'; | ||||
|     os.arch = 'x64'; | ||||
|  | ||||
|     let match = await im.getInfoFromManifest('1.9.7', true, 'mocktoken'); | ||||
|     expect(match).toBeDefined(); | ||||
|     expect(match!.resolvedVersion).toBe('1.9.7'); | ||||
|     expect(match!.type).toBe('manifest'); | ||||
|     expect(match!.downloadUrl).toBe( | ||||
|       'https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-darwin-x64.tar.gz' | ||||
|     ); | ||||
|     expect(versions).toBeDefined(); | ||||
|     let l: number = versions ? versions.length : 0; | ||||
|     expect(l).toBe(91); | ||||
|   }); | ||||
|  | ||||
|   it('finds stable match for exact version', async () => { | ||||
|   it('can find 1.9 from manifest on linux', async () => { | ||||
|     os.platform = 'linux'; | ||||
|     os.arch = 'x64'; | ||||
|  | ||||
|     let match = await im.getInfoFromManifest('1.9.7', true, 'mocktoken'); | ||||
|     expect(match).toBeDefined(); | ||||
|     expect(match!.resolvedVersion).toBe('1.9.7'); | ||||
|     expect(match!.type).toBe('manifest'); | ||||
|     expect(match!.downloadUrl).toBe( | ||||
|       'https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-linux-x64.tar.gz' | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('can find 1.9 from manifest on windows', async () => { | ||||
|     os.platform = 'win32'; | ||||
|     os.arch = 'x64'; | ||||
|  | ||||
|     // get request is already mocked | ||||
|     // spec: 1.13.7 => 1.13.7 (exact) | ||||
|     let match: im.IGoVersion | undefined = await im.findMatch('1.13.7', true); | ||||
|     let match = await im.getInfoFromManifest('1.9.7', true, 'mocktoken'); | ||||
|     expect(match).toBeDefined(); | ||||
|     let version: string = match ? match.version : ''; | ||||
|     expect(version).toBe('go1.13.7'); | ||||
|     let fileName = match ? match.files[0].filename : ''; | ||||
|     expect(fileName).toBe('go1.13.7.windows-amd64.zip'); | ||||
|     expect(match!.resolvedVersion).toBe('1.9.7'); | ||||
|     expect(match!.type).toBe('manifest'); | ||||
|     expect(match!.downloadUrl).toBe( | ||||
|       'https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-win32-x64.zip' | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('finds stable match for exact dot zero version', async () => { | ||||
| @@ -208,6 +230,7 @@ describe('setup-go', () => { | ||||
|     await main.run(); | ||||
|  | ||||
|     let expPath = path.join(toolPath, 'bin'); | ||||
|     expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); | ||||
|   }); | ||||
|  | ||||
|   it('finds a version in the cache and adds it to the path', async () => { | ||||
| @@ -261,10 +284,124 @@ describe('setup-go', () => { | ||||
|     await main.run(); | ||||
|  | ||||
|     expect(cnSpy).toHaveBeenCalledWith( | ||||
|       `::error::Could not find a version that satisfied version spec: 9.99.9${osm.EOL}` | ||||
|       `::error::Unable to find Go version '9.99.9' for platform linux and architecture x64.${osm.EOL}` | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('downloads a version from a manifest match', async () => { | ||||
|     os.platform = 'linux'; | ||||
|     os.arch = 'x64'; | ||||
|  | ||||
|     // a version which is in the manifest | ||||
|     let versionSpec = '1.12.16'; | ||||
|  | ||||
|     inputs['go-version'] = versionSpec; | ||||
|     inputs['token'] = 'faketoken'; | ||||
|  | ||||
|     let expectedUrl = | ||||
|       'https://github.com/actions/go-versions/releases/download/1.12.16-20200616.20/go-1.12.16-linux-x64.tar.gz'; | ||||
|  | ||||
|     // ... but not in the local cache | ||||
|     findSpy.mockImplementation(() => ''); | ||||
|  | ||||
|     dlSpy.mockImplementation(async () => '/some/temp/path'); | ||||
|     let toolPath = path.normalize('/cache/go/1.12.16/x64'); | ||||
|     exSpy.mockImplementation(async () => '/some/other/temp/path'); | ||||
|     cacheSpy.mockImplementation(async () => toolPath); | ||||
|  | ||||
|     await main.run(); | ||||
|  | ||||
|     let expPath = path.join(toolPath, 'bin'); | ||||
|  | ||||
|     expect(dlSpy).toHaveBeenCalled(); | ||||
|     expect(exSpy).toHaveBeenCalled(); | ||||
|     expect(logSpy).not.toHaveBeenCalledWith( | ||||
|       'Not found in manifest.  Falling back to download directly from Go' | ||||
|     ); | ||||
|     expect(logSpy).toHaveBeenCalledWith( | ||||
|       `Acquiring 1.12.16 from ${expectedUrl}` | ||||
|     ); | ||||
|  | ||||
|     expect(logSpy).toHaveBeenCalledWith(`Added go to the path`); | ||||
|     expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`); | ||||
|   }); | ||||
|  | ||||
|   it('downloads a major and minor from a manifest match', async () => { | ||||
|     os.platform = 'linux'; | ||||
|     os.arch = 'x64'; | ||||
|  | ||||
|     // a version which is in the manifest | ||||
|     let versionSpec = '1.12'; | ||||
|  | ||||
|     inputs['go-version'] = versionSpec; | ||||
|     inputs['token'] = 'faketoken'; | ||||
|  | ||||
|     let expectedUrl = | ||||
|       'https://github.com/actions/go-versions/releases/download/1.12.17-20200616.21/go-1.12.17-linux-x64.tar.gz'; | ||||
|  | ||||
|     // ... but not in the local cache | ||||
|     findSpy.mockImplementation(() => ''); | ||||
|  | ||||
|     dlSpy.mockImplementation(async () => '/some/temp/path'); | ||||
|     let toolPath = path.normalize('/cache/go/1.12.17/x64'); | ||||
|     exSpy.mockImplementation(async () => '/some/other/temp/path'); | ||||
|     cacheSpy.mockImplementation(async () => toolPath); | ||||
|  | ||||
|     await main.run(); | ||||
|  | ||||
|     let expPath = path.join(toolPath, 'bin'); | ||||
|  | ||||
|     expect(dlSpy).toHaveBeenCalled(); | ||||
|     expect(exSpy).toHaveBeenCalled(); | ||||
|     expect(logSpy).not.toHaveBeenCalledWith( | ||||
|       'Not found in manifest.  Falling back to download directly from Go' | ||||
|     ); | ||||
|     expect(logSpy).toHaveBeenCalledWith( | ||||
|       `Acquiring 1.12.17 from ${expectedUrl}` | ||||
|     ); | ||||
|  | ||||
|     expect(logSpy).toHaveBeenCalledWith(`Added go to the path`); | ||||
|     expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`); | ||||
|   }); | ||||
|  | ||||
|   it('falls back to a version from node dist', async () => { | ||||
|     os.platform = 'linux'; | ||||
|     os.arch = 'x64'; | ||||
|  | ||||
|     // a version which is not in the manifest but is in node dist | ||||
|     let versionSpec = '1.12.14'; | ||||
|  | ||||
|     inputs['go-version'] = versionSpec; | ||||
|     inputs['token'] = 'faketoken'; | ||||
|  | ||||
|     let expectedUrl = | ||||
|       'https://github.com/actions/go-versions/releases/download/1.12.14-20200616.18/go-1.12.14-linux-x64.tar.gz'; | ||||
|  | ||||
|     // ... but not in the local cache | ||||
|     findSpy.mockImplementation(() => ''); | ||||
|  | ||||
|     dlSpy.mockImplementation(async () => '/some/temp/path'); | ||||
|     let toolPath = path.normalize('/cache/go/1.12.14/x64'); | ||||
|     exSpy.mockImplementation(async () => '/some/other/temp/path'); | ||||
|     cacheSpy.mockImplementation(async () => toolPath); | ||||
|  | ||||
|     await main.run(); | ||||
|  | ||||
|     let expPath = path.join(toolPath, 'bin'); | ||||
|     expect(logSpy).toHaveBeenCalledWith('Setup go stable version spec 1.12.14'); | ||||
|     expect(findSpy).toHaveBeenCalled(); | ||||
|     expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.12.14...'); | ||||
|     expect(dlSpy).toHaveBeenCalled(); | ||||
|     expect(logSpy).toHaveBeenCalledWith('matching 1.12.14...'); | ||||
|     expect(exSpy).toHaveBeenCalled(); | ||||
|     expect(logSpy).toHaveBeenCalledWith( | ||||
|       'Not found in manifest.  Falling back to download directly from Go' | ||||
|     ); | ||||
|     expect(logSpy).toHaveBeenCalledWith(`Install from dist`); | ||||
|     expect(logSpy).toHaveBeenCalledWith(`Added go to the path`); | ||||
|     expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`); | ||||
|   }); | ||||
|  | ||||
|   it('reports a failed download', async () => { | ||||
|     let errMsg = 'unhandled download message'; | ||||
|     os.platform = 'linux'; | ||||
| @@ -283,22 +420,6 @@ describe('setup-go', () => { | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('reports empty query results', async () => { | ||||
|     let errMsg = 'unhandled download message'; | ||||
|     os.platform = 'linux'; | ||||
|     os.arch = 'x64'; | ||||
|  | ||||
|     inputs['go-version'] = '1.13.1'; | ||||
|  | ||||
|     findSpy.mockImplementation(() => ''); | ||||
|     getSpy.mockImplementation(() => null); | ||||
|     await main.run(); | ||||
|  | ||||
|     expect(cnSpy).toHaveBeenCalledWith( | ||||
|       `::error::Failed to download version 1.13.1: Error: golang download url did not return results${osm.EOL}` | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it('does not add BIN if go is not in path', async () => { | ||||
|     whichSpy.mockImplementation(async () => { | ||||
|       return ''; | ||||
|   | ||||
							
								
								
									
										14
									
								
								__tests__/verify-go.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								__tests__/verify-go.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,14 @@ | ||||
|    | ||||
| #!/bin/sh | ||||
|  | ||||
| if [ -z "$1" ]; then | ||||
|   echo "Must supply go version argument" | ||||
|   exit 1 | ||||
| fi | ||||
|  | ||||
| go_version="$(go version)" | ||||
| echo "Found go version '$go_version'" | ||||
| if [ -z "$(echo $go_version | grep $1)" ]; then | ||||
|   echo "Unexpected version" | ||||
|   exit 1 | ||||
| fi | ||||
| @@ -7,6 +7,9 @@ inputs: | ||||
|   stable: | ||||
|     description: 'Whether to download only stable versions' | ||||
|     default: 'true' | ||||
|   token: | ||||
|     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 }} | ||||
| runs: | ||||
|   using: 'node12' | ||||
|   main: 'dist/index.js' | ||||
|   | ||||
							
								
								
									
										679
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										679
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										12644
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										12644
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -23,10 +23,10 @@ | ||||
|   "author": "GitHub", | ||||
|   "license": "MIT", | ||||
|   "dependencies": { | ||||
|     "@actions/core": "^1.2.2", | ||||
|     "@actions/core": "^1.2.3", | ||||
|     "@actions/http-client": "^1.0.6", | ||||
|     "@actions/io": "^1.0.2", | ||||
|     "@actions/tool-cache": "^1.3.3", | ||||
|     "@actions/tool-cache": "^1.5.5", | ||||
|     "semver": "^6.1.1" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
| @@ -39,6 +39,6 @@ | ||||
|     "nock": "^10.0.6", | ||||
|     "prettier": "^1.17.1", | ||||
|     "ts-jest": "^24.0.2", | ||||
|     "typescript": "^3.5.1" | ||||
|     "typescript": "^3.8.3" | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										215
									
								
								src/installer.ts
									
									
									
									
									
								
							
							
						
						
									
										215
									
								
								src/installer.ts
									
									
									
									
									
								
							| @@ -1,46 +1,12 @@ | ||||
| import * as tc from '@actions/tool-cache'; | ||||
| import * as core from '@actions/core'; | ||||
| import * as path from 'path'; | ||||
| import * as semver from 'semver'; | ||||
| import * as httpm from '@actions/http-client'; | ||||
| import * as sys from './system'; | ||||
| import {debug} from '@actions/core'; | ||||
| import os from 'os'; | ||||
|  | ||||
| export async function downloadGo( | ||||
|   versionSpec: string, | ||||
|   stable: boolean | ||||
| ): Promise<string | undefined> { | ||||
|   let toolPath: string | undefined; | ||||
|  | ||||
|   try { | ||||
|     let match: IGoVersion | undefined = await findMatch(versionSpec, stable); | ||||
|  | ||||
|     if (match) { | ||||
|       // download | ||||
|       debug(`match ${match.version}`); | ||||
|       let downloadUrl: string = `https://storage.googleapis.com/golang/${match.files[0].filename}`; | ||||
|       console.log(`Downloading from ${downloadUrl}`); | ||||
|  | ||||
|       let downloadPath: string = await tc.downloadTool(downloadUrl); | ||||
|       debug(`downloaded to ${downloadPath}`); | ||||
|  | ||||
|       // extract | ||||
|       console.log('Extracting ...'); | ||||
|       let extPath: string = | ||||
|         sys.getPlatform() == 'windows' | ||||
|           ? await tc.extractZip(downloadPath) | ||||
|           : await tc.extractTar(downloadPath); | ||||
|       debug(`extracted to ${extPath}`); | ||||
|  | ||||
|       // extracts with a root folder that matches the fileName downloaded | ||||
|       const toolRoot = path.join(extPath, 'go'); | ||||
|       toolPath = await tc.cacheDir(toolRoot, 'go', makeSemver(match.version)); | ||||
|     } | ||||
|   } catch (error) { | ||||
|     throw new Error(`Failed to download version ${versionSpec}: ${error}`); | ||||
|   } | ||||
|  | ||||
|   return toolPath; | ||||
| } | ||||
| type InstallationType = 'dist' | 'manifest'; | ||||
|  | ||||
| export interface IGoVersionFile { | ||||
|   filename: string; | ||||
| @@ -55,6 +21,160 @@ export interface IGoVersion { | ||||
|   files: IGoVersionFile[]; | ||||
| } | ||||
|  | ||||
| export interface IGoVersionInfo { | ||||
|   type: InstallationType; | ||||
|   downloadUrl: string; | ||||
|   resolvedVersion: string; | ||||
|   fileName: string; | ||||
| } | ||||
|  | ||||
| export async function getGo( | ||||
|   versionSpec: string, | ||||
|   stable: boolean, | ||||
|   auth: string | undefined | ||||
| ) { | ||||
|   let osPlat: string = os.platform(); | ||||
|   let osArch: string = os.arch(); | ||||
|  | ||||
|   // check cache | ||||
|   let toolPath: string; | ||||
|   toolPath = tc.find('go', versionSpec); | ||||
|   // If not found in cache, download | ||||
|   if (toolPath) { | ||||
|     core.info(`Found in cache @ ${toolPath}`); | ||||
|     return toolPath; | ||||
|   } | ||||
|   core.info(`Attempting to download ${versionSpec}...`); | ||||
|   let downloadPath = ''; | ||||
|   let info: IGoVersionInfo | null = null; | ||||
|  | ||||
|   // | ||||
|   // Try download from internal distribution (popular versions only) | ||||
|   // | ||||
|   try { | ||||
|     info = await getInfoFromManifest(versionSpec, stable, auth); | ||||
|     if (info) { | ||||
|       downloadPath = await installGoVersion(info, auth); | ||||
|     } 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(err.stack); | ||||
|     core.info('Falling back to download directly from Go'); | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   // Download from storage.googleapis.com | ||||
|   // | ||||
|   if (!downloadPath) { | ||||
|     info = await getInfoFromDist(versionSpec, stable); | ||||
|     if (!info) { | ||||
|       throw new Error( | ||||
|         `Unable to find Go version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.` | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     try { | ||||
|       core.info('Install from dist'); | ||||
|       downloadPath = await installGoVersion(info, undefined); | ||||
|     } catch (err) { | ||||
|       throw new Error(`Failed to download version ${versionSpec}: ${err}`); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return downloadPath; | ||||
| } | ||||
|  | ||||
| async function installGoVersion( | ||||
|   info: IGoVersionInfo, | ||||
|   auth: string | undefined | ||||
| ): Promise<string> { | ||||
|   core.info(`Acquiring ${info.resolvedVersion} from ${info.downloadUrl}`); | ||||
|   const downloadPath = await tc.downloadTool(info.downloadUrl, undefined, auth); | ||||
|  | ||||
|   core.info('Extracting Go...'); | ||||
|   let extPath = await extractGoArchive(downloadPath); | ||||
|   core.info(`Successfully extracted go to ${extPath}`); | ||||
|   if (info.type === 'dist') { | ||||
|     extPath = path.join(extPath, 'go'); | ||||
|   } | ||||
|  | ||||
|   core.info('Adding to the cache ...'); | ||||
|   const cachedDir = await tc.cacheDir( | ||||
|     extPath, | ||||
|     'go', | ||||
|     makeSemver(info.resolvedVersion) | ||||
|   ); | ||||
|   core.info(`Successfully cached go to ${cachedDir}`); | ||||
|   return cachedDir; | ||||
| } | ||||
|  | ||||
| export async function extractGoArchive(archivePath: string): Promise<string> { | ||||
|   const arch = os.arch(); | ||||
|   let extPath: string; | ||||
|  | ||||
|   if (arch === 'win32') { | ||||
|     extPath = await tc.extractZip(archivePath); | ||||
|   } else { | ||||
|     extPath = await tc.extractTar(archivePath); | ||||
|   } | ||||
|  | ||||
|   return extPath; | ||||
| } | ||||
|  | ||||
| export async function getInfoFromManifest( | ||||
|   versionSpec: string, | ||||
|   stable: boolean, | ||||
|   auth: string | undefined | ||||
| ): Promise<IGoVersionInfo | null> { | ||||
|   let info: IGoVersionInfo | null = null; | ||||
|   const releases = await tc.getManifestFromRepo('actions', 'go-versions', auth); | ||||
|   core.info(`matching ${versionSpec}...`); | ||||
|   const rel = await tc.findFromManifest(versionSpec, stable, releases); | ||||
|  | ||||
|   if (rel && rel.files.length > 0) { | ||||
|     info = <IGoVersionInfo>{}; | ||||
|     info.type = 'manifest'; | ||||
|     info.resolvedVersion = rel.version; | ||||
|     info.downloadUrl = rel.files[0].download_url; | ||||
|     info.fileName = rel.files[0].filename; | ||||
|   } | ||||
|  | ||||
|   return info; | ||||
| } | ||||
|  | ||||
| async function getInfoFromDist( | ||||
|   versionSpec: string, | ||||
|   stable: boolean | ||||
| ): Promise<IGoVersionInfo | null> { | ||||
|   let version: IGoVersion | undefined; | ||||
|   version = await findMatch(versionSpec, stable); | ||||
|   if (!version) { | ||||
|     return null; | ||||
|   } | ||||
|  | ||||
|   let downloadUrl: string = `https://storage.googleapis.com/golang/${version.files[0].filename}`; | ||||
|  | ||||
|   return <IGoVersionInfo>{ | ||||
|     type: 'dist', | ||||
|     downloadUrl: downloadUrl, | ||||
|     resolvedVersion: version.version, | ||||
|     fileName: version.files[0].filename | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export async function findMatch( | ||||
|   versionSpec: string, | ||||
|   stable: boolean | ||||
| @@ -66,7 +186,9 @@ export async function findMatch( | ||||
|   let match: IGoVersion | undefined; | ||||
|  | ||||
|   const dlUrl: string = 'https://golang.org/dl/?mode=json&include=all'; | ||||
|   let candidates: IGoVersion[] | null = await module.exports.getVersions(dlUrl); | ||||
|   let candidates: IGoVersion[] | null = await module.exports.getVersionsDist( | ||||
|     dlUrl | ||||
|   ); | ||||
|   if (!candidates) { | ||||
|     throw new Error(`golang download url did not return results`); | ||||
|   } | ||||
| @@ -83,18 +205,20 @@ export async function findMatch( | ||||
|       version = version + '.0'; | ||||
|     } | ||||
|  | ||||
|     debug(`check ${version} satisfies ${versionSpec}`); | ||||
|     core.debug(`check ${version} satisfies ${versionSpec}`); | ||||
|     if ( | ||||
|       semver.satisfies(version, versionSpec) && | ||||
|       (!stable || candidate.stable === stable) | ||||
|     ) { | ||||
|       goFile = candidate.files.find(file => { | ||||
|         debug(`${file.arch}===${archFilter} && ${file.os}===${platFilter}`); | ||||
|         core.debug( | ||||
|           `${file.arch}===${archFilter} && ${file.os}===${platFilter}` | ||||
|         ); | ||||
|         return file.arch === archFilter && file.os === platFilter; | ||||
|       }); | ||||
|  | ||||
|       if (goFile) { | ||||
|         debug(`matched ${candidate.version}`); | ||||
|         core.debug(`matched ${candidate.version}`); | ||||
|         match = candidate; | ||||
|         break; | ||||
|       } | ||||
| @@ -110,9 +234,14 @@ export async function findMatch( | ||||
|   return result; | ||||
| } | ||||
|  | ||||
| export async function getVersions(dlUrl: string): Promise<IGoVersion[] | null> { | ||||
| export async function getVersionsDist( | ||||
|   dlUrl: string | ||||
| ): Promise<IGoVersion[] | null> { | ||||
|   // this returns versions descending so latest is first | ||||
|   let http: httpm.HttpClient = new httpm.HttpClient('setup-go'); | ||||
|   let http: httpm.HttpClient = new httpm.HttpClient('setup-go', [], { | ||||
|     allowRedirects: true, | ||||
|     maxRedirects: 3 | ||||
|   }); | ||||
|   return (await http.getJson<IGoVersion[]>(dlUrl)).result; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										57
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								src/main.ts
									
									
									
									
									
								
							| @@ -1,10 +1,10 @@ | ||||
| import * as core from '@actions/core'; | ||||
| import * as io from '@actions/io'; | ||||
| import * as tc from '@actions/tool-cache'; | ||||
| import * as installer from './installer'; | ||||
| import path from 'path'; | ||||
| import cp from 'child_process'; | ||||
| import fs from 'fs'; | ||||
| import {URL} from 'url'; | ||||
|  | ||||
| export async function run() { | ||||
|   try { | ||||
| @@ -18,47 +18,35 @@ export async function run() { | ||||
|     // since getting unstable versions should be explicit | ||||
|     let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE'; | ||||
|  | ||||
|     console.log( | ||||
|       `Setup go ${stable ? 'stable' : ''} version spec ${versionSpec}` | ||||
|     ); | ||||
|     core.info(`Setup go ${stable ? 'stable' : ''} version spec ${versionSpec}`); | ||||
|  | ||||
|     if (versionSpec) { | ||||
|       let installDir: string | undefined = tc.find('go', versionSpec); | ||||
|       let token = core.getInput('token'); | ||||
|       let auth = !token || isGhes() ? undefined : `token ${token}`; | ||||
|  | ||||
|       if (!installDir) { | ||||
|         console.log( | ||||
|           `A version satisfying ${versionSpec} not found locally, attempting to download ...` | ||||
|         ); | ||||
|         installDir = await installer.downloadGo(versionSpec, stable); | ||||
|         console.log('Installed'); | ||||
|       } | ||||
|       const installDir = await installer.getGo(versionSpec, stable, auth); | ||||
|  | ||||
|       if (installDir) { | ||||
|         core.exportVariable('GOROOT', installDir); | ||||
|         core.addPath(path.join(installDir, 'bin')); | ||||
|         console.log('Added go to the path'); | ||||
|       core.exportVariable('GOROOT', installDir); | ||||
|       core.addPath(path.join(installDir, 'bin')); | ||||
|       core.info('Added go to the path'); | ||||
|  | ||||
|         let added = addBinToPath(); | ||||
|         core.debug(`add bin ${added}`); | ||||
|       } else { | ||||
|         throw new Error( | ||||
|           `Could not find a version that satisfied version spec: ${versionSpec}` | ||||
|         ); | ||||
|       } | ||||
|       let added = await addBinToPath(); | ||||
|       core.debug(`add bin ${added}`); | ||||
|       core.info(`Successfully setup go version ${versionSpec}`); | ||||
|     } | ||||
|  | ||||
|     // add problem matchers | ||||
|     const matchersPath = path.join(__dirname, '..', 'matchers.json'); | ||||
|     console.log(`##[add-matcher]${matchersPath}`); | ||||
|     core.info(`##[add-matcher]${matchersPath}`); | ||||
|  | ||||
|     // output the version actually being used | ||||
|     let goPath = await io.which('go'); | ||||
|     let goVersion = (cp.execSync(`${goPath} version`) || '').toString(); | ||||
|     console.log(goVersion); | ||||
|     core.info(goVersion); | ||||
|  | ||||
|     core.startGroup('go env'); | ||||
|     let goEnv = (cp.execSync(`${goPath} env`) || '').toString(); | ||||
|     console.log(goEnv); | ||||
|     core.info(goEnv); | ||||
|     core.endGroup(); | ||||
|   } catch (error) { | ||||
|     core.setFailed(error.message); | ||||
| @@ -68,25 +56,25 @@ export async function run() { | ||||
| export async function addBinToPath(): Promise<boolean> { | ||||
|   let added = false; | ||||
|   let g = await io.which('go'); | ||||
|   _debug(`which go :${g}:`); | ||||
|   core.debug(`which go :${g}:`); | ||||
|   if (!g) { | ||||
|     _debug('go not in the path'); | ||||
|     core.debug('go not in the path'); | ||||
|     return added; | ||||
|   } | ||||
|  | ||||
|   let buf = cp.execSync('go env GOPATH'); | ||||
|   if (buf) { | ||||
|     let gp = buf.toString().trim(); | ||||
|     _debug(`go env GOPATH :${gp}:`); | ||||
|     core.debug(`go env GOPATH :${gp}:`); | ||||
|     if (!fs.existsSync(gp)) { | ||||
|       // some of the hosted images have go install but not profile dir | ||||
|       _debug(`creating ${gp}`); | ||||
|       core.debug(`creating ${gp}`); | ||||
|       io.mkdirP(gp); | ||||
|     } | ||||
|  | ||||
|     let bp = path.join(gp, 'bin'); | ||||
|     if (!fs.existsSync(bp)) { | ||||
|       _debug(`creating ${bp}`); | ||||
|       core.debug(`creating ${bp}`); | ||||
|       io.mkdirP(bp); | ||||
|     } | ||||
|  | ||||
| @@ -96,6 +84,9 @@ export async function addBinToPath(): Promise<boolean> { | ||||
|   return added; | ||||
| } | ||||
|  | ||||
| export function _debug(message: string) { | ||||
|   core.debug(message); | ||||
| function isGhes(): boolean { | ||||
|   const ghUrl = new URL( | ||||
|     process.env['GITHUB_SERVER_URL'] || 'https://github.com' | ||||
|   ); | ||||
|   return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM'; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user