Skip to main content

max / makenotwork

Report git_sha in Multithreaded's health body A redeploy at the same semver was invisible to PoM, which only saw `version`. Mirror the MNW server: stamp the short HEAD sha in build.rs and return it from /api/health, null when there is no git metadata. Left out of pom-hetzner.toml on purpose. PoM's json_fields is exact-match, so pinning a sha there would go Degraded on the next deploy; the presence assertion lives in the crate's own test instead, as it does for the server.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-07-29 13:15 UTC
Signed with PGP, not checked
Commit: 5bbd8ab3caf2898753b1db20e4f8c7120f149a06
Parent: 099174c
2 files changed, +40 insertions, -0 deletions
@@ -5,10 +5,32 @@
5 5 use std::process::Command;
6 6
7 7 fn main() {
8 + stamp_git_hash();
8 9 build_frontend();
9 10 fingerprint_assets();
10 11 }
11 12
13 + /// Stamp the short commit sha into `GIT_HASH` for `option_env!()` to pick up
14 + /// in the `/api/health` body.
15 + ///
16 + /// Empty on a build with no git metadata (a source tarball, a container
17 + /// without `.git`), which the health body maps to `null` rather than to a
18 + /// misleading empty string.
19 + fn stamp_git_hash() {
20 + let hash = Command::new("git")
21 + .args(["rev-parse", "--short", "HEAD"])
22 + .output()
23 + .ok()
24 + .filter(|o| o.status.success())
25 + .and_then(|o| String::from_utf8(o.stdout).ok())
26 + .map(|s| s.trim().to_string())
27 + .unwrap_or_default();
28 +
29 + println!("cargo::rustc-env=GIT_HASH={hash}");
30 + // Only re-run when HEAD moves.
31 + println!("cargo::rerun-if-changed=.git/HEAD");
32 + }
33 +
12 34 /// Content-hash the served static files and emit the template partials that
13 35 /// carry a `?v=<hash>` cache-buster on every asset URL.
14 36 ///
@@ -544,6 +544,10 @@
544 544 serde_json::json!({
545 545 "status": status,
546 546 "version": env!("CARGO_PKG_VERSION"),
547 + // The commit this binary was built from (short sha, set by build.rs).
548 + // `null` on a build without git metadata. Lets monitoring see a
549 + // same-semver redeploy, which `version` alone cannot distinguish.
550 + "git_sha": option_env!("GIT_HASH").filter(|h| !h.is_empty()),
547 551 "database": db_ok,
548 552 })
549 553 }
@@ -586,6 +590,20 @@
586 590 );
587 591 }
588 592
593 + /// The `git_sha` key is what tells monitoring a same-semver redeploy
594 + /// happened, so lock its presence. Its value varies per build (and is
595 + /// `null` without git metadata), which is why it is asserted here rather
596 + /// than in PoM's exact-match `json_fields`.
597 + #[test]
598 + fn health_body_carries_version_and_git_sha_keys() {
599 + let body = health_body(true);
600 + assert_eq!(body["version"], env!("CARGO_PKG_VERSION"));
601 + assert!(
602 + body.get("git_sha").is_some(),
603 + "git_sha key must be present (null is fine)"
604 + );
605 + }
606 +
589 607 /// A reachable DB is `200`; an unreachable DB is `503` so status-only probes
590 608 /// don't read a degraded box as healthy. PoM expects `200` for operational.
591 609 #[test]