Files
Evan b56e9438d1 github PR gate (#4070)
## Description:

## Summary

Adds a GitHub Action that auto-closes PRs which don't follow the
contribution workflow, so maintainer review time goes to legitimate
contributions instead of off-roadmap or AI-generated submissions.

Triggered on `pull_request_target: [opened, reopened]` and **defaults to
dry-run** so it's safe to merge before flipping live.

## Gate logic (first match wins)

1. **Maintainer bypass** — PR carries `bypass-pr-check` label → pass.
2. **Org/repo member** — `author_association` is `OWNER` / `MEMBER` /
`COLLABORATOR` → pass.
3. **Approved work** — PR body links an issue (`Closes/Fixes/Resolves
#N`) that carries the `approved` label and the PR author is in the
issue's assignees → pass.
4. **Small fix** — `additions + deletions ≤ 50` → pass + apply
`small-fix` label.
5. **Otherwise** — apply `auto-closed-needs-issue` label, post rejection
comment, close.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
2026-05-29 18:28:52 -07:00

1.9 KiB

PR Gate

Deterministic GitHub Action that auto-closes PRs that don't follow the project's contribution workflow. Trigger: pull_request_target: [opened, reopened].

Gate logic (first match wins)

  1. Maintainer bypass — PR carries the bypass-pr-check label → pass. Apply this label and reopen if the gate closed something you wanted through.
  2. Org/repo member bypassauthor_association is OWNER, MEMBER, or COLLABORATOR → pass.
  3. Approved-work bypass — PR body links an issue (via Closes #N / Fixes #N / Resolves #N) that carries the approved label, and the PR author is in the issue's assignees → pass.
  4. Small-fix bypassadditions + deletions ≤ 50 → pass + apply small-fix label.
  5. Otherwise — apply auto-closed-needs-issue label, post rejection comment, close.

Local testing

cd scripts/pr-gate
npm install
export GITHUB_TOKEN=ghp_... # PAT with repo scope
npx tsx index.ts --pr 1234  # always dry-run unless --no-dry-run

The CLI prints the decision and exits without touching the PR.

Toggling dry-run in production

  1. Go to repo Settings → Secrets and variables → Actions → Variables.
  2. Edit PR_GATE_DRY_RUN.
  3. Set to false to make the Action take real action; any other value (or unset) keeps it in dry-run mode.

The default is true — the gate logs decisions but does not act until the maintainer flips the variable.

Tweaking rules

Known limitations

  • Runs only on PR open/reopen — not on synchronize. A PR that grows past 50 lines after being passed will not be re-gated.
  • Cross-repo issue references (owner/repo#N) are not honored.
  • No LLM is called. This Action is fully deterministic.