Files
Pac-cogs/.github/workflows/claude-review.yml
2024-12-10 15:04:08 -05:00

157 lines
5.1 KiB
YAML

name: Claude Code Review
permissions:
contents: read
pull-requests: write
on:
pull_request:
types: [opened, reopened, synchronize]
workflow_dispatch:
inputs:
pr_number:
description: 'Pull Request Number'
required: true
type: string
jobs:
code-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get PR number
id: pr-number
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "number=${{ inputs.pr_number }}" >> $GITHUB_OUTPUT
else
echo "number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
fi
- name: Get PR details
if: github.event_name == 'workflow_dispatch'
id: pr-details
uses: actions/github-script@v7
with:
script: |
try {
const { owner, repo } = context.repo;
console.log(`Getting PR #${{ inputs.pr_number }} from ${owner}/${repo}`);
const pr = await github.rest.pulls.get({
owner: owner,
repo: repo,
pull_number: parseInt(${{ inputs.pr_number }})
});
return {
base_sha: pr.data.base.sha,
head_sha: pr.data.head.sha
};
} catch (error) {
core.setFailed(`Failed to get PR details: ${error.message}`);
throw error;
}
- name: Analyze code with Claude
if: steps.changed-files.outputs.diff_size != '0'
id: analysis
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
DIFF_CONTENT=$(cat filtered_changes.diff)
# Escape the diff content for JSON
DIFF_CONTENT_ESCAPED=$(echo "$DIFF_CONTENT" | jq -Rs .)
# Create the prompt with escaped content
PROMPT=$(cat << 'EOL'
You are performing a code review. Please analyze this code diff and provide a thorough review that covers:
1. Potential conflicts with existing codebase
2. Code correctness and potential bugs
3. Security vulnerabilities or risks
4. Performance implications
5. Maintainability and readability issues
6. Adherence to best practices and coding standards
7. Suggestions for improvements
For each issue found:
- Explain the problem clearly
- Rate the severity (Critical/High/Medium/Low)
- Provide specific recommendations for fixes
- Include code examples where helpful
If no issues are found in a particular area, explicitly state that.
Here is the code diff to review:
```
EOL
)
# Prepare the API request body using jq
REQUEST_BODY=$(jq -n \
--arg prompt "$PROMPT" \
--arg diff "$DIFF_CONTENT" \
'{
"model": "claude-3-sonnet-20241022",
"max_tokens": 4096,
"temperature": 0.7,
"messages": [{
"role": "user",
"content": ($prompt + $diff + "\n```")
}]
}')
# Make the API request
RESPONSE=$(curl -s https://api.anthropic.com/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d "$REQUEST_BODY")
# Extract the review content from the response and handle potential errors
if echo "$RESPONSE" | jq -e '.content[0].text' > /dev/null; then
REVIEW=$(echo "$RESPONSE" | jq -r '.content[0].text')
else
echo "Error in Claude API response: $RESPONSE"
echo "Request body was: $REQUEST_BODY"
exit 1
fi
# Escape the review content for GitHub Actions
REVIEW="${REVIEW//'%'/'%25'}"
REVIEW="${REVIEW//$'\n'/'%0A'}"
REVIEW="${REVIEW//$'\r'/'%0D'}"
# Save the review to the output
echo "review=$REVIEW" >> $GITHUB_OUTPUT
- name: Post review comment
if: steps.changed-files.outputs.diff_size != '0'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
try {
const { owner, repo } = context.repo;
const prNumber = ${{ steps.pr-number.outputs.number }};
const review = `${{ steps.analysis.outputs.review }}`;
console.log(`Posting review to PR #${prNumber} in ${owner}/${repo}`);
await github.rest.issues.createComment({
owner: owner,
repo: repo,
issue_number: prNumber,
body: `# Claude Code Review\n\n${review}`
});
} catch (error) {
core.setFailed(`Failed to post review: ${error.message}`);
throw error;
}