hephaestus/crates/heph-core/build.rs
Erich Blume 1603b37f74
All checks were successful
Build / validate (push) Successful in 6m13s
fix: --version no longer false-positives -dirty on clean release installs
The build-time dirty check used `git status --porcelain`, which counts
untracked files — including cargo's own `.cargo-ok` marker in a
`cargo install --git` checkout — so a clean tagged build reported e.g.
`1.0.1 (bcab3c16b-dirty)`. Use `git diff --quiet HEAD` (tracked changes only).

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

48 lines
1.8 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;
}
// Tracked changes only. `git status --porcelain` would also count
// untracked files — including cargo's own `.cargo-ok` marker in a
// `cargo install --git` checkout — and falsely tag a clean release build
// `-dirty`. `git diff --quiet HEAD` exits non-zero only on tracked edits.
let dirty = !Command::new("git")
.args(["diff", "--quiet", "HEAD"])
.status()
.map(|s| s.success())
.unwrap_or(true);
Some(if dirty { format!("{sha}-dirty") } else { sha })
}