Skip to content
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

build: use a zero for third digit for major release, such as 'go1.21.0' #57631

Closed
thepudds opened this issue Jan 5, 2023 · 37 comments
Closed

Comments

@thepudds
Copy link
Contributor

thepudds commented Jan 5, 2023

Summary

#32450 and #27255 proposed adopting semantic versioning for Go releases. semver has a very specific definition, which means fully adopting it has significant challenges, including it raises certain expectations that don't apply, there are differences between what the go project vs. semver considered a "major release", and other sample problems mentioned here or here. Personally, I don't think it would be worthwhile to adopt semver for Go releases.

This is intentionally a narrower proposal, which is just to start adding the .0 to major releases at some point, such as go1.23.0.

Rationale 1: Stop old releases from using code they don't understand

Part of the context for this proposal is the auto-upgrading forward compatibility proposal (#57001), which would be a transition point for how Go versions overall are managed, and the related possible transition in the semantics of loop variables (#56010).

In #57001 (comment), Russ wrote (responding to @rittneje):

As an example, one of our teams tends to end up on officially unsupported versions because qualifying new releases is a large effort and doing it every six months is not feasible. It would be better if an explicit failure could be induced in older compilers (e.g., by adding a new directive to go.mod) instead of just assuming no one would use one.

For exactly the same kind of backwards compatibility, unrecognized lines in dependency go.mod files are ignored. So we've painted ourselves into a bit of a corner where the best we can do is prepare K versions that recognize that they don't understand the new code and then issue the K+1'th version supporting the new code. The only thing we really have control over is the choice of K. In the quoted text I was assuming K=1. Maybe we should do K=2, but I wouldn't want to do more than that and I'm not even sure K=2 is worth it.

Older go versions I think stretching back to go1.14 will reject a go.mod if the go line has a go version with a third digit, so always using three digits in the go.mod could be a way to cause even very old versions of cmd/go to fail if for example #56010 is adopted.

The majority of gophers would get the good behavior described in #57001 because most gophers would land within that K=1 or K=2 window, but this would be a broader enforcement mechanism that handles old Go releases outside that K window.

Example error (playground link):

go: errors parsing go.mod:
go.mod:3: invalid go version '1.25.0': must match format 1.23

In other words:

  • "enforcement & good errors" for most gophers
  • "enforcement & subotimal but google-able error" for much smaller subset of gophers using versions outside that K window

...which might be better than "unexpected semantics & no error" for that subset of gophers.

Rationale 2: Current source of confusion

I think releases like go1.20 have been a source of confusion, including when gophers are talking to each other about what version they are currently running or should run. Some older comments in a similar spirit:

@mvdan wrote in #29984:

I too have wished for 1.11 to be 1.11.0 for a while. Too many users think they're running the latest 1.11 because they're on 1.11. "What do you mean the latest 1.11? I am on 1.11"

@bcmills wrote in #29984:

Personally, I think it's pretty confusing to have the first patch version in the 1.11 line be named go1.11 rather than go1.11.0. [...] The lack of minor-version on the first release buries a major clue to the user that there might be more recent versions available. I would like to see us release Go 1.12 as go1.12.0 instead of go1.12.

Some costs

  1. Code or scripts that parse go versions would need to be updated or at least visited to ensure they handle the new format.

    • (In some cases, code that knows how to parse go1.23.1 might already handle go1.23.0).
    • (Also, any such code or scripts that is looking at go.mod already would need to be updated to handle the three digits for patch releases in go.mod proposed in #57001).
  2. Documentation, blogs, books, and so on would also need to be updated or be slightly stale.

    • (However, the impact of being stale or the work to update for a third digit might be small compared to the impact of #57001 overall).

In general, using a transition point to introduce even more change is a terrible idea in some cases. In other cases, it can be helpful to piggyback a desirable change on top of another transition. That said, I'm not sure which of those cases this proposal is. ;-)

Alternative

An alternative form of this proposal might be to just use zero in the third digit in go.mod and nowhere else, which might be a smaller change, but that then might be a ~mild source of confusion if it is inconsistent with other go version uses.

@gopherbot gopherbot added this to the Proposal milestone Jan 5, 2023
@mvdan
Copy link
Member

mvdan commented Jan 5, 2023

I continue having to explain around the confusion of the missing trailing dot-zero. Especially when users report bugs on my projects written in Go, as they say "I'm on Go 1.X", and that is very ambiguous - especially given that many new users see go version go1.20 and assume that there are no 1.20.x releases to watch out for, like Bryan says.

In other words, some people understand 1.20 to mean 1.20.0 (the first bugfix version), whereas others understand it to mean 1.20.x (the latest bugfix version), and that isn't likely to change.

An alternative form of this proposal might be to just use zero in the third digit in go.mod and nowhere else

Perhaps unsurprisingly, I wouldn't support this alternative :) I want to make the release versions explicit.

@ianlancetaylor ianlancetaylor moved this to Incoming in Proposals Jan 5, 2023
@ianlancetaylor
Copy link
Member

CC @golang/release

@rsc
Copy link
Contributor

rsc commented Jan 6, 2023

This may be an idea whose time has come. I'll reserve feedback for later to let more people weigh in. I just wanted to reply to this:

go: errors parsing go.mod:
go.mod:3: invalid go version '1.25.0': must match format 1.23

This error only happens for the work module's go.mod. In dependency go.mod files, the parser runs in 'lax' mode, where it is more forgiving of things it doesn't understand. For the go line, if the lax parser sees go 1.25.0 or even go 1.25asdfasdfasdf, it will treat it the same as go 1.25. I did this a few releases back specifically to make changes along these lines safer. Of course, that was back when I thought we'd want Go 1.19 to be able to build and run dependencies that said go 1.25.0. Now with #57001 we don't. A failure of vision I suppose.

@thepudds
Copy link
Contributor Author

thepudds commented Jan 6, 2023

Hi @rsc 👋

This error only happens for the work module's go.mod. In dependency go.mod files, the parser runs in 'lax' mode, where it is more forgiving of things it doesn't understand.

Ah, I didn't check that.

That might close off this avenue for helping with broader enforcement for things like #56010.... though maybe there is some other potential modification... but that's perhaps unlikely, and probably even less likely to be as natural as just using three digits in the existing go line.

As an example of another possibility, this seems to fail even in lax parsing mode for a dependency:

go go1.25.0

... but that stutter is a bit ugly. (Playground link, in case anyone wants to try variations).

I suppose cmd/go could take on doing some transformation to a breaking format when something like go mod tidy or go get is run at a sufficiently high go version line... but maybe this is a well painted corner after all. 😅

prepare K versions that recognize that they don't understand the new code and then issue the K+1'th version supporting the new code. The only thing we really have control over is the choice of K. In the quoted text I was assuming K=1. Maybe we should do K=2, but I wouldn't want to do more than that and I'm not even sure K=2 is worth it.

As a side note, I'd vote for a K > 1. There's a decently long tail of people out there that don't quite move at the pace of the Go project's officially supported versions...

@thepudds
Copy link
Contributor Author

thepudds commented Jan 6, 2023

And of course, when it comes to K, it could be worth cheating time a bit by adding some tiny bit of knowledge in a patch release, similar to how go1.11 was the first Go version of modules, but go1.9.7 and go1.10.3 picked up a tiny bit of knowledge to help with the transition.

Picking sample numbers, something like:

  • go1.19.10 and go1.20.5 could learn that go 1.23 or higher in a go.mod is a hard error
  • go1.21 could learn how to auto upgrade
  • go1.23 could change loop variable semantics

Alternatively, instead of the first bullet there picking a specific version to consider a hard error, a patch release could roll back the three-digit lax parsing in dependencies, or something along those lines. Given this would be done now with foreknowledge, it could be a friendlier error.

Finally, it looks like the lax parser also rejects a go directive more more than two terms, which means something like go language 1.23.0 would be rejected, but that's probably not a perfect choice either. (It allows go v1.23.0 ;-).

@rsc
Copy link
Contributor

rsc commented Feb 22, 2023

I think we can leave intentionally breaking old toolchains to #57001. Writing 'go 1.21.0' would work today in the past many Go versions. So this issue can just be about "should we call the next release Go 1.21.0" instead of "Go 1.21"?

Probably we should call it "Go 1.21.0" so that when people say "Go 1.21" it is clear they mean the overall sequence of point releases and not specifically the first one. For example in Docker golang you can ask for go1.21.1 but as I understand it you can't ask for go1.20. Saying "FROM golang:1.20" gets you the latest 1.20 point release.

Is there anything that would break if we call the next major release Go 1.21.0? We know version strings can handle 'go1.21.0' because they handle 'go1.21.1'.

@dmitshur
Copy link
Contributor

dmitshur commented Feb 22, 2023

Is there anything that would break if we call the next major release Go 1.21.0? We know version strings can handle 'go1.21.0' because they handle 'go1.21.1'.

At least some code that parses Go versions and/or tags may have special cases to account for ".0" currently being left out, and that would need to change (for example, see here) to treat go1.21.0 the same as go1.21.

Code that constructs Go download URLs by relying on the current pattern (e.g. "https://go.dev/dl/" + version + suffix) instead of using the "filename" field from the go.dev/dl/?mode=json API response would also presumably need to be updated to handle .0 releases.

I don't see discussion of what, if anything, should happen to pre-release versions like RC 1 above. More changes may be needed to handle pre-release versions depending on the answer to that.

@rsc rsc moved this from Incoming to Active in Proposals Feb 22, 2023
@rsc
Copy link
Contributor

rsc commented Feb 22, 2023

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@thepudds
Copy link
Contributor Author

thepudds commented Feb 22, 2023

Hi @dmitshur

I don't see discussion of what, if anything, should happen to pre-release versions like RC 1 above. More changes may be needed to handle pre-release versions depending on the answer to that.

Personally, I think the pre-release versions could be left alone and there could be go1.21rc1, go1.21.0, and go1.21.1, or at least, that was the intent of this intentionally narrow proposal. I think they are not a major source of confusion today. They don't follow semver, but I think that's OK for some of the reasons mentioned above, and of course there would be additional costs if they were to change as well. That said, others might have different opinions.

@zikaeroh
Copy link
Contributor

The standard format for a semver prerelease would be something like 1.21.0-rc.1, which IMO is fine. If everyone has to fix up things to support a new patch=0 release, I don't think it's that much of a problem for it to also be updated to support a new RC format.

That and everyone who has an existing semver library they could use (e.g. actions/setup-go and so on) will be in a better place, and probably Go itself if it wants to be distributed via the module proxy, which would too expect valid semver.

@willfaught
Copy link
Contributor

The standard format for a semver prerelease would be something like 1.21.0-rc.1, which IMO is fine. If everyone has to fix up things to support a new patch=0 release, I don't think it's that much of a problem for it to also be updated to support a new RC format.

Agreed. Better to rip off the band aid and align everything under one naming scheme.

@rsc
Copy link
Contributor

rsc commented Mar 1, 2023

It's already not semver because there is a "go" prefix. We're going to keep that. We also don't have prereleases of point releases - there is no go1.21.1rc2 today. We're not going to move to semver, so we don't need to be "more" like semver.

Let's keep this proposal focused on adding the .0 only. Thanks.

@rsc
Copy link
Contributor

rsc commented Mar 1, 2023

@dmitshur, re

At least some code that parses Go versions and/or tags may have special cases to account for ".0" currently being left out, and that would need to change (for example, see here) to treat go1.21.0 the same as go1.21.

Code that constructs Go download URLs by relying on the current pattern (e.g. "https://go.dev/dl/" + version + suffix) instead of using the "filename" field from the go.dev/dl/?mode=json API response would also presumably need to be updated to handle .0 releases.

I don't understand this. If we change the version to go1.21.0 won't we also change the file name to say 1.21.0, which would make this pattern continue to work?

@rsc
Copy link
Contributor

rsc commented Mar 1, 2023

There are a few minor details to work out but in general people seem okay with this. Are there any concerns remaining?

@rsc
Copy link
Contributor

rsc commented Mar 1, 2023

Worth noting that if we accept this proposal we should probably decline #32450.

@willfaught
Copy link
Contributor

We're not going to move to semver, so we don't need to be "more" like semver.

Worth noting that if we accept this proposal we should probably decline ["proposal: Go 2: start using semantic versions for Go releases"].

I would think that that proposal would already be declined if the Go team is already resolved to not use semver.

I don't see the connection between this proposal and that one. Both could be adopted, for example, because adding a 0 is compatible with semver.

@rsc
Copy link
Contributor

rsc commented Mar 1, 2023

Many proposals are not declined simply because we haven't had bandwidth to give them a full hearing. "Not declined" != "still going to happen". But sure, we can keep it open instead.

@rsc rsc moved this from Active to Likely Accept in Proposals Mar 8, 2023
@rsc
Copy link
Contributor

rsc commented Mar 8, 2023

Based on the discussion above, this proposal seems like a likely accept.
— rsc for the proposal review group

@tmthrgd
Copy link
Contributor

tmthrgd commented Mar 8, 2023

Just to clarify, what’s likely accept here? This proposal seems to talk about both renaming the first point release and changing the go.mod version string. Are these both likely accept or only the release renaming?

@thepudds
Copy link
Contributor Author

thepudds commented Mar 9, 2023

Hi @tmthrgd, the forward compatibility proposal #57001 covers changing the go directive in go.mod to add the patch release digit for versions such as go 1.30.1.

However, as originally proposed, #57001 would have spelled the first Go 1.30 release in go.mod as go 1.30 (without a zero in the third digit following the conventions we have in place today).

This proposal is instead suggesting that the first Go 1.30 release would be spelled as go 1.30.0 in a go.mod, and similarly go version and the release download page and so on would all also use the zero in the third digit for a first release of a major version.

In other words, if this proposal is accepted, it would affect both the general naming of the first point release as well as how it appears in go.mod.

(On mobile; sorry if that’s unclear or if I misunderstood the question).

@rsc
Copy link
Contributor

rsc commented Mar 15, 2023

Yes, the proposal here is that the official name of Go 1.21 will be "go1.21.0" when it appears in file names and the like. Similarly, the go.mod line will say go 1.21.0. (The ability to say go 1.21.1 was added in #57001.)

@dmitshur dmitshur modified the milestones: Backlog, Go1.21 May 9, 2023
@dmitshur dmitshur self-assigned this May 10, 2023
@heschi
Copy link
Contributor

heschi commented May 12, 2023

After further review, I believe the work for this is done. Dmitri will cross-check and close.

@heschi heschi removed their assignment May 12, 2023
@rsc rsc changed the title use a zero for third digit for major release, such as 'go1.23.0' build: use a zero for third digit for major release, such as 'go1.23.0' May 16, 2023
@rsc rsc changed the title build: use a zero for third digit for major release, such as 'go1.23.0' build: use a zero for third digit for major release, such as 'go1.21.0' May 16, 2023
@dmitshur
Copy link
Contributor

dmitshur commented May 23, 2023

Everything captured in #57631 (comment) looks good to me.
I found a few more things, but they're very minor.

In maintapi.parseInternalBranchVersion, it would previously reject a branch name not following the "internal-branch.goX.Y-suffix" pattern exactly, but as of CL 479556 it will accept "internal-branch.goX.Y.Z-suffix" too even though we don't have plans to start making such internal branches. This is extremely harmless and fine.

The release history page (https://go.dev/doc/devel/release) needs a small change to fix the "#go1.21.0" anchor that we'll be linking to in few places. I sent CL 497497 to fix that.

The pkg.go.dev website may also need some updates in its stdlib package to be able to process future Go releases. I filed #60373 for that.

Closing this as done.

@github-project-automation github-project-automation bot moved this from In Progress to Done in Go Release May 23, 2023
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/497497 mentions this issue: internal/history: include ".0" in go1.21.0 and onwards

gopherbot pushed a commit to golang/website that referenced this issue May 23, 2023
Now that proposal go.dev/issue/57631 is accepted, the upcoming major Go
release version will not omit its trailing zero component in "go1.21.0".
Update the behavior and documentation of Version accordingly.

Drop IsMajor and IsMinor since they would need to be updated but aren't
used anywhere. Instead, add MajorPrefix and use it to not break the
future Go 1.21 release notes link. We decided those release notes
document the entire release series, not just the first release,
so it needs to eventually stay as "/doc/go1.21" and not "/doc/go1.21.0".

For golang/go#57631.

Change-Id: I069d171354752e5123b7950c45581a236b304f95
Reviewed-on: https://go-review.googlesource.com/c/website/+/497497
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/504521 mentions this issue: internal/task: add ".0" to major release tweets

gopherbot pushed a commit to golang/build that referenced this issue Jun 22, 2023
There's one more place to update for the upcoming go1.21.0 version name,
the tweet announcing major releases.

Increase the consistency between the templates and other similar code
in the announcing, tweeting and mail-dl-cl tasks, to make them easier
to maintain.

The next CL will apply a few more simplifications.

For golang/go#57631.

Change-Id: I21957b05d14834f8d2d64a09a6f93bfb66ec228a
Reviewed-on: https://go-review.googlesource.com/c/build/+/504521
Reviewed-by: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/515036 mentions this issue: internal/task: use Go1.N milestone for go1.N.0 major release

gopherbot pushed a commit to golang/build that referenced this issue Aug 1, 2023
We're still using Go1.N milestones to track major Go release development
and need to update FetchMilestones to handle that as of go1.21.0, the .0
version component is explicitly included in the major version string.

For golang/go#57631.

Change-Id: I1dcc366796af2e3831ff866e957bcbb0967bdfe5
Reviewed-on: https://go-review.googlesource.com/c/build/+/515036
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/497498 mentions this issue: cmd/golangorg, internal/history: add test case for Go 1.21.0

gopherbot pushed a commit to golang/website that referenced this issue Aug 8, 2023
Go 1.21.0 is the first major Go release that explicitly includes the
trailing ".0" version component. Add a test case covering changes to
the history.Version type and the template that uses it.

For golang/go#57631.

Change-Id: I97581b650604c25b6996305ecf4ad9d883cd85ba
Reviewed-on: https://go-review.googlesource.com/c/website/+/497498
Reviewed-by: Heschi Kreinick <heschi@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
@rsc rsc removed this from Proposals May 23, 2024
@golang golang locked and limited conversation to collaborators Aug 7, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Archived in project
Development

No branches or pull requests