xtask/tests/ossf_files.rs
//! **What the OpenSSF Scorecard reads, kept true** (lane MON-OSSF, 2026-10-31; Gunnar's and
//! Holger's since OSSF-NEXT). git.gunnar.rs runs no bot and no Actions, so the files below are
//! the policy any tool that reads them follows, and the dwarves forge does the work:
//!
//! * `SECURITY.md`: how to report a vulnerability privately, and the answer times;
//! * `renovate.json`: the update policy (Cargo locks weekly, advisories at once, images and
//! actions pinned by digest); the forge's weekly `deps-monetize` job proposes the moves;
//! * `.github/workflows/*.yml`: every action pinned to a full commit, and every workflow with a
//! `permissions:` block (read-only unless it says why), so a moved tag or the default token's
//! write access is never what a mirror's run gets;
//! * `fuzz/`: the cargo-fuzz crate the forge fuzzes every night.
use std::path::{Path, PathBuf};
fn root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).parent().expect("xtask has a parent").to_path_buf()
}
fn read(rel: &str) -> String {
std::fs::read_to_string(root().join(rel)).unwrap_or_else(|e| panic!("{rel}: {e}"))
}
#[test]
fn a_security_policy_says_where_to_report_privately() {
let s = read("SECURITY.md");
assert!(s.contains("gunnar@gunnar.rs"), "the private reporting address");
assert!(s.contains("Do not open a public issue"), "no public issue for a vulnerability");
assert!(s.contains("14 days") && s.contains("90 days"), "the answer and the publication times");
assert!(s.contains("osv-scanner.toml") && s.contains("deny.toml"), "how advisories are triaged");
}
#[test]
fn renovate_says_the_weekly_update_policy() {
// xtask parses no JSON (its one dependency is nornir-xtask-support): the file is small and
// of one fixed shape, so its lines are read as text.
let r = read("renovate.json");
let flat: String = r.split_whitespace().collect();
for want in [
r#""enabledManagers":["cargo","dockerfile","github-actions"]"#,
r#""rangeStrategy":"update-lockfile""#,
r#""lockFileMaintenance":{"enabled":true"#,
r#""vulnerabilityAlerts":{"enabled":true,"schedule":["atanytime"]}"#,
r#""pinDigests":true"#,
r#""schedule":["before6amonmonday"]"#,
] {
assert!(flat.contains(want), "renovate.json does not say {want}:\n{r}");
}
}
#[test]
fn every_workflow_pins_its_actions_and_says_its_permissions() {
let dir = root().join(".github/workflows");
let mut wrong = Vec::new();
let mut n = 0;
for e in std::fs::read_dir(&dir).expect(".github/workflows").flatten() {
let name = e.file_name().to_string_lossy().to_string();
if !(name.ends_with(".yml") || name.ends_with(".yaml")) {
continue;
}
n += 1;
let text = std::fs::read_to_string(e.path()).unwrap();
if !text.lines().any(|l| l.starts_with("permissions:")) {
wrong.push(format!("{name}: no top-level `permissions:` block"));
}
for l in text.lines() {
let code = l.split(" #").next().unwrap_or("").trim();
let Some(uses) = code.strip_prefix("- uses:").or_else(|| code.strip_prefix("uses:")) else { continue };
let uses = uses.trim();
let pinned = uses.rsplit_once('@').is_some_and(|(_, r)| r.len() == 40 && r.bytes().all(|b| b.is_ascii_hexdigit()));
if !pinned && !uses.starts_with("./") {
wrong.push(format!("{name}: `{uses}` is not pinned to a full commit"));
}
}
}
assert!(n > 0, "the walk found the workflows");
assert!(wrong.is_empty(), "{}", wrong.join("\n"));
}
#[test]
fn the_fuzz_crate_is_where_the_forge_and_the_scorecard_look() {
let m = read("fuzz/Cargo.toml");
assert!(m.contains("cargo-fuzz = true") && m.contains("libfuzzer-sys"), "the cargo-fuzz layout");
for t in ["pay_callback", "feed_config", "signed_facts", "fleet_door", "fleet_orders"] {
assert!(root().join(format!("fuzz/fuzz_targets/{t}.rs")).is_file(), "{t}");
assert!(root().join(format!("fuzz/corpus/{t}")).is_dir(), "{t}'s seeds");
}
}