ref:45992034a3b55690328f40d455f072e0357dcbf7

feat(ci): bake CalVer version into released binaries (#4)

## Summary - Add `build.rs` that runs `git describe --tags --always` and sets `ANVIL_VERSION` at compile time - Clap reads `ANVIL_VERSION` for `--version` output instead of `CARGO_PKG_VERSION` - CI bootstrap-builds once (to get the anvil binary for release.sh), computes the CalVer version, creates a local git tag, then rebuilds so the version is baked into the released binary - Dev builds report git SHA (`anvil 9ff9d8e`), release builds report CalVer (`anvil 2026.04.2`) ## How it works The local tag only exists inside the CI container — it never gets pushed. The server-side tag is created by `anvil release create --tag $VERSION`. No commits to main, no branch protection issues, no CI loops. Refs #1 ## Test plan - [x] Local build without tags → reports git SHA - [x] Local build with tag → reports tag - [x] fmt, clippy, tests pass - [ ] CI publishes release with version-stamped binary
SHA: 45992034a3b55690328f40d455f072e0357dcbf7
Author: Anvil <noreply@anvil.fangorn.io>
Date: 2026-04-12 17:27
Parents: 9ff9d8e
5 files changed +56 -18
Type
.anvil.yml +1 −1
@@ -62,7 +62,7 @@
# Delegated to a bash script because the runner invokes /bin/sh (dash)
# and we need bash features (pipefail, trap ERR) for publish rollback.
run: |
apt-get update && apt-get install -y bash gcc-x86-64-linux-gnu jq 2>&1
apt-get update && apt-get install -y bash curl gcc-x86-64-linux-gnu jq 2>&1
exec bash ci/build-runner.sh
depends_on: [test, clippy, fmt]
cache:
build.rs +26 −0
@@ -1,0 +1,26 @@
use std::process::Command;
fn main() {
// Watch the ref that HEAD points to (detects new commits on current branch),
// HEAD itself (detects branch switches / detached checkout),
// and the tags directory (detects new tags created before a rebuild).
if let Ok(head) = std::fs::read_to_string(".git/HEAD") {
if let Some(ref_path) = head.trim().strip_prefix("ref: ") {
println!("cargo:rerun-if-changed=.git/{ref_path}");
}
}
println!("cargo:rerun-if-changed=.git/HEAD");
println!("cargo:rerun-if-changed=.git/refs/tags");
let version = Command::new("git")
.args(["describe", "--tags", "--always"])
.output()
.ok()
.filter(|o| o.status.success())
.and_then(|o| String::from_utf8(o.stdout).ok())
.map(|s| s.trim().to_string())
.unwrap_or_else(|| env!("CARGO_PKG_VERSION").to_string());
let out = std::env::var("OUT_DIR").unwrap();
std::fs::write(format!("{out}/version.txt"), &version).unwrap();
}