Skip to content

Commit c09ad78

Browse files
authored
feat: add claude code review workflow (#104)
* feat: implement GitHub issue #80 ephemeral password support with for_each This PR addresses GitHub issue #80 by providing comprehensive ephemeral password support: ## Changes Made 1. **Fix Terraform version requirement**: Updated to >= 1.11.0 for ephemeral resources support 2. **Add working user pattern**: Created ephemeral-for-each-example.tf demonstrating the solution 3. **Comprehensive documentation**: Added detailed explanations of limitations and workarounds 4. **Enhanced examples**: Updated README with advanced patterns and migration guidance ## Issue Resolution **Problem**: User wanted to use ephemeral random_password with for_each patterns in the module **Root Cause**: Terraform architectural limitation - ephemeral variables can't be used with for_each **Solution**: Provide direct AWS resources approach that achieves the same security goals ## Security Validation ✅ Ephemeral passwords never stored in Terraform state ✅ Write-only parameters prevent state persistence ✅ KMS encryption support maintained ✅ End-to-end testing validates security guarantees ## Files Added/Modified - versions.tf: Updated minimum Terraform version to >= 1.11.0 - examples/ephemeral/ephemeral-for-each-example.tf: Working solution for user's pattern - examples/ephemeral/README.md: Enhanced with advanced patterns documentation - examples/ephemeral/ephemeral-for-each-patterns.md: Technical analysis and solutions - examples/ephemeral/ephemeral-limitations.md: Detailed limitation explanations The implementation provides full ephemeral password functionality while working within Terraform's architectural constraints. * fix: correct terraform formatting issues - Fixed spacing and alignment in ephemeral-for-each-example.tf - Updated README references to use correct filename * docs: update README with Terraform >= 1.11.0 requirement - Updated by terraform_docs pre-commit hook to reflect version changes - Shows Terraform >= 1.11.0 requirement for ephemeral resources support * feat: add claude code review workflow Add GitHub Actions workflow for AI-powered code reviews with multiple modes: - Comment-triggered reviews (codebot hunt/analyze/security/performance/review) - Manual workflow dispatch via GitHub CLI - Supports comprehensive code quality and security analysis
1 parent ae939f9 commit c09ad78

1 file changed

Lines changed: 209 additions & 48 deletions

File tree

Lines changed: 209 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,239 @@
11
name: Claude Code Review
22

33
on:
4+
# Comment-based triggers (like Cursor's Bugbot)
5+
issue_comment:
6+
types: [created]
7+
pull_request_review_comment:
8+
types: [created]
49
pull_request:
510
types: [opened, synchronize]
6-
# Optional: Only run on specific file changes
7-
# paths:
8-
# - "src/**/*.ts"
9-
# - "src/**/*.tsx"
10-
# - "src/**/*.js"
11-
# - "src/**/*.jsx"
11+
12+
# Manual triggers via GitHub CLI
13+
workflow_dispatch:
14+
inputs:
15+
review_mode:
16+
description: 'Review mode to use'
17+
required: false
18+
default: 'hunt'
19+
type: choice
20+
options:
21+
- hunt
22+
- analyze
23+
- security
24+
- performance
25+
- review
26+
focus:
27+
description: 'Focus areas (comma-separated)'
28+
required: false
29+
default: 'bugs,security,performance'
30+
type: string
31+
verbose:
32+
description: 'Enable verbose output'
33+
required: false
34+
default: false
35+
type: boolean
1236

1337
jobs:
14-
claude-review:
15-
# Optional: Filter by PR author
16-
# if: |
17-
# github.event.pull_request.user.login == 'external-contributor' ||
18-
# github.event.pull_request.user.login == 'new-developer' ||
19-
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
20-
38+
# Handle workflow_dispatch by creating a comment to trigger Claude
39+
dispatch-trigger:
40+
if: github.event_name == 'workflow_dispatch'
41+
runs-on: ubuntu-latest
42+
permissions:
43+
pull-requests: write
44+
issues: write
45+
steps:
46+
- name: Find open PR
47+
id: find-pr
48+
run: |
49+
# Find the most recent open PR for this branch
50+
PR_NUMBER=$(gh pr list --repo ${{ github.repository }} --state open --head ${{ github.ref_name }} --json number --jq '.[0].number // empty')
51+
if [ -z "$PR_NUMBER" ]; then
52+
echo "No open PR found for branch ${{ github.ref_name }}"
53+
exit 1
54+
fi
55+
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
56+
env:
57+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58+
59+
- name: Create trigger comment
60+
run: |
61+
COMMENT_BODY="codebot ${{ github.event.inputs.review_mode || 'hunt' }}"
62+
if [ "${{ github.event.inputs.verbose }}" = "true" ]; then
63+
COMMENT_BODY="$COMMENT_BODY verbose"
64+
fi
65+
66+
gh pr comment ${{ steps.find-pr.outputs.pr_number }} --repo ${{ github.repository }} --body "$COMMENT_BODY"
67+
env:
68+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
69+
70+
claude:
71+
# Only run on comment triggers or specific PR conditions
72+
if: |
73+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, 'codebot')) ||
74+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, 'codebot')) ||
75+
(github.event_name == 'pull_request' && (
76+
github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' ||
77+
contains(github.event.pull_request.title, '[auto-review]')
78+
))
79+
2180
runs-on: ubuntu-latest
2281
permissions:
2382
contents: read
2483
pull-requests: read
2584
issues: read
2685
id-token: write
27-
86+
2887
steps:
2988
- name: Checkout repository
3089
uses: actions/checkout@v4
3190
with:
3291
fetch-depth: 1
3392

93+
- name: Parse comment command
94+
id: parse-command
95+
env:
96+
COMMENT_BODY: ${{ github.event.comment.body }}
97+
run: |
98+
# Default values
99+
echo "mode=review" >> $GITHUB_OUTPUT
100+
echo "focus=code-quality,security,performance" >> $GITHUB_OUTPUT
101+
echo "verbose=false" >> $GITHUB_OUTPUT
102+
echo "include_tests=true" >> $GITHUB_OUTPUT
103+
104+
# Parse comment content for commands
105+
if [ "${{ github.event_name }}" == "issue_comment" ] || [ "${{ github.event_name }}" == "pull_request_review_comment" ]; then
106+
COMMENT="$COMMENT_BODY"
107+
108+
# Extract command and parameters
109+
if echo "$COMMENT" | grep -qi "codebot hunt"; then
110+
echo "mode=hunt" >> $GITHUB_OUTPUT
111+
echo "focus=bugs,security,performance" >> $GITHUB_OUTPUT
112+
echo "verbose=false" >> $GITHUB_OUTPUT
113+
elif echo "$COMMENT" | grep -qi "codebot analyze"; then
114+
echo "mode=analyze" >> $GITHUB_OUTPUT
115+
echo "focus=architecture,patterns,complexity" >> $GITHUB_OUTPUT
116+
echo "verbose=true" >> $GITHUB_OUTPUT
117+
elif echo "$COMMENT" | grep -qi "codebot security"; then
118+
echo "mode=security" >> $GITHUB_OUTPUT
119+
echo "focus=security,vulnerabilities,compliance" >> $GITHUB_OUTPUT
120+
echo "verbose=true" >> $GITHUB_OUTPUT
121+
elif echo "$COMMENT" | grep -qi "codebot performance"; then
122+
echo "mode=performance" >> $GITHUB_OUTPUT
123+
echo "focus=performance,optimization,bottlenecks" >> $GITHUB_OUTPUT
124+
echo "verbose=true" >> $GITHUB_OUTPUT
125+
elif echo "$COMMENT" | grep -qi "codebot review"; then
126+
echo "mode=review" >> $GITHUB_OUTPUT
127+
echo "focus=code-quality,security,performance" >> $GITHUB_OUTPUT
128+
echo "verbose=true" >> $GITHUB_OUTPUT
129+
elif echo "$COMMENT" | grep -qi "codebot"; then
130+
# Default to hunt mode for simple "codebot" command
131+
echo "mode=hunt" >> $GITHUB_OUTPUT
132+
echo "focus=bugs,security,performance" >> $GITHUB_OUTPUT
133+
echo "verbose=false" >> $GITHUB_OUTPUT
134+
fi
135+
136+
# Check for verbose flag
137+
if echo "$COMMENT" | grep -qi "verbose\|detailed"; then
138+
echo "verbose=true" >> $GITHUB_OUTPUT
139+
fi
140+
141+
# Check for specific focus areas
142+
if echo "$COMMENT" | grep -qi "security"; then
143+
echo "focus=security,vulnerabilities,compliance" >> $GITHUB_OUTPUT
144+
elif echo "$COMMENT" | grep -qi "performance"; then
145+
echo "focus=performance,optimization,bottlenecks" >> $GITHUB_OUTPUT
146+
elif echo "$COMMENT" | grep -qi "tests"; then
147+
echo "focus=test-coverage,test-quality" >> $GITHUB_OUTPUT
148+
fi
149+
fi
150+
151+
152+
34153
- name: Run Claude Code Review
35-
id: claude-review
154+
id: claude
36155
uses: anthropics/claude-code-action@beta
37156
with:
38157
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
39158

40-
# Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4)
41-
# model: "claude-opus-4-20250514"
42-
43-
# Direct prompt for automated review (no @claude mention needed)
159+
# Optional: Add specific tools for running tests or linting
160+
# allowed_tools: "Bash(npm run test),Bash(npm run lint),Bash(npm run typecheck)"
161+
162+
# Dynamic prompt based on review mode
44163
direct_prompt: |
45-
Please review this pull request and provide feedback on:
164+
${{ steps.parse-command.outputs.mode == 'hunt' && format('
165+
🕵️ BUG HUNT MODE - Find potential issues quickly:
166+
- Focus on critical bugs, security vulnerabilities, and performance issues
167+
- Prioritize high-impact problems over style suggestions
168+
- Be concise and actionable
169+
- Provide clear, actionable feedback
170+
') || '' }}
171+
172+
${{ steps.parse-command.outputs.mode == 'analyze' && format('
173+
📊 ANALYSIS MODE - Deep technical analysis:
174+
- Analyze architecture, patterns, and design decisions
175+
- Evaluate code complexity and maintainability
176+
- Assess test coverage and quality
177+
- Provide strategic recommendations
178+
- Consider long-term implications and scalability
179+
') || '' }}
180+
181+
${{ steps.parse-command.outputs.mode == 'security' && format('
182+
🔒 SECURITY MODE - Security-focused review:
183+
- Identify security vulnerabilities and compliance issues
184+
- Check for proper authentication and authorization
185+
- Validate input sanitization and output encoding
186+
- Review encryption and key management
187+
- Assess data protection and privacy concerns
188+
') || '' }}
189+
190+
${{ steps.parse-command.outputs.mode == 'performance' && format('
191+
⚡ PERFORMANCE MODE - Performance optimization review:
192+
- Identify performance bottlenecks and optimization opportunities
193+
- Analyze resource usage and efficiency
194+
- Check for memory leaks and scalability issues
195+
- Review caching strategies and database queries
196+
- Consider load testing and monitoring needs
197+
') || '' }}
198+
199+
${{ steps.parse-command.outputs.mode == 'review' && format('
200+
📝 STANDARD REVIEW MODE - Comprehensive code review:
46201
- Code quality and best practices
47202
- Potential bugs or issues
48203
- Performance considerations
49204
- Security concerns
50-
- Test coverage
51-
52-
Be constructive and helpful in your feedback.
53-
54-
# Optional: Use sticky comments to make Claude reuse the same comment on subsequent pushes to the same PR
55-
# use_sticky_comment: true
56-
57-
# Optional: Customize review based on file types
58-
# direct_prompt: |
59-
# Review this PR focusing on:
60-
# - For TypeScript files: Type safety and proper interface usage
61-
# - For API endpoints: Security, input validation, and error handling
62-
# - For React components: Performance, accessibility, and best practices
63-
# - For tests: Coverage, edge cases, and test quality
64-
65-
# Optional: Different prompts for different authors
66-
# direct_prompt: |
67-
# ${{ github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' &&
68-
# 'Welcome! Please review this PR from a first-time contributor. Be encouraging and provide detailed explanations for any suggestions.' ||
69-
# 'Please provide a thorough code review focusing on our coding standards and best practices.' }}
70-
71-
# Optional: Add specific tools for running tests or linting
72-
# allowed_tools: "Bash(npm run test),Bash(npm run lint),Bash(npm run typecheck)"
73-
74-
# Optional: Skip review for certain conditions
75-
# if: |
76-
# !contains(github.event.pull_request.title, '[skip-review]') &&
77-
# !contains(github.event.pull_request.title, '[WIP]')
205+
- Test coverage and quality
206+
207+
Focus areas: {0}
208+
Verbose output: {1}
209+
210+
Be constructive and helpful.
211+
', steps.parse-command.outputs.focus, steps.parse-command.outputs.verbose) || '' }}
212+
213+
# Use sticky comments for better UX
214+
use_sticky_comment: true
78215

216+
- name: Workflow Summary
217+
if: always()
218+
run: |
219+
echo "## 🤖 Claude Code Review Summary" >> $GITHUB_STEP_SUMMARY
220+
echo "" >> $GITHUB_STEP_SUMMARY
221+
echo "**Review Mode:** \`${{ steps.parse-command.outputs.mode }}\`" >> $GITHUB_STEP_SUMMARY
222+
echo "**Focus Areas:** \`${{ steps.parse-command.outputs.focus }}\`" >> $GITHUB_STEP_SUMMARY
223+
echo "**Verbose Output:** \`${{ steps.parse-command.outputs.verbose }}\`" >> $GITHUB_STEP_SUMMARY
224+
echo "" >> $GITHUB_STEP_SUMMARY
225+
echo "### 📝 Available Commands" >> $GITHUB_STEP_SUMMARY
226+
echo "Comment any of these in PRs to trigger specific review types:" >> $GITHUB_STEP_SUMMARY
227+
echo "- \`codebot hunt\` - Quick bug detection (like Bugbot)" >> $GITHUB_STEP_SUMMARY
228+
echo "- \`codebot analyze\` - Deep technical analysis" >> $GITHUB_STEP_SUMMARY
229+
echo "- \`codebot security\` - Security-focused review" >> $GITHUB_STEP_SUMMARY
230+
echo "- \`codebot performance\` - Performance optimization review" >> $GITHUB_STEP_SUMMARY
231+
echo "- \`codebot review\` - Comprehensive review" >> $GITHUB_STEP_SUMMARY
232+
echo "- \`codebot\` - Defaults to hunt mode" >> $GITHUB_STEP_SUMMARY
233+
echo "" >> $GITHUB_STEP_SUMMARY
234+
echo "### 🚀 Manual Triggers" >> $GITHUB_STEP_SUMMARY
235+
echo "Run via GitHub CLI:" >> $GITHUB_STEP_SUMMARY
236+
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
237+
echo "gh workflow run claude-code-review.yml -f review_mode=hunt" >> $GITHUB_STEP_SUMMARY
238+
echo "gh workflow run claude-code-review.yml -f review_mode=security -f verbose=true" >> $GITHUB_STEP_SUMMARY
239+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY

0 commit comments

Comments
 (0)