Test AI Code Review #9
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: AI Code Review | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| workflow_dispatch: | |
| permissions: | |
| pull-requests: write | |
| contents: read | |
| jobs: | |
| code-review: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout PR code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get PR diff | |
| id: diff | |
| run: | | |
| git diff origin/${{ github.base_ref }}...HEAD > pr.diff | |
| MAX_SIZE=50000 | |
| if [ $(wc -c < pr.diff) -gt $MAX_SIZE ]; then | |
| head -c $MAX_SIZE pr.diff > pr_truncated.diff | |
| mv pr_truncated.diff pr.diff | |
| echo "warning=Diff truncated to ${MAX_SIZE} bytes" >> $GITHUB_OUTPUT | |
| fi | |
| FILES_CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | wc -l) | |
| echo "files_changed=$FILES_CHANGED" >> $GITHUB_OUTPUT | |
| - name: Code Review | |
| id: review | |
| env: | |
| API_KEY: ${{ secrets.AI_PROVIDER_API_KEY }} | |
| API_ENDPOINT: ${{ secrets.AI_PROVIDER_API_ENDPOINT }} | |
| MODEL: ${{ secrets.AI_PROVIDER_MODEL }} | |
| run: | | |
| set +x # Disable verbose mode to prevent secret leakage in logs | |
| DIFF=$(cat pr.diff | jq -Rs .) | |
| # Retry logic with exponential backoff | |
| MAX_RETRIES=3 | |
| RETRY_COUNT=0 | |
| HTTP_CODE=0 | |
| while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do | |
| HTTP_CODE=$(curl -s -o response.json -w "%{http_code}" $API_ENDPOINT \ | |
| -H "Authorization: Bearer $API_KEY" \ | |
| -H "Content-Type: application/json" \ | |
| -H "Accept-Language: en-US,en" \ | |
| -d "{ | |
| \"model\": \"$MODEL\", | |
| \"messages\": [ | |
| { | |
| \"role\": \"system\", | |
| \"content\": \"You are an expert code reviewer. Analyze the PR diff and provide:\\n\\n1. **Summary**: Brief overview\\n2. **Issues**: Bugs or problems (if any)\\n3. **Security**: Security concerns (if any)\\n4. **Performance**: Performance considerations (if any)\\n5. **Best Practices**: Swift 6, concurrency, architecture (if any)\\n6. **Suggestions**: Optional improvements\\n\\nBe concise but thorough. Use markdown formatting.\" | |
| }, | |
| { | |
| \"role\": \"user\", | |
| \"content\": ${DIFF} | |
| } | |
| ], | |
| \"temperature\": 0.3, | |
| \"max_tokens\": 4096 | |
| }") | |
| if [ "$HTTP_CODE" -eq 200 ]; then | |
| break | |
| fi | |
| RETRY_COUNT=$((RETRY_COUNT + 1)) | |
| if [ $RETRY_COUNT -lt $MAX_RETRIES ]; then | |
| WAIT_TIME=$((2 ** RETRY_COUNT)) | |
| echo "API returned $HTTP_CODE. Retrying in ${WAIT_TIME}s... (Attempt $RETRY_COUNT/$MAX_RETRIES)" | |
| sleep $WAIT_TIME | |
| fi | |
| done | |
| if [ "$HTTP_CODE" -ne 200 ]; then | |
| echo "Error: API returned $HTTP_CODE after $MAX_RETRIES attempts" | |
| cat response.json | |
| exit 1 | |
| fi | |
| RESPONSE=$(cat response.json) | |
| REVIEW=$(echo "$RESPONSE" | jq -r '.choices[0].message.content') | |
| # Check if review was extracted successfully | |
| if [ -z "$REVIEW" ] || [ "$REVIEW" == "null" ]; then | |
| echo "Error: Failed to extract review content from API response" | |
| echo "Response: $RESPONSE" | |
| exit 1 | |
| fi | |
| echo "$REVIEW" > review.md | |
| cat > review_with_header.md << EOF | |
| ### 🧠 AI Code Review | |
| $REVIEW | |
| EOF | |
| if [ -n "${{ steps.diff.outputs.warning }}" ]; then | |
| echo "" >> review_with_header.md | |
| echo "⚠️ **Note**: ${{ steps.diff.outputs.warning }}" >> review_with_header.md | |
| fi | |
| - name: Post review as PR comment | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const review = fs.readFileSync('review_with_header.md', 'utf8'); | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const botComment = comments.find(comment => | |
| comment.user.type === 'Bot' && | |
| comment.body.includes('AI Code Review') | |
| ); | |
| if (botComment) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: botComment.id, | |
| body: review | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: review | |
| }); | |
| } |