Skip to content

UID2-7011: skip zizmor scan when there is nothing to scan#253

Merged
swibi-ttd merged 7 commits into
mainfrom
swi-UID2-7011-zizmor-central-control
Jul 6, 2026
Merged

UID2-7011: skip zizmor scan when there is nothing to scan#253
swibi-ttd merged 7 commits into
mainfrom
swi-UID2-7011-zizmor-central-control

Conversation

@swibi-ttd

@swibi-ttd swibi-ttd commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Makes a repo with nothing to scan pass instead of fail, so the scan can be applied blanket-style (e.g. the UnifiedID2 required-workflow ruleset targeting ~ALL repos).

zizmor exit 3 ("no inputs collected") now splits by intent:

  • default scan_paths: '.' → the repo genuinely has no GitHub Actions content → skip green with a summary notice
  • explicit scan_paths → an empty collection is a probable typo → fail closed, as before

Verified empirically that a repo with no Actions content yields exit 3; actionlint + zizmor self-scan clean.

Also makes this repo's own caller bare (severity floors inherit the shared defaults — same effective values) and drops the with: line from the README adoption example.

Must merge and ship in a v3 release before uid2-okta-configuration#222 applies, since the ruleset-injected workflow calls @v3.

🤖 Generated with Claude Code

min_severity and fail_severity now resolve with precedence: explicit caller
input > calling repo's ZIZMOR_MIN_SEVERITY / ZIZMOR_FAIL_SEVERITY Actions
variable > central default (high / never). Callers should be bare (no with:)
so the org-wide rollout can be retuned without touching 50+ caller files:
a central default change here ships to every bare caller via the moving v3
tag, and a repo variable flips one repo with no PR at all.

Effective values are unchanged for all existing callers: the input defaults
move from concrete values to an empty sentinel, and the fallback chain
reproduces the old defaults when neither input nor variable is set.

Also makes this repo's own caller bare (same behaviour as before via the
central defaults) and documents the three-lever precedence in the README.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
swibi-ttd and others added 4 commits July 3, 2026 14:09
zizmor exit 3 (no inputs collected) now splits by intent: with the default
scan_paths '.', it means the repo genuinely has no GitHub Actions content -
legitimate for ruleset-injected runs that target every repo in an org - so
the job skips green with a notice in the summary. With caller-specified
scan_paths, an empty collection is more likely a typo'd path and keeps
failing closed (the fail-open concern from the original review stands).

This lets the UnifiedID2 required-workflow ruleset target ~ALL repos
instead of maintaining an include-list of repos with workflows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Revert the ZIZMOR_MIN_SEVERITY / ZIZMOR_FAIL_SEVERITY vars fallback and the
empty-sentinel input defaults: minimal solution preferred - central control
via bare callers inheriting the shared defaults is sufficient, and per-repo
override support can be added later if staged per-repo gating turns out to
need it. Inputs go back to concrete defaults (high / never).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@swibi-ttd swibi-ttd changed the title UID2-7011: centrally controllable zizmor severity floors UID2-7011: skip zizmor scan when there is nothing to scan Jul 3, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@BehnamMozafari

Copy link
Copy Markdown
Contributor

Two things worth addressing on the new exit-3 handling before the gate flips to enforcing under UID2-7425 (non-blocking for merging this as staged report-only):

1. The skip-green path is fail-open and not falsifiable. On scan_paths='.', exit 3 → exit 0 based only on the exit code plus a SCAN_PATHS == "." string match. Exit 3 is generically "no inputs collected" — it doesn't confirm the repo is genuinely Actions-free vs. a collection/checkout anomaly — and this is exactly the path the org-wide required workflow uses. Unlike the normal path, the skip branch emits no evidence table (version / inputs-audited / floors / exit code), so a green skip is indistinguishable from a scan that silently did nothing, which cuts against this file's own "evidence so a green run is falsifiable" philosophy.

Suggest: grep zizmor.log to confirm the "no inputs collected" reason before going green, and emit the evidence table (+ the exit code) on the skip path so a skip is auditable as a deliberate decision.

(Realistic risk today is low — a GitHub-executed workflow lives in .github/workflows, which '.' scans — but this is the behaviour that matters once the gate is enforcing.)

2. This branch is untested and unreachable by this repo's own CI. Since uid2-shared-actions has Actions content, the self-scan always takes the 0|11|12|13|14 path and never exercises the new 3) case — neither the skip-green nor the explicit-paths exit 1 sub-branch. A quoting slip or an inverted if would merge green and ship in v3 with no signal, and the only current verification is a one-time manual check.

Suggest: add a shell/bats fixture test (empty repo + default ., empty + explicit scan_paths, non-empty) that pins "empty ⇒ exit 3 ⇒ skip green" against the pinned zizmor version, so a future upgrade can't silently reroute it.

…gate

Address review feedback on the exit-3 path: instead of a separate skip
branch with its own summary and exit 0, a verified nothing-to-scan run
(exit 3 on the default '.' scan, 'no inputs collected' confirmed in the
scan log) flows through the shared summary block and the severity gate.
The skip therefore carries the same evidence as a real run (version,
paths, inputs audited: 0, floors, config, gate, full scan log) and passes
the gate naturally since 3 is below every fail threshold. Exit 3 without
the logged reason, or with explicit scan_paths, still fails closed.

Verified with a fixture matrix: empty repo + default '.' (skips green,
including under fail_severity: high), empty + explicit paths (fails),
repo with workflows (normal path unchanged).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@swibi-ttd

Copy link
Copy Markdown
Contributor Author

@BehnamMozafari

  1. Added a grep for no inputs collected and also show the summary table on the skip path
  2. Would prefer not to set up tests for this as it would require some refactoring + the workflow isn't super critical. Will run some test manually after this is merged

@swibi-ttd swibi-ttd merged commit 4c68d6d into main Jul 6, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants