Files
rdbms-playground/docs/adr/0054-release-versioning-and-version-surfaces.md
T
claude@clouddev1 bd5be5ecc7
ci / gate (push) Successful in 3m12s
release / test (push) Successful in 2m44s
release / build (aarch64-pc-windows-gnullvm) (push) Successful in 3m56s
release / build (aarch64-unknown-linux-musl) (push) Successful in 4m18s
release / build (x86_64-pc-windows-gnu) (push) Successful in 4m39s
release / build (x86_64-unknown-linux-musl) (push) Successful in 3m50s
fix(ci): read release version from Cargo.toml, not cargo metadata (ADR-0054)
The ADR-0054 version guard piped `nix develop -c cargo metadata` to node,
but the flake devShell prints a banner to stdout — corrupting the JSON
pipe, so the guard aborted under `set -e` and the v0.2.0 release failed
there (before building anything). Replace it with a toolchain-free
`grep -m1 '^version = ' Cargo.toml` (the anchor excludes dependency
`version =` keys). No real version mismatch occurred — the tagged commit
has version 0.2.0.
2026-06-17 21:58:32 +00:00

3.9 KiB

ADR-0054: Release versioning policy + version surfaces (--version / version)

Status

Accepted — implemented 2026-06-16 (plan: docs/plans/20260616-public-availability.md, step 1). First step on the road to public availability. Adds a --version / -V CLI flag and an in-app version command, both reporting CARGO_PKG_VERSION, plus a release-CI guard that the v* tag equals that version. No prior issue or requirements.md item existed for this — it was an untracked gap.

Context

Before this, Cargo.toml carried version = "0.1.0", the binary exposed no way to report its version, and release.yaml named assets from the git tag (rdbms-playground-<tag>-<target>) while building from Cargo.toml. Tag and crate version were decoupled: tagging v0.2.0 would publish an asset named …-v0.2.0-… containing a binary that (had it been able to say) reported 0.1.0. On the way to public availability — where users download a versioned artifact and file bug reports against "the version I'm running" — that drift is a correctness problem.

Decision

  1. Cargo.toml version is the single source of truth. This is the idiomatic Rust position and avoids making Cargo.toml lie. The version is read at compile time via env!("CARGO_PKG_VERSION"); no build-time injection of the tag into the crate.

  2. Two user-facing surfaces, one source:

    • --version / -V — CLI flag (hand-rolled parser, mirrors --help): prints and exits before any other work (main.rs).
    • version — an in-app app command (REGISTRY node app::VERSION, AppCommand::Version), emitting the same line into the output panel. Both go through cli::version_text() → the catalog key cli.version_line ("rdbms-playground {version}"), so there is exactly one rendered string and one version source.
  3. Release-CI discipline. release.yaml's pre-build test job gains a version guard: it reads the [package] version directly from Cargo.toml (grep -m1 '^version = ' — toolchain-free; an earlier cargo metadata | node form broke on the flake devShell's stdout banner) and fails the release unless the pushed tag equals v<that version>. So --version, the release name, and the downloaded asset are always in lockstep — enforced by the machine, not by memory.

  4. The release ritual: bump Cargo.toml → commit → tag v<that number> → push the tag. The guard rejects any deviation.

Rejected / deferred

  • Inject the tag into the build (tag as source of truth): fiddly with cargo and makes Cargo.toml a placeholder/lie. Rejected.
  • Git-hash + build-date enrichment (a build.rs so dev builds read 0.2.0 (a1b2c3d)): useful for bug reports, but not needed for the tag↔release↔--version consistency this ADR is about. Deferred; can be added behind the same version_text() seam without changing the policy.
  • UI placement beyond the version command (status-bar string, etc.): the command + help listing is enough for now (user decision).

Consequences

  • A release can no longer ship a binary whose self-reported version disagrees with its tag/filename.
  • Cutting a release now requires a Cargo.toml bump commit — a small, deliberate step (and a natural place to update a changelog later).
  • New keys: cli.version_line (+ help.app.version, parse.usage.version, hint.cmd.version.what/.example); a new REGISTRY command means the comprehensiveness coverage test now also requires hint.cmd.version, which is supplied. Tested: CLI flag parse (--version/-V/default-off), version_text() carries CARGO_PKG_VERSION, the in-app command parses to AppCommand::Version and emits the version.
  • This is step 1 of docs/plans/20260616-public-availability.md; the installer (install.sh) and package-manager work (D3) build on top.