I'm running a GitHub pipeline that (among other tests) ensures that code is properly formatted. I do that by running go fmt ./...
on my source and then checking that this doesn't change anything with git diff -q
. In addition to that, I'm running the pipeline using different versions of Go (1.20 to 1.22) to ensure compatibility. Please take into consideration that I may be misunderstanding the content of the go.mod
file and that I'm not using it properly to express my intentions.
Anyhow, the format check used to work fine in the past, but I'm having issues with it now. I can't get this to work without triggering unwanted changes to go.mod
. Apart from the actual dependencies, I have this in the go.mod
:
module my-module
go 1.20
require (
....
)
My intention with the go 1.20
is to mark this as compatible with version 1.20. If I run go fmt ./...
with Go 1.22, it fails and tells me to run go mod tidy
first. Doing so, changes go.mod
to this:
module my-module
go 1.22
toolchain go1.22.4
require (
....
)
This conflicts with my intentions, because Go 1.20 doesn't recognize toolchain
and fails on that then.
go
directive in go.mod
even the correct way to say that the module is compatible with that Go version?go fmt
with different versions as described above?go mod tidy
or go get
be considered a bug? After all, it's actively ignoring the go 1.20
directive and breaking the code for older versions.As a workaround, I could exclude changes to go.mod
from my checks in the pipeline. That's IMHO not a proper fix but rather a hack though. In any case, I have a feeling that I don't fully understand Go's dependency management infrastructure yet, so if you think I don't, give me a nudge in the right direction! :)
go-version-test
.go mod init go-version-test
using Go 1.20.main.go
as below.go get -u -v
using Go 1.20.go mod tidy -go=1.20
using Go 1.22.The content of main.go
is:
package main
import (
"go.mongodb.org/mongo-driver/mongo"
)
func main() {
// Note: This won't compile, but that doesn't matter!
_, _ := mongo.Connect(ctx, opts)
}
The last command will generate an error:
go: github.com/youmark/pkcs8@v0.0.0-20240424034433-3c2c7870ae76 requires go@1.22, but 1.20 is requested
As I understand it, the MongoDB driver package, pulls in the pkcs8 package. Both work well with Go 1.20, but the pkcs8 package has a go 1.22
directive in its go.mod
file. Others already reported this as an issue, too.
This is a change introduced with go 1.21:
So my guess would be that you have some module requiring go 1.22. It might or might not still work with go 1.20, but for example be aware of the loopvar experiment - programs written for go 1.22 might compile with go 1.20, but do not run correctly.
In order to find the dependency requiring Go 1.22, you can run go mod tidy -go=1.20
using Go 1.22. This will give you an error in the form go: some/dependent/package requires go@1.22, but 1.20 is requested
.