Skip to content
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2348a86
ci: fix Claude Code Review workflow to post PR comments
tianjianjiang Nov 1, 2025
76b6d1e
ci: skip fork PRs gracefully and allow workflow self-testing
tianjianjiang Nov 1, 2025
44bbfda
ci: restore paths-ignore to prevent OIDC validation errors
tianjianjiang Nov 1, 2025
cf370da
ci: switch to MCP GitHub tools for reliable PR review posting
tianjianjiang Nov 1, 2025
d7a697f
ci: add mcp__github__get_pull_request to claude.yml for consistency
tianjianjiang Nov 1, 2025
3ee085e
ci: refactor to reusable workflow and add mcp__github__get_me
tianjianjiang Nov 2, 2025
02e01cd
style: use multiline yaml per Coplit review
tianjianjiang Nov 2, 2025
b67b868
ci: fix action syntax per Copilot review
tianjianjiang Nov 2, 2025
119bd35
ci: replicate permissions per Copilot review
tianjianjiang Nov 2, 2025
2ddad7e
ci: replicate permissions per Copilot review
tianjianjiang Nov 2, 2025
d330005
ci: add mcp__github__list_pull_requests to prevent permission denials
tianjianjiang Nov 2, 2025
632b4d1
ci: fix permissions for Claude workflows to enable PR comment posting
tianjianjiang Nov 2, 2025
6ed24e4
ci: update actions/checkout to v5 in Claude reusable workflow
tianjianjiang Nov 2, 2025
ef58b77
ci: standardize Claude workflow permissions and fix OIDC validation
tianjianjiang Nov 2, 2025
ec00bd9
ci: add max-turns parameter to prevent Claude turn exhaustion
tianjianjiang Nov 2, 2025
bd74079
ci: add concurrency control to Claude workflows
tianjianjiang Nov 2, 2025
e89db76
ci: add timeout and error handling to Claude review step
tianjianjiang Nov 2, 2025
0a3e6e5
ci: add enhanced logging for Claude review results
tianjianjiang Nov 2, 2025
bdf7f15
ci: add workflow status reporting for Claude review failures
tianjianjiang Nov 2, 2025
2eb1eaa
c: apply suggestion from @Copilot
tianjianjiang Nov 2, 2025
9e25833
ci: fix YAML comment indentation in claude-code-review workflow
tianjianjiang Nov 2, 2025
204bd77
ci: fix event condition in reusable workflow failure reporting
tianjianjiang Nov 2, 2025
2b61375
ci: improve claude_args configuration readability in reusable workflow
tianjianjiang Nov 2, 2025
404049b
ci: improve error message readability in Claude failure reporting
tianjianjiang Nov 2, 2025
101f14b
ci: improve workflow conditions to reduce manual approval requirements
tianjianjiang Nov 2, 2025
779c3ab
ci: add Copilot bot exclusions to prevent manual approval triggers
tianjianjiang Nov 2, 2025
5a5cb03
ci: fix Copilot bot names to use correct GitHub identifiers
tianjianjiang Nov 2, 2025
a51d166
ci: remove deprecated claude_args_override parameter
tianjianjiang Nov 2, 2025
d001d47
ci: apply suggestion from @Copilot
tianjianjiang Nov 2, 2025
d8f97f3
ci: fix Claude workflow to only run on PR-related events
tianjianjiang Nov 2, 2025
395a7ff
ci: fix Copilot bot name to use correct GitHub Apps identifier
tianjianjiang Nov 2, 2025
9b36841
ci: remove redundant permissions from reusable workflow
tianjianjiang Nov 2, 2025
f66bc92
ci: enhance workflow conditions and add repository settings guidance
tianjianjiang Nov 2, 2025
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
123 changes: 68 additions & 55 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,68 +5,81 @@ on:
types: [opened, synchronize, reopened]
paths-ignore:
- '.github/workflows/claude-code-review.yml'
# Optional: Only run on specific file changes
# paths:
# - "src/**/*.ts"
# - "src/**/*.tsx"
# - "src/**/*.js"
# - "src/**/*.jsx"
- '.github/workflows/claude-review-reusable.yml'

concurrency:
group: claude-review-${{ github.event.pull_request.number }}
cancel-in-progress: true

# Note: This workflow skips when modifying Claude workflow files to avoid OIDC token validation errors.
# GitHub's security model requires workflow files using id-token: write to be identical
# to the version on the master branch. PRs that modify workflows cannot pass OIDC
# validation until merged. This is intentional security and cannot be bypassed.
# Workflow changes should be manually reviewed and will apply to future PRs after merge.
#
# Optional: Only run on specific file changes
# 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'
# Note: Fork PRs are automatically skipped because they cannot access repository
# secrets (CLAUDE_CODE_OAUTH_TOKEN) or generate OIDC tokens. This is GitHub's
# security model and cannot be overridden.
#
# For fork PRs, maintainers can:
# 1. Merge the PR first, then Claude will review on the next PR
# 2. Use the on-demand claude.yml workflow by commenting @claude on the PR
# 3. Manually review the code
#
# This workflow only runs on PRs from branches within this repository.
# Skip for fork PRs and automated bots to avoid manual approval requirements
if: |
github.event.pull_request.head.repo.full_name == github.repository &&
!contains(fromJSON('["dependabot[bot]", "renovate[bot]", "github-actions[bot]", "copilot-pull-request-reviewer[bot]", "github-copilot[bot]", "copilot-autofix[bot]"]'), github.actor)

Comment thread
tianjianjiang marked this conversation as resolved.
runs-on: ubuntu-latest
# Explicitly declare permissions required by the reusable workflow
permissions:
contents: read
pull-requests: read
issues: read
id-token: write

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:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
prompt: |
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}

Please review this PR focusing ONLY on critical issues. Use the repository's CLAUDE.md for conventions.

Review for:
- Potential bugs or logic errors
- Security vulnerabilities
- Performance problems
- Correctness issues
- Violations of repository coding standards
contents: read # Required for repository checkout
issues: read # Required for reading issue context
pull-requests: write # Required for posting PR reviews
actions: read # Required for Claude to read CI results
id-token: write # Required for OIDC token exchange
# Use the reusable workflow which contains the standardized MCP tool configuration
# This eliminates duplication and ensures consistency across all Claude workflows
uses: ./.github/workflows/claude-review-reusable.yml
with:
prompt: |
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}

Keep your response concise:
- Maximum 10 bullet points in summary
- Use inline comments with code suggestions for specific fixes
- Group similar issues together to avoid repetition
- Skip style/formatting nitpicks unless they impact security or performance
- No general observations, praise, or minor suggestions
Please review this PR focusing ONLY on critical issues. Use the repository's CLAUDE.md for conventions.

Format:
- Start with 1-2 sentence overview
- List only critical/high-priority issues as bullet points
- For each issue: what, where, why it matters, suggested fix
- End with sign-off: APPROVED or ISSUES FOUND
Review for:
- Potential bugs or logic errors
- Security vulnerabilities
- Performance problems
- Correctness issues
- Violations of repository coding standards

Use `gh pr comment` with your Bash tool to leave your concise review as a comment on the PR.
Keep your response concise:
- Focus on critical/high-priority issues only
- Use inline comments with code suggestions in GitHub's ```suggestion blocks for specific fixes
- Group similar issues together to avoid repetition
- Skip style/formatting nitpicks unless they impact security or performance
- No general observations, praise, or minor suggestions

# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://docs.claude.com/en/docs/claude-code/cli-reference for available options
claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)" --max-turns 5'
Use the GitHub review system to post your feedback:
1. Use `mcp__github__get_pull_request` to understand the PR context if needed
2. Use `mcp__github__get_me` to get authenticated user context if needed
3. Use `mcp__github__create_pending_pull_request_review` to start a pending review
4. Use `mcp__github__get_pull_request_diff` to see the code changes and line numbers
5. Use `mcp__github__add_comment_to_pending_review` for inline comments on specific lines
6. Use `mcp__github__submit_pending_pull_request_review` with event type "COMMENT" to publish

When suggesting code changes, use GitHub's ```suggestion blocks so authors can apply changes directly.
secrets:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
93 changes: 93 additions & 0 deletions .github/workflows/claude-review-reusable.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: Claude PR Review (Reusable)

# Reusable workflow for Claude Code PR reviews
# Used by both claude.yml and claude-code-review.yml to maintain consistency
# and eliminate duplication of MCP tool configuration.

on:
workflow_call:
inputs:
prompt:
description: 'The prompt to send to Claude for PR review'
required: true
type: string
claude_args:
description: 'Claude arguments for the review'
required: false
type: string
default: '--max-turns 10 --allowedTools mcp__github__get_me,mcp__github__get_pull_request,mcp__github__list_pull_requests,mcp__github__create_pending_pull_request_review,mcp__github__get_pull_request_diff,mcp__github__add_comment_to_pending_review,mcp__github__submit_pending_pull_request_review'
Comment thread
tianjianjiang marked this conversation as resolved.
secrets:
CLAUDE_CODE_OAUTH_TOKEN:
description: 'OAuth token for Claude Code authentication'
required: true

jobs:
review:
runs-on: ubuntu-latest
# Note: Permissions are inherited from calling workflows (claude.yml, claude-code-review.yml)
# Caller permissions take precedence over reusable workflow permissions

steps:
- name: Checkout repository
uses: actions/checkout@v5
Comment thread
tianjianjiang marked this conversation as resolved.
Comment thread
tianjianjiang marked this conversation as resolved.
Comment thread
tianjianjiang marked this conversation as resolved.
with:
fetch-depth: 1

- name: Run Claude Code Review
id: claude-review
timeout-minutes: 15
continue-on-error: true
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
prompt: ${{ inputs.prompt }}

# Standard configuration for GitHub PR reviews
# This is the single source of truth for Claude arguments across all workflows
#
# Parameters:
# - --max-turns 10: Increase turn limit to prevent exhaustion during complex reviews
#
# Tools included:
# - mcp__github__get_me: Get authenticated user context (prevents permission denials)
# - mcp__github__get_pull_request: Get PR metadata, title, description (context understanding)
# - mcp__github__list_pull_requests: List/search PRs in the repository (context discovery)
# - mcp__github__create_pending_pull_request_review: Start a pending review
# - mcp__github__get_pull_request_diff: Get code changes and line numbers for inline comments
# - mcp__github__add_comment_to_pending_review: Add inline review comments
# - mcp__github__submit_pending_pull_request_review: Publish the review
claude_args: ${{ inputs.claude_args }}

- name: Log Claude Review Results
if: always()
run: |
echo "Claude review completed with status: ${{ steps.claude-review.outcome }}"
echo "Claude review conclusion: ${{ steps.claude-review.conclusion }}"
if [ "${{ steps.claude-review.outcome }}" = "failure" ]; then
echo "Claude review failed - check logs above for details"
elif [ "${{ steps.claude-review.outcome }}" = "success" ]; then
echo "Claude review completed successfully"
fi

- name: Report Claude Review Failure
if: steps.claude-review.outcome == 'failure'
uses: actions/github-script@v7
env:
FAILURE_MESSAGE: |
**Claude Code Review Failed**

The automated Claude review encountered an error and could not complete. You can:

- Check the [workflow logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details
- Trigger a manual review by commenting `@claude` on this PR
- The review will be retried automatically on the next push

This does not affect the PR approval process.
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: process.env.FAILURE_MESSAGE
})
79 changes: 31 additions & 48 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,59 +5,42 @@ on:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]

concurrency:
group: claude-manual-${{ github.event.pull_request.number || github.event.issue.number }}
Comment thread
tianjianjiang marked this conversation as resolved.
cancel-in-progress: true

jobs:
claude:
# Only trigger when @claude is mentioned in PR-related events
# Note: This workflow requires PR context and will not run on plain issues
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && github.event.issue.pull_request) ||
(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')))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write # Required for posting inline review comments
issues: read
id-token: write
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:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

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

# Enable inline review comments with suggestions for PR reviews
# When @claude is mentioned in PR comments, it will provide detailed inline feedback
prompt: |
Please review this PR and provide inline feedback using the GitHub review system. Follow these steps:

1. **Start a review**: Use `mcp__github__create_pending_pull_request_review` to begin a pending review
2. **Get diff information**: Use `mcp__github__get_pull_request_diff` to understand the code changes and line numbers
3. **Add inline comments**: Use `mcp__github__add_comment_to_pending_review` for each specific piece of feedback on particular lines
4. **Submit the review**: Use `mcp__github__submit_pending_pull_request_review` with event type "COMMENT" (not "REQUEST_CHANGES") to publish all comments as a non-blocking review

When suggesting code changes, use GitHub's suggestion format with ```suggestion blocks so authors can apply changes directly.

# Enable GitHub MCP server tools for inline review comments
# See: https://github.com/anthropics/claude-code-action/issues/60
claude_args: >-
--allowedTools
mcp__github__create_pending_pull_request_review,
mcp__github__get_pull_request_diff,
mcp__github__add_comment_to_pending_review,
mcp__github__submit_pending_pull_request_review
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude'))

Comment thread
tianjianjiang marked this conversation as resolved.
permissions:
contents: read # Required for repository checkout
issues: read # Required for reading issue context
pull-requests: write # Required for posting PR reviews
actions: read # Required for Claude to read CI results
id-token: write # Required for OIDC token exchange
# Use the reusable workflow which contains the standardized MCP tool configuration
# This eliminates duplication and ensures consistency across all Claude workflows
uses: ./.github/workflows/claude-review-reusable.yml
Comment thread
tianjianjiang marked this conversation as resolved.
with:
prompt: |
Please review this PR and provide inline feedback using the GitHub review system. Follow these steps:

1. **Get PR context** (optional): Use `mcp__github__get_pull_request` to understand the PR's purpose, title, and description
2. **Get user context** (optional): Use `mcp__github__get_me` to understand the authenticated user
3. **Start a review**: Use `mcp__github__create_pending_pull_request_review` to begin a pending review
4. **Get diff information**: Use `mcp__github__get_pull_request_diff` to understand the code changes and line numbers
5. **Add inline comments**: Use `mcp__github__add_comment_to_pending_review` for each specific piece of feedback on particular lines
6. **Submit the review**: Use `mcp__github__submit_pending_pull_request_review` with event type "COMMENT" (not "REQUEST_CHANGES") to publish all comments as a non-blocking review

When suggesting code changes, use GitHub's suggestion format with ```suggestion blocks so authors can apply changes directly.
secrets:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}