From 7cc6ff856b5653039c3d04307d16858c12d93596f7738c0fb89e27caf7f185c6 Mon Sep 17 00:00:00 2001 From: Till Wegmueller Date: Tue, 18 Nov 2025 12:50:20 +0100 Subject: [PATCH] Refactor runner setup and diagnostics; improve tooling support and NDJSON logging - Enhance runner logging with status-specific messages and structured JSON fields for better traceability. - Add SHA256 object format detection and initialization for Git repos when applicable. - Improve shell script execution by adding verbose mode and safe commands handling. - Extend package installation scripts to support Clang and related tooling across multiple environments. - Increment orchestrator version for release. Signed-off-by: Till Wegmueller --- .solstice/job.sh | 16 +++++----- crates/workflow-runner/src/main.rs | 51 ++++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/.solstice/job.sh b/.solstice/job.sh index a856bf1..e227d88 100755 --- a/.solstice/job.sh +++ b/.solstice/job.sh @@ -29,22 +29,22 @@ install_linux() { apt) sudo -n true 2>/dev/null || true sudo apt-get update -y || apt-get update -y || true - sudo apt-get install -y --no-install-recommends curl ca-certificates git build-essential pkg-config libssl-dev protobuf-compiler cmake || true + sudo apt-get install -y --no-install-recommends curl ca-certificates git build-essential pkg-config libssl-dev protobuf-compiler cmake clang libclang-dev || true ;; dnf) - sudo dnf install -y curl ca-certificates git gcc gcc-c++ make pkgconf-pkg-config openssl-devel protobuf-compiler || true + sudo dnf install -y curl ca-certificates git gcc gcc-c++ make pkgconf-pkg-config openssl-devel protobuf-compiler clang clang-libs || true ;; yum) - sudo yum install -y curl ca-certificates git gcc gcc-c++ make pkgconfig openssl-devel protobuf-compiler || true + sudo yum install -y curl ca-certificates git gcc gcc-c++ make pkgconfig openssl-devel protobuf-compiler clang clang-libs || true ;; zypper) - sudo zypper --non-interactive install curl ca-certificates git gcc gcc-c++ make pkg-config libopenssl-devel protobuf || true + sudo zypper --non-interactive install curl ca-certificates git gcc gcc-c++ make pkg-config libopenssl-devel protobuf clang || true ;; apk) - sudo apk add --no-cache curl ca-certificates git build-base pkgconfig openssl-dev protoc || true + sudo apk add --no-cache curl ca-certificates git build-base pkgconfig openssl-dev protoc clang clang-libs || true ;; pacman) - sudo pacman -Sy --noconfirm curl ca-certificates git base-devel pkgconf openssl protobuf || true + sudo pacman -Sy --noconfirm curl ca-certificates git base-devel pkgconf openssl protobuf clang || true ;; *) log "unknown package manager ($PM); skipping linux deps install" @@ -56,9 +56,9 @@ install_illumos() { if command -v pkg >/dev/null 2>&1; then # OpenIndiana IPS packages (best-effort) sudo pkg refresh || true - sudo pkg install -v developer/build/gnu-make developer/gcc-13 git developer/protobuf developer/rustc || true + sudo pkg install -v developer/build/gnu-make developer/gcc-13 git developer/protobuf developer/rustc developer/clang || true elif command -v pkgin >/dev/null 2>&1; then - sudo pkgin -y install git gcc gmake protobuf || true + sudo pkgin -y install git gcc gmake protobuf clang || true else log "no known package manager found on illumos" fi diff --git a/crates/workflow-runner/src/main.rs b/crates/workflow-runner/src/main.rs index d418c4c..64434c6 100644 --- a/crates/workflow-runner/src/main.rs +++ b/crates/workflow-runner/src/main.rs @@ -181,7 +181,16 @@ async fn preflight(repo: &str, workdir: &str) -> Result<()> { if let Some((host, port)) = parse_repo_host_port(repo) { let ok = check_network_connect(&host, port, 2000).await; let lvl = if ok { "info" } else { "warn" }; - println!("{}", ndjson_line("env", lvl, "network connectivity", Some(serde_json::json!({"host": host, "port": port, "reachable": ok})))); + let status_msg = if ok { "reachable" } else { "unreachable" }; + println!( + "{}", + ndjson_line( + "env", + lvl, + &format!("network: {}:{} {}", host, port, status_msg), + Some(serde_json::json!({"host": host, "port": port, "reachable": ok})) + ) + ); } Ok(()) @@ -258,19 +267,48 @@ async fn fetch_repo_via_archive(repo_https: &str, sha: &str, workdir: &str) -> R Err(miette::miette!("failed to fetch repo archive via HTTP for {url}")) } +fn is_hex(s: &str) -> bool { s.chars().all(|c| c.is_ascii_hexdigit()) } + async fn ensure_repo(repo: &str, sha: &str, workdir: &str) -> Result<()> { fs::create_dir_all(workdir).await.into_diagnostic()?; let repo_eff = to_https_if_codeberg(repo); // Prefer git when available; fall back to archive download when git is missing or fetch fails. if has_cmd("git").await { + // Determine object format: if SHA looks like 64-hex, assume sha256 object format + let sha_len = sha.len(); + let is_sha256 = sha_len == 64 && is_hex(sha); + let obj_fmt = if is_sha256 { Some("sha256") } else { None }; + // Emit NDJSON about chosen method + println!( + "{}", + ndjson_line( + "env_setup", + "info", + &format!( + "fetch via git (object-format={})", + obj_fmt.unwrap_or("sha1") + ), + Some(serde_json::json!({ + "method": "git", + "object_format": obj_fmt.unwrap_or("sha1"), + "sha_len": sha_len, + "detached": true + })) + ) + ); + let cmds = vec![ - format!("cd {workdir} && git init"), + // Re-initialize repository to ensure correct object format + format!("cd {workdir} && rm -rf .git || true"), + if let Some(fmt) = obj_fmt { format!("cd {workdir} && git init --object-format={fmt}") } else { format!("cd {workdir} && git init") }, format!( "cd {workdir} && git remote remove origin >/dev/null 2>&1 || true && git remote add origin {repo_eff}" ), - format!("cd {workdir} && git fetch --depth=1 origin {sha}"), - format!("cd {workdir} && git checkout -q FETCH_HEAD"), + // Use protocol v2 features when available and keep it light + format!("cd {workdir} && git -c protocol.version=2 fetch --filter=blob:none --depth=1 --no-tags origin {sha}"), + // Checkout the requested commit in detached HEAD + format!("cd {workdir} && git checkout -q --detach {sha}"), ]; for c in cmds { match run_shell(&c).await { @@ -301,7 +339,7 @@ async fn run_job_script(workdir: &str) -> Result { let mut cmd = Command::new("/bin/sh"); cmd.arg("-lc") - .arg(format!("cd {workdir} && {}", script)) + .arg(format!("set -ex; cd {workdir}; {}", script)) .stdout(Stdio::piped()) .stderr(Stdio::piped()); let mut child = cmd.spawn().into_diagnostic()?; @@ -406,7 +444,8 @@ async fn main() -> Result<()> { // Emit startup environment and tool checks let uname = Command::new("/bin/sh").arg("-lc").arg("uname -a || echo unknown").output().await.ok() .and_then(|o| String::from_utf8(o.stdout).ok()).unwrap_or_else(|| "unknown".into()); - println!("{}", ndjson_line("env", "info", "system", Some(serde_json::json!({"uname": uname.trim()})))); + let uname_trim = uname.trim().to_string(); + println!("{}", ndjson_line("env", "info", &format!("system: {}", uname_trim), Some(serde_json::json!({"uname": uname_trim})))); // Preflight environment checks (tools, workdir, network) if let Err(e) = preflight(&repo, &workdir).await {