Closed gaby closed 1 year ago
Thanks for reporting this. CC @bcmills, @matloob.
I wanted to clarify a part of the "What did you do?" section. Specifically, when you start out with a go.mod file with support for Go 1.17 through 1.20 and a go 1.18
directive, how does it end up with go 1.21
?
I tried to reproduce it as follows (using go1.21.0
):
$ cd $(mktemp -d)
$ cat <<EOF >go.mod
module github.com/my/lib
go 1.18
require github.com/google/uuid v1.2.0
EOF
$ cat <<EOF >p.go
package p
import _ "github.com/google/uuid"
EOF
At that point, doing go get -u -v
updated the uuid to its latest version v1.3.1, but left the go directive at its starting 1.18 value:
$ go get -u -v
go: trying upgrade to github.com/google/uuid@v1.3.1
go: upgraded github.com/google/uuid v1.2.0 => v1.3.1
$ cat go.mod
module github.com/my/lib
go 1.18
require github.com/google/uuid v1.3.1
Similarly, running go mod tidy
did clean up unused entries from go.sum, but otherwise left go.mod as it was before, with go 1.18
:
$ go mod tidy
$ echo $?
0
$ cat go.mod
module m
go 1.18
require github.com/google/uuid v1.3.1
Can you clarify what the reproduction steps are missing that's causing the problem? Thanks.
@dmitshur Interesting, could this be triggered by a dependency having a toolchain directive on their go.mod
file?
Example CI that is currently failing using 1.21: https://github.com/gofiber/contrib/actions/runs/6047961443/job/16412414494
The CI file is located here: https://github.com/gofiber/contrib/blob/main/.github/workflows/govulncheck.yml
The go.mod for when the failure happens is here: https://github.com/gofiber/contrib/blob/main/paseto/go.mod
This also happens with all the go.mod files in each directory of https://github.com/gofiber/contrib/
Yes, that appears to be what's happening.
As far as I can see, the root problem is that as of https://github.com/gofiber/fiber/pull/2588, the go.mod of the module github.com/gofiber/fiber/v2 states "go 1.21", which means that module requires Go language 1.21 or higher to be used. So when go mod tidy
is run in the github.com/gofiber/contrib/paseto
module which requires github.com/gofiber/fiber/v2@v2.49.0
, it upgrades said module's go line to be 1.21 too. Notably, if you run go get go@1.18
in paseto, it downgrades to github.com/gofiber/fiber/v2@v2.48.0
.
(Please refer to https://go.dev/ref/mod#go-mod-file-go and https://go.dev/blog/toolchain for more detailed information on this topic.)
@dmitshur I just literally realize that too... Sending a message to the Fiber maintainers as I am typing this.
My guess is that the only fix is to roll back those changes in gofiber/fiber
.
@dmitshur Thanks for your help, this can be closed. It's a Fiber issue, not Go.
Glad that we figured out what was causing this. Thanks for the detailed report.
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
This is a continuation of https://github.com/golang/go/issues/57001
Lets say, I have a library made with Go that supports go version
1.17
,1.18
,1.19
, and1.20
.My go.mod file looks as follow:
Normally when getting updates, you would do
go get -u -v
thengo mod tidy
. Since go1.21 runninggo mod tidy
now changes your go.mod file to the following:This a breaking change behavior, given that now if I commit that code? Any previous CI/CD process, or any other developer in the team that's using a different version of
go
can no longer build/test/run the code because of thetoolchain
directive.What did you expect to see?
I expected that running
go mod tidy
would only cleanup imports and thego.sum
file.What did you see instead?
Running
go mod tidy
changes thego.mod
go version and adds a toolchain directive that's not available in any previous go version.Suggested solution
There's two possible solutions here:
go
commands use thelocal
install by default instead ofauto
.go mod tidy
command shouldn't change the version/add a directive togo.mod
Example running with
go 1.20.7
in Docker:This bring the question, how can we write libraries that are backward compatible with previous go versions?