CI setup

Run cms-lab after your app is built and serving. The scanner exits with a stable status code and can produce a single static HTML report artifact.

GitHub Actions

- uses: i-afaqrashid/cms-lab@v1
  with:
    config: cms-lab.config.ts
    report: true
    fail-on: error

For teams that prefer explicit shell steps:

Copy-paste workflow

This workflow builds the app, starts it, waits for the local URL, runs cms-lab, and uploads the HTML report even when the scan fails.

name: cms-lab
on: [pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: 22
      - run: corepack enable
      - run: corepack prepare pnpm@10.33.4 --activate
      - run: pnpm install --frozen-lockfile
      - run: pnpm build
      - run: pnpm start &
      - run: pnpm dlx wait-on http://localhost:3000
      - run: npx @cms-lab/cli scan --ci --report
      - uses: actions/upload-artifact@v7
        if: always()
        with:
          name: cms-lab-report
          path: .cms-lab/report.html

Thresholds

By default, errors fail the job and warnings do not. Tighten that after the project has a baseline.

npx @cms-lab/cli scan --ci --fail-on error
npx @cms-lab/cli scan --ci --fail-on warning
npx @cms-lab/cli scan --ci --max-warnings 0
npx @cms-lab/cli scan --ci --max-info 0
npx @cms-lab/cli scan --ci --strict
npx @cms-lab/cli scan --ci --fail-on never

Baseline

Turning cms-lab on against an existing repo with legacy warnings is easier with a baseline. Capture the current diagnostics once, commit the file, and subsequent scans exit 0 unless something new appears.

# capture the current diagnostics
npx @cms-lab/cli baseline write

# commit the file so CI uses the same set
git add .cms-lab/baseline.json
git commit -m "chore: cms-lab baseline"

# scan in CI; only NEW diagnostics fail the build
npx @cms-lab/cli scan --ci

# ignore the baseline temporarily to see everything
npx @cms-lab/cli scan --ci --no-baseline

The baseline file is small, human-readable JSON. Inspect it before committing and shrink it over time as you fix the legacy diagnostics and re-run cms-lab baseline write.

Compare reports

For PR pipelines the useful question is "did this PR introduce new diagnostics vs main?" cms-lab compare diffs two scan JSON outputs by a stable fingerprint and exits 1 only when there are net-new errors.

# scan main and the PR head, then diff
npx @cms-lab/cli scan --json > main.json
npx @cms-lab/cli scan --json > head.json
npx @cms-lab/cli compare main.json head.json

# paste-ready PR comment
npx @cms-lab/cli compare main.json head.json --markdown diff.md

# machine-readable form
npx @cms-lab/cli compare main.json head.json --json

Artifacts

The report is a self-contained HTML file. It can be opened locally, uploaded as a CI artifact, or attached to release notes.

npx @cms-lab/cli scan --ci --report --share-report
Keep reports privateReports stay in your workspace unless your CI uploads them. Treat report artifacts as project data when they include route paths or CMS type names. Use --share-report for public issue attachments; it removes CMS source IDs and local project paths from the HTML report.