diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index af2c58de2..4e5d20606 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -1,5 +1,24 @@ name: Claude Code +# @claude runs only when a maintainer (OWNER/MEMBER/COLLABORATOR) explicitly mentions the +# bot in an issue, an issue comment, a PR review, or a PR review comment. It deliberately +# does NOT trigger on `pull_request_target`: +# - Anthropic's OIDC exchange is broken for that event (401 "Invalid OIDC token"; +# anthropics/claude-code-action#713), and +# - a PR-body `@claude` check self-triggered it, because bot-authored PR descriptions +# carry attribution text like "Generated by the @claude workflow". Attribution text +# must never be interpreted as a command. +# If automatic PR-open reviews are wanted later, add a dedicated workflow with a fixed +# prompt rather than reading a PR body for `@claude`. +# +# Separate known limitation — CI does not auto-run on @claude-authored PRs. The bot pushes +# its branch with GITHUB_TOKEN, GitHub does not fire `push` workflows for GITHUB_TOKEN +# pushes, and test.yml is push-only, so a claude/** branch never runs the test suite and +# the PR looks mergeable while unvalidated. The setup steps below let @claude self-verify +# in-run (partial mitigation); still verify @claude PRs locally, or re-push the branch with +# a human token to trigger test.yml, before merging. Proper fix: push with a PAT/App token +# as the action's github_token. + on: issue_comment: types: [created] @@ -9,8 +28,6 @@ on: types: [opened, assigned] pull_request_review: types: [submitted] - pull_request_target: - types: [opened, synchronize] env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" @@ -22,18 +39,14 @@ jobs: (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || - (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) || - (github.event_name == 'pull_request_target' && contains(github.event.pull_request.body, '@claude')) + (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) ) && ( github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR' || github.event.sender.author_association == 'OWNER' || github.event.sender.author_association == 'MEMBER' || - github.event.sender.author_association == 'COLLABORATOR' || - github.event.pull_request.author_association == 'OWNER' || - github.event.pull_request.author_association == 'MEMBER' || - github.event.pull_request.author_association == 'COLLABORATOR' + github.event.sender.author_association == 'COLLABORATOR' ) runs-on: ubuntu-latest permissions: @@ -49,10 +62,28 @@ jobs: - name: Checkout repository uses: actions/checkout@v6 with: - # For pull_request_target, checkout the PR head to review the actual changes - ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || github.sha }} fetch-depth: 1 + # Provision the toolchain @claude needs to self-verify a change before pushing. + # Without this the runner has no just/uv, so a run burns its whole time budget on + # pip workarounds and can time out AFTER writing the code but BEFORE committing + # (that is what happened on the first #1011 run). Mirrors test.yml's known-good setup. + - name: Set up Python 3.12 + uses: actions/setup-python@v6 + with: + python-version: "3.12" + cache: "pip" + + - name: Install uv + run: pip install uv + + - uses: extractions/setup-just@v4 + + - name: Create virtual env and install dependencies + run: | + uv venv + uv pip install -e ".[dev]" + - name: Run Claude Code id: claude uses: anthropics/claude-code-action@v1