Skip to content

Commit 25fbaf2

Browse files
authored
fix: long version info not displayed correctly in release builds (#1374)
Goreleaser allows injecting the `vcs.revision` and `vcs.time` variables directly using ldflags, which is more reliable than using `debug.ReadBuildInfo()` and should fix the long version output for GitHub releases. `debug.ReadBuildInfo()` is still used as a fallback in case the binary was not built using goreleaser. The `go mod tidy` before hook was removed from the goreleaser config as we already keep our go mod tidied using renovate.
1 parent 6db0a92 commit 25fbaf2

3 files changed

Lines changed: 66 additions & 19 deletions

File tree

.goreleaser.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
version: 2
22
before:
33
hooks:
4-
- go mod tidy
54
- ./scripts/completions.sh
65
- go run ./scripts manpages
76

@@ -16,6 +15,9 @@ builds:
1615
- -w
1716
- -X {{ .ModulePath }}/internal/version.version={{ .Version }}
1817
- -X {{ .ModulePath }}/internal/version.versionPrerelease={{- if .IsSnapshot -}}dev+{{ .ShortCommit }}{{- end -}}
18+
- -X {{ .ModulePath }}/internal/version.commit={{ .FullCommit }}
19+
- -X {{ .ModulePath }}/internal/version.commitDate={{ .CommitDate }}
20+
- -X {{ .ModulePath }}/internal/version.modified={{ .IsGitDirty }}
1921
env:
2022
- CGO_ENABLED=0
2123

@@ -110,6 +112,9 @@ kos:
110112
- -w
111113
- -X {{ .ModulePath }}/internal/version.version={{ .Version }}
112114
- -X {{ .ModulePath }}/internal/version.versionPrerelease={{- if .IsSnapshot -}}dev+{{ .ShortCommit }}{{- end -}}
115+
- -X {{ .ModulePath }}/internal/version.commit={{ .FullCommit }}
116+
- -X {{ .ModulePath }}/internal/version.commitDate={{ .CommitDate }}
117+
- -X {{ .ModulePath }}/internal/version.modified={{ .IsGitDirty }}
113118
- -X {{ .ModulePath }}/internal/state/config.defaultConfigPathOverride=/config.toml
114119

115120
snapshot:

internal/cmd/version/version.go

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package version
33
import (
44
"fmt"
55
"runtime"
6-
"runtime/debug"
76
"text/tabwriter"
87

98
"github.com/spf13/cobra"
@@ -35,25 +34,14 @@ func runVersion(cmd *cobra.Command, _ []string) error {
3534
fmt.Fprintf(tw, "go version:\t%s (%s)\n", runtime.Version(), runtime.Compiler)
3635
fmt.Fprintf(tw, "platform:\t%s/%s\n", runtime.GOOS, runtime.GOARCH)
3736

38-
if info, ok := debug.ReadBuildInfo(); ok {
39-
rev := getSettingsValue(info.Settings, "vcs.revision", "unknown")
40-
if modified := getSettingsValue(info.Settings, "vcs.modified", "false"); modified == "true" {
41-
rev += " (modified)"
42-
}
43-
44-
fmt.Fprintf(tw, "revision:\t%s\n", rev)
45-
fmt.Fprintf(tw, "revision date:\t%s\n", getSettingsValue(info.Settings, "vcs.time", "unknown"))
37+
rev := version.Commit
38+
if version.Modified {
39+
rev += " (modified)"
4640
}
41+
42+
fmt.Fprintf(tw, "revision:\t%s\n", rev)
43+
fmt.Fprintf(tw, "revision date:\t%s\n", version.CommitDate)
4744
return tw.Flush()
4845
}
4946
return nil
5047
}
51-
52-
func getSettingsValue(settings []debug.BuildSetting, key, def string) string {
53-
for _, setting := range settings {
54-
if setting.Key == key {
55-
return setting.Value
56-
}
57-
}
58-
return def
59-
}

internal/version/version.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package version
22

3+
import "runtime/debug"
4+
35
var (
46
// version is a semver version (https://semver.org).
57
version = "1.62.0" // x-releaser-pleaser-version
@@ -16,4 +18,56 @@ var (
1618
}
1719
return version
1820
}()
21+
22+
// Can be set by goreleaser because debug.ReadBuildInfo() is not available for goreleaser builds
23+
commit = ""
24+
25+
// Commit is the latest full commit hash during build time
26+
Commit = func() string {
27+
if commit != "" {
28+
return commit
29+
}
30+
return getSettingsValue("vcs.revision", "unknown")
31+
}()
32+
33+
// Can be set by goreleaser because debug.ReadBuildInfo() is not available for goreleaser builds
34+
commitDate = ""
35+
36+
// CommitDate is the timestamp of the latest commit during build time in RFC3339
37+
CommitDate = func() string {
38+
if commitDate != "" {
39+
return commitDate
40+
}
41+
return getSettingsValue("vcs.time", "unknown")
42+
}()
43+
44+
// Can be set by goreleaser because debug.ReadBuildInfo() is not available for goreleaser builds
45+
modified = ""
46+
47+
// Modified specifies whether the git worktree was dirty during build time
48+
Modified = func() bool {
49+
if modified != "" {
50+
return modified == "true"
51+
}
52+
return getSettingsValue("vcs.modified", "false") == "true"
53+
}()
54+
55+
// used for getSettingsValue
56+
info, ok = debug.ReadBuildInfo()
1957
)
58+
59+
// getSettingsValue is a helper for getting values from debug.ReadBuildInfo()
60+
// This is only a fallback for builds that do not use goreleaser, since goreleaser
61+
// usually injects the above variables using ldflags. debug.ReadBuildInfo() will be
62+
// used for example when installing using 'go install'.
63+
func getSettingsValue(key, def string) string {
64+
if !ok {
65+
return def
66+
}
67+
for _, setting := range info.Settings {
68+
if setting.Key == key {
69+
return setting.Value
70+
}
71+
}
72+
return def
73+
}

0 commit comments

Comments
 (0)