A pull-request hygiene gate — checks the basics and posts a checklist. Zero dependencies.
prgate looks at a pull request and verifies the small things reviewers
otherwise chase by hand: is there a real description, were tests touched when code
changed, is the diff a reasonable size, is there a changelog entry. It posts a
checklist comment and, in CI, fails the job when a required check is missing — so
the gate is enforced, not just suggested.
No language model, no API keys, no third-party packages: just the GitHub REST API and the Python standard library.
| Check | Default | What it verifies |
|---|---|---|
description |
required | The PR description is at least N characters. |
tests |
required | If code changed, at least one test file changed too. |
size |
required | The diff is at most N changed lines. |
changelog |
advisory | A CHANGELOG file is part of the change. |
title |
advisory | The title follows Conventional Commits. |
linked-issue |
advisory | The body references an issue (#123). |
Advisory checks are reported but never fail the gate, until you promote them.
pip install prgateRequires Python 3.8+.
export GITHUB_TOKEN=ghp_...
# Print the checklist (exit code reflects the gate)
prgate --repo octocat/hello-world --pr 42
# Post it as a comment, require a changelog entry, allow bigger diffs
prgate --repo octocat/hello-world --pr 42 --post --require-changelog --max-changes 800| Flag | Description |
|---|---|
--repo OWNER/NAME / --pr N |
The pull request (required). |
--min-description N |
Minimum description length (default 20). |
--max-changes N |
Maximum changed lines (default 500). |
--no-require-description / --no-require-tests / --no-require-size |
Relax a default-required check. |
--require-changelog / --require-title / --require-linked-issue |
Promote an advisory check. |
--post |
Post the checklist as a PR comment. |
--soft |
Always exit 0 (report only, never block). |
Gate every pull request:
name: prgate
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
gate:
runs-on: ubuntu-latest
steps:
- uses: Sev7nOfNine/[email protected]
with:
max-changes: "600"
require-changelog: "false"With the default settings the job fails if a required check is not met, which
blocks the merge until the PR is cleaned up. Set soft: "true" to report without
blocking.
pip install -e ".[test]"
python -m pytestAll tests run offline; the GitHub layer accepts an injectable opener.
MIT — see LICENSE.