From 89a385159fca4a8f6a06e5a752f3062653a63eb1 Mon Sep 17 00:00:00 2001 From: Joseph Schuchart Date: Fri, 17 Apr 2026 11:14:08 -0400 Subject: [PATCH] ci/backport: fix slash command permission check and update github-script getCollaboratorPermissionLevel requires org-level "Members" read permission, which GITHUB_TOKEN cannot provide for organization repos, causing "Resource not accessible by integration" on every invocation. Replace with a check on author_association (OWNER/MEMBER/COLLABORATOR), which is available directly in the webhook payload. Also upgrade all actions/github-script@v7 to @v8 (Node.js 20 is deprecated and will be removed 2026-09-16). Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Joseph Schuchart --- .github/workflows/backport-command.yaml | 31 +++++++------------------ .github/workflows/backport.yaml | 12 +++++----- 2 files changed, 15 insertions(+), 28 deletions(-) diff --git a/.github/workflows/backport-command.yaml b/.github/workflows/backport-command.yaml index c5738b2cd69..381a80a38a0 100644 --- a/.github/workflows/backport-command.yaml +++ b/.github/workflows/backport-command.yaml @@ -34,7 +34,7 @@ jobs: steps: - name: Parse command and validate PR id: parse - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | const body = context.payload.comment.body; @@ -54,30 +54,17 @@ jobs: return; } - // Check actual repository permission level rather than - // author_association: MEMBER alone does not imply write - // access on org-owned public repos. - let permission = 'none'; - try { - const { data } = await github.rest.repos.getCollaboratorPermissionLevel({ - owner: context.repo.owner, - repo: context.repo.repo, - username: login, - }); - // Use role_name rather than permission: the legacy - // permission field collapses 'maintain' into 'write', - // losing the distinction between the two tiers. - permission = data.role_name; // 'admin' | 'maintain' | 'write' | 'triage' | 'read' - } catch (err) { - if (err.status !== 404) throw err; - // 404 = not a collaborator; permission stays 'none' - } - if (!['admin', 'maintain', 'write'].includes(permission)) { + // Use author_association from the webhook payload — no extra + // API call required. GITHUB_TOKEN cannot call + // getCollaboratorPermissionLevel on org repos (needs org-level + // "Members" read permission unavailable to GITHUB_TOKEN). + const assoc = context.payload.comment.author_association; + if (!['OWNER', 'MEMBER', 'COLLABORATOR'].includes(assoc)) { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issueNumber, - body: `⚠️ @${login} Backports can only be triggered by users with write, maintain, or admin access.`, + body: `⚠️ @${login} Backports can only be triggered by repository owners, organization members, or collaborators.`, }); core.setOutput('triggered', 'false'); return; @@ -166,7 +153,7 @@ jobs: - name: Trigger backport workflow if: steps.parse.outputs.triggered == 'true' - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: PR_NUMBER: ${{ steps.parse.outputs.pr_number }} BRANCHES: ${{ steps.parse.outputs.branches }} diff --git a/.github/workflows/backport.yaml b/.github/workflows/backport.yaml index ebff4e66ace..724f678707b 100644 --- a/.github/workflows/backport.yaml +++ b/.github/workflows/backport.yaml @@ -54,7 +54,7 @@ jobs: steps: - name: Determine backport targets id: targets - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | let branches = []; @@ -137,7 +137,7 @@ jobs: # Use paginate() so PRs with more than 100 commits are handled correctly. - name: Fetch PR metadata id: pr_meta - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | const pr = await github.rest.pulls.get({ @@ -163,7 +163,7 @@ jobs: # work. Post a comment and skip if it does not. - name: Validate target branch exists id: validate - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | try { @@ -264,7 +264,7 @@ jobs: # All commits were already present in the target branch — no PR needed. - name: Comment when nothing to backport if: steps.cherry_pick.outputs.nothing_to_backport == 'true' - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | await github.rest.issues.createComment({ @@ -280,7 +280,7 @@ jobs: if: >- steps.cherry_pick.outputs.cherry_pick_failed == 'false' && steps.cherry_pick.outputs.nothing_to_backport == 'false' - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: ORIGINAL_TITLE: ${{ steps.pr_meta.outputs.title }} ORIGINAL_BODY: ${{ steps.pr_meta.outputs.body }} @@ -348,7 +348,7 @@ jobs: # developer knows to create the backport manually. - name: Comment on cherry-pick failure if: steps.cherry_pick.outputs.cherry_pick_failed == 'true' - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: FAILED_SHA: ${{ steps.cherry_pick.outputs.failed_sha }} with: