Pipeline · gated, not blocked

A gate that blocks regressions, not progress

A hard threshold on day one will fail on any repository with history. Start by gating new findings only, then tighten the absolute floor as the debt comes down.

Three gates, escalating

Each one is a different promise. Use them in this order.

Gate 1

Block new findings

--baseline plus --fail-new 0 fails the build only when a finding appears that wasn't there before. Existing debt stops the build exactly zero times.

Gate 2

Block new criticals

--fail-new-critical is the narrower version: only a brand-new CRITICAL finding fails. Good for teams with a large existing backlog.

Gate 3

Block on absolute score

--fail-under 75 is the end state. Raise the floor as findings get fixed; the trend command tells you whether it's realistic yet.

# first run: capture the baseline
reproguard scan . --format json --output-dir .reproguard

# every run after: block on regressions only
reproguard scan . --baseline .reproguard/reproguard-report.json --fail-new 0
reproguard scan . --baseline .reproguard/reproguard-report.json --fail-new-critical

Exit codes: 1 when a gate trips, 2 for an invalid baseline or unusable arguments.

GitHub Actions

Two options: the reusable composite action, or a plain workflow you control.

name: ReproGuard
on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: vipulgote1999/ReproGuard/.github/actions/reproguard-scan@v0.5.0
        with:
          target: "."
          fail-under: 50
          profile: genai
          format: sarif
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: .reproguard/reproguard-report.sarif

The action installs ReproGuard from PyPI, runs the scan, and uploads every generated report as an artifact. Inputs: target, format, fail-under, fail-new, baseline, execute, profile, version. It emits SARIF by default.

name: ReproGuard
on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - run: pip install reproguard
      - run: reproguard scan . --format sarif --fail-under 50
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: .reproguard/reproguard-report.sarif

On GitHub Actions, CRITICAL and HIGH findings are also emitted as ::error workflow annotations automatically, so they appear inline on the diff.

# scan only what changed — seconds instead of minutes
- run: |
    git fetch --depth=2 origin "${{ github.base_ref }}"
    reproguard scan . --since "origin/${{ github.base_ref }}" \
      --format sarif --fail-new 0

--since <ref> skips untouched files while repo-level checks still run, so hygiene findings never slip through.

GitLab CI

The GitLab Code Quality report annotates merge requests directly, no extra upload step required.

reproguard:
  stage: test
  image: python:3.11-slim
  script:
    - pip install reproguard
    - reproguard scan . --format gitlab --fail-under 50
  artifacts:
    reports:
      codequality: .reproguard/gl-code-quality-report.json
    paths:
      - .reproguard/
    when: always

Pre-commit

Catch problems at commit time, before they reach CI.

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/vipulgote1999/ReproGuard
    rev: v0.5.0
    hooks:
      - id: reproguard-scan
        args: ["--fail-under", "75"]

The hook scans the whole repository on each commit and blocks when the score falls below the threshold. Keep rev pinned to a released tag — this project's own CI tests assert that the documented rev matches the current version.

Drift detection over time

Every scan appends to a per-project history in .reproguard/history. Use it to see whether things are improving, and to fail on sudden drops.

# where has this project been?
reproguard trend -n 10

# fail when the score dropped 5+ points since the last scan
reproguard scan . --fail-trend 5
History is per-project and local. It lives in .reproguard/history, which is gitignored by default. Nothing is uploaded anywhere — the trend is yours alone.

Secrets that were committed months ago

Scan git history

A scanner that only looks at the working tree misses the key you committed and then deleted three sprints ago. --git-history runs the PII and secret pipeline over git log -p diffs, strips commit metadata, deduplicates findings, and caps the output.

reproguard scan . --git-history

Stop the next one

--fix gitignore appends .env protection so future secret files are never staged. It is idempotent — running it twice changes nothing the second time.

reproguard scan . --fix gitignore

Add the gate in one command

reproguard init --ci github writes the config and a working workflow for you.