Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ repos:
name: license header check (hawkeye)
entry: hawkeye check --config licenserc.toml
language: system
types_or: [rust, python, shell]
types_or: [rust, python, shell, markdown]
pass_filenames: false
groups: [local-tools] # runs in the dedicated `license-headers` CI job (pinned prebuilt binary, no Action)

Expand Down
35 changes: 35 additions & 0 deletions xtask/src/workflow_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2062,6 +2062,41 @@ esac
);
}

/// The hawkeye version CONTRIBUTING.md documents and the version `ci.yml`'s
/// `license-headers` job installs must never drift: if they do, a
/// contributor's local pre-commit hook can bless a header hawkeye's CI
/// build would reject, or vice versa.
///
/// The version lives in exactly one place — `ci.yml`'s `license-headers`
/// job's `env:` mapping — and is read from there with the extractors this
/// file already has fixture tests for (`job_block`, `job_mapping`), rather
/// than duplicated into a constant, so a bump only ever needs the two
/// edits this test actually guards (ci.yml and CONTRIBUTING.md).
#[test]
fn hawkeye_pin_matches_ci_workflow() {
let ci = read_workflow("ci.yml");
let job = job_block(&ci, "license-headers");
let env = job_mapping(job, "env");
let installed = env
.get("HAWKEYE_VERSION")
.unwrap_or_else(|| panic!("license-headers job has no HAWKEYE_VERSION entry"));
// ci.yml's env var is `v`-prefixed (`v7.0.0`); CONTRIBUTING.md's prose
// is not (`hawkeye@7.0.0`).
let version = installed
.strip_prefix('v')
.unwrap_or_else(|| panic!("HAWKEYE_VERSION `{installed}` must be `v`-prefixed"));

let contributing = repo_root().join("CONTRIBUTING.md");
let contributing_text = std::fs::read_to_string(&contributing)
.unwrap_or_else(|e| panic!("reading {}: {e}", contributing.display()));
let documented = format!("cargo install hawkeye@{version} --locked");
assert!(
contributing_text.contains(&documented),
"CONTRIBUTING.md must instruct `{documented}` to match ci.yml's \
license-headers job (HAWKEYE_VERSION: {installed})"
);
}

// Extractor guards: prove the helpers actually parse multiline forms, so the
// contract tests above can't silently false-pass on a shape they don't handle.
#[test]
Expand Down
Loading