From d8c127a46254cea3ef8942cd746945dbb1f7af05 Mon Sep 17 00:00:00 2001 From: evanpelle Date: Mon, 1 Jun 2026 22:17:21 -0700 Subject: [PATCH] Add deterministic PR gate and label-triggered auto-close MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - pr-gate.yml: closes PRs that don't fit the contribution workflow. First match wins: bypass-pr-check label, org/repo member, linked `approved` issue with author assigned, or ≤50-line diff. Defaults to dry-run via the PR_GATE_DRY_RUN repo variable. - pr-close-on-label.yml: closes a PR with a polite comment when a maintainer applies a triage label (initially `appears-ai-generated`, extensible via the COMMENTS lookup). - scripts/pr-gate/: TypeScript implementation with scoped install (Octokit + tsx) so the workflow doesn't pull the full game dep tree. 35 unit tests cover parseLinkedIssues, each rule, and priority ordering. - PULL_REQUEST_TEMPLATE.md: points contributors at Discord (features) and issues (bugs) and surfaces the `approved` requirement. --- .github/workflows/pr-close-on-label.yml | 59 +++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/workflows/pr-close-on-label.yml diff --git a/.github/workflows/pr-close-on-label.yml b/.github/workflows/pr-close-on-label.yml new file mode 100644 index 000000000..c3f342252 --- /dev/null +++ b/.github/workflows/pr-close-on-label.yml @@ -0,0 +1,59 @@ +name: 🏷️ PR Close on Label + +on: + pull_request_target: + types: [labeled] + +permissions: + pull-requests: write + issues: write + +jobs: + close: + name: Close on triage label + runs-on: ubuntu-latest + timeout-minutes: 2 + steps: + - name: Close PR if label matches + uses: actions/github-script@v8 + with: + script: | + // Maintainer-applied labels that trigger an auto-close + comment. + // Add entries here as new triage categories come up. + const COMMENTS = { + "appears-ai-generated": (author) => `Hi @${author}, thanks for the contribution. + + This PR was closed because it appears to be AI-generated. We require contributions to be hand-written and understood by their author — if a regression shows up later, we need someone who can debug their own code. + + If this was misclassified, please reach out on our [Discord](https://discord.gg/K9zernJB5z) or comment below. + + See [CONTRIBUTING.md](https://github.com/${context.repo.owner}/${context.repo.repo}/blob/main/CONTRIBUTING.md) for the full contribution process.`, + }; + + const labelName = context.payload.label?.name; + if (!labelName || !(labelName in COMMENTS)) { + core.info(`Label "${labelName}" is not a close-on-label trigger, skipping`); + return; + } + + const pr = context.payload.pull_request; + if (pr.state !== "open") { + core.info(`PR #${pr.number} is already ${pr.state}, skipping`); + return; + } + + const body = COMMENTS[labelName](pr.user.login); + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body, + }); + await github.rest.pulls.update({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: pr.number, + state: "closed", + }); + core.info(`Closed PR #${pr.number} after "${labelName}" label was applied`);