Deterministic pull request risk checks for busy maintainers
Project description
PR Sheriff
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:
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a08b817d3a153357fd78674bc66fc0853453cd07dc3e3eb4b7477cdffc1fcf03
|
|
| MD5 |
a40aabf46797478960381f4ee706064a
|
|
| BLAKE2b-256 |
816559cab9051a9d733fcf93a8c3fc96227b2c0003cbb11a69e649994e4531c5
|
Provenance
The following attestation bundles were made for pr_sheriff-0.5.0.tar.gz:
Publisher:
publish-pypi.yml on Hayal08/pr-sheriff
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pr_sheriff-0.5.0.tar.gz -
Subject digest:
a08b817d3a153357fd78674bc66fc0853453cd07dc3e3eb4b7477cdffc1fcf03 - Sigstore transparency entry: 1745224227
- Sigstore integration time:
-
Permalink:
Hayal08/pr-sheriff@4f454c4dd8b02a7f85e24748e490ef82e543dac1 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Hayal08
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4f454c4dd8b02a7f85e24748e490ef82e543dac1 -
Trigger Event:
workflow_dispatch
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b54b422dd4d117e71c3f99e5d41e185baba82afb18889027901800d9da97649
|
|
| MD5 |
50922bd4bf2702be54d46f389b255425
|
|
| BLAKE2b-256 |
00e7f27cd73793429fa94976d582707d4cf98f8eb45a81a7e9fecd925216a78c
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pr_sheriff-0.5.0-py3-none-any.whl -
Subject digest:
6b54b422dd4d117e71c3f99e5d41e185baba82afb18889027901800d9da97649 - Sigstore transparency entry: 1745224462
- Sigstore integration time:
-
Permalink:
Hayal08/pr-sheriff@4f454c4dd8b02a7f85e24748e490ef82e543dac1 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Hayal08
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4f454c4dd8b02a7f85e24748e490ef82e543dac1 -
Trigger Event:
workflow_dispatch
-
Statement type: