From b967a467e1c904489be015f76916b6bb83d60ef2 Mon Sep 17 00:00:00 2001 From: Matthew Hughes Date: Mon, 25 Aug 2025 20:08:21 +0100 Subject: [PATCH] squash! Prefer installing version from `toolchain` directive Avoid installing from `toolchain` if `GOTOOLCHAIN` is `local`, also better regex for matching toolchain directive --- __tests__/setup-go.test.ts | 89 +++++++++++++++++++++++++++----------- dist/setup/index.js | 12 +++-- src/installer.ts | 14 ++++-- 3 files changed, 82 insertions(+), 33 deletions(-) diff --git a/__tests__/setup-go.test.ts b/__tests__/setup-go.test.ts index e167ce6..b89c08f 100644 --- a/__tests__/setup-go.test.ts +++ b/__tests__/setup-go.test.ts @@ -129,6 +129,9 @@ describe('setup-go', () => { }); afterEach(() => { + // clear out env var set during 'run' + delete process.env[im.GOTOOLCHAIN_ENV_VAR]; + //jest.resetAllMocks(); jest.clearAllMocks(); //jest.restoreAllMocks(); @@ -989,11 +992,16 @@ use . }); describe('go-version-file-toolchain', () => { - const goModContents = `module example.com/mymodule + const goVersions = ['1.22.0', '1.21rc2', '1.18']; + const placeholderVersion = '1.19'; + const buildGoMod = ( + goVersion: string, + toolchainVersion: string + ) => `module example.com/mymodule -go 1.14 +go ${goVersion} -toolchain go1.21.0 +toolchain go${toolchainVersion} require ( example.com/othermodule v1.2.3 @@ -1005,36 +1013,67 @@ replace example.com/thatmodule => ../thatmodule exclude example.com/thismodule v1.3.0 `; - const goWorkContents = `go 1.19 + const buildGoWork = ( + goVersion: string, + toolchainVersion: string + ) => `go 1.19 -toolchain go1.21.0 +toolchain go${toolchainVersion} use . `; - it('reads version from toolchain directive in go.mod', async () => { - inputs['go-version-file'] = 'go.mod'; - existsSpy.mockImplementation(() => true); - readFileSpy.mockImplementation(() => Buffer.from(goModContents)); + goVersions.forEach(version => { + [ + { + goVersionfile: 'go.mod', + fileContents: Buffer.from(buildGoMod(placeholderVersion, version)), + expected_version: version, + desc: 'from toolchain directive' + }, + { + goVersionfile: 'go.work', + fileContents: Buffer.from(buildGoMod(placeholderVersion, version)), + expected_version: version, + desc: 'from toolchain directive' + }, + { + goVersionfile: 'go.mod', + fileContents: Buffer.from(buildGoMod(placeholderVersion, version)), + gotoolchain_env: 'local', + expected_version: placeholderVersion, + desc: 'from go directive when GOTOOLCHAIN is local' + }, + { + goVersionfile: 'go.work', + fileContents: Buffer.from(buildGoMod(placeholderVersion, version)), + gotoolchain_env: 'local', + expected_version: placeholderVersion, + desc: 'from go directive when GOTOOLCHAIN is local' + } + ].forEach(test => { + it(`reads version (${version}) in ${test.goVersionfile} ${test.desc}`, async () => { + inputs['go-version-file'] = test.goVersionfile; + if (test.gotoolchain_env !== undefined) { + process.env[im.GOTOOLCHAIN_ENV_VAR] = test.gotoolchain_env; + } + existsSpy.mockImplementation(() => true); + readFileSpy.mockImplementation(() => Buffer.from(test.fileContents)); - await main.run(); + await main.run(); - expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.21.0'); - expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.21.0...'); - expect(logSpy).toHaveBeenCalledWith('matching 1.21.0...'); - }); - - it('reads version from toolchain directive in go.work', async () => { - inputs['go-version-file'] = 'go.work'; - existsSpy.mockImplementation(() => true); - readFileSpy.mockImplementation(() => Buffer.from(goWorkContents)); - - await main.run(); - - expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.21.0'); - expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.21.0...'); - expect(logSpy).toHaveBeenCalledWith('matching 1.21.0...'); + expect(logSpy).toHaveBeenCalledWith( + `Setup go version spec ${test.expected_version}` + ); + expect(logSpy).toHaveBeenCalledWith( + `Attempting to download ${test.expected_version}...` + ); + expect(logSpy).toHaveBeenCalledWith( + `matching ${test.expected_version}...` + ); + }); + }); }); }); diff --git a/dist/setup/index.js b/dist/setup/index.js index ca909af..96f4ef9 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -94666,10 +94666,14 @@ function parseGoVersionFile(versionFilePath) { const contents = fs_1.default.readFileSync(versionFilePath).toString(); if (path.basename(versionFilePath) === 'go.mod' || path.basename(versionFilePath) === 'go.work') { - // toolchain directive: https://go.dev/ref/mod#go-mod-file-toolchain - const matchToolchain = contents.match(/^toolchain go(\d+(\.\d+)*)/m); - if (matchToolchain) { - return matchToolchain[1]; + // for backwards compatibility: use version from go directive if + // 'GOTOOLCHAIN' has been explicitly set + if (process.env[exports.GOTOOLCHAIN_ENV_VAR] !== exports.GOTOOLCHAIN_LOCAL_VAL) { + // toolchain directive: https://go.dev/ref/mod#go-mod-file-toolchain + const matchToolchain = contents.match(/^toolchain go(1\.\d+(?:\.\d+|rc\d+)?)/m); + if (matchToolchain) { + return matchToolchain[1]; + } } // go directive: https://go.dev/ref/mod#go-mod-file-go const matchGo = contents.match(/^go (\d+(\.\d+)*)/m); diff --git a/src/installer.ts b/src/installer.ts index 7887ba2..2fad1d8 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -497,10 +497,16 @@ export function parseGoVersionFile(versionFilePath: string): string { path.basename(versionFilePath) === 'go.mod' || path.basename(versionFilePath) === 'go.work' ) { - // toolchain directive: https://go.dev/ref/mod#go-mod-file-toolchain - const matchToolchain = contents.match(/^toolchain go(\d+(\.\d+)*)/m); - if (matchToolchain) { - return matchToolchain[1]; + // for backwards compatibility: use version from go directive if + // 'GOTOOLCHAIN' has been explicitly set + if (process.env[GOTOOLCHAIN_ENV_VAR] !== GOTOOLCHAIN_LOCAL_VAL) { + // toolchain directive: https://go.dev/ref/mod#go-mod-file-toolchain + const matchToolchain = contents.match( + /^toolchain go(1\.\d+(?:\.\d+|rc\d+)?)/m + ); + if (matchToolchain) { + return matchToolchain[1]; + } } // go directive: https://go.dev/ref/mod#go-mod-file-go