From ef799fd57a77ff34eba85cae283267fb98543ad4 Mon Sep 17 00:00:00 2001 From: Shadow Date: Thu, 30 Apr 2026 18:32:23 -0500 Subject: [PATCH] ci: exclude app PRs from active limit --- .github/workflows/labeler.yml | 19 ++++++++++++++++ scripts/github/barnacle-auto-response.mjs | 23 ++++++++++++++++---- test/scripts/barnacle-auto-response.test.ts | 24 +++++++++++++++++++++ 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index dbc38db73ec..2b492cac80a 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -296,6 +296,25 @@ jobs: .filter((name) => typeof name === "string"), ); + if (pullRequest.user?.type === "Bot" || /\[bot\]$/i.test(authorLogin) || authorLogin.startsWith("app/")) { + if (labelNames.has(activePrLimitLabel)) { + try { + await github.rest.issues.removeLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pullRequest.number, + name: activePrLimitLabel, + }); + } catch (error) { + if (error?.status !== 404) { + throw error; + } + } + } + core.info(`Skipping active PR limit for GitHub App author ${authorLogin}.`); + return; + } + if (labelNames.has(activePrLimitOverrideLabel)) { if (labelNames.has(activePrLimitLabel)) { try { diff --git a/scripts/github/barnacle-auto-response.mjs b/scripts/github/barnacle-auto-response.mjs index 710ab15f7a8..7d67b40b8c4 100644 --- a/scripts/github/barnacle-auto-response.mjs +++ b/scripts/github/barnacle-auto-response.mjs @@ -728,10 +728,17 @@ async function applyPullRequestCandidateLabels(github, context, core, pullReques ); } +function isAutomationUser(user, fallbackLogin = "") { + const login = user?.login ?? fallbackLogin; + return user?.type === "Bot" || /\[bot\]$/i.test(login) || login.startsWith("app/"); +} + function isAutomationActor(context) { - const sender = context.payload.sender; - const login = sender?.login ?? context.actor ?? ""; - return sender?.type === "Bot" || /\[bot\]$/i.test(login); + return isAutomationUser(context.payload.sender, context.actor ?? ""); +} + +function isGitHubAppPullRequestAuthor(pullRequest) { + return isAutomationUser(pullRequest.user); } function candidateActionRuleForLabelSet(labelSet, preferredLabel = "") { @@ -975,6 +982,11 @@ export async function runBarnacleAutoResponse({ github, context, core = console return; } + if (isGitHubAppPullRequestAuthor(pullRequest)) { + await removeLabels(github, context, pullRequest.number, [activePrLimitLabel], labelSet); + core.info(`Skipping active PR limit for GitHub App-authored PR #${pullRequest.number}.`); + } + await applyPullRequestCandidateLabels(github, context, core, pullRequest, labelSet); if (labelSet.has(dirtyLabel)) { @@ -1061,7 +1073,10 @@ export async function runBarnacleAutoResponse({ github, context, core = console if (pullRequest && labelSet.has(activePrLimitOverrideLabel)) { labelSet.delete(activePrLimitLabel); } - if (pullRequest && isAutomationPullRequest(pullRequest)) { + if ( + pullRequest && + (isAutomationPullRequest(pullRequest) || isGitHubAppPullRequestAuthor(pullRequest)) + ) { await removeLabels(github, context, pullRequest.number, [activePrLimitLabel], labelSet); } diff --git a/test/scripts/barnacle-auto-response.test.ts b/test/scripts/barnacle-auto-response.test.ts index b3e8ccf3288..94d884a31d8 100644 --- a/test/scripts/barnacle-auto-response.test.ts +++ b/test/scripts/barnacle-auto-response.test.ts @@ -492,6 +492,30 @@ describe("barnacle-auto-response", () => { } }); + it("removes stale PR-limit labels from GitHub App-authored PRs", async () => { + const { calls, github } = barnacleGithub([file("README.md")]); + + await runBarnacleAutoResponse({ + github, + context: barnacleContext( + { + user: { + login: "renovate[bot]", + type: "Bot", + }, + }, + ["r: too-many-prs"], + ), + core: { + info: () => undefined, + }, + }); + + expect(calls.removeLabel).toContainEqual(expect.objectContaining({ name: "r: too-many-prs" })); + expect(calls.createComment).toEqual([]); + expect(calls.update).toEqual([]); + }); + it("still adds candidate labels to broad contributor PRs", async () => { const { calls, github } = barnacleGithub([ file("ui/src/app.ts"),