CI

Run owlwarden in CI

Exit 0 means clean, 1 means findings, and 2 means the scan failed. The same run can write SARIF, JUnit, JSON, or Markdown.

One scan, several report formats

  1. SARIF Code scanningFindings land on the exact source line.
  2. JUNIT Test UISecurity results sit beside the test suite.
  3. MD Review summaryA compact report fits the pull request.
exit 0 clean, exit 1 findings, exit 2 scan error
- uses: suthat/owlwarden/action@v1
  with:
    fail-on: medium
    format: sarif
    since: ${{ github.event.pull_request.base.sha }}

The exit-code contract

CodeMeans
0Scanned, nothing at or above --fail-on
1Findings at or above the threshold
2Could not run because of a bad flag, unreadable tree, or missing engine

Exit code 2 keeps a scan error separate from a finding. CI should fail in both cases but can report them differently.

What --ci refuses

Under --ci, project configuration cannot set the gate knobs, and inline suppressions and --baseline are ignored unless the operator opts in explicitly. A pull request cannot weaken the check by editing repository config.

A truncated report is not a clean report

If the engine hits its finding cap it says so, and the run fails even with no retained findings above the threshold. Exiting 0 would hide whatever it did not get to.

Only what changed

owlwarden turn --base origin/main --fail-on medium
owlwarden scan --since origin/main --fail-on medium
owlwarden scan --staged            # a pre-commit hook

A pull request is a turn with a named base. owlwarden turn --base origin/main fails the job for what the branch introduced and stays silent about what main already carried. Use scan --since when you want the findings on the changed files regardless of who introduced them. Needs the full history: set fetch-depth: 0 on actions/checkout, or the base ref will not resolve.

A diff-scoped scan states its scope in every format, so a clean result can never be mistaken for a clean repository. Project-scope rules still run when their own declared inputs changed - a commit touching only package.json still fires the dependency rules.

Keep reading