feat: inject git describe into dev builds for --version (#208) - #209
Conversation
make build now stamps `git describe --tags --dirty` into the binary via -ldflags -X, so a develop-branch build self-identifies (e.g. "1.28.0 (dev: v1.28.0-2-g140e3c6-dirty)") instead of showing the same plain version as a release build. A clean build of the release tag, or a plain go build/go test without the Makefile's ldflags, is unaffected. The static version var (and man pages/genman) stay untouched by construction. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR makes developer builds of lmm self-identifying by embedding git describe --tags --dirty at build time and surfacing it via Cobra’s --version, while keeping the static released version (and thus generated man pages) unchanged by default.
Changes:
- Stamp a build-time
buildDescribestring viamake build/makeusing-ldflags -X, and show it in the build echo line. - Add
computeDisplayVersion()to conditionally append(dev: <describe>)to the user-facing--versionoutput, plus table-driven tests covering key cases. - Update README + CHANGELOG to document the new dev build provenance behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents that make build stamps git provenance so dev binaries self-identify via --version. |
| Makefile | Adds git describe capture and injects it into the binary via -ldflags -X; updates build output message. |
| cmd/lmm/version_test.go | Adds table-driven tests for the version/provenance display logic. |
| cmd/lmm/root.go | Introduces buildDescribe and computeDisplayVersion(), wiring the computed display string into Cobra’s Version. |
| CHANGELOG.md | Adds an [Unreleased] entry describing the new dev-build provenance stamping behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ## build: Build the binary | ||
| build: | ||
| @echo "Building $(BINARY_NAME) v$(VERSION)..." | ||
| @echo "Building $(BINARY_NAME) v$(VERSION) ($(DESCRIBE))..." |
There was a problem hiding this comment.
Fixed in 726d99f — empty parens suppressed via $(if ...).
| MAIN_PATH := ./cmd/lmm | ||
| VERSION := $(shell grep 'version = ' cmd/lmm/root.go | cut -d'"' -f2) | ||
| LDFLAGS := -ldflags "-s -w" | ||
| DESCRIBE := $(shell git describe --tags --dirty 2>/dev/null) |
There was a problem hiding this comment.
Fixed in 726d99f — --always added; a bare-hash describe renders as 'dev: ' (pinned with a new table case).
Add --always to git describe so shallow or tag-less clones stamp a commit hash instead of silently matching a release build. Also skip the empty "()" in the Building echo when DESCRIBE is unset via $(if ...). computeDisplayVersion already renders a bare hash sensibly as "dev: <hash>"; added a test case to pin it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Suppressed comments (3)
cmd/lmm/root.go:47
- This comment says the Makefile injects
git describe --tags --dirty, but the Makefile usesgit describe --tags --always --dirty. Updating this keeps the inline documentation accurate (and aligns with the tag-less clone behavior covered by tests).
// buildDescribe is injected at build time via -ldflags -X (see the
// Makefile's `build` target) with `git describe --tags --dirty`.
// Empty for builds made without that ldflags (plain `go build`/`go
// test`), which display identically to a clean release build.
CHANGELOG.md:13
- CHANGELOG entry documents stamping
git describe --tags --dirty, but the Makefile usesgit describe --tags --always --dirty(fallback to commit hash when tags are missing). Update the command here to match the implementation.
- `make build` (and `make`) now stamp `git describe --tags --dirty` into the binary via `-ldflags -X`, so `lmm --version` on a dev build self-identifies (e.g. `1.28.0 (dev: v1.28.0-2-g140e3c6-dirty)`) instead of showing the same plain `1.28.0` as a release build — the confusion this fixed came up during the v1.28.0 cycle. A build exactly on the release tag (clean) still shows the plain version; a plain `go build`/`go test` (no ldflags) is unaffected. The static `version` var and man pages are untouched by construction (#208)
README.md:1129
- README claims
make buildstampsgit describe --tags --dirty, but the Makefile actually runsgit describe --tags --always --dirty(important for tag-less clones/shallow checkouts). Update the command string here to match the real build behavior.
`make build` (or `make`) is the preferred way to build a working binary: it
stamps `git describe --tags --dirty` into the binary, so `lmm --version` on
a dev build self-identifies as e.g. `1.28.0 (dev: v1.28.0-2-g140e3c6-dirty)`
instead of silently claiming the last released version. A plain
`go build`/`go test` (no ldflags) behaves exactly like a clean release build.
Summary
make buildnow stampsgit describe --tags --dirtyinto the binary via-ldflags -X main.buildDescribe=..., and theBuilding lmm ...echo line shows the describe string too, so dev builds are visually distinguishable at build time.cmd/lmm/root.go: newbuildDescribevar (empty by default, staticversionvar UNCHANGED).--version(and any other Cobra surface readingrootCmd.Version) shows the plain static version whenbuildDescribeis empty or exactlyv<version>(a clean tag build); otherwise it appends(dev: <describe>), with-dirtypassing through verbatim. JSON surfaces are unaffected (none of them emit the app's own version). The TUI has no version display surface to update.cmd/lmm/version_test.go) cover empty/clean-tag/ahead/dirty/ahead+dirty.make manproduces a zero diff againstdocs/man/man1(existing genman drift test also still passes), proving the man pages are untouched by construction.make buildself-identifying dev binaries.[Unreleased]entry added.Closes #208.
Test plan
go test ./cmd/lmm/... -run TestDisplayVersion -v(new table-driven test, all cases pass)make check(fmt, lint, vet, full test suite) — all greenmake man— zero diff vs committeddocs/man/man1make build && ./lmm --version→lmm version 1.28.0 (dev: v1.28.0-2-g140e3c6-dirty)go build -o lmm ./cmd/lmm && ./lmm --version(no ldflags) →lmm version 1.28.0(unchanged)🤖 Generated with Claude Code