Skip to content

Add JSON-based AI reviewer with workflow automation #18

Add JSON-based AI reviewer with workflow automation

Add JSON-based AI reviewer with workflow automation #18

name: AI Code Reviewer
on:
pull_request:
types: [labeled]
jobs:
comprehensive-review:
name: 🤖 AI Code Review
runs-on: ubuntu-latest
if: github.event.action == 'labeled' && github.event.label.name == 'ai_code_review'
permissions:
contents: read
pull-requests: write
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y jq
- name: Get PR diff
run: |
# Fetch the base branch (works for any target branch, not just main)
git fetch origin ${{ github.event.pull_request.base.ref }}
git diff origin/${{ github.event.pull_request.base.ref }}...HEAD --no-color > diff.txt
- name: AI Code Review
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
AI_MODEL: z-ai/glm-4.6
AI_TEMPERATURE: 0.1
AI_MAX_TOKENS: 2000
MAX_DIFF_SIZE: 800000
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO_FULL_NAME: ${{ github.repository }}
FAIL_ON_REQUESTED_CHANGES: ${{ vars.FAIL_ON_REQUESTED_CHANGES || 'false' }}
run: |
# Run the AI reviewer and save response to file
echo "Running AI code review..."
AI_RESPONSE=$(cat diff.txt | bash ai-reviewer.sh)
# Debug: Show what AI returned
echo "=== AI RESPONSE START ==="
echo "$AI_RESPONSE"
echo "=== AI RESPONSE END ==="
# Save response for debugging
echo "$AI_RESPONSE" > ai_response.txt
# Check if AI_RESPONSE is empty
if [ -z "$AI_RESPONSE" ]; then
echo "❌ AI response is empty"
exit 1
fi
# Parse JSON response with enhanced error handling
if ! echo "$AI_RESPONSE" | jq . >/dev/null 2>&1; then
echo "⚠️ AI response is not valid JSON. Posting raw response for debugging."
echo "$AI_RESPONSE" | gh pr comment ${{ github.event.pull_request.number }} --repo ${{ github.repository }} -F -
echo "Raw AI response saved for debugging:"
echo "$AI_RESPONSE"
exit 1
fi
# Extract fields from JSON with additional safety checks
echo "Extracting fields from AI response..."
# Test the jq command with explicit error handling
if ! REVIEW=$(echo "$AI_RESPONSE" | jq -r '.review // "No review provided"' 2>/dev/null); then
echo "❌ Failed to extract review field"
echo "AI_RESPONSE content: $AI_RESPONSE"
exit 1
fi
if ! DECISION=$(echo "$AI_RESPONSE" | jq -r '.fail_pass_workflow // "uncertain"' 2>/dev/null); then
echo "❌ Failed to extract decision field"
echo "AI_RESPONSE content: $AI_RESPONSE"
exit 1
fi
if ! LABELS=$(echo "$AI_RESPONSE" | jq -r '.labels_added[]? // empty' 2>/dev/null); then
echo "⚠️ Failed to extract labels field, continuing without labels"
LABELS=""
fi
echo "✅ Successfully extracted fields from AI response"
# Post the review as PR comment
echo "$REVIEW" | gh pr comment ${{ github.event.pull_request.number }} --repo ${{ github.repository }} -F -
# Add labels to PR
echo "Labels to add: $LABELS"
for label in $LABELS; do
echo "Adding label: $label"
if gh label create "$label" --color "0366d6" --description "Auto-created by AI reviewer" 2>/dev/null; then
echo "Created new label: $label"
else
echo "Label already exists: $label"
fi
if gh label "$label" --add ${{ github.event.pull_request.number }} 2>/dev/null; then
echo "Successfully added label: $label"
else
echo "Failed to add label: $label"
fi
done
# Handle workflow decision
echo "AI decision: $DECISION"
if [ "$FAIL_ON_REQUESTED_CHANGES" = "true" ] && [ "$DECISION" = "fail" ]; then
echo "❌ AI requested changes and FAIL_ON_REQUESTED_CHANGES is enabled. Failing workflow."
exit 1
fi
echo "✅ AI review completed successfully"
- name: Cleanup
if: always()
run: |
rm -f diff.txt ai_response.txt