-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/go: toolchain directive in go.mod being updated unnecessarily #65847
Comments
Please fill out the complete issue template. In particular: what version of Go are you using, what was your |
@bcmills updated - can you take a look again and see if I'm missing anything? |
Adding my own experiences for reference. At work, we would definitely prefer to have the ability to disable the automatic toolchain upgrades (and possibly fail builds that would otherwise require a newer toolchain). We have many modules with the This feature started causing issues for us when one engineer using Go 1.21.x locally updated some dependency and ran Without the ability to opt out of automatic toolchain upgrades we are now forced to synchronize the Go version across CI and every developer machine. While that's not an unreasonable stance in the general case, it is a new restriction/requirement that, as far as I've seen, is not called out in the release notes. We have tried setting One could also argue that forcing more conservative development shops to always stay on the most current Go release, despite the previous minor release being explicitly supported, is a bad situation. |
As of Go 1.21, the initial toolchain release has a And for the Some specifics:
|
You do have that ability: you can set You can also force
That is exactly the problem that |
This works, but it also means that as soon as anyone moves to a newer Go release then everyone else in the organization must also move to that same newer version immediately. This is a problem in tightly regulated environments where, as an example Go 1.22.x may not be "certified" but Go 1.21.5 is. As it stands today it's not possible to both fix CI to 1.21.x and also allow developers to use a newer 1.21.y or 1.22.
TIL. Thanks for this. |
There are environments where setting an env. var. is not possible. For example, the public Renovate service does not support this. There are other ways to pin the golang version in Renovate, but they're undesirable for maintainability reasons. Devcontainers could be another example, where the tooling env. is shared, and must remain static, for consistency across a whole team of developers. In any case, my point is there are places where setting env. vars. isn't a viable workaround. IMHO such major behavior changes should almost always default to the previous or "least disruptive" option. |
I just ran into this same issue, go1.21 is supported but my box has go1.22. I can't run any commands because This is for a library used by a lot of users and it should support go1.21 and go1.22 |
Still a problem, it just makes a complete mess any time common CI server is used by few people |
I'm not seeing this already mentioned here, but in situations where you're looking to change the $ cat go.mod
module example.com
go 1.21.0
$ go get [email protected] toolchain@none
go: upgraded go 1.21.0 => 1.22.6 That comes with the disadvantages of not having the toolchain version written down, but that's no different from the outcome where it's manually removed after |
This comment was marked as off-topic.
This comment was marked as off-topic.
A while ago one would set the
A while ago |
Thanks for posting this. That's exactly the behaviour I (and probably others) had been looking for and was originally the behaviour that I thought that Certainly for my own individual modules I'd likely move to a model of always doing: Ideally I'd want to bake that client behaviour into the |
This comment was marked as spam.
This comment was marked as spam.
I would argue that by adding
I have found this really painful for library developers as well. I've had to ask maintainers to lower the versioning or remove the toolchain directive in a popular OSS lib to support said release policy. As with others, I'm finding I'm constantly wasting time having to unwind/remove the toolchain directive as we run a |
This is a massive nuisance, and |
We've been using GOTOOLCHAIN=local |
So have I but it still likes to blast the go.mod file. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@matthewhartstonge I'd like to understand the issue with library modules better. Is the issue that when a library module has a toolchain directive, it may not be tested with older Go versions in CI and may develop incompatibilities? |
@matloob i think he was conflating the go and toolchain directives there. Where the go directive implicitly also becomes the minimum toolchain version for all consuming modules See sigstore/rekor#2323 and similar PRs that aim to rectify this. As soon as one module bumps their go directive up then it’s a cascading ripple across chains of modules, forcing everyone to bump to match. Ideally the Go directive would never have become a toolchain version and would have remained as purely major language level |
@matloob yeah, it is a conflation - and [my understanding] is that most Go developers won't/don't know the difference. Even massive projects have been affected by this (k8s, gRPC and Google's own API SDKs). The conflation comes because the recognisable pattern developers hook on to is that a new As @dnwe mentioned, the change to the go directive/toolchain has become a pervasive change that has affected the whole dependency ecosystem, forcing dependants to bump project go versions. Personally, I've ended up spending many hours with CI breaking and having to request/informing upstream library authors that they've broken go version compatibility since this change has come in - for example if an external dependency/library happens to set the latest version of go that dropped that week. Due to our business' specific requirements with government, security and our ISO response to CVEs, It's easier to forefront these changes. When a dependency creates a new release, dependabot will pick up and explode anytime the go directive is changed even if the API is compatible. We've locked our lint, build, and SAST tools to the latest "n-1" version of Go. If the @cevich explains it well in relation to CI: #65847 (comment) (RenovateBot being the cause of the recent go directive updates across the Google Cloud Go SDKs) Hope that helps bring some understanding? |
@matthewhartstonge It would be very helpful to have a video or phone chat about this if you're able. |
@matloob Hit me up on |
Yeah my reading from the docs and the announcement was the toolchain directive would for users that have it configured, pick the best toolchain to use automatically. It is independent of the go directive. But in practice, it just seems to additionally replace the go directive which becomes unusable as the toolchain is used for everything. |
This means you cannot pin |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Change https://go.dev/cl/656835 mentions this issue: |
There doesn't seem to be a way to stop the
toolchain
directive from being updated when running variousgo
commandsIn our OSS project we rely on the
go
directive in the go.mod to ensure a min go version. We do not want to use thetoolchain
directive as we always expect it to match thego
directive.some user feedback
Go Version
Go ENV
expand
Scenario 1 - creating a new module and downgrading go
What did you do
What did you see happen?
What did you expect to happen?
toolchain
directive to be added1.21
- since I didn't specify the point releaseScenario 2 - pulling a new dependency that upgraded the go version
What did you do
Project structure
Fetch a dependency that updates the go min version
What did you see happen?
console output
go.mod output
What did you expect to happen?
toolchain
directive shouldn't appear. We want it to always default to the same as thego
directiveThe text was updated successfully, but these errors were encountered: