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.
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
-
Cargo.tomlversionis the single source of truth. This is the idiomatic Rust position and avoids makingCargo.tomllie. The version is read at compile time viaenv!("CARGO_PKG_VERSION"); no build-time injection of the tag into the crate. -
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 nodeapp::VERSION,AppCommand::Version), emitting the same line into the output panel. Both go throughcli::version_text()→ the catalog keycli.version_line("rdbms-playground {version}"), so there is exactly one rendered string and one version source.
-
Release-CI discipline.
release.yaml's pre-buildtestjob gains a version guard: it reads the[package]version directly fromCargo.toml(grep -m1 '^version = '— toolchain-free; an earliercargo metadata | nodeform broke on the flake devShell's stdout banner) and fails the release unless the pushed tag equalsv<that version>. So--version, the release name, and the downloaded asset are always in lockstep — enforced by the machine, not by memory. -
The release ritual: bump
Cargo.toml→ commit → tagv<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.tomla placeholder/lie. Rejected. - Git-hash + build-date enrichment (a
build.rsso dev builds read0.2.0 (a1b2c3d)): useful for bug reports, but not needed for the tag↔release↔--versionconsistency this ADR is about. Deferred; can be added behind the sameversion_text()seam without changing the policy. - UI placement beyond the
versioncommand (status-bar string, etc.): the command +helplisting 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.tomlbump 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 requireshint.cmd.version, which is supplied. Tested: CLI flag parse (--version/-V/default-off),version_text()carriesCARGO_PKG_VERSION, the in-app command parses toAppCommand::Versionand 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.