build(vulkan-smoke): capture build toolchain metadata

This commit is contained in:
2026-06-25 07:41:26 +04:00
parent 25d26a87a4
commit 0caa36d923
2 changed files with 69 additions and 3 deletions
+39
View File
@@ -6,6 +6,8 @@ use std::process::Command;
fn main() { fn main() {
println!("cargo:rerun-if-env-changed=TARGET"); println!("cargo:rerun-if-env-changed=TARGET");
println!("cargo:rerun-if-env-changed=RUSTC");
println!("cargo:rerun-if-env-changed=RUSTUP_TOOLCHAIN");
println!("cargo:rerun-if-env-changed=GITHUB_SHA"); println!("cargo:rerun-if-env-changed=GITHUB_SHA");
println!("cargo:rerun-if-env-changed=SOURCE_VERSION"); println!("cargo:rerun-if-env-changed=SOURCE_VERSION");
println!("cargo:rerun-if-env-changed=BUILD_VCS_NUMBER"); println!("cargo:rerun-if-env-changed=BUILD_VCS_NUMBER");
@@ -13,6 +15,9 @@ fn main() {
if let Ok(target) = env::var("TARGET") { if let Ok(target) = env::var("TARGET") {
println!("cargo:rustc-env=FPARKAN_BUILD_TARGET_TRIPLE={target}"); println!("cargo:rustc-env=FPARKAN_BUILD_TARGET_TRIPLE={target}");
} }
if let Some(toolchain) = rustc_release() {
println!("cargo:rustc-env=FPARKAN_BUILD_RUST_TOOLCHAIN={toolchain}");
}
let workspace_root = let workspace_root =
PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("manifest dir")).join("../.."); PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("manifest dir")).join("../..");
@@ -23,6 +28,9 @@ fn main() {
if let Some(commit_sha) = env_commit_sha().or_else(|| git_head_commit_sha(&workspace_root)) { if let Some(commit_sha) = env_commit_sha().or_else(|| git_head_commit_sha(&workspace_root)) {
println!("cargo:rustc-env=FPARKAN_BUILD_COMMIT_SHA={commit_sha}"); println!("cargo:rustc-env=FPARKAN_BUILD_COMMIT_SHA={commit_sha}");
} }
if let Some(git_dirty) = git_dirty(&workspace_root) {
println!("cargo:rustc-env=FPARKAN_BUILD_GIT_DIRTY={git_dirty}");
}
} }
fn env_commit_sha() -> Option<String> { fn env_commit_sha() -> Option<String> {
@@ -47,6 +55,19 @@ fn git_head_commit_sha(workspace_root: &Path) -> Option<String> {
is_commit_sha(&value).then_some(value) is_commit_sha(&value).then_some(value)
} }
fn git_dirty(workspace_root: &Path) -> Option<bool> {
let output = Command::new("git")
.args(["-C"])
.arg(workspace_root)
.args(["status", "--short"])
.output()
.ok()?;
output
.status
.success()
.then(|| !String::from_utf8_lossy(&output.stdout).trim().is_empty())
}
fn git_dir(workspace_root: &Path) -> Option<PathBuf> { fn git_dir(workspace_root: &Path) -> Option<PathBuf> {
let output = Command::new("git") let output = Command::new("git")
.args(["-C"]) .args(["-C"])
@@ -69,6 +90,7 @@ fn emit_git_rerun_hints(git_dir: &Path) {
"cargo:rerun-if-changed={}", "cargo:rerun-if-changed={}",
git_dir.join("packed-refs").display() git_dir.join("packed-refs").display()
); );
println!("cargo:rerun-if-changed={}", git_dir.join("index").display());
let Some(reference) = std::fs::read_to_string(&head).ok().and_then(|value| { let Some(reference) = std::fs::read_to_string(&head).ok().and_then(|value| {
value value
.strip_prefix("ref: ") .strip_prefix("ref: ")
@@ -86,3 +108,20 @@ fn emit_git_rerun_hints(git_dir: &Path) {
fn is_commit_sha(value: &str) -> bool { fn is_commit_sha(value: &str) -> bool {
value.len() == 40 && value.chars().all(|ch| ch.is_ascii_hexdigit()) value.len() == 40 && value.chars().all(|ch| ch.is_ascii_hexdigit())
} }
fn rustc_release() -> Option<String> {
let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".to_string());
let output = Command::new(rustc).arg("-Vv").output().ok()?;
if !output.status.success() {
return None;
}
String::from_utf8(output.stdout)
.ok()?
.lines()
.find_map(|line| {
line.strip_prefix("release: ")
.map(str::trim)
.filter(|value| !value.is_empty())
.map(ToString::to_string)
})
}
+30 -3
View File
@@ -198,10 +198,10 @@ impl SmokeApp {
let smoke_report = SmokeReport { let smoke_report = SmokeReport {
schema_version: SCHEMA_VERSION, schema_version: SCHEMA_VERSION,
commit_sha: compiled_commit_sha(), commit_sha: compiled_commit_sha(),
git_dirty: current_git_dirty(), git_dirty: compiled_git_dirty(),
runner_identity: measured_runner_identity(), runner_identity: measured_runner_identity(),
runner_architecture: actual_architecture(), runner_architecture: actual_architecture(),
rust_toolchain: current_rustc_release(), rust_toolchain: compiled_rust_toolchain(),
target_triple: compiled_target_triple(), target_triple: compiled_target_triple(),
platform: actual_platform(), platform: actual_platform(),
status, status,
@@ -559,7 +559,13 @@ fn runtime_git_commit_sha() -> String {
.unwrap_or_else(|| "unknown".to_string()) .unwrap_or_else(|| "unknown".to_string())
} }
fn current_git_dirty() -> bool { fn compiled_git_dirty() -> bool {
option_env!("FPARKAN_BUILD_GIT_DIRTY")
.and_then(parse_bool_env)
.unwrap_or_else(runtime_git_dirty)
}
fn runtime_git_dirty() -> bool {
Command::new("git") Command::new("git")
.args(["status", "--short"]) .args(["status", "--short"])
.output() .output()
@@ -569,6 +575,12 @@ fn current_git_dirty() -> bool {
.is_some_and(|output| !output.trim().is_empty()) .is_some_and(|output| !output.trim().is_empty())
} }
fn compiled_rust_toolchain() -> String {
option_env!("FPARKAN_BUILD_RUST_TOOLCHAIN")
.filter(|value| !value.trim().is_empty())
.map_or_else(current_rustc_release, ToString::to_string)
}
fn current_rustc_release() -> String { fn current_rustc_release() -> String {
Command::new("rustc") Command::new("rustc")
.arg("-Vv") .arg("-Vv")
@@ -624,6 +636,14 @@ fn is_commit_sha(value: &str) -> bool {
value.len() == 40 && value.chars().all(|ch| ch.is_ascii_hexdigit()) value.len() == 40 && value.chars().all(|ch| ch.is_ascii_hexdigit())
} }
fn parse_bool_env(value: &str) -> Option<bool> {
match value {
"true" => Some(true),
"false" => Some(false),
_ => None,
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@@ -724,6 +744,13 @@ mod tests {
assert!(!is_commit_sha("zz23456789abcdef0123456789abcdef01234567")); assert!(!is_commit_sha("zz23456789abcdef0123456789abcdef01234567"));
} }
#[test]
fn parses_bool_env_values() {
assert_eq!(parse_bool_env("true"), Some(true));
assert_eq!(parse_bool_env("false"), Some(false));
assert_eq!(parse_bool_env("1"), None);
}
#[test] #[test]
fn smoke_report_json_contains_expected_fields() { fn smoke_report_json_contains_expected_fields() {
let json = serde_json::to_string_pretty(&SmokeReport { let json = serde_json::to_string_pretty(&SmokeReport {