From 7f7424dd1e3ba71a2169e6d24f7c2ce00321518d Mon Sep 17 00:00:00 2001 From: Bryan Morgan Date: Sun, 15 Feb 2026 10:08:28 -0500 Subject: [PATCH] fix(workflows): fix GitHub App token permissions for maintainer detection (#19139) --- .../gemini-scheduled-stale-issue-closer.yml | 2 +- .../gemini-scheduled-stale-pr-closer.yml | 4 +- .../pr-contribution-guidelines-notifier.yml | 40 ++++++++++++++++--- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/.github/workflows/gemini-scheduled-stale-issue-closer.yml b/.github/workflows/gemini-scheduled-stale-issue-closer.yml index fe9032983b..c7aef65a73 100644 --- a/.github/workflows/gemini-scheduled-stale-issue-closer.yml +++ b/.github/workflows/gemini-scheduled-stale-issue-closer.yml @@ -27,7 +27,7 @@ jobs: steps: - name: 'Generate GitHub App Token' id: 'generate_token' - uses: 'actions/create-github-app-token@v1' + uses: 'actions/create-github-app-token@v2' with: app-id: '${{ secrets.APP_ID }}' private-key: '${{ secrets.PRIVATE_KEY }}' diff --git a/.github/workflows/gemini-scheduled-stale-pr-closer.yml b/.github/workflows/gemini-scheduled-stale-pr-closer.yml index bd7fd0ddc9..4198945159 100644 --- a/.github/workflows/gemini-scheduled-stale-pr-closer.yml +++ b/.github/workflows/gemini-scheduled-stale-pr-closer.yml @@ -23,12 +23,10 @@ jobs: steps: - name: 'Generate GitHub App Token' id: 'generate_token' - uses: 'actions/create-github-app-token@v1' + uses: 'actions/create-github-app-token@v2' with: app-id: '${{ secrets.APP_ID }}' private-key: '${{ secrets.PRIVATE_KEY }}' - owner: '${{ github.repository_owner }}' - repositories: 'gemini-cli' - name: 'Process Stale PRs' uses: 'actions/github-script@v7' diff --git a/.github/workflows/pr-contribution-guidelines-notifier.yml b/.github/workflows/pr-contribution-guidelines-notifier.yml index 2658520371..5ee1b37f57 100644 --- a/.github/workflows/pr-contribution-guidelines-notifier.yml +++ b/.github/workflows/pr-contribution-guidelines-notifier.yml @@ -19,7 +19,7 @@ jobs: APP_ID: '${{ secrets.APP_ID }}' if: |- ${{ env.APP_ID != '' }} - uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' # ratchet:actions/create-github-app-token@v2 + uses: 'actions/create-github-app-token@v2' with: app-id: '${{ secrets.APP_ID }}' private-key: '${{ secrets.PRIVATE_KEY }}' @@ -35,6 +35,37 @@ jobs: const pr_number = context.payload.pull_request.number; // 1. Check if the PR author is a maintainer + // Check team membership (most reliable for private org members) + let isTeamMember = false; + const teams = ['gemini-cli-maintainers', 'gemini-cli-askmode-approvers', 'gemini-cli-docs']; + for (const team_slug of teams) { + try { + const members = await github.paginate(github.rest.teams.listMembersInOrg, { + org: org, + team_slug: team_slug + }); + if (members.some(m => m.login.toLowerCase() === username.toLowerCase())) { + isTeamMember = true; + core.info(`${username} is a member of ${team_slug}. No notification needed.`); + break; + } + } catch (e) { + core.warning(`Failed to fetch team members from ${team_slug}: ${e.message}`); + } + } + + if (isTeamMember) return; + + // Check author_association from webhook payload + const authorAssociation = context.payload.pull_request.author_association; + const isRepoMaintainer = ['OWNER', 'MEMBER', 'COLLABORATOR'].includes(authorAssociation); + + if (isRepoMaintainer) { + core.info(`${username} is a maintainer (author_association: ${authorAssociation}). No notification needed.`); + return; + } + + // Check if author is a Googler const isGoogler = async (login) => { try { const orgs = ['googlers', 'google']; @@ -55,11 +86,8 @@ jobs: return false; }; - const authorAssociation = context.payload.pull_request.author_association; - const isRepoMaintainer = ['OWNER', 'MEMBER', 'COLLABORATOR'].includes(authorAssociation); - - if (isRepoMaintainer || await isGoogler(username)) { - core.info(`${username} is a maintainer or Googler. No notification needed.`); + if (await isGoogler(username)) { + core.info(`${username} is a Googler. No notification needed.`); return; }