From fa9ba8925c3d2823f7e46b66ba728a32d30b5802 Mon Sep 17 00:00:00 2001 From: Gergo Magyar Date: Mon, 9 Mar 2026 15:33:41 +0000 Subject: [PATCH] fix(ci): support fork PRs in Claude Code Review workflow claude-code-action fetches branches by name from origin, which fails for fork PRs since the branch only exists on the fork remote. Work around by detecting fork PRs and temporarily pushing the branch to origin before the action runs, then cleaning up afterwards. Also changed trigger from automatic (every push) to on-demand only (label "claude-review" or comment "@claude" / "/review"). --- .github/workflows/claude-code-review.yml | 29 ++++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 0b48f0e6f..afa25cffd 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -41,30 +41,33 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 permissions: - contents: read + contents: write # needed to push fork branch to origin pull-requests: write issues: read id-token: write steps: - # For issue_comment triggers, resolve the PR number and head SHA + # For issue_comment triggers, resolve the PR number, head SHA, and branch name - name: Resolve PR context id: pr uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 with: script: | + let pr; if (context.eventName === 'issue_comment') { - const pr = await github.rest.pulls.get({ + const resp = await github.rest.pulls.get({ owner: context.repo.owner, repo: context.repo.repo, pull_number: context.payload.issue.number, }); - core.setOutput('number', pr.data.number); - core.setOutput('sha', pr.data.head.sha); + pr = resp.data; } else { - core.setOutput('number', context.payload.pull_request.number); - core.setOutput('sha', context.payload.pull_request.head.sha); + pr = context.payload.pull_request; } + core.setOutput('number', pr.number); + core.setOutput('sha', pr.head.sha); + core.setOutput('branch', pr.head.ref); + core.setOutput('is_fork', String(pr.head.repo.full_name !== pr.base.repo.full_name)); - name: Checkout PR head uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 @@ -72,6 +75,13 @@ jobs: ref: ${{ steps.pr.outputs.sha }} fetch-depth: 1 + # claude-code-action fetches branches by name from origin, which fails + # for fork PRs. Work around by pushing the fork branch to origin so + # the action can find it. Cleaned up in the post step below. + - name: Push fork branch to origin + if: steps.pr.outputs.is_fork == 'true' + run: git push origin HEAD:refs/heads/${{ steps.pr.outputs.branch }} + - name: Run Claude Code Review id: claude-review uses: anthropics/claude-code-action@9469d113c6afd29550c402740f22d1a97dd1209b # v1 @@ -80,3 +90,8 @@ jobs: plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' plugins: 'code-review@claude-code-plugins' prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ steps.pr.outputs.number }}' + + # Clean up the temporary branch we pushed for fork PRs + - name: Delete fork branch from origin + if: always() && steps.pr.outputs.is_fork == 'true' + run: git push origin --delete refs/heads/${{ steps.pr.outputs.branch }} || true