diff --git a/.github/workflows/ai-review.yml b/.github/workflows/ai-review.yml index 934f0bb2..ab307fcf 100644 --- a/.github/workflows/ai-review.yml +++ b/.github/workflows/ai-review.yml @@ -1,20 +1,11 @@ # 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] + pull_request: + types: [opened, synchronize, ready_for_review, reopened] issue_comment: types: [created] workflow_dispatch: @@ -24,15 +15,6 @@ on: 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-${{ @@ -48,7 +30,6 @@ concurrency: jobs: review: - name: Claude Code Review runs-on: [self-hosted, cliproxy] permissions: contents: read @@ -56,36 +37,24 @@ jobs: 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 == 'pull_request' || 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: gemini-claude-opus-4-5-thinking ANTHROPIC_AUTH_TOKEN: ccs-internal-managed ANTHROPIC_MODEL: gemini-claude-opus-4-5-thinking ANTHROPIC_DEFAULT_OPUS_MODEL: gemini-claude-opus-4-5-thinking ANTHROPIC_DEFAULT_SONNET_MODEL: gemini-claude-sonnet-4-5-thinking ANTHROPIC_DEFAULT_HAIKU_MODEL: gemini-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 @@ -94,99 +63,49 @@ jobs: private-key: ${{ secrets.CCS_REVIEWER_PRIVATE_KEY }} - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: - fetch-depth: 0 + fetch-depth: 1 - - 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 + - name: PR Review uses: anthropics/claude-code-action@v1 with: - anthropic_api_key: ${{ secrets.CLIPROXY_API_KEY }} + anthropic_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 + track_progress: true 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. + Perform a comprehensive code review with the following focus areas: - ## Review Focus Areas + 1. **Code Quality** + - Clean code principles and best practices + - Proper error handling and edge cases + - Code readability and maintainability - 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 + 2. **Security** + - Check for potential security vulnerabilities + - Validate input sanitization + - Review authentication/authorization logic - ## Output Structure + 3. **Performance** + - Identify potential performance bottlenecks + - Review database queries for efficiency + - Check for memory leaks or resource issues - 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) + 4. **Testing** + - Verify adequate test coverage + - Review test quality and edge cases + - Check for missing test scenarios - 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. + 5. **Documentation** + - Ensure code is properly documented + - Verify README updates for new features + - Check API documentation accuracy - 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 + Provide detailed feedback using inline comments for specific issues. + Use top-level comments for general observations or praise. 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 }}