zuka
zuka/build.rs

worklyn / zukapublic

Agent-first git hosting. One Rust binary: git over HTTP and SSH, a REST API, MCP, CI, and multi-tenant isolation.

Get a copy: git clone https://zuka.worklyn.com/worklyn/zuka.git
zuka/build.rs
RSbuild.rs2.1 KBDownload
1// Embeds the commit this binary was built from.
2//
3// The semantic version is bumped by CI and is the number for humans. The build
4// identity is version plus commit, and that is what upgrade detection compares —
5// because a forgotten version bump would make an old tenant look current, and the
6// failure mode of that is a security patch silently not landing.
7
8use std::process::Command;
9
10fn main() {
11 // CI checks a commit out into a bare work tree with no `.git` directory, so
12 // asking git here finds nothing. The runner already knows the commit and puts it
13 // in the environment, so prefer that: without it every binary CI produces would
14 // report `unknown`, they would all compare equal, and no upgrade would ever be
15 // detected — which is precisely the thing this file exists to prevent.
16 let commit = std::env::var("ZUKA_SHA")
17 .ok()
18 .filter(|s| !s.is_empty())
19 .map(|s| s.chars().take(12).collect::<String>())
20 .or_else(git_commit)
21 // A source tarball with neither git history nor a build environment still has
22 // to compile. Two such builds compare equal, which is the honest answer when
23 // there is nothing to tell them apart.
24 .unwrap_or_else(|| "unknown".to_string());
25
26 let dirty = Command::new("git")
27 .args(["status", "--porcelain"])
28 .output()
29 .ok()
30 .filter(|o| o.status.success())
31 .map(|o| !o.stdout.is_empty())
32 .unwrap_or(false);
33
34 println!(
35 "cargo:rustc-env=ZUKA_BUILD_COMMIT={commit}{}",
36 if dirty { "-dirty" } else { "" }
37 );
38
39 println!("cargo:rerun-if-env-changed=ZUKA_SHA");
40 // Rebuild when HEAD moves, so the embedded commit cannot go stale.
41 println!("cargo:rerun-if-changed=.git/HEAD");
42 println!("cargo:rerun-if-changed=.git/refs");
43}
44
45fn git_commit() -> Option<String> {
46 Command::new("git")
47 .args(["rev-parse", "--short=12", "HEAD"])
48 .output()
49 .ok()
50 .filter(|o| o.status.success())
51 .map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string())
52 .filter(|s| !s.is_empty())
53}