Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ jobs:
fi
agent-spec --version

- name: Tests (workspace: lib, bins, doctests, ux-harness)
- name: "Tests (workspace: lib, bins, doctests, ux-harness)"
run: cargo test --workspace

- name: Static UX audit (gate policy: tools/ux-harness/gate.json)
- name: "Static UX audit (gate policy: tools/ux-harness/gate.json)"
# Source-only audit: token contrast, token discipline, translation
# coverage. Thresholds are a ratchet documented in gate.json.
run: |
Expand Down
37 changes: 37 additions & 0 deletions tests/ci_policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,43 @@ fn run_lines(job: &str) -> Vec<String> {
out
}

/// GitHub silently refuses to run a workflow whose YAML does not parse — the
/// run shows up as "workflow file issue" and, worse, the PR simply has no
/// `spec gate` check at all, so a broken file looks green. Without a YAML
/// dependency we enforce the one mistake that bit us: an unquoted scalar
/// containing `: ` (e.g. `name: Tests (workspace: lib)`) is a nested mapping
/// to YAML. Every single-line `name:` / `run:` value with `: ` must be quoted.
#[test]
fn ci_workflow_scalars_with_colon_space_are_quoted() {
for rel in [".github/workflows/main.yml", ".github/workflows/builds.yml"] {
let wf = read(rel);
for (i, line) in wf.lines().enumerate() {
let t = line.trim_start();
if t.starts_with('#') {
continue;
}
// Steps are list items: `- name: …` — drop the bullet before matching keys.
let t = t.strip_prefix("- ").map(str::trim_start).unwrap_or(t);
for key in ["name:", "run:", "if:", "key:"] {
let Some(rest) = t.strip_prefix(key) else { continue };
let v = rest.trim();
if v.is_empty() || v == "|" || v == ">" || v == "|-" {
continue;
}
let quoted = (v.starts_with('"') && v.ends_with('"'))
|| (v.starts_with('\'') && v.ends_with('\''));
// `${{ ... }}` expressions are fine; a bare `: ` elsewhere is not.
let stripped = v.replace("${{", "").replace("}}", "");
assert!(
quoted || !stripped.contains(": "),
"{rel}:{}: unquoted YAML scalar contains `: ` — quote it: {line}",
i + 1
);
}
}
}
}

#[test]
fn ci_workflow_runs_all_cargo_test_targets() {
let wf = read(".github/workflows/main.yml");
Expand Down
Loading