Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Claude Code Review

on:
pull_request:
types: [opened, synchronize, ready_for_review, reopened]
# Optional: Only run on specific file changes
Comment on lines +3 to +6
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow runs on pull_request events but depends on secrets.ANTHROPIC_API_KEY. For PRs from forks, GitHub will not provide repository secrets, so the action will fail (or behave unexpectedly) on those PRs. Add a job-level guard to skip forked PRs (e.g., if: github.event.pull_request.head.repo.fork == false) and/or document that it only supports same-repo branches.

Copilot uses AI. Check for mistakes.
# paths:
# - "src/**/*.ts"
# - "src/**/*.tsx"
# - "src/**/*.js"
# - "src/**/*.jsx"

jobs:
claude-review:
# Optional: Filter by PR author
# if: |
# github.event.pull_request.user.login == 'external-contributor' ||
# github.event.pull_request.user.login == 'new-developer' ||
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'

runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
Comment on lines +24 to +26
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The job permissions are read-only (pull-requests: read, issues: read), but a code review action typically needs to publish a review comment back onto the PR. With read-only permissions it won't be able to post results via GITHUB_TOKEN. Grant the minimal required write permissions (usually pull-requests: write; add issues: write only if it posts to issues) and consider removing id-token: write unless OIDC is actually used.

Suggested change
pull-requests: read
issues: read
id-token: write
pull-requests: write
issues: read

Copilot uses AI. Check for mistakes.

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options

50 changes: 50 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Claude Code

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]
Comment on lines +3 to +11
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow can be triggered by anyone opening an issue or posting a comment containing @claude, which will run with secrets.ANTHROPIC_API_KEY available in the base repo context. This creates a real secret-exposure / prompt-injection risk and can also be abused to burn API quota. Restrict execution to trusted actors (e.g., check author_association/repo membership in the job if:) and/or remove the issues trigger (or limit to workflow_dispatch/maintainers only).

Copilot uses AI. Check for mistakes.

jobs:
claude:
if: |
(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')))
Comment on lines +16 to +19
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contains() is evaluated on fields that can be null/empty (e.g., github.event.review.body for a submitted review without text, or github.event.issue.body for an issue created without a body). In GitHub Actions expressions this can cause the job if: evaluation to fail. Coerce these to empty strings (e.g., ...body || '') or add explicit null checks before calling contains().

Suggested change
(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')))

Copilot uses AI. Check for mistakes.
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
Comment on lines +23 to +25
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The job permissions are set to pull-requests: read / issues: read, but this workflow is expected to respond back on PRs/issues when invoked. With read-only permissions, the action will be unable to create comments/reviews/status updates via the GITHUB_TOKEN. Grant the minimal required write scopes (typically pull-requests: write and/or issues: write), and consider dropping id-token: write unless the action is actually using OIDC.

Suggested change
pull-requests: read
issues: read
id-token: write
pull-requests: write
issues: write

Copilot uses AI. Check for mistakes.
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read
Comment on lines +39 to +42
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

additional_permissions requests actions: read, but the job already has actions: read in permissions. Keeping both is redundant and can confuse future maintenance; prefer a single source of truth (either rely on workflow permissions or remove the duplicated action input if it isn't required).

Suggested change
# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read

Copilot uses AI. Check for mistakes.
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
# prompt: 'Update the pull request description to include a summary of changes.'

# Optional: Add claude_args to customize behavior and configuration
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
# claude_args: '--allowed-tools Bash(gh pr:*)'

Loading