fix(analyze): contain staged embedding writes to clean generation #1620
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Claude Code | |
| # Label-triggered code-review requests use pull_request_target so the workflow | |
| # runs as defined on the default branch, which allows access to secrets for | |
| # posting review comments on fork PRs. SECURITY: PR checkouts pin the fork's | |
| # HEAD SHA (not the branch name) to prevent TOCTOU races. | |
| # The claude-code-action sandboxes execution; it does not run arbitrary code | |
| # from the checked-out source. | |
| on: | |
| issue_comment: | |
| types: [created] | |
| pull_request_target: | |
| types: [labeled] | |
| pull_request_review_comment: | |
| types: [created] | |
| issues: | |
| types: [opened, assigned] | |
| pull_request_review: | |
| types: [submitted] | |
| permissions: | |
| contents: read | |
| # Concurrency convention: see CONTRIBUTING.md → "GitHub Actions — Concurrency Convention". | |
| # Serialize per-PR/issue to avoid racing comments. | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.issue.number || github.event.pull_request.number || github.event.issue.id }} | |
| cancel-in-progress: false | |
| jobs: | |
| claude: | |
| if: | | |
| ( | |
| github.event_name == 'issue_comment' && | |
| ( | |
| contains(github.event.comment.body, '@claude') || | |
| (github.event.issue.pull_request && contains(github.event.comment.body, '/review')) | |
| ) && | |
| (github.event.comment.author_association == 'OWNER' || | |
| github.event.comment.author_association == 'MEMBER' || | |
| github.event.comment.author_association == 'COLLABORATOR') | |
| ) || | |
| ( | |
| github.event_name == 'pull_request_review_comment' && | |
| contains(github.event.comment.body, '@claude') && | |
| (github.event.comment.author_association == 'OWNER' || | |
| github.event.comment.author_association == 'MEMBER' || | |
| github.event.comment.author_association == 'COLLABORATOR') | |
| ) || | |
| ( | |
| github.event_name == 'pull_request_review' && | |
| contains(github.event.review.body, '@claude') && | |
| (github.event.review.author_association == 'OWNER' || | |
| github.event.review.author_association == 'MEMBER' || | |
| github.event.review.author_association == 'COLLABORATOR') | |
| ) || | |
| ( | |
| github.event_name == 'issues' && | |
| (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) && | |
| (github.event.issue.author_association == 'OWNER' || | |
| github.event.issue.author_association == 'MEMBER' || | |
| github.event.issue.author_association == 'COLLABORATOR') | |
| ) || | |
| ( | |
| github.event_name == 'pull_request_target' && | |
| github.event.label.name == 'claude-review' && | |
| github.event.pull_request.draft == false && | |
| (github.event.pull_request.author_association == 'OWNER' || | |
| github.event.pull_request.author_association == 'MEMBER' || | |
| github.event.pull_request.author_association == 'COLLABORATOR') | |
| ) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| id-token: write | |
| actions: read # required for Claude to read CI results on PRs | |
| steps: | |
| # For PR-related triggers, resolve the fork repo so we can checkout correctly. | |
| - name: Resolve PR context | |
| id: pr | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v7 | |
| with: | |
| script: | | |
| // Determine if this event is PR-related | |
| let pr = null; | |
| if (context.eventName === 'issue_comment' && context.payload.issue.pull_request) { | |
| const resp = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.payload.issue.number, | |
| }); | |
| pr = resp.data; | |
| } else if (context.eventName === 'pull_request_review_comment') { | |
| pr = context.payload.pull_request; | |
| } else if (context.eventName === 'pull_request_review') { | |
| pr = context.payload.pull_request; | |
| } else if (context.eventName === 'pull_request_target') { | |
| pr = context.payload.pull_request; | |
| } | |
| if (!pr) { | |
| core.setOutput('is_pr', 'false'); | |
| return; | |
| } | |
| core.setOutput('is_pr', 'true'); | |
| core.setOutput('number', String(pr.number)); | |
| core.setOutput('sha', pr.head.sha); | |
| core.setOutput('repo', pr.head.repo.full_name); | |
| core.setOutput('branch', pr.head.ref); | |
| - name: Resolve Claude mode | |
| id: mode | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v7 | |
| with: | |
| script: | | |
| const body = (context.payload.comment?.body ?? '').toLowerCase(); | |
| const isCodeReview = | |
| (context.eventName === 'pull_request_target' && | |
| context.payload.label?.name === 'claude-review') || | |
| (context.eventName === 'issue_comment' && | |
| Boolean(context.payload.issue?.pull_request) && | |
| body.includes('/review')); | |
| core.setOutput('code_review', isCodeReview ? 'true' : 'false'); | |
| - name: Checkout repository | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| repository: ${{ steps.pr.outputs.is_pr == 'true' && steps.pr.outputs.repo || github.repository }} | |
| ref: ${{ steps.pr.outputs.is_pr == 'true' && steps.pr.outputs.sha || '' }} | |
| fetch-depth: 1 | |
| - name: Run Claude Code | |
| if: steps.mode.outputs.code_review != 'true' | |
| id: claude | |
| uses: anthropics/claude-code-action@9469d113c6afd29550c402740f22d1a97dd1209b # v1 | |
| with: | |
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| allowed_non_write_users: '*' | |
| show_full_output: true | |
| # This is an optional setting that allows Claude to read CI results on PRs | |
| additional_permissions: | | |
| actions: read | |
| - name: Run Claude Code Review | |
| if: steps.mode.outputs.code_review == 'true' | |
| id: claude-review | |
| uses: anthropics/claude-code-action@9469d113c6afd29550c402740f22d1a97dd1209b # v1 | |
| with: | |
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| allowed_non_write_users: '*' | |
| show_full_output: true | |
| # Review posts use Bash (`gh`, etc.); default mode asks for approval — impossible in CI. | |
| claude_args: '--dangerously-skip-permissions' | |
| plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' | |
| plugins: 'code-review@claude-code-plugins' | |
| prompt: '/code-review:code-review https://github.com/${{ github.repository }}/pull/${{ steps.pr.outputs.number }} --comment' |