# AI Code Review Workflow # Uses anthropics/claude-code-action with CLIProxy (localhost:8317) # Posts as ccs-agy-reviewer[bot] via GitHub App # # Triggers: # - Automatically when PR is opened, receives new commits, or is reopened # - Manually via /review comment on PR # - Manually via workflow_dispatch # # Note: Concurrency group cancels in-progress reviews when new commits arrive. # This prevents wasting resources on outdated code reviews. name: AI Code Review on: pull_request_target: types: [opened, synchronize, reopened] issue_comment: types: [created] workflow_dispatch: inputs: pr_number: description: 'PR number to review' required: true type: string # Smart concurrency: Prevents self-cancellation when bot posts review comment # # Problem: When the bot posts a review comment, GitHub fires an issue_comment event. # This new workflow run joins the same concurrency group and cancels the in-progress # run BEFORE job `if` conditions are evaluated - causing "operation was canceled" error. # # Solution: Non-actionable triggers (bot comments, comments without /review) get a # unique per-run group, while legitimate triggers share the PR-based group for proper # cancellation of outdated reviews. concurrency: group: >- ai-review-${{ github.event_name == 'issue_comment' && ( github.event.comment.user.type == 'Bot' || !contains(github.event.comment.body, '/review') ) && format('skip-{0}', github.run_id) || github.event.pull_request.number || github.event.issue.number || github.event.inputs.pr_number }} cancel-in-progress: true jobs: review: name: Claude Code Review runs-on: [self-hosted, cliproxy] permissions: contents: read pull-requests: write issues: write id-token: write # Conditions: # - PR event: on opened, synchronize (new commits), or reopened # - Comment event: only if it's a PR, contains /review, and NOT from a bot if: > github.event_name == 'pull_request_target' || github.event_name == 'workflow_dispatch' || (github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '/review') && github.event.comment.user.type != 'Bot') # CLIProxy environment for model routing env: ANTHROPIC_BASE_URL: http://localhost:8317 REVIEW_MODEL: claude-opus-4-6-thinking ANTHROPIC_AUTH_TOKEN: ccs-internal-managed ANTHROPIC_MODEL: claude-opus-4-6-thinking ANTHROPIC_DEFAULT_OPUS_MODEL: claude-opus-4-6-thinking ANTHROPIC_DEFAULT_SONNET_MODEL: claude-sonnet-4-5-thinking ANTHROPIC_DEFAULT_HAIKU_MODEL: claude-sonnet-4-5 DISABLE_BUG_COMMAND: "1" DISABLE_ERROR_REPORTING: "1" DISABLE_TELEMETRY: "1" CLAUDE_CODE_MAX_OUTPUT_TOKENS: "64000" MAX_THINKING_TOKENS: "32000" steps: - name: Clear Claude install locks run: rm -rf ~/.local/state/claude/locks/* 2>/dev/null || true - name: Generate App Token id: app-token uses: actions/create-github-app-token@v1 with: app-id: ${{ secrets.CCS_REVIEWER_APP_ID }} private-key: ${{ secrets.CCS_REVIEWER_PRIVATE_KEY }} - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - name: Checkout PR code env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | PR_NUM="${{ github.event.pull_request.number || github.event.issue.number || github.event.inputs.pr_number }}" if [ -n "$PR_NUM" ]; then gh pr checkout $PR_NUM || git checkout ${{ github.event.pull_request.head.sha }} 2>/dev/null || true fi - name: Add reaction to comment if: github.event_name == 'issue_comment' run: | gh api repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \ --method POST -f content=eyes env: GH_TOKEN: ${{ steps.app-token.outputs.token }} - name: Run Claude Code Review id: claude-review uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.CLIPROXY_API_KEY }} github_token: ${{ steps.app-token.outputs.token }} path_to_claude_code_executable: /home/github-runner/.local/bin/claude track_progress: false # Disabled - no progress comments, just final review prompt: | ultrathink REPO: ${{ github.repository }} PR NUMBER: ${{ github.event.pull_request.number || github.event.issue.number || github.event.inputs.pr_number }} Perform a comprehensive code review. Follow the repository's CLAUDE.md for project-specific guidelines. ## Review Focus Areas 1. ๐Ÿ”’ **Security** - OWASP Top 10, injection, auth bypass, secrets exposure 2. โœ… **Correctness** - Logic errors, edge cases, error handling 3. ๐Ÿ—๏ธ **Architecture** - Coupling, cohesion, API contracts, backward compatibility 4. ๐Ÿงช **Testing** - Coverage, edge cases, test quality 5. โšก **Performance** - Algorithm complexity, memory leaks, query efficiency 6. ๐Ÿ“– **Maintainability** - Naming, complexity, consistency with codebase ## Output Structure Use visual hierarchy with emojis and `---` separators between major sections: - ๐Ÿ“‹ **Summary** (2-3 sentences) - โœ… **Strengths** (numbered, with file:line references, use โญ for exceptional items) - ๐Ÿ” **Observations & Suggestions** (with code examples, priority tags) - ๐Ÿ”’ **Security Considerations** (โœ…/โŒ checklist table) - ๐Ÿ“Š **Code Quality Checklist** (โœ…/โŒ table format) - ๐Ÿ’ก **Recommendations** (๐Ÿ”ด High / ๐ŸŸก Medium / ๐ŸŸข Low priority) - ๐ŸŽฏ **Overall Assessment** (โœ… APPROVED / โš ๏ธ APPROVED WITH NOTES / โŒ CHANGES REQUESTED) Be thorough but concise. Skip empty sections. Include code examples for non-trivial suggestions. Use tables for checklists. Bold important terms. Make the review visually scannable. End your review with: > ๐Ÿค– Reviewed by `${{ env.REVIEW_MODEL }}` ## IMPORTANT: Posting the Review After completing your analysis, post the review as a PR comment. STEP 1: First, use the Read tool to check if pr_review.md exists (it may not exist yet, that's OK) STEP 2: Use the Write tool to write your review to pr_review.md in the current working directory STEP 3: Post with: gh pr comment ${{ github.event.pull_request.number || github.event.issue.number || github.event.inputs.pr_number }} --body-file pr_review.md IMPORTANT RULES: - Write to pr_review.md (in working directory), NOT /tmp/pr_review.md - Do NOT use shell operators like || or && in bash commands - Do NOT use heredoc (<<) syntax in bash commands - Use simple, single-purpose bash commands only claude_args: | --model ${{ env.REVIEW_MODEL }} --allowedTools "Edit,Glob,Grep,LS,Read,Write,Bash(gh pr comment *),Bash(gh pr diff *),Bash(gh pr view *),Bash(gh issue view *),Bash(gh api *),Bash(git diff *),Bash(git log *),Bash(git status *),Bash(cat *),Bash(ls *),Bash(rm pr_review.md)" continue-on-error: true - name: Add success reaction if: success() && github.event_name == 'issue_comment' run: | gh api repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \ --method POST -f content=rocket env: GH_TOKEN: ${{ steps.app-token.outputs.token }} - name: Add failure reaction if: failure() && github.event_name == 'issue_comment' run: | gh api repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \ --method POST -f content=confused env: GH_TOKEN: ${{ steps.app-token.outputs.token }}