hephaestus/crates/heph-core/build.rs
Erich Blume 598dc59580
Some checks failed
Build / validate (pull_request) Has been cancelled
fix: --version reports release version + build SHA; release tags a version-bump commit
heph-core gains a build.rs that captures the short git SHA and a
`heph_core::VERSION` const ("<crate-version> (<sha>)"); heph and hephd use it
for clap's --version. The crate version stays sourced from Cargo.toml.

release.yaml now bumps the workspace version into Cargo.toml + Cargo.lock on a
commit that only the tag points at, tags it manually, and pushes just the tag —
so cargo install --git --tag vX.Y.Z reports the real version while main stays at
0.0.0. The changelog commit moved ahead of the tag so the release includes its
own changelog.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 09:43:10 -07:00

44 lines
1.5 KiB
Rust

//! Build script: capture the short git SHA this build came from so the CLI
//! surfaces can report `<version> (<sha>)`. The crate version itself comes from
//! `Cargo.toml` (bumped to the release version on the release tag — see
//! `.forgejo/workflows/release.yaml`); this only adds the provenance suffix.
//!
//! Resolution order: the `HEPH_BUILD_SHA` env override (an escape hatch for
//! builds with no `.git`, e.g. a source tarball) → `git rev-parse` → `unknown`.
use std::process::Command;
fn main() {
println!("cargo:rerun-if-env-changed=HEPH_BUILD_SHA");
// Rebuild when HEAD moves so the embedded SHA stays accurate. Best-effort:
// a missing path here is harmless (cargo just won't watch it).
println!("cargo:rerun-if-changed=../../.git/HEAD");
let sha = std::env::var("HEPH_BUILD_SHA")
.ok()
.filter(|s| !s.is_empty())
.or_else(git_short_sha)
.unwrap_or_else(|| "unknown".to_string());
println!("cargo:rustc-env=HEPH_BUILD_SHA={sha}");
}
fn git_short_sha() -> Option<String> {
let out = Command::new("git")
.args(["rev-parse", "--short=9", "HEAD"])
.output()
.ok()?;
if !out.status.success() {
return None;
}
let sha = String::from_utf8(out.stdout).ok()?.trim().to_string();
if sha.is_empty() {
return None;
}
let dirty = Command::new("git")
.args(["status", "--porcelain"])
.output()
.map(|o| !o.stdout.is_empty())
.unwrap_or(false);
Some(if dirty { format!("{sha}-dirty") } else { sha })
}