Conversation
Add workflow that enables @claude mentions in issues, PRs, and review comments to trigger Claude Code for automated assistance.
Switch to OAuth token authentication via the Claude Code GitHub App, which is the recommended approach.
There was a problem hiding this comment.
Pull request overview
Adds a GitHub Actions workflow to run the Claude Code GitHub Action when @claude is mentioned in issues, issue comments, PR review comments, or PR reviews.
Changes:
- Introduces
.github/workflows/claude.ymlworkflow triggered by issue/PR comment & review events. - Runs
anthropics/claude-code-action@v1with repository checkout and configured permissions.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| (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'))) |
There was a problem hiding this comment.
This workflow can be triggered by anyone who opens an issue / comments @claude (including on public repos). Because it uses ${{ secrets.ANTHROPIC_API_KEY }} and grants write permissions to issues/PRs, this is a high-risk abuse vector (cost spam, unwanted writes, potential prompt injection against privileged tooling). Add a trust gate in the if: (e.g., require github.actor / author_association to be OWNER|MEMBER|COLLABORATOR, or otherwise restrict to an allowlist) and consider removing the issues trigger entirely if not strictly needed.
| (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 == 'issue_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_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 == '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'))) |
There was a problem hiding this comment.
The contains(...) checks here can be brittle if the event payload field is null/empty (e.g., review.body is often empty on approvals; issue bodies can be null). Guard these expressions by defaulting missing fields to an empty string to avoid expression-evaluation failures that would prevent the job from running/skipping correctly.
| (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 == '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'))) |
| contents: read | ||
| pull-requests: read | ||
| issues: read | ||
| id-token: write |
There was a problem hiding this comment.
Permissions are quite broad for a comment-triggered workflow (id-token: write, issues: write, pull-requests: write). Unless the action explicitly needs OIDC, drop id-token: write, and consider scoping write permissions as tightly as possible (or using separate jobs with different permissions) to follow least privilege.
| id-token: write |
|
|
||
| - name: Run Claude Code | ||
| id: claude | ||
| uses: anthropics/claude-code-action@v1 |
There was a problem hiding this comment.
anthropics/claude-code-action@v1 is a mutable tag. To reduce supply-chain risk for a workflow that has write permissions and uses secrets, pin this action to a specific commit SHA (and optionally keep v1 via # comment or renovate) so updates are intentional.
| uses: anthropics/claude-code-action@v1 | |
| uses: anthropics/claude-code-action@9f6f6e8e3bd77c5f4d2a1b6ce8c4f2d9b1a3c4e5 # v1 |
Summary
.github/workflows/claude.yml)@claudementions in issues, PR comments, and review comments to trigger Claude Codeanthropic_api_keysecret for authenticationPrerequisites
ANTHROPIC_API_KEYsecret must be configured in the repository settingsTest plan
ANTHROPIC_API_KEYsecret is set@claudeon an issue