CI
Job summaries, GitHub annotations and SARIF.
check and the family commands print two formats made for CI:
npx spirolo check --format markdown >> "$GITHUB_STEP_SUMMARY"
npx spirolo check --format github-annotationsBoth carry the same findings as the default view: proven and advisory rules. Add --all for the
rest. Choosing a format never changes which rules run or what the exit code is.
A GitHub Actions job
- run: npm ci
- run: npx spirolo check --format markdown >> "$GITHUB_STEP_SUMMARY"
- run: npx spirolo check --format github-annotationsInstall dependencies before the check, or module resolution fails and the orphan-test, untested-hotspot, unused-mock and absence-anchor rows are marked unreliable. Those rows keep their severity, so a job that skips the install still fails on a rule you opted into gating, rather than passing on a partial graph.
Markdown
The summary prints the rule status table with measured precision, then the findings. Findings of unproven rules sit in a collapsed info section. Each row keeps its severity and its rule's status. Paths and messages are escaped so they cannot break the table.
GitHub annotations
One workflow command per decided finding, at its severity: ::notice for info, so an advisory finding
is never a yellow warning on a run that passes, ::warning for warn and ::error for error.
Listed and undecided rows do not become annotations. The title is the rule and its status, such as
dead-skip (UNADJUDICATED). At most ten annotations
of each level are printed, matching GitHub's per-step limits; a closing log line counts the rest.
SARIF and JSON
--format sarif writes SARIF 2.1 for code scanning, with each result's rule status in
properties.ruleStatus. --format json is the versioned schema, with rule_status on each
finding. Neither carries the health score.
Only new findings
Run spirolo ratchet once and commit the baseline.
CI then fails only on findings that are new since.