From 7db48b2ef299851a999671472a8ec1bffe8c7b4c Mon Sep 17 00:00:00 2001 From: Don Petry <36422719+don-petry@users.noreply.github.com> Date: Sun, 10 May 2026 22:57:02 -0500 Subject: [PATCH 1/3] fix(claude): add copilot-pull-request-reviewer and gemini-code-assist to bot allow list The pull_request_review_comment condition allowed coderabbitai[bot] and Copilot but missed two other active review bots: - copilot-pull-request-reviewer[bot]: GitHub Copilot PR review app - gemini-code-assist[bot]: Google Gemini code review app Both are installed org-wide and regularly leave actionable review comments that Claude should respond to. Without these entries their comments caused the 'claude' job to be skipped every time. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/claude-code-reusable.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/claude-code-reusable.yml b/.github/workflows/claude-code-reusable.yml index 4d1fc9ff8..eecf0ae33 100644 --- a/.github/workflows/claude-code-reusable.yml +++ b/.github/workflows/claude-code-reusable.yml @@ -26,7 +26,7 @@ jobs: (github.event_name == 'pull_request_review_comment' && github.event.comment.user.login != 'claude[bot]' && (contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association) || - contains(fromJson('["coderabbitai[bot]","Copilot"]'), github.event.comment.user.login))) + contains(fromJson('["coderabbitai[bot]","Copilot","copilot-pull-request-reviewer[bot]","gemini-code-assist[bot]"]'), github.event.comment.user.login))) runs-on: ubuntu-latest timeout-minutes: 60 permissions: From 7d35b69679462555cd2565f09ec56877a2adcda0 Mon Sep 17 00:00:00 2001 From: Don Petry <36422719+don-petry@users.noreply.github.com> Date: Sun, 10 May 2026 23:03:06 -0500 Subject: [PATCH 2/3] fix(claude): guard bot allow list against fork PRs Per security review: bot logins have author_association 'NONE', so the new allow list could allow secrets-bearing runs triggered by bot comments on fork PRs. Add a same-repo guard so bot-triggered reviews only fire when the PR head is within the same repo. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/claude-code-reusable.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/claude-code-reusable.yml b/.github/workflows/claude-code-reusable.yml index eecf0ae33..57144b419 100644 --- a/.github/workflows/claude-code-reusable.yml +++ b/.github/workflows/claude-code-reusable.yml @@ -26,7 +26,8 @@ jobs: (github.event_name == 'pull_request_review_comment' && github.event.comment.user.login != 'claude[bot]' && (contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association) || - contains(fromJson('["coderabbitai[bot]","Copilot","copilot-pull-request-reviewer[bot]","gemini-code-assist[bot]"]'), github.event.comment.user.login))) + (github.event.pull_request.head.repo.full_name == github.repository && + contains(fromJson('["coderabbitai[bot]","Copilot","copilot-pull-request-reviewer[bot]","gemini-code-assist[bot]"]'), github.event.comment.user.login)))) runs-on: ubuntu-latest timeout-minutes: 60 permissions: From cf9a8e5229c61801e80a290ed8fad4adf82e4457 Mon Sep 17 00:00:00 2001 From: Don Petry <36422719+don-petry@users.noreply.github.com> Date: Sun, 10 May 2026 23:07:59 -0500 Subject: [PATCH 3/3] fix(claude-ci-fix): correct self-loop guard and add fork PR trust gate - Fix self-loop: check run names for reusable workflows are prefixed by the calling job name (e.g. 'claude-code / claude-ci-fix'), not by the workflow display name 'Claude Code'; switch to startsWith 'claude-code / ' - Add fork PR trust gate in Resolve PR number step: verify head.repo matches target repo before running Claude with privileged credentials Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/claude-code-reusable.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/claude-code-reusable.yml b/.github/workflows/claude-code-reusable.yml index 57144b419..4cf481efe 100644 --- a/.github/workflows/claude-code-reusable.yml +++ b/.github/workflows/claude-code-reusable.yml @@ -56,7 +56,7 @@ jobs: if: >- github.event_name == 'check_run' && github.event.check_run.conclusion == 'failure' && - !startsWith(github.event.check_run.name, 'Claude Code') + !startsWith(github.event.check_run.name, 'claude-code / ') concurrency: group: claude-ci-fix-${{ github.event.check_run.head_sha }} cancel-in-progress: true @@ -81,6 +81,15 @@ jobs: "repos/${{ github.repository }}/commits/${{ github.event.check_run.head_sha }}/pulls" \ --jq '[.[] | select(.state == "open")] | first | .number // empty') fi + # Trust gate: skip fork PRs — this job has write/secret access + if [ -n "$PR" ]; then + HEAD_REPO=$(gh api "repos/${{ github.repository }}/pulls/$PR" \ + --jq '.head.repo.full_name // empty') + if [ "$HEAD_REPO" != "${{ github.repository }}" ]; then + echo "Skipping: fork PR (head=$HEAD_REPO)" + PR="" + fi + fi echo "number=$PR" >> "$GITHUB_OUTPUT" - name: Checkout repository if: steps.pr.outputs.number != ''