mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-25 22:02:44 +00:00
Exempt Dependabot PRs from the PR gate (#4395)
## What Adds a trusted-bot exception to the PR gate so Dependabot's PRs are no longer auto-closed. ## Why The PR gate (`scripts/pr-gate/`, run by `.github/workflows/pr-gate.yml`) auto-closes PRs that don't fit the contribution workflow. Dependabot PRs were getting closed because the bot: - has no repo permission, - links no `approved` issue, and - opens dependency bumps that often exceed the 50-line small-fix cap. ## How - `config.ts` — new `TRUSTED_BOT_AUTHORS` constant (currently `["dependabot[bot]"]`), so the allowlist is easy to extend. - `rules.ts` — new `checkTrustedBot()` rule, wired into `evaluate()` right after the maintainer bypass and before the repo-access check. - `tests/PrGateRules.test.ts` — unit tests for the rule plus an `evaluate()`-level test proving a 5000-line Dependabot PR now passes instead of closing. - `README.md` — documented the new rule in the gate-logic ordering. The match is exact, so a lookalike login (e.g. `not-dependabot[bot]`) won't slip through. Add more bots (Renovate, etc.) to `TRUSTED_BOT_AUTHORS` as needed. ## Testing `npx vitest tests/PrGateRules.test.ts --run` → 39 passed. Lint + prettier clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,10 +5,11 @@ Deterministic GitHub Action that auto-closes PRs that don't follow the project's
|
||||
## 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 bypass** — `author_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 bypass** — `additions + deletions ≤ 50` → pass + apply `small-fix` label.
|
||||
5. **Otherwise** — apply `auto-closed-needs-issue` label, post rejection comment, close.
|
||||
2. **Trusted-bot bypass** — PR author is a trusted bot (e.g. `dependabot[bot]`) → pass. List is in `TRUSTED_BOT_AUTHORS`.
|
||||
3. **Org/repo member bypass** — `author_association` is `OWNER`, `MEMBER`, or `COLLABORATOR` → pass.
|
||||
4. **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.
|
||||
5. **Small-fix bypass** — `additions + deletions ≤ 50` → pass + apply `small-fix` label.
|
||||
6. **Otherwise** — apply `auto-closed-needs-issue` label, post rejection comment, close.
|
||||
|
||||
## Local testing
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@ export const REPO = { owner: "openfrontio", repo: "OpenFrontIO" } as const;
|
||||
|
||||
export const TRUSTED_REPO_PERMISSIONS = ["admin", "maintain", "write"] as const;
|
||||
|
||||
// Bot authors whose PRs are exempt from the gate (e.g. Dependabot dependency bumps).
|
||||
export const TRUSTED_BOT_AUTHORS = ["dependabot[bot]"] as const;
|
||||
|
||||
export const SMALL_FIX_LINE_THRESHOLD = 50;
|
||||
|
||||
export const APPROVED_ISSUE_LABEL = "approved";
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
APPROVED_ISSUE_LABEL,
|
||||
LABELS,
|
||||
SMALL_FIX_LINE_THRESHOLD,
|
||||
TRUSTED_BOT_AUTHORS,
|
||||
TRUSTED_REPO_PERMISSIONS,
|
||||
} from "./config";
|
||||
|
||||
@@ -54,6 +55,16 @@ export function checkBypass(pr: PRMetadata): RuleResult {
|
||||
return { action: "next" };
|
||||
}
|
||||
|
||||
export function checkTrustedBot(pr: PRMetadata): RuleResult {
|
||||
if ((TRUSTED_BOT_AUTHORS as readonly string[]).includes(pr.user.login)) {
|
||||
return {
|
||||
action: "pass",
|
||||
reason: `Author "${pr.user.login}" is a trusted bot`,
|
||||
};
|
||||
}
|
||||
return { action: "next" };
|
||||
}
|
||||
|
||||
export async function checkRepoAccess(
|
||||
pr: PRMetadata,
|
||||
getRepoPermission: GetRepoPermission,
|
||||
@@ -113,6 +124,9 @@ export async function evaluate(
|
||||
const r0 = checkBypass(pr);
|
||||
if (r0.action !== "next") return r0;
|
||||
|
||||
const rBot = checkTrustedBot(pr);
|
||||
if (rBot.action !== "next") return rBot;
|
||||
|
||||
const r1 = await checkRepoAccess(pr, getRepoPermission);
|
||||
if (r1.action !== "next") return r1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user