mirror of
				https://github.com/actions/setup-go.git
				synced 2025-10-31 16:13:43 +00:00 
			
		
		
		
	Configure environment to avoid toolchain installs
Force `go` to always use the local toolchain (i.e. the one the one that
shipped with the go command being run) via setting the `GOTOOLCHAIN`
environment variable to `local`[1]:
> When GOTOOLCHAIN is set to local, the go command always runs the
bundled Go toolchain.
This is how things are setup in the official Docker images (e.g.[2], see
also the discussion around that change[3]). The motivation behind this
is to:
* Reduce duplicate work: if the `toolchain` version in `go.mod` was
  greated than the `go` version, the version from the `go` directive
  would be installed, then Go would detect the `toolchain` version and
  additionally install that
* Avoid Unexpected behaviour: if you specify this action runs with some Go
  version (e.g. `1.21.0`) but your go.mod contains a `toolchain` or `go`
  directive for a newer version (e.g. `1.22.0`) then, without any other
  configuration/environment setup, any go commands will be run using go
  `1.22.0`
This will be a **breaking change** for some workflows. Given a `go.mod`
like:
    module proj
    go 1.22.0
Then running any `go` command, e.g. `go mod tidy`, in an environment
where only go versions before `1.22.0` were installed would previously
trigger a toolchain download of Go `1.22.0` and that version being used
to execute the command. With this change the above would error out with
something like:
> go: go.mod requires go >= 1.22.0 (running go 1.21.7;
GOTOOLCHAIN=local)
[1] https://go.dev/doc/toolchain#select
[2] dae3405a32/Dockerfile-linux.template (L163)
[3] https://github.com/docker-library/golang/issues/472
			
			
This commit is contained in:
		
							parent
							
								
									e75c3e80bc
								
							
						
					
					
						commit
						613315d242
					
				| @ -285,7 +285,7 @@ describe('setup-go', () => { | ||||
|     expect(logSpy).toHaveBeenCalledWith(`Setup go version spec 1.13.0`); | ||||
|   }); | ||||
| 
 | ||||
|   it('does not export any variables for Go versions >=1.9', async () => { | ||||
|   it('does not export GOROOT for Go versions >=1.9', async () => { | ||||
|     inputs['go-version'] = '1.13.0'; | ||||
|     inSpy.mockImplementation(name => inputs[name]); | ||||
| 
 | ||||
| @ -298,7 +298,7 @@ describe('setup-go', () => { | ||||
|     }); | ||||
| 
 | ||||
|     await main.run(); | ||||
|     expect(vars).toStrictEqual({}); | ||||
|     expect(vars).not.toHaveProperty('GOROOT'); | ||||
|   }); | ||||
| 
 | ||||
|   it('exports GOROOT for Go versions <1.9', async () => { | ||||
| @ -314,9 +314,7 @@ describe('setup-go', () => { | ||||
|     }); | ||||
| 
 | ||||
|     await main.run(); | ||||
|     expect(vars).toStrictEqual({ | ||||
|       GOROOT: toolPath | ||||
|     }); | ||||
|     expect(vars).toHaveProperty('GOROOT', toolPath); | ||||
|   }); | ||||
| 
 | ||||
|   it('finds a version of go already in the cache', async () => { | ||||
| @ -989,4 +987,18 @@ use . | ||||
|       } | ||||
|     ); | ||||
|   }); | ||||
| 
 | ||||
|   it('exports GOTOOLCHAIN and sets it in current process env', async () => { | ||||
|     inputs['go-version'] = '1.21.0'; | ||||
|     inSpy.mockImplementation(name => inputs[name]); | ||||
| 
 | ||||
|     const vars: {[key: string]: string} = {}; | ||||
|     exportVarSpy.mockImplementation((name: string, val: string) => { | ||||
|       vars[name] = val; | ||||
|     }); | ||||
| 
 | ||||
|     await main.run(); | ||||
|     expect(vars).toStrictEqual({GOTOOLCHAIN: 'local'}); | ||||
|     expect(process.env).toHaveProperty('GOTOOLCHAIN', 'local'); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
							
								
								
									
										16
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							| @ -94777,6 +94777,7 @@ const os_1 = __importDefault(__nccwpck_require__(2037)); | ||||
| function run() { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         try { | ||||
|             setToolchain(); | ||||
|             //
 | ||||
|             // 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.
 | ||||
| @ -94890,6 +94891,21 @@ function resolveVersionInput() { | ||||
|     } | ||||
|     return version; | ||||
| } | ||||
| function setToolchain() { | ||||
|     // docs: https://go.dev/doc/toolchain
 | ||||
|     // "local indicates the bundled Go toolchain (the one that shipped with the go command being run)"
 | ||||
|     // this is so any 'go' command is run with the selected Go version
 | ||||
|     // and doesn't trigger a toolchain download and run commands with that
 | ||||
|     // see e.g. issue #424
 | ||||
|     // and a similar discussion: https://github.com/docker-library/golang/issues/472
 | ||||
|     const toolchain = 'local'; | ||||
|     const toolchainVar = 'GOTOOLCHAIN'; | ||||
|     // set the value in process env so any `go` commands run as child-process
 | ||||
|     // don't cause toolchain downloads
 | ||||
|     process.env[toolchainVar] = toolchain; | ||||
|     // and in the runner env so e.g. a user running `go mod tidy` won't cause it
 | ||||
|     core.exportVariable(toolchainVar, toolchain); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /***/ }), | ||||
|  | ||||
							
								
								
									
										18
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/main.ts
									
									
									
									
									
								
							| @ -11,6 +11,7 @@ import os from 'os'; | ||||
| 
 | ||||
| export async function run() { | ||||
|   try { | ||||
|     setToolchain(); | ||||
|     //
 | ||||
|     // 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.
 | ||||
| @ -160,3 +161,20 @@ function resolveVersionInput(): string { | ||||
| 
 | ||||
|   return version; | ||||
| } | ||||
| 
 | ||||
| function setToolchain() { | ||||
|   // docs: https://go.dev/doc/toolchain
 | ||||
|   // "local indicates the bundled Go toolchain (the one that shipped with the go command being run)"
 | ||||
|   // this is so any 'go' command is run with the selected Go version
 | ||||
|   // and doesn't trigger a toolchain download and run commands with that
 | ||||
|   // see e.g. issue #424
 | ||||
|   // and a similar discussion: https://github.com/docker-library/golang/issues/472
 | ||||
|   const toolchain = 'local'; | ||||
|   const toolchainVar = 'GOTOOLCHAIN'; | ||||
| 
 | ||||
|   // set the value in process env so any `go` commands run as child-process
 | ||||
|   // don't cause toolchain downloads
 | ||||
|   process.env[toolchainVar] = toolchain; | ||||
|   // and in the runner env so e.g. a user running `go mod tidy` won't cause it
 | ||||
|   core.exportVariable(toolchainVar, toolchain); | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user