Update claude-review.yml

This commit is contained in:
pacnpal
2024-12-10 15:11:10 -05:00
committed by GitHub
parent 563b96a85c
commit 77b72e2ba8

View File

@@ -32,30 +32,74 @@ jobs:
fi fi
- name: Get PR details - name: Get PR details
if: github.event_name == 'workflow_dispatch'
id: pr-details id: pr-details
uses: actions/github-script@v7 uses: actions/github-script@v7
with: with:
script: | script: |
try { try {
const { owner, repo } = context.repo; const { owner, repo } = context.repo;
console.log(`Getting PR #${{ inputs.pr_number }} from ${owner}/${repo}`); const prNumber = ${{ steps.pr-number.outputs.number }};
console.log(`Getting PR #${prNumber} from ${owner}/${repo}`);
const pr = await github.rest.pulls.get({ const pr = await github.rest.pulls.get({
owner: owner, owner: owner,
repo: repo, repo: repo,
pull_number: parseInt(${{ inputs.pr_number }}) pull_number: prNumber
});
console.log('PR Details:', {
base: pr.data.base.ref,
base_sha: pr.data.base.sha,
head: pr.data.head.ref,
head_sha: pr.data.head.sha
}); });
return { return {
base_sha: pr.data.base.sha, base_sha: pr.data.base.sha,
head_sha: pr.data.head.sha head_sha: pr.data.head.sha,
base_ref: pr.data.base.ref,
head_ref: pr.data.head.ref
}; };
} catch (error) { } catch (error) {
core.setFailed(`Failed to get PR details: ${error.message}`); core.setFailed(`Failed to get PR details: ${error.message}`);
throw error; throw error;
} }
- name: Generate diff
id: changed-files
run: |
# Configure git to fetch PR refs
git config --local --add remote.origin.fetch "+refs/pull/*/head:refs/remotes/origin/pr/*"
git fetch origin
BASE_SHA="${{ fromJSON(steps.pr-details.outputs.result).base_sha }}"
HEAD_SHA="${{ fromJSON(steps.pr-details.outputs.result).head_sha }}"
echo "Comparing $BASE_SHA..$HEAD_SHA"
# Get the diff
git diff "$BASE_SHA" "$HEAD_SHA" > changes.diff
# Filter the diff for specific file types
if [ -s changes.diff ]; then
cat changes.diff | grep -v -E '(package-lock.json|yarn.lock|node_modules|\.md$|\.json$)' | grep -E '\.(js|ts|py|cpp|h|java|cs)$' > filtered_changes.diff || true
if [ -s filtered_changes.diff ]; then
DIFF_SIZE=$(wc -c < filtered_changes.diff)
echo "Found $DIFF_SIZE bytes of relevant changes"
echo "diff_size=$DIFF_SIZE" >> $GITHUB_OUTPUT
echo "Preview of changes:"
head -n 5 filtered_changes.diff
else
echo "No relevant file changes found"
echo "diff_size=0" >> $GITHUB_OUTPUT
fi
else
echo "No changes found"
echo "diff_size=0" >> $GITHUB_OUTPUT
fi
- name: Analyze code with Claude - name: Analyze code with Claude
if: steps.changed-files.outputs.diff_size != '0' if: steps.changed-files.outputs.diff_size != '0'
id: analysis id: analysis
@@ -64,12 +108,9 @@ jobs:
run: | run: |
DIFF_CONTENT=$(cat filtered_changes.diff) DIFF_CONTENT=$(cat filtered_changes.diff)
# Escape the diff content for JSON # Create the request body using jq
DIFF_CONTENT_ESCAPED=$(echo "$DIFF_CONTENT" | jq -Rs .) REQUEST_BODY=$(jq -n \
--arg content "You are performing a code review. Please analyze this code diff and provide a thorough review that covers:
# 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 1. Potential conflicts with existing codebase
2. Code correctness and potential bugs 2. Code correctness and potential bugs
@@ -89,21 +130,16 @@ jobs:
Here is the code diff to review: Here is the code diff to review:
``` \`\`\`
EOL $DIFF_CONTENT
) \`\`\`" \
# Prepare the API request body using jq
REQUEST_BODY=$(jq -n \
--arg prompt "$PROMPT" \
--arg diff "$DIFF_CONTENT" \
'{ '{
"model": "claude-3-sonnet-20241022", "model": "claude-3-sonnet-20241022",
"max_tokens": 4096, "max_tokens": 4096,
"temperature": 0.7, "temperature": 0.7,
"messages": [{ "messages": [{
"role": "user", "role": "user",
"content": ($prompt + $diff + "\n```") "content": $content
}] }]
}') }')
@@ -114,43 +150,32 @@ jobs:
-H "anthropic-version: 2023-06-01" \ -H "anthropic-version: 2023-06-01" \
-d "$REQUEST_BODY") -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 if echo "$RESPONSE" | jq -e '.content[0].text' > /dev/null; then
REVIEW=$(echo "$RESPONSE" | jq -r '.content[0].text') REVIEW=$(echo "$RESPONSE" | jq -r '.content[0].text')
# Escape the review content for GitHub Actions
REVIEW="${REVIEW//'%'/'%25'}"
REVIEW="${REVIEW//$'\n'/'%0A'}"
REVIEW="${REVIEW//$'\r'/'%0D'}"
echo "review=$REVIEW" >> $GITHUB_OUTPUT
else else
echo "Error in Claude API response: $RESPONSE" echo "Error in Claude API response: $RESPONSE"
echo "Request body was: $REQUEST_BODY"
exit 1 exit 1
fi 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 - name: Post review comment
if: steps.changed-files.outputs.diff_size != '0' if: steps.changed-files.outputs.diff_size != '0'
uses: actions/github-script@v7 uses: actions/github-script@v7
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
script: | script: |
try { const review = `${{ steps.analysis.outputs.review }}`;
const { owner, repo } = context.repo; const prNumber = ${{ steps.pr-number.outputs.number }};
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: context.repo.owner,
await github.rest.issues.createComment({ repo: context.repo.name,
owner: owner, issue_number: prNumber,
repo: repo, body: `# Claude Code Review\n\n${review}`
issue_number: prNumber, });
body: `# Claude Code Review\n\n${review}`
});
} catch (error) {
core.setFailed(`Failed to post review: ${error.message}`);
throw error;
}