Skip to content

feat(buildinfo): fall back to debug.BuildInfo when ldflags unset#161

Merged
aksOps merged 1 commit into
mainfrom
feat/buildinfo-debug-fallback
May 14, 2026
Merged

feat(buildinfo): fall back to debug.BuildInfo when ldflags unset#161
aksOps merged 1 commit into
mainfrom
feat/buildinfo-debug-fallback

Conversation

@aksOps
Copy link
Copy Markdown
Contributor

@aksOps aksOps commented May 14, 2026

Summary

`go install github.com/randomcodespace/codeiq/go/cmd/codeiq@v0.3.0` produces a working binary, but it reports `dev / unknown / unknown` for `codeiq --version` because the `-ldflags -X buildinfo.X=…` path only runs under goreleaser. Same story for local `go build` from a git checkout.

Fix

Add an `init()` hydrate step in `internal/buildinfo` that reads `runtime/debug.BuildInfo` and fills any var still at its default:

Source Target
`Main.Version` (skips `(devel)` sentinel) `Version`
`Settings[vcs.revision]` (7-char short hash) `Commit`
`Settings[vcs.time]` `Date`
`Settings[vcs.modified]` (only `false → true`, never demotes) `Dirty`

Resolution priority (per var):

  1. `-ldflags -X` (release builds via goreleaser) — wins
  2. `runtime/debug.BuildInfo` — `go install …@` or local `go build`
  3. Defaults (`dev` / `unknown`) — last resort, e.g. cross-compiled stripped binaries with `-buildvcs=false`

No release-workflow change needed — goreleaser still wins because it sets the vars at link time before `init()` reads them.

Tested locally

```

plain go build (worktree)

$ go build . && ./codeiq --version
codeiq dev
commit: e5fd3fe (dirty)
built: 2026-05-14T01:37:03Z

go install (also locally — full @ path needs this PR merged + a re-tag first)

$ GOBIN=/tmp/gobin go install ./cmd/codeiq && /tmp/gobin/codeiq --version
codeiq dev
commit: e5fd3fe (dirty)
built: 2026-05-14T01:37:03Z

release-style ldflags

$ go build -ldflags "-X buildinfo.Version=v0.3.0 -X buildinfo.Commit=abc1234 -X buildinfo.Date=2026-05-14T00:00:00Z" .
$ ./codeiq --version
codeiq v0.3.0
commit: abc1234 (dirty)
built: 2026-05-14T00:00:00Z
```

After this lands, `go install github.com/randomcodespace/codeiq/go/cmd/codeiq@v0.3.1` (or any future tag) will produce a binary that reports the tagged version + the source commit, with no branch push required at tag-time — the toolchain handles it.

Tests

  • 6 buildinfo tests pass (was 5). The old `TestDefaultsWithoutLdflags` was brittle once `init()` ran; replaced with:
    • `TestBuildInfoVarsWellFormed` — vars are non-empty strings; Dirty parses as bool
    • `TestHydratePreservesLdflags` — pins the priority contract via the sync.Once guard
  • Full suite: 884 passed.

🤖 Generated with Claude Code

`go install github.com/randomcodespace/codeiq/go/cmd/codeiq@v0.3.0`
worked but the resulting binary reported "dev / unknown / unknown"
because the -ldflags path only runs under goreleaser. Same story for
`go build` from a local git checkout.

Add an init() hydrate step that reads runtime/debug.BuildInfo and
fills any var still at its default:

  - Main.Version  → Version  (skips "(devel)" sentinel)
  - vcs.revision  → Commit   (7-char short hash)
  - vcs.time      → Date
  - vcs.modified  → Dirty    (only promotes "false" → "true")

Resolution priority:
  1. -ldflags -X (release builds via goreleaser) — highest
  2. runtime/debug.BuildInfo — `go install …@<tag>` or local `go build`
  3. Defaults ("dev" / "unknown") — last resort

Verified:
  - plain `go build` from a worktree:
      codeiq dev
        commit: e5fd3fe (dirty)
        built:  2026-05-14T01:37:03Z
  - `-ldflags -X buildinfo.Version=v0.3.0 …`:
      codeiq v0.3.0
        commit: abc1234 (dirty)
        built:  2026-05-14T00:00:00Z

Tests:
  - 6 buildinfo tests pass (was 5). Old "must be exactly defaults"
    test was brittle once init() ran; replaced with two tests covering
    well-formedness and the ldflags-preservation contract.
  - Full suite: 884 passed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@aksOps aksOps merged commit c20c109 into main May 14, 2026
13 checks passed
@aksOps aksOps deleted the feat/buildinfo-debug-fallback branch May 14, 2026 04:25
aksOps added a commit that referenced this pull request May 14, 2026
Move the contents of [Unreleased] under a new [v0.4.0] - 2026-05-14
heading. Repopulate [Unreleased] with the three post-v0.4.0 items
already on main: #163 (pflag bump), #164 (harden-runner bump), #165
(release-darwin race fix).

Add a header note explaining the release-history reset: deleting the
pre-v0.4.0 tags from GitHub does not delete them from proxy.golang.org;
every reused tag name would serve the old (often Python-era) content.
v0.4.0 is the first never-previously-used version.

Two factual additions to v0.4.0:
  * PR #162 (module hoist) — was missing from the original Changed
    block when the section was still labelled [Unreleased].
  * PR #161 (BuildInfo fallback) — moved into a dedicated Added bullet
    so `go install` users know their binaries self-identify now.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant