mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-03-25 09:25:50 +00:00
178 lines
No EOL
6.6 KiB
YAML
178 lines
No EOL
6.6 KiB
YAML
name: Claude Code Review
|
||
|
||
on:
|
||
pull_request:
|
||
types: [opened, synchronize]
|
||
# Optional: Only run on specific file changes
|
||
# paths:
|
||
# - "src/**/*.ts"
|
||
# - "src/**/*.tsx"
|
||
# - "src/**/*.js"
|
||
# - "src/**/*.jsx"
|
||
|
||
# Cancel in-progress runs when a new commit is pushed to the same PR
|
||
concurrency:
|
||
group: claude-review-${{ github.event.pull_request.number }}
|
||
cancel-in-progress: true
|
||
|
||
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: blacksmith-8vcpu-ubuntu-2404-arm
|
||
permissions:
|
||
contents: write
|
||
pull-requests: write
|
||
issues: write
|
||
id-token: write
|
||
|
||
steps:
|
||
- name: Checkout repository
|
||
uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 0 # Full history for better context
|
||
|
||
- name: Check permissions
|
||
id: check-permissions
|
||
run: |
|
||
# Check if this is from a fork (external contributor)
|
||
if [[ "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.repository }}" ]]; then
|
||
echo "is_fork=true" >> $GITHUB_OUTPUT
|
||
echo "ℹ️ PR from fork detected - Claude review will be skipped due to permissions"
|
||
else
|
||
echo "is_fork=false" >> $GITHUB_OUTPUT
|
||
fi
|
||
|
||
- name: Check if already reviewed
|
||
id: check-review
|
||
if: steps.check-permissions.outputs.is_fork != 'true'
|
||
uses: actions/github-script@v7
|
||
with:
|
||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||
script: |
|
||
// Check if Claude has already reviewed this commit
|
||
const currentSha = context.payload.pull_request.head.sha;
|
||
|
||
// Get all comments on the PR
|
||
const comments = await github.rest.issues.listComments({
|
||
owner: context.repo.owner,
|
||
repo: context.repo.repo,
|
||
issue_number: context.issue.number,
|
||
per_page: 100
|
||
});
|
||
|
||
// Check if Claude has already reviewed this specific commit
|
||
const alreadyReviewed = comments.data.some(comment =>
|
||
comment.user.login === 'claude[bot]' &&
|
||
comment.body.includes(currentSha)
|
||
);
|
||
|
||
if (alreadyReviewed) {
|
||
core.info(`Claude has already reviewed commit ${currentSha}`);
|
||
core.setOutput('skip', 'true');
|
||
} else {
|
||
core.info(`No Claude review found for commit ${currentSha}`);
|
||
core.setOutput('skip', 'false');
|
||
}
|
||
|
||
- name: Run Claude Code Review
|
||
if: steps.check-permissions.outputs.is_fork != 'true' && steps.check-review.outputs.skip != 'true'
|
||
id: claude-review
|
||
continue-on-error: true
|
||
uses: anthropics/claude-code-action@beta
|
||
with:
|
||
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||
|
||
# Use Claude Sonnet 4 (default model)
|
||
# model: "claude-opus-4-20250514"
|
||
|
||
# Direct prompt for automated review with detailed instructions
|
||
direct_prompt: |
|
||
Please provide a comprehensive code review for this pull request. Structure your review as follows:
|
||
|
||
## 📋 Summary
|
||
Brief overview of the changes and their purpose.
|
||
|
||
## ✅ Positive Aspects
|
||
What's done well in this PR.
|
||
|
||
## 🔍 Areas for Improvement
|
||
|
||
### Code Quality
|
||
- Naming conventions, code organization, readability
|
||
- Adherence to project patterns and best practices
|
||
- DRY principle violations or code duplication
|
||
|
||
### Potential Issues
|
||
- Bugs or logic errors
|
||
- Edge cases not handled
|
||
- Error handling gaps
|
||
|
||
### Performance
|
||
- Inefficient algorithms or data structures
|
||
- Unnecessary re-renders (for UI components)
|
||
- Resource leaks or memory issues
|
||
|
||
### Security
|
||
- Input validation issues
|
||
- Authentication/authorization concerns
|
||
- Potential vulnerabilities
|
||
|
||
### Testing
|
||
- Missing test coverage
|
||
- Test quality and completeness
|
||
- Edge cases that should be tested
|
||
|
||
## 💡 Suggestions
|
||
Specific, actionable improvements with code examples where helpful.
|
||
|
||
## 🎯 Priority Items
|
||
List the most important items that should be addressed before merging.
|
||
|
||
---
|
||
*Reviewed commit: ${{ github.event.pull_request.head.sha }}*
|
||
*Files changed: ${{ github.event.pull_request.changed_files }}*
|
||
|
||
# Enhanced tool access for better analysis
|
||
allowed_tools: |
|
||
Bash(pnpm install)
|
||
Bash(pnpm run build)
|
||
Bash(pnpm run test)
|
||
Bash(pnpm run test:*)
|
||
Bash(pnpm run lint)
|
||
Bash(pnpm run lint:*)
|
||
Bash(pnpm run typecheck)
|
||
Bash(pnpm run format)
|
||
Bash(pnpm run format:check)
|
||
Glob
|
||
Grep
|
||
Read
|
||
|
||
# Environment variables for Claude's context
|
||
claude_env: |
|
||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
|
||
BASE_BRANCH: ${{ github.event.pull_request.base.ref }}
|
||
HEAD_BRANCH: ${{ github.event.pull_request.head.ref }}
|
||
CHANGED_FILES: ${{ github.event.pull_request.changed_files }}
|
||
ADDITIONS: ${{ github.event.pull_request.additions }}
|
||
DELETIONS: ${{ github.event.pull_request.deletions }}
|
||
|
||
- name: Clean up old Claude comments
|
||
if: steps.check-permissions.outputs.is_fork != 'true' && steps.check-review.outputs.skip != 'true'
|
||
continue-on-error: true
|
||
uses: actions/github-script@v7
|
||
with:
|
||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||
script: |
|
||
// Wait a bit to ensure the new comment is posted
|
||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||
|
||
// Use the cleanup script
|
||
const cleanup = require('./.github/scripts/cleanup-claude-comments.js');
|
||
await cleanup({ github, context, core }); |