Skip to content

Commit 442286f

Browse files
authored
Merge pull request #45 from ActiDoo/codex/fix-clusterrebootd-version-output
Fix version command to report release build
2 parents d20748b + dccad44 commit 442286f

File tree

3 files changed

+129
-2
lines changed

3 files changed

+129
-2
lines changed

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ GOOS ?= $(PACKAGE_GOOS)
1414
GOARCH ?= $(shell go env GOARCH 2>/dev/null || echo amd64)
1515
LDFLAGS ?= -s -w
1616
VERSION ?= $(shell go run ./cmd/$(BINARY_NAME) version 2>/dev/null || echo 0.0.0-dev)
17+
VERSION_PKG := github.com/clusterrebootd/clusterrebootd/pkg/version
18+
GO_LDFLAGS := $(LDFLAGS) -X $(VERSION_PKG).Version=$(VERSION)
1719
SYFT ?= syft
1820
COSIGN ?= cosign
1921
SBOM_FORMAT ?= cyclonedx-json
@@ -30,7 +32,7 @@ all: build
3032
build:
3133
@echo "==> Building $(BINARY_NAME) ($(GOOS)/$(GOARCH))"
3234
@mkdir -p $(DIST_DIR)/$(GOOS)_$(GOARCH)
33-
CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) go build -trimpath -ldflags "$(LDFLAGS)" -o $(DIST_DIR)/$(GOOS)_$(GOARCH)/$(BINARY_NAME) ./cmd/$(BINARY_NAME)
35+
CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) go build -trimpath -ldflags "$(GO_LDFLAGS)" -o $(DIST_DIR)/$(GOOS)_$(GOARCH)/$(BINARY_NAME) ./cmd/$(BINARY_NAME)
3436
@cp $(DIST_DIR)/$(GOOS)_$(GOARCH)/$(BINARY_NAME) $(BINARY_PATH)
3537

3638
clean:

pkg/version/version.go

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,80 @@
11
package version
22

3-
const Version = "0.1.0-dev"
3+
import (
4+
"runtime/debug"
5+
"strings"
6+
)
7+
8+
const defaultVersion = "0.1.0-dev"
9+
10+
// Version holds the semantic version for the running binary.
11+
// It defaults to a development marker but can be overridden at
12+
// build time via -ldflags "-X github.com/clusterrebootd/clusterrebootd/pkg/version.Version=<value>".
13+
var Version = defaultVersion
14+
15+
var readBuildInfo = debug.ReadBuildInfo
16+
17+
func init() {
18+
Version = deriveVersion(Version)
19+
}
20+
21+
func deriveVersion(current string) string {
22+
if current != "" && current != defaultVersion {
23+
return current
24+
}
25+
26+
info, ok := readBuildInfo()
27+
if !ok || info == nil {
28+
return current
29+
}
30+
31+
if v := sanitizeModuleVersion(info.Main.Version); v != "" {
32+
return v
33+
}
34+
35+
if v := deriveFromSettings(info.Settings); v != "" {
36+
return v
37+
}
38+
39+
return current
40+
}
41+
42+
func sanitizeModuleVersion(v string) string {
43+
v = strings.TrimSpace(v)
44+
switch v {
45+
case "", "(devel)":
46+
return ""
47+
default:
48+
return v
49+
}
50+
}
51+
52+
func deriveFromSettings(settings []debug.BuildSetting) string {
53+
var (
54+
revision string
55+
modified bool
56+
)
57+
58+
for _, setting := range settings {
59+
switch setting.Key {
60+
case "vcs.revision":
61+
revision = strings.TrimSpace(setting.Value)
62+
case "vcs.modified":
63+
modified = setting.Value == "true"
64+
}
65+
}
66+
67+
if revision == "" {
68+
return ""
69+
}
70+
71+
if len(revision) > 12 {
72+
revision = revision[:12]
73+
}
74+
75+
if modified {
76+
revision += "-dirty"
77+
}
78+
79+
return "devel+" + revision
80+
}

pkg/version/version_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package version
2+
3+
import (
4+
"runtime/debug"
5+
"testing"
6+
)
7+
8+
func TestDeriveVersionPreservesOverride(t *testing.T) {
9+
t.Cleanup(func() { readBuildInfo = debug.ReadBuildInfo })
10+
readBuildInfo = func() (*debug.BuildInfo, bool) {
11+
t.Fatalf("unexpected call to readBuildInfo")
12+
return nil, false
13+
}
14+
15+
const override = "1.2.3"
16+
if got := deriveVersion(override); got != override {
17+
t.Fatalf("expected override %q to be preserved, got %q", override, got)
18+
}
19+
}
20+
21+
func TestDeriveVersionUsesModuleVersion(t *testing.T) {
22+
t.Cleanup(func() { readBuildInfo = debug.ReadBuildInfo })
23+
readBuildInfo = func() (*debug.BuildInfo, bool) {
24+
return &debug.BuildInfo{
25+
Main: debug.Module{Version: "v1.4.0"},
26+
}, true
27+
}
28+
29+
if got := deriveVersion(defaultVersion); got != "v1.4.0" {
30+
t.Fatalf("expected module version to be used, got %q", got)
31+
}
32+
}
33+
34+
func TestDeriveVersionUsesRevisionFallback(t *testing.T) {
35+
t.Cleanup(func() { readBuildInfo = debug.ReadBuildInfo })
36+
readBuildInfo = func() (*debug.BuildInfo, bool) {
37+
return &debug.BuildInfo{
38+
Settings: []debug.BuildSetting{
39+
{Key: "vcs.revision", Value: "abcdef1234567890"},
40+
{Key: "vcs.modified", Value: "true"},
41+
},
42+
}, true
43+
}
44+
45+
if got := deriveVersion(defaultVersion); got != "devel+abcdef123456-dirty" {
46+
t.Fatalf("expected revision fallback, got %q", got)
47+
}
48+
}

0 commit comments

Comments
 (0)