Skip to content

test(version): pin the semver release reported by /version (#23) - #59

Open
tarakanof wants to merge 3 commits into
mainfrom
feat/server-version
Open

test(version): pin the semver release reported by /version (#23)#59
tarakanof wants to merge 3 commits into
mainfrom
feat/server-version

Conversation

@tarakanof

Copy link
Copy Markdown
Owner

Summary

Working #23 turned up that the feature is already shipped on main — it landed in #31 (server) and #32 (menu app). The issue is stale. This PR therefore pins the behaviour with real regression tests instead of re-implementing it, and fixes one stale doc line.

Verified end to end on main:

Link Where
ldflags target cmd/ember/version.go (var version = "dev")
/version payload cmd/ember/admin.go (Version string \json:"version"``)
metrics label cmd/ember/metrics.go (ember_build_info{revision,go_version,version})
build arg → ldflags Dockerfile (ARG VERSION=dev-X main.version=$VERSION)
tag → build arg .github/workflows/docker-publish.yml (build-args: VERSION=…)
app decode + prefer macos/Sources/EmberKit/ServerInfo.swift
both Server-version rows ConnectionTab.swift, AppTab.swift (via AppEnvironment.serverVersion())

Empirically:

go build -ldflags="-X main.version=9.9.9-test" ./cmd/ember  →  ember 9.9.9-test (unknown, go1.26.5)
go build ./cmd/ember                                        →  ember dev (unknown, go1.26.5)

Changes

  • cmd/ember/admin_test.go — the pre-existing test only asserted the version key existed, never its value. Adds TestVersionHandler_ReportsInjectedRelease / TestVersionHandler_ReportsDevWithoutInjectedRelease plus a fetchVersion helper. Non-tautology checked: stripping the json tag and the Version: assignment makes both fail.
  • README.mdember_build_info{revision,go_version}{revision,go_version,version}, stale since feat(version): report semver in /version and /metrics #31.

No production Go / Swift / Docker / CI code changed.

One deviation from the issue text

The issue's acceptance says a released image reports version: "v0.22.0". It actually reports 0.22.0docker/metadata-action's {{version}} strips the leading v before it reaches build-args.

Left as-is deliberately, and the tests now pin the bare form:

  • it matches the published image tag exactly (dtarakanov/ember:0.22.0), so /version output pastes straight into a docker pull;
  • every already-published image (0.9.0 … 0.22.0) reports bare semver — switching now would leave 0.22.0 and v0.23.0 coexisting;
  • bare is already the convention: scripts/release.sh normalises the v away, MARKETING_VERSION is bare, and ServerInfoTests.swift already encodes "0.9.0".

If a v is ever wanted it belongs in ServerInfo.short (presentation), not the wire value.

Known gap, out of scope

Nothing pins the symbol path main.version that the Dockerfile targets. If version moves packages, Go still compiles, these tests still pass, but -X main.version= silently no-ops (the linker doesn't error on an unresolved -X) and released images regress to dev — exactly the bug #23 was filed for. A testing.Short()-gated test that shells out to go build -ldflags … would close it. Worth a follow-up issue.

Test plan

  • gofmt -l . — clean
  • go vet ./... — clean
  • go test ./... -race — all packages pass
  • swift test --package-path macos — 165 tests pass
  • ldflags e2e: built with -X main.version=v9.9.9, ran it, curled /version{"binary":"ember","version":"v9.9.9",…}

Closes #23.

The semver reported by /version comes from -ldflags "-X main.version=…"
at release build time, so nothing in the test suite noticed if the field
stopped being wired: the existing handler test only asserted the key was
present, whatever its value.

Cover both build shapes end of the wire — a release build's injected
"v0.22.0" and a plain source build's "dev" default (issue #23).
The metric gained a version label when the semver release started being
embedded; the README metric list still advertised only revision and
go_version.
…mits

docker/metadata-action's {{version}} strips the leading v, so a released
image reports "0.22.0", not "v0.22.0". Pinning the v-prefixed form invited a
future consumer to assume a prefix that never arrives on the wire.
@tarakanof

Copy link
Copy Markdown
Owner Author

Code review (independent pass)

Reviewed the branch against origin/main, re-verified the #23 chain from scratch, and re-ran the suite.

Verdict: safe to merge. No blocking defects. One should-fix was found and is already applied in 3c278bb.

Verified independently

The whole chain is present on main (version.goadmin.go payload → metrics.go label → Dockerfile ARG/ldflags → docker-publish.yml build-args → ServerInfo.swift → both UI rows via AppEnvironment.serverVersion()), and both UI rows share one code path, so #32 fixed them together. Empirical check confirmed the ldflags path is live (injected build reports the injected string; plain build reports dev). Acceptance criterion "local/dev builds still show something sensible" is met — ember @ 44143ca, pinned by ServerInfoTests.swift.

#23 can be closed as already-implemented.

Should-fix — applied

  • cmd/ember/admin_test.go pinned "v0.22.0", a wire format the release pipeline never emits (docker-publish.yml passes steps.meta.outputs.version, and metadata-action's {{version}} strips the v). Left alone, a future consumer could tighten ServerInfo.swift to assume/strip a mandatory v and silently misbehave against every real image. Fixed in 3c278bb: pins "0.22.0" and documents why.

Nits — not addressed, judgment call

  • The two new tests differ by one input and repeat the same 5-line setup; docs/STYLE.md prefers table-driven + t.Run for this shape, and the same file already table-drives TestDiffConfig_*. Low value to churn for two cases.
  • TestVersionHandler_ReportsDevWithoutInjectedRelease partly overlaps metrics_test.go, which already asserts version="dev" off the same struct. Different endpoint, so kept.
  • fetchVersion is introduced while the older TestVersionHandler_PublicAndJSON still hand-rolls its GET — it asserts Content-Type and raw key presence, so it can't fully adopt the typed helper.
  • The app.versionInfo.Version = … mutation must precede app.routes() because handleVersion closes over the struct by value. Fails loudly rather than silently; a comment was added in 3c278bb.

README.md

Accurate — matches metrics.go exactly, label order included, and it's the only place in the repo that enumerates build_info labels, so nothing else was left stale.

Suite (actual output)

gofmt -l .                        → clean
go vet ./...                      → clean
go test ./cmd/ember/ -race -count=1 → ok  github.com/tarakanof/ember/cmd/ember  8.173s
swift test --package-path macos   → 165 tests passed

Follow-up worth filing

Nothing pins the symbol path main.version that the Dockerfile targets — see the PR description's "Known gap". That is the regression this PR nominally set out to prevent, and it stays open.

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.

Server should report its semver release version in /version

1 participant