Skip to main content

Deterministic pull request risk checks for busy maintainers

Project description

PR Sheriff

CI GitHub Marketplace Good first issues PyPI

PR Sheriff is a tiny, deterministic pull request risk checker for busy open-source maintainers. It catches oversized changes, missing tests, and edits to sensitive files before review time is spent.

It has no runtime dependencies, sends no code anywhere, and works in any Git repository.

Live demo

See PR Sheriff working in the demo repository:

PR Sheriff reporting a sensitive migration path rule

Why PR Sheriff?

Large or sensitive pull requests consume disproportionate review time. PR Sheriff gives contributors fast, predictable feedback before a maintainer starts reviewing:

  • contributors learn when a change needs tests or should be split;
  • maintainers see sensitive paths and review risk immediately;
  • teams keep policy in a small, version-controlled JSON file;
  • every decision remains deterministic and explainable.

Quick start

python -m pip install pr-sheriff
pr-sheriff install-github --preset python

Commit the two generated files and open a pull request. PR Sheriff starts in advisory mode, so it reports risks without blocking contributors. Use --preset javascript for JavaScript and TypeScript repositories, or add --mode enforce when the policy is ready to become required.

For local-only checks:

pr-sheriff init --preset python
pr-sheriff check --base origin/main

Example output:

PR risk: MEDIUM (39/100)
Changed: 3 files, 94 lines
Sensitive files:
  - .github/workflows/release.yml
Policy check passed.

The command exits with 1 when policy violations exist, making it suitable for CI and pre-push hooks. Use --json for integrations.

Start with --advisory to report violations without blocking contributors:

pr-sheriff check --base origin/main --advisory

What it checks

  • Maximum changed lines and files
  • Whether non-trivial changes include tests
  • Sensitive paths such as workflows, authentication, migrations, and lockfiles
  • A simple risk score that is explainable and stable
  • Ignored paths that should not consume the review budget

Customize the generated .pr-sheriff.json to fit your repository. All matching uses portable glob patterns.

GitHub Action

Add .github/workflows/pr-sheriff.yml to your repository:

name: PR Sheriff

on:
  pull_request:

permissions:
  contents: read
  pull-requests: write

jobs:
  review-risk:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - uses: Hayal08/pr-sheriff@v0.5.0
        with:
          base: origin/${{ github.base_ref }}

The Action adds a report to the GitHub Job Summary, emits annotations for sensitive files and policy violations, creates or updates one pull request comment, and fails when policy is violated.

Action inputs

Input Default Purpose
base origin/main Base git ref for the three-dot diff
head HEAD Head git ref for the three-dot diff
config .pr-sheriff.json Path to repository policy
comment true Create or update a report comment on pull requests
mode enforce Use advisory to report without failing the check

The Action exposes risk, score, changed-files, changed-lines, and tests-changed outputs for later workflow steps. The policy-passed output is false when violations exist, including in advisory mode.

Gradual rollout

Use advisory mode to learn what the policy would flag before making it a required check:

- uses: Hayal08/pr-sheriff@v0.5.0
  with:
    base: origin/${{ github.base_ref }}
    mode: advisory

Advisory mode keeps the Job Summary, PR comment, outputs, and annotations, but turns policy errors into warnings and returns a successful exit code.

Configuration

Run pr-sheriff init, choose a ready-made python or javascript preset, or add .pr-sheriff.json manually:

pr-sheriff init --preset python

The presets recognize ecosystem-specific test files, manifests, lockfiles, and database migrations. Generated policies remain ordinary JSON and can be customized at any time.

{
  "max_changed_lines": 800,
  "max_changed_files": 30,
  "require_tests_after_lines": 120,
  "test_patterns": ["tests/**", "**/*_test.*", "**/*.test.*"],
  "sensitive_patterns": [".github/workflows/**", "**/auth/**", "**/migrations/**"],
  "ignore_patterns": ["**/*.md", "docs/**"],
  "path_rules": []
}

Unknown configuration keys are rejected so typos cannot silently weaken a policy.

Path-specific rules

Different parts of a repository can have stricter review policies. Each matched rule is shown separately in the report:

{
  "path_rules": [
    {
      "name": "database migrations",
      "patterns": ["**/migrations/**"],
      "max_changed_lines": 100,
      "require_tests_after_lines": 1
    },
    {
      "name": "frontend",
      "patterns": ["web/**"],
      "max_changed_files": 15,
      "require_tests_after_lines": 80
    }
  ]
}

Path rules support max_changed_lines, max_changed_files, and require_tests_after_lines. Global limits still apply.

Explainable risk score

Human-readable, JSON, Job Summary, and PR comment reports now show how changed lines, changed files, and sensitive paths contribute to the risk score. JSON consumers can use score_breakdown and path_rule_results for custom dashboards or workflow decisions.

Try it safely

Open a pull request that changes more than require_tests_after_lines without changing a test file. PR Sheriff will add a policy violation to its single updatable PR comment and fail the check. Add a test file and push again to see the same comment update and the check pass.

For pull requests from forks, GitHub may provide a read-only token. In that case, PR Sheriff still runs but reports that it could not update the comment.

Philosophy

PR Sheriff does not claim to decide whether code is good. It gives maintainers a consistent early warning so they can ask for smaller PRs, tests, or a deeper security review.

See CONTRIBUTING.md to help shape the project.

Contributing

First-time contributors are welcome. Start with a good first issue or read CONTRIBUTING.md for the local development workflow.

Useful ways to help:

  • try PR Sheriff in a real repository and report confusing behavior;
  • improve docs and policy examples;
  • add focused policy checks with tests;
  • share maintainer workflows that should influence the roadmap.

Please open an issue before starting a large change. Small pull requests are easier to review and are a good way to get involved.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pr_sheriff-0.5.0.tar.gz (17.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pr_sheriff-0.5.0-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

Details for the file pr_sheriff-0.5.0.tar.gz.

File metadata

  • Download URL: pr_sheriff-0.5.0.tar.gz
  • Upload date:
  • Size: 17.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pr_sheriff-0.5.0.tar.gz
Algorithm Hash digest
SHA256 a08b817d3a153357fd78674bc66fc0853453cd07dc3e3eb4b7477cdffc1fcf03
MD5 a40aabf46797478960381f4ee706064a
BLAKE2b-256 816559cab9051a9d733fcf93a8c3fc96227b2c0003cbb11a69e649994e4531c5

See more details on using hashes here.

Provenance

The following attestation bundles were made for pr_sheriff-0.5.0.tar.gz:

Publisher: publish-pypi.yml on Hayal08/pr-sheriff

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pr_sheriff-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: pr_sheriff-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 13.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pr_sheriff-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6b54b422dd4d117e71c3f99e5d41e185baba82afb18889027901800d9da97649
MD5 50922bd4bf2702be54d46f389b255425
BLAKE2b-256 00e7f27cd73793429fa94976d582707d4cf98f8eb45a81a7e9fecd925216a78c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pr_sheriff-0.5.0-py3-none-any.whl:

Publisher: publish-pypi.yml on Hayal08/pr-sheriff

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page