From fc952ad45a57908b519079484e03b071ac61772f Mon Sep 17 00:00:00 2001 From: plukevdh Date: Fri, 19 May 2023 15:17:09 -0400 Subject: [PATCH 1/4] add rudimentary .tool-versions parser --- .github/workflows/versions.yml | 16 ++++ __tests__/data/.tool-versions | 4 + __tests__/setup-go.test.ts | 153 +++++++++++++++++++++------------ src/installer.ts | 7 ++ src/main.ts | 27 ++++-- 5 files changed, 148 insertions(+), 59 deletions(-) create mode 100644 __tests__/data/.tool-versions diff --git a/.github/workflows/versions.yml b/.github/workflows/versions.yml index 89fc7b8d3..b25d1d719 100644 --- a/.github/workflows/versions.yml +++ b/.github/workflows/versions.yml @@ -134,6 +134,22 @@ jobs: run: __tests__/verify-go.sh 1.19 shell: bash + tool-versions-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: + tool-versions-file: __tests__/data/.tool-versions + - name: verify go + run: __tests__/verify-go.sh 1.16.3 + shell: bash + setup-versions-from-manifest: name: Setup ${{ matrix.go }} ${{ matrix.os }} runs-on: ${{ matrix.os }} diff --git a/__tests__/data/.tool-versions b/__tests__/data/.tool-versions new file mode 100644 index 000000000..cce7a1b62 --- /dev/null +++ b/__tests__/data/.tool-versions @@ -0,0 +1,4 @@ +terraform 1.3.7 +golang 1.16.3 +python 3.10.11 +ruby 3.2.1 diff --git a/__tests__/setup-go.test.ts b/__tests__/setup-go.test.ts index cea14f4e8..7a028cefe 100644 --- a/__tests__/setup-go.test.ts +++ b/__tests__/setup-go.test.ts @@ -138,7 +138,7 @@ describe('setup-go', () => { 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' + 'https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-darwin-x64.tar.gz' ); }); @@ -151,7 +151,7 @@ describe('setup-go', () => { 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' + 'https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-linux-x64.tar.gz' ); }); @@ -164,7 +164,7 @@ describe('setup-go', () => { 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' + 'https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-win32-x64.zip' ); }); @@ -263,7 +263,7 @@ describe('setup-go', () => { const toolPath = path.normalize('/cache/go/1.13.0/x64'); findSpy.mockImplementation(() => toolPath); - const vars: {[key: string]: string} = {}; + const vars: { [key: string]: string } = {}; exportVarSpy.mockImplementation((name: string, val: string) => { vars[name] = val; }); @@ -279,7 +279,7 @@ describe('setup-go', () => { const toolPath = path.normalize('/cache/go/1.8.0/x64'); findSpy.mockImplementation(() => toolPath); - const vars: {[key: string]: string} = {}; + const vars: { [key: string]: string } = {}; exportVarSpy.mockImplementation((name: string, val: string) => { vars[name] = val; }); @@ -359,9 +359,9 @@ describe('setup-go', () => { const expPath = path.win32.join(toolPath, 'bin'); expect(dlSpy).toHaveBeenCalledWith( - 'https://storage.googleapis.com/golang/go1.13.1.windows-amd64.zip', - 'C:\\temp\\go1.13.1.windows-amd64.zip', - undefined + 'https://storage.googleapis.com/golang/go1.13.1.windows-amd64.zip', + 'C:\\temp\\go1.13.1.windows-amd64.zip', + undefined ); expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`); }); @@ -376,7 +376,7 @@ describe('setup-go', () => { await main.run(); expect(cnSpy).toHaveBeenCalledWith( - `::error::Unable to find Go version '9.99.9' for platform linux and architecture x64.${osm.EOL}` + `::error::Unable to find Go version '9.99.9' for platform linux and architecture x64.${osm.EOL}` ); }); @@ -390,7 +390,7 @@ describe('setup-go', () => { inputs['token'] = 'faketoken'; const expectedUrl = - 'https://github.com/actions/go-versions/releases/download/1.12.16-20200616.20/go-1.12.16-linux-x64.tar.gz'; + '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(() => ''); @@ -407,10 +407,10 @@ describe('setup-go', () => { expect(dlSpy).toHaveBeenCalled(); expect(extractTarSpy).toHaveBeenCalled(); 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' ); expect(logSpy).toHaveBeenCalledWith( - `Acquiring 1.12.16 from ${expectedUrl}` + `Acquiring 1.12.16 from ${expectedUrl}` ); expect(logSpy).toHaveBeenCalledWith(`Added go to the path`); @@ -427,7 +427,7 @@ describe('setup-go', () => { inputs['token'] = 'faketoken'; const expectedUrl = - 'https://github.com/actions/go-versions/releases/download/1.12.17-20200616.21/go-1.12.17-linux-x64.tar.gz'; + '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(() => ''); @@ -444,10 +444,10 @@ describe('setup-go', () => { expect(dlSpy).toHaveBeenCalled(); expect(extractTarSpy).toHaveBeenCalled(); 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' ); expect(logSpy).toHaveBeenCalledWith( - `Acquiring 1.12.17 from ${expectedUrl}` + `Acquiring 1.12.17 from ${expectedUrl}` ); expect(logSpy).toHaveBeenCalledWith(`Added go to the path`); @@ -481,7 +481,7 @@ describe('setup-go', () => { expect(logSpy).toHaveBeenCalledWith('matching 1.12.14...'); expect(extractTarSpy).toHaveBeenCalled(); 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' ); expect(logSpy).toHaveBeenCalledWith(`Install from dist`); expect(logSpy).toHaveBeenCalledWith(`Added go to the path`); @@ -502,7 +502,7 @@ describe('setup-go', () => { await main.run(); expect(cnSpy).toHaveBeenCalledWith( - `::error::Failed to download version 1.13.1: Error: ${errMsg}${osm.EOL}` + `::error::Failed to download version 1.13.1: Error: ${errMsg}${osm.EOL}` ); }); @@ -523,7 +523,8 @@ describe('setup-go', () => { return '/Users/testuser/go'; }); - mkdirpSpy.mockImplementation(async () => {}); + mkdirpSpy.mockImplementation(async () => { + }); existsSpy.mockImplementation(() => { return false; }); @@ -667,7 +668,7 @@ describe('setup-go', () => { expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); expect(logSpy).not.toHaveBeenCalledWith( - 'Attempting to resolve the latest version from the manifest...' + 'Attempting to resolve the latest version from the manifest...' ); }); @@ -709,20 +710,20 @@ describe('setup-go', () => { await main.run(); expect(logSpy).toHaveBeenCalledWith( - `Setup go version spec ${versionSpec}` + `Setup go version spec ${versionSpec}` ); expect(logSpy).toHaveBeenCalledWith( - 'Attempting to resolve the latest version from the manifest...' + 'Attempting to resolve the latest version from the manifest...' ); expect(logSpy).toHaveBeenCalledWith(`Resolved as '${patchVersion}'`); expect(logSpy).toHaveBeenCalledWith( - `Attempting to download ${patchVersion}...` + `Attempting to download ${patchVersion}...` ); expect(logSpy).toHaveBeenCalledWith('Extracting Go...'); expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...'); expect(logSpy).toHaveBeenCalledWith('Added go to the path'); expect(logSpy).toHaveBeenCalledWith( - `Successfully set up Go version ${versionSpec}` + `Successfully set up Go version ${versionSpec}` ); }); @@ -752,13 +753,13 @@ describe('setup-go', () => { expect(dlSpy).toHaveBeenCalled(); expect(extractTarSpy).toHaveBeenCalled(); expect(logSpy).toHaveBeenCalledWith( - 'Attempting to resolve the latest version from the manifest...' + 'Attempting to resolve the latest version from the manifest...' ); expect(logSpy).toHaveBeenCalledWith( - `Failed to resolve version ${versionSpec} from manifest` + `Failed to resolve version ${versionSpec} from manifest` ); expect(logSpy).toHaveBeenCalledWith( - `Attempting to download ${versionSpec}...` + `Attempting to download ${versionSpec}...` ); expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`); }); @@ -793,21 +794,21 @@ describe('setup-go', () => { const expPath = path.join(toolPath, 'bin'); expect(logSpy).toHaveBeenCalledWith( - `Failed to resolve version ${versionSpec} from manifest` + `Failed to resolve version ${versionSpec} from manifest` ); expect(dlSpy).toHaveBeenCalled(); expect(extractTarSpy).toHaveBeenCalled(); expect(logSpy).toHaveBeenCalledWith( - 'Attempting to resolve the latest version from the manifest...' + 'Attempting to resolve the latest version from the manifest...' ); expect(logSpy).toHaveBeenCalledWith( - 'Unable to resolve a version from the manifest...' + 'Unable to resolve a version from the manifest...' ); expect(logSpy).toHaveBeenCalledWith( - `Failed to resolve version ${versionSpec} from manifest` + `Failed to resolve version ${versionSpec} from manifest` ); expect(logSpy).toHaveBeenCalledWith( - `Attempting to download ${versionSpec}...` + `Attempting to download ${versionSpec}...` ); expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`); @@ -891,7 +892,7 @@ use . await main.run(); expect(cnSpy).toHaveBeenCalledWith( - `::error::The specified go version file at: go.mod does not exist${osm.EOL}` + `::error::The specified go version file at: go.mod does not exist${osm.EOL}` ); }); @@ -911,9 +912,9 @@ use . inputs['architecture'] = arch; const expectedUrl = - platform === 'win32' - ? `https://github.com/actions/go-versions/releases/download/${version}/go-${version}-${platform}-${arch}.${fileExtension}` - : `https://storage.googleapis.com/golang/go${version}.${osSpec}-${arch}.${fileExtension}`; + platform === 'win32' + ? `https://github.com/actions/go-versions/releases/download/${version}/go-${version}-${platform}-${arch}.${fileExtension}` + : `https://storage.googleapis.com/golang/go${version}.${osSpec}-${arch}.${fileExtension}`; // ... but not in the local cache findSpy.mockImplementation(() => ''); @@ -925,36 +926,80 @@ use . await main.run(); expect(logSpy).toHaveBeenCalledWith( - `Acquiring go${version} from ${expectedUrl}` + `Acquiring go${version} from ${expectedUrl}` ); } }, 100000); it.each(['stable', 'oldstable'])( - 'acquires latest go version with %s go-version input', - async (alias: string) => { - const arch = 'x64'; - os.platform = 'darwin'; - os.arch = arch; + 'acquires latest go version with %s go-version input', + async (alias: string) => { + const arch = 'x64'; + os.platform = 'darwin'; + os.arch = arch; - inputs['go-version'] = alias; - inputs['architecture'] = os.arch; + inputs['go-version'] = alias; + inputs['architecture'] = os.arch; - // ... but not in the local cache - findSpy.mockImplementation(() => ''); + // ... but not in the local cache + findSpy.mockImplementation(() => ''); - dlSpy.mockImplementation(async () => '/some/temp/path'); - const toolPath = path.normalize(`/cache/go/${alias}/${arch}`); - cacheSpy.mockImplementation(async () => toolPath); + dlSpy.mockImplementation(async () => '/some/temp/path'); + const toolPath = path.normalize(`/cache/go/${alias}/${arch}`); + cacheSpy.mockImplementation(async () => toolPath); - await main.run(); + await main.run(); - const releaseIndex = alias === 'stable' ? 0 : 1; + const releaseIndex = alias === 'stable' ? 0 : 1; - expect(logSpy).toHaveBeenCalledWith( - `${alias} version resolved as ${goTestManifest[releaseIndex].version}` - ); - } + expect(logSpy).toHaveBeenCalledWith( + `${alias} version resolved as ${goTestManifest[releaseIndex].version}` + ); + } ); }); + + describe('tool-versions-file', () => { + const toolVersionsFile = `terraform 1.3.7 +golang 1.16.3 +python 3.10.11 +ruby 3.2.1 +`; + + it('reads version from .tool-versions when specified', async () => { + inputs['tool-versions-file'] = '.special-tool-versions' + existsSpy.mockImplementation(() => true); + readFileSpy.mockImplementation(() => Buffer.from(toolVersionsFile)) + + await main.run(); + + expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.16.3'); + expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.16.3...'); + expect(logSpy).toHaveBeenCalledWith('matching 1.16.3...'); + }); + + it('is overwritten by go-version param', async () => { + inputs['go-version'] = '1.18.2' + inputs['tool-versions-file'] = '.special-tool-versions' + existsSpy.mockImplementation(() => true); + readFileSpy.mockImplementation(() => Buffer.from(toolVersionsFile)) + + await main.run(); + + expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.18.2'); + expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.18.2...'); + expect(logSpy).toHaveBeenCalledWith('matching 1.18.2...'); + }); + + it('uses .tool-versions as a default when no version specified', async () => { + existsSpy.mockImplementation(() => true); + readFileSpy.mockImplementation(() => Buffer.from(toolVersionsFile)) + + await main.run(); + + expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.16.3'); + expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.16.3...'); + expect(logSpy).toHaveBeenCalledWith('matching 1.16.3...'); + }); + }); }); diff --git a/src/installer.ts b/src/installer.ts index 013fb6405..2894d3e28 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -366,6 +366,13 @@ export function parseGoVersionFile(versionFilePath: string): string { return contents.trim(); } +export function parseToolVersionsFile(toolVersionsPath: string): string { + const contents = fs.readFileSync(toolVersionsPath).toString(); + + const match = contents.match(/^golang (\d+(\.\d+)*)/m); + return match ? match[1] : ''; +} + async function resolveStableVersionDist(versionSpec: string, arch: string) { const archFilter = sys.getArch(arch); const platFilter = sys.getPlatform(); diff --git a/src/main.ts b/src/main.ts index d3fb857df..5e4b2601b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -138,24 +138,41 @@ export function parseGoVersion(versionString: string): string { function resolveVersionInput(): string { let version = core.getInput('go-version'); const versionFilePath = core.getInput('go-version-file'); + let toolVersionsPath = core.getInput('tool-versions-file'); - if (version && versionFilePath) { + if (version && (versionFilePath || toolVersionsPath)) { core.warning( - 'Both go-version and go-version-file inputs are specified, only go-version will be used' + 'Multiple version inputs are specified, only go-version will be used' ); } if (version) { return version; - } - - if (versionFilePath) { + } else if (versionFilePath) { if (!fs.existsSync(versionFilePath)) { throw new Error( `The specified go version file at: ${versionFilePath} does not exist` ); } version = installer.parseGoVersionFile(versionFilePath); + } else { + // in the case of no version specification, reach for .tool-versions + if(toolVersionsPath && !fs.existsSync(toolVersionsPath)) { + throw new Error( + `The specified .tool-versions file at ${toolVersionsPath} does not exist` + ) + } + + if (!toolVersionsPath) { + toolVersionsPath = '.tool-versions' + if(!fs.existsSync(toolVersionsPath)) { + throw new Error( + `No .tool-versions file was found in the project path. Please specify using tool-versions-file` + ) + } + } + + version = installer.parseToolVersionsFile(toolVersionsPath) } return version; From c401b8cb9dc90ad9dd00b0c905695b5f14bf740a Mon Sep 17 00:00:00 2001 From: plukevdh Date: Fri, 19 May 2023 15:32:26 -0400 Subject: [PATCH 2/4] fix whitespace reformat and missing ; --- __tests__/setup-go.test.ts | 121 ++++++++++++++++++------------------- src/main.ts | 8 +-- 2 files changed, 64 insertions(+), 65 deletions(-) diff --git a/__tests__/setup-go.test.ts b/__tests__/setup-go.test.ts index 7a028cefe..3a55c53f7 100644 --- a/__tests__/setup-go.test.ts +++ b/__tests__/setup-go.test.ts @@ -138,7 +138,7 @@ describe('setup-go', () => { 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' + 'https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-darwin-x64.tar.gz' ); }); @@ -151,7 +151,7 @@ describe('setup-go', () => { 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' + 'https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-linux-x64.tar.gz' ); }); @@ -164,7 +164,7 @@ describe('setup-go', () => { 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' + 'https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-win32-x64.zip' ); }); @@ -263,7 +263,7 @@ describe('setup-go', () => { const toolPath = path.normalize('/cache/go/1.13.0/x64'); findSpy.mockImplementation(() => toolPath); - const vars: { [key: string]: string } = {}; + const vars: {[key: string]: string} = {}; exportVarSpy.mockImplementation((name: string, val: string) => { vars[name] = val; }); @@ -279,7 +279,7 @@ describe('setup-go', () => { const toolPath = path.normalize('/cache/go/1.8.0/x64'); findSpy.mockImplementation(() => toolPath); - const vars: { [key: string]: string } = {}; + const vars: {[key: string]: string} = {}; exportVarSpy.mockImplementation((name: string, val: string) => { vars[name] = val; }); @@ -359,9 +359,9 @@ describe('setup-go', () => { const expPath = path.win32.join(toolPath, 'bin'); expect(dlSpy).toHaveBeenCalledWith( - 'https://storage.googleapis.com/golang/go1.13.1.windows-amd64.zip', - 'C:\\temp\\go1.13.1.windows-amd64.zip', - undefined + 'https://storage.googleapis.com/golang/go1.13.1.windows-amd64.zip', + 'C:\\temp\\go1.13.1.windows-amd64.zip', + undefined ); expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`); }); @@ -376,7 +376,7 @@ describe('setup-go', () => { await main.run(); expect(cnSpy).toHaveBeenCalledWith( - `::error::Unable to find Go version '9.99.9' for platform linux and architecture x64.${osm.EOL}` + `::error::Unable to find Go version '9.99.9' for platform linux and architecture x64.${osm.EOL}` ); }); @@ -390,7 +390,7 @@ describe('setup-go', () => { inputs['token'] = 'faketoken'; const expectedUrl = - 'https://github.com/actions/go-versions/releases/download/1.12.16-20200616.20/go-1.12.16-linux-x64.tar.gz'; + '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(() => ''); @@ -407,10 +407,10 @@ describe('setup-go', () => { expect(dlSpy).toHaveBeenCalled(); expect(extractTarSpy).toHaveBeenCalled(); 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' ); expect(logSpy).toHaveBeenCalledWith( - `Acquiring 1.12.16 from ${expectedUrl}` + `Acquiring 1.12.16 from ${expectedUrl}` ); expect(logSpy).toHaveBeenCalledWith(`Added go to the path`); @@ -427,7 +427,7 @@ describe('setup-go', () => { inputs['token'] = 'faketoken'; const expectedUrl = - 'https://github.com/actions/go-versions/releases/download/1.12.17-20200616.21/go-1.12.17-linux-x64.tar.gz'; + '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(() => ''); @@ -444,10 +444,10 @@ describe('setup-go', () => { expect(dlSpy).toHaveBeenCalled(); expect(extractTarSpy).toHaveBeenCalled(); 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' ); expect(logSpy).toHaveBeenCalledWith( - `Acquiring 1.12.17 from ${expectedUrl}` + `Acquiring 1.12.17 from ${expectedUrl}` ); expect(logSpy).toHaveBeenCalledWith(`Added go to the path`); @@ -481,7 +481,7 @@ describe('setup-go', () => { expect(logSpy).toHaveBeenCalledWith('matching 1.12.14...'); expect(extractTarSpy).toHaveBeenCalled(); 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' ); expect(logSpy).toHaveBeenCalledWith(`Install from dist`); expect(logSpy).toHaveBeenCalledWith(`Added go to the path`); @@ -502,7 +502,7 @@ describe('setup-go', () => { await main.run(); expect(cnSpy).toHaveBeenCalledWith( - `::error::Failed to download version 1.13.1: Error: ${errMsg}${osm.EOL}` + `::error::Failed to download version 1.13.1: Error: ${errMsg}${osm.EOL}` ); }); @@ -523,8 +523,7 @@ describe('setup-go', () => { return '/Users/testuser/go'; }); - mkdirpSpy.mockImplementation(async () => { - }); + mkdirpSpy.mockImplementation(async () => {}); existsSpy.mockImplementation(() => { return false; }); @@ -668,7 +667,7 @@ describe('setup-go', () => { expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`); expect(logSpy).not.toHaveBeenCalledWith( - 'Attempting to resolve the latest version from the manifest...' + 'Attempting to resolve the latest version from the manifest...' ); }); @@ -710,20 +709,20 @@ describe('setup-go', () => { await main.run(); expect(logSpy).toHaveBeenCalledWith( - `Setup go version spec ${versionSpec}` + `Setup go version spec ${versionSpec}` ); expect(logSpy).toHaveBeenCalledWith( - 'Attempting to resolve the latest version from the manifest...' + 'Attempting to resolve the latest version from the manifest...' ); expect(logSpy).toHaveBeenCalledWith(`Resolved as '${patchVersion}'`); expect(logSpy).toHaveBeenCalledWith( - `Attempting to download ${patchVersion}...` + `Attempting to download ${patchVersion}...` ); expect(logSpy).toHaveBeenCalledWith('Extracting Go...'); expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...'); expect(logSpy).toHaveBeenCalledWith('Added go to the path'); expect(logSpy).toHaveBeenCalledWith( - `Successfully set up Go version ${versionSpec}` + `Successfully set up Go version ${versionSpec}` ); }); @@ -753,13 +752,13 @@ describe('setup-go', () => { expect(dlSpy).toHaveBeenCalled(); expect(extractTarSpy).toHaveBeenCalled(); expect(logSpy).toHaveBeenCalledWith( - 'Attempting to resolve the latest version from the manifest...' + 'Attempting to resolve the latest version from the manifest...' ); expect(logSpy).toHaveBeenCalledWith( - `Failed to resolve version ${versionSpec} from manifest` + `Failed to resolve version ${versionSpec} from manifest` ); expect(logSpy).toHaveBeenCalledWith( - `Attempting to download ${versionSpec}...` + `Attempting to download ${versionSpec}...` ); expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`); }); @@ -794,21 +793,21 @@ describe('setup-go', () => { const expPath = path.join(toolPath, 'bin'); expect(logSpy).toHaveBeenCalledWith( - `Failed to resolve version ${versionSpec} from manifest` + `Failed to resolve version ${versionSpec} from manifest` ); expect(dlSpy).toHaveBeenCalled(); expect(extractTarSpy).toHaveBeenCalled(); expect(logSpy).toHaveBeenCalledWith( - 'Attempting to resolve the latest version from the manifest...' + 'Attempting to resolve the latest version from the manifest...' ); expect(logSpy).toHaveBeenCalledWith( - 'Unable to resolve a version from the manifest...' + 'Unable to resolve a version from the manifest...' ); expect(logSpy).toHaveBeenCalledWith( - `Failed to resolve version ${versionSpec} from manifest` + `Failed to resolve version ${versionSpec} from manifest` ); expect(logSpy).toHaveBeenCalledWith( - `Attempting to download ${versionSpec}...` + `Attempting to download ${versionSpec}...` ); expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`); @@ -892,7 +891,7 @@ use . await main.run(); expect(cnSpy).toHaveBeenCalledWith( - `::error::The specified go version file at: go.mod does not exist${osm.EOL}` + `::error::The specified go version file at: go.mod does not exist${osm.EOL}` ); }); @@ -912,9 +911,9 @@ use . inputs['architecture'] = arch; const expectedUrl = - platform === 'win32' - ? `https://github.com/actions/go-versions/releases/download/${version}/go-${version}-${platform}-${arch}.${fileExtension}` - : `https://storage.googleapis.com/golang/go${version}.${osSpec}-${arch}.${fileExtension}`; + platform === 'win32' + ? `https://github.com/actions/go-versions/releases/download/${version}/go-${version}-${platform}-${arch}.${fileExtension}` + : `https://storage.googleapis.com/golang/go${version}.${osSpec}-${arch}.${fileExtension}`; // ... but not in the local cache findSpy.mockImplementation(() => ''); @@ -926,36 +925,36 @@ use . await main.run(); expect(logSpy).toHaveBeenCalledWith( - `Acquiring go${version} from ${expectedUrl}` + `Acquiring go${version} from ${expectedUrl}` ); } }, 100000); it.each(['stable', 'oldstable'])( - 'acquires latest go version with %s go-version input', - async (alias: string) => { - const arch = 'x64'; - os.platform = 'darwin'; - os.arch = arch; + 'acquires latest go version with %s go-version input', + async (alias: string) => { + const arch = 'x64'; + os.platform = 'darwin'; + os.arch = arch; - inputs['go-version'] = alias; - inputs['architecture'] = os.arch; + inputs['go-version'] = alias; + inputs['architecture'] = os.arch; - // ... but not in the local cache - findSpy.mockImplementation(() => ''); + // ... but not in the local cache + findSpy.mockImplementation(() => ''); - dlSpy.mockImplementation(async () => '/some/temp/path'); - const toolPath = path.normalize(`/cache/go/${alias}/${arch}`); - cacheSpy.mockImplementation(async () => toolPath); + dlSpy.mockImplementation(async () => '/some/temp/path'); + const toolPath = path.normalize(`/cache/go/${alias}/${arch}`); + cacheSpy.mockImplementation(async () => toolPath); - await main.run(); + await main.run(); - const releaseIndex = alias === 'stable' ? 0 : 1; + const releaseIndex = alias === 'stable' ? 0 : 1; - expect(logSpy).toHaveBeenCalledWith( - `${alias} version resolved as ${goTestManifest[releaseIndex].version}` - ); - } + expect(logSpy).toHaveBeenCalledWith( + `${alias} version resolved as ${goTestManifest[releaseIndex].version}` + ); + } ); }); @@ -967,9 +966,9 @@ ruby 3.2.1 `; it('reads version from .tool-versions when specified', async () => { - inputs['tool-versions-file'] = '.special-tool-versions' + inputs['tool-versions-file'] = '.special-tool-versions'; existsSpy.mockImplementation(() => true); - readFileSpy.mockImplementation(() => Buffer.from(toolVersionsFile)) + readFileSpy.mockImplementation(() => Buffer.from(toolVersionsFile)); await main.run(); @@ -979,10 +978,10 @@ ruby 3.2.1 }); it('is overwritten by go-version param', async () => { - inputs['go-version'] = '1.18.2' - inputs['tool-versions-file'] = '.special-tool-versions' + inputs['go-version'] = '1.18.2'; + inputs['tool-versions-file'] = '.special-tool-versions'; existsSpy.mockImplementation(() => true); - readFileSpy.mockImplementation(() => Buffer.from(toolVersionsFile)) + readFileSpy.mockImplementation(() => Buffer.from(toolVersionsFile)); await main.run(); @@ -993,7 +992,7 @@ ruby 3.2.1 it('uses .tool-versions as a default when no version specified', async () => { existsSpy.mockImplementation(() => true); - readFileSpy.mockImplementation(() => Buffer.from(toolVersionsFile)) + readFileSpy.mockImplementation(() => Buffer.from(toolVersionsFile)); await main.run(); diff --git a/src/main.ts b/src/main.ts index 5e4b2601b..a0bea0199 100644 --- a/src/main.ts +++ b/src/main.ts @@ -160,19 +160,19 @@ function resolveVersionInput(): string { if(toolVersionsPath && !fs.existsSync(toolVersionsPath)) { throw new Error( `The specified .tool-versions file at ${toolVersionsPath} does not exist` - ) + ); } if (!toolVersionsPath) { - toolVersionsPath = '.tool-versions' + toolVersionsPath = '.tool-versions'; if(!fs.existsSync(toolVersionsPath)) { throw new Error( `No .tool-versions file was found in the project path. Please specify using tool-versions-file` - ) + ); } } - version = installer.parseToolVersionsFile(toolVersionsPath) + version = installer.parseToolVersionsFile(toolVersionsPath); } return version; From a9bf05db077bde6d86fedee138c53b95aa9ce31c Mon Sep 17 00:00:00 2001 From: plukevdh Date: Mon, 22 May 2023 09:41:36 -0400 Subject: [PATCH 3/4] run lint and build tasks --- .github/workflows/versions.yml | 2 +- dist/setup/index.js | 28 ++++++++++++++++++++++++---- src/main.ts | 8 ++++---- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/.github/workflows/versions.yml b/.github/workflows/versions.yml index b25d1d719..1fd581c44 100644 --- a/.github/workflows/versions.yml +++ b/.github/workflows/versions.yml @@ -139,7 +139,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ ubuntu-latest, windows-latest, macos-latest ] + os: [ubuntu-latest, windows-latest, macos-latest] steps: - uses: actions/checkout@v3 - name: Setup Go and check latest diff --git a/dist/setup/index.js b/dist/setup/index.js index 0dcd2342d..56b4268e6 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -61337,7 +61337,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.resolveStableVersionInput = exports.parseGoVersionFile = exports.makeSemver = exports.getVersionsDist = exports.findMatch = exports.getInfoFromManifest = exports.getManifest = exports.extractGoArchive = exports.getGo = void 0; +exports.resolveStableVersionInput = exports.parseToolVersionsFile = exports.parseGoVersionFile = exports.makeSemver = exports.getVersionsDist = exports.findMatch = exports.getInfoFromManifest = exports.getManifest = exports.extractGoArchive = exports.getGo = void 0; const tc = __importStar(__nccwpck_require__(7784)); const core = __importStar(__nccwpck_require__(2186)); const path = __importStar(__nccwpck_require__(1017)); @@ -61598,6 +61598,12 @@ function parseGoVersionFile(versionFilePath) { return contents.trim(); } exports.parseGoVersionFile = parseGoVersionFile; +function parseToolVersionsFile(toolVersionsPath) { + const contents = fs_1.default.readFileSync(toolVersionsPath).toString(); + const match = contents.match(/^golang (\d+(\.\d+)*)/m); + return match ? match[1] : ''; +} +exports.parseToolVersionsFile = parseToolVersionsFile; function resolveStableVersionDist(versionSpec, arch) { return __awaiter(this, void 0, void 0, function* () { const archFilter = sys.getArch(arch); @@ -61794,18 +61800,32 @@ exports.parseGoVersion = parseGoVersion; function resolveVersionInput() { 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'); + let toolVersionsPath = core.getInput('tool-versions-file'); + if (version && (versionFilePath || toolVersionsPath)) { + core.warning('Multiple version inputs are specified, only go-version will be used'); } if (version) { return version; } - if (versionFilePath) { + else if (versionFilePath) { if (!fs_1.default.existsSync(versionFilePath)) { throw new Error(`The specified go version file at: ${versionFilePath} does not exist`); } version = installer.parseGoVersionFile(versionFilePath); } + else { + // in the case of no version specification, reach for .tool-versions + if (toolVersionsPath && !fs_1.default.existsSync(toolVersionsPath)) { + throw new Error(`The specified .tool-versions file at ${toolVersionsPath} does not exist`); + } + if (!toolVersionsPath) { + toolVersionsPath = '.tool-versions'; + if (!fs_1.default.existsSync(toolVersionsPath)) { + throw new Error(`No .tool-versions file was found in the project path. Please specify using tool-versions-file`); + } + } + version = installer.parseToolVersionsFile(toolVersionsPath); + } return version; } diff --git a/src/main.ts b/src/main.ts index a0bea0199..8be7c6e6e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -157,17 +157,17 @@ function resolveVersionInput(): string { version = installer.parseGoVersionFile(versionFilePath); } else { // in the case of no version specification, reach for .tool-versions - if(toolVersionsPath && !fs.existsSync(toolVersionsPath)) { + if (toolVersionsPath && !fs.existsSync(toolVersionsPath)) { throw new Error( - `The specified .tool-versions file at ${toolVersionsPath} does not exist` + `The specified .tool-versions file at ${toolVersionsPath} does not exist` ); } if (!toolVersionsPath) { toolVersionsPath = '.tool-versions'; - if(!fs.existsSync(toolVersionsPath)) { + if (!fs.existsSync(toolVersionsPath)) { throw new Error( - `No .tool-versions file was found in the project path. Please specify using tool-versions-file` + `No .tool-versions file was found in the project path. Please specify using tool-versions-file` ); } } From f162814e287ccb3fd8b1d7428f1d854892f642a6 Mon Sep 17 00:00:00 2001 From: plukevdh Date: Mon, 22 May 2023 09:49:54 -0400 Subject: [PATCH 4/4] some basic documentation for .tool-versions --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index eb4f9dd23..81dcf5a28 100644 --- a/README.md +++ b/README.md @@ -218,6 +218,10 @@ The `go-version` input supports the following syntax: For more information about semantic versioning, please refer to [semver](https://github.com/npm/node-semver) documentation. +The action can also utilize a [`.tool-versions` file](https://asdf-vm.com/manage/configuration.html#tool-versions) +if `go-version` is not specified (`go-version` will take precedence over any `.tool-versions` specified). If the `. +tool-versions` is not in the project root, you can specify its location via the `tool-version-file` input. + ## Using `setup-go` on GHES `setup-go` comes pre-installed on the appliance with GHES if Actions is enabled. When dynamically downloading Go