Add Straitjacket to CI
Run Straitjacket on every push with the bundled GitHub Action, and configure it with typed fields.
Straitjacket is built to fail CI when it finds slop. The bundled GitHub Action downloads the prebuilt binary and runs it over your repo — every rule, including duplication, in one self-contained pass. It fails the job on any error-level finding, and by default posts those findings to GitHub code scanning as SARIF — annotations right on the PR diff.
Minimal setup
Drop this in .github/workflows/straitjacket.yml:
name: straitjacket
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
permissions:
security-events: write # let the default SARIF upload post annotations
contents: read
steps:
- uses: actions/checkout@v4
- uses: zmaril/straitjacket@v0.2.3
with:
version: "v0.2.3" # pin the scanner, not just the Action wrapperThat's the whole thing. No toolchain to set up, no Node — the Action fetches a
single static binary and runs it. The security-events: write permission lets it
post findings as PR annotations; leave it off and the scan still runs and gates,
you just don't get the annotations.
Pin the full version — both halves. The
@v0.2.3on theuses:line pins the Action wrapper; theversion:input pins the scanner binary it downloads. Leaveversionunset and it defaults tolatest, so a new Straitjacket release applies its new rules to your repo the moment it ships — failing an unrelated PR on a rule you never opted into. Pin both to the same tag and bump deliberately. The newest release is on the Releases page.
Configure it
Pass typed fields rather than a raw argument string. Each maps to a CLI flag:
- uses: zmaril/straitjacket@v0.2.3
with:
paths: "src tests" # default "."
skip: "motion,slop-prose"
only: "" # run only these rules
max-lines: "800" # file-size budget (0 disables)
prose-window: "600" # slop-prose density window
dup-min-tokens: "80" # duplication clone size
format: "text" # job-log format — or "json"
sarif: "true" # upload to code scanning (default)
no-ignore: "false"
no-fail: "false"
working-directory: "."
version: "v0.2.3" # pin the scanner; "latest" applies new rules the moment they shipEvery field is optional; blanks fall back to Straitjacket's own defaults. The complete list is in the GitHub Action reference.
Report without failing
To surface findings without failing the build (useful while you're adopting it),
set no-fail:
- uses: zmaril/straitjacket@v0.2.3
with:
no-fail: "true"SARIF / inline PR annotations
The Action uploads its findings to GitHub code scanning as SARIF by default — they show as annotations on the PR diff and in the repo's Security tab, right where the reviewer is looking. It still fails the job on findings (a straitjacket is tight) — the SARIF uploads first, so you get the annotations and the gate.
All the minimal setup needs is the security-events: write
permission so the upload can post. That permission is the only extra step:
permissions:
security-events: write
contents: readUnder the hood, in one pass the Action writes a readable text report to the job
log and a side SARIF file, uploads the SARIF with
github/codeql-action/upload-sarif, then fails the job on findings. Adopting
gradually and want annotations without failing? Add no-fail: "true". Don't want
code scanning at all? Set sarif: "false" — it falls back to a plain text scan
that still gates.
Without the security-events: write permission the upload step is skipped
gracefully: no annotations, but the scan still runs and gates on findings.
Outside the Action, produce SARIF yourself:
straitjacket --format sarif --no-fail > straitjacket.sarifOther CI systems
There's no runtime dependency, so any CI works — install the binary and run it:
curl -fsSL https://raw.githubusercontent.com/zmaril/straitjacket/main/install.sh | sh
straitjacketThe command exits non-zero on any error-level finding, which fails the job on every CI system that respects exit codes.