Skip to content

Commit 566aaa8

Browse files
authored
fix(internal/librarian): ignore retracted tags when report version (#3063)
Introduce a hardcoded list of retracted versions and use pseudo-version string instead. It's less ideal that we keep this hardcoded apart from go.mod record. But consider retracted versions are should be fairly rare, this should be acceptable. **The issue:** v1.0.0 and v1.0.1 was previously retracted and added to go.mod retract list in #2904. These tags are still present, this caused problem to `version` command as `info.Main.Versio` is determined during `go build` and for local builds, it would end up prefix with "v1.0.2-". Note, this problem only occurs for local dev builds from untagged commits. If you run version command from v0.7.0, it correctly prints the version. **Alternative approaches considered:** - **Runtime `go.mod` parsing**: This makes the binary fragile. the binary dependent on the presence and structure of `go.mod` at runtime, not the best practice. - **`go generate` for retraction list**: Create a build-time script that reads go.mod and automatically generates a Go source file containing the list of retracted versions. The complexity of this setup and parsing logic seems overkill for these rare occurrences. - **delete retracted tags and `git fetch --prune`**: Not best practice as it's a destructive action that rewrites history. Fix #3048
1 parent 9a37edc commit 566aaa8

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

internal/librarian/version.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ import (
2424
//go:embed version.txt
2525
var versionString string
2626

27+
// retractedVersions is a list of Go module versions that have been officially retracted
28+
// via the go.mod 'retract' directive. v1.0.2 added to account for local dev builds
29+
// from untagged commits.
30+
var retractedVersions = []string{"v1.0.0", "v1.0.1", "v1.0.2"}
31+
2732
// Version return the version information for the binary, which is constructed
2833
// following https://go.dev/ref/mod#versions.
2934
func Version() string {
@@ -35,10 +40,24 @@ func Version() string {
3540
}
3641

3742
func version(info *debug.BuildInfo) string {
38-
if info.Main.Version != "" && info.Main.Version != "(devel)" {
39-
return info.Main.Version
43+
isRetracted := false
44+
for _, v := range retractedVersions {
45+
if strings.HasPrefix(info.Main.Version, v) {
46+
isRetracted = true
47+
break
48+
}
49+
}
50+
// A pseudo-version should be used for retracted versions or for
51+
// development builds that don't have a proper version tag.
52+
isDevelBuild := info.Main.Version == "" || info.Main.Version == "(devel)"
53+
if isRetracted || isDevelBuild {
54+
return newPseudoVersion(info)
4055
}
56+
return info.Main.Version
57+
}
4158

59+
// newPseudoVersion constructs a pseudo-version string from the build info.
60+
func newPseudoVersion(info *debug.BuildInfo) string {
4261
var revision, at string
4362
for _, s := range info.Settings {
4463
if s.Key == "vcs.revision" {
@@ -52,7 +71,6 @@ func version(info *debug.BuildInfo) string {
5271
if revision == "" && at == "" {
5372
return "not available"
5473
}
55-
5674
// Construct the pseudo-version string per
5775
// https://go.dev/ref/mod#pseudo-versions.
5876
var buf strings.Builder

internal/librarian/version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.2.0
1+
0.7.0

internal/librarian/version_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,32 @@ func TestVersion(t *testing.T) {
9090
want: "not available",
9191
buildinfo: &debug.BuildInfo{},
9292
},
93+
{
94+
name: "retracted version, build from tagged commit",
95+
want: fmt.Sprintf("%s-123456789000-20230125195754", baseVersion),
96+
buildinfo: &debug.BuildInfo{
97+
Main: debug.Module{
98+
Version: "v1.0.0",
99+
},
100+
Settings: []debug.BuildSetting{
101+
{Key: "vcs.revision", Value: "1234567890001234"},
102+
{Key: "vcs.time", Value: "2023-01-25T19:57:54Z"},
103+
},
104+
},
105+
},
106+
{
107+
name: "retracted version, local dev builds from untagged commits",
108+
want: fmt.Sprintf("%s-123456789000-20230125195754", baseVersion),
109+
buildinfo: &debug.BuildInfo{
110+
Main: debug.Module{
111+
Version: "v1.0.2-0.20251125150633-68dcc1cc4ab4+dirty",
112+
},
113+
Settings: []debug.BuildSetting{
114+
{Key: "vcs.revision", Value: "1234567890001234"},
115+
{Key: "vcs.time", Value: "2023-01-25T19:57:54Z"},
116+
},
117+
},
118+
},
93119
} {
94120
t.Run(test.name, func(t *testing.T) {
95121
if got := version(test.buildinfo); got != test.want {

0 commit comments

Comments
 (0)