DEV Community

brian austin
brian austin

Posted on

GitHub Actions + Claude API: automate your code review for $0.02 per PR

GitHub Actions + Claude API: automate your code review for $0.02 per PR

I've been using Claude API in GitHub Actions to auto-review pull requests. The cost? About $0.02 per PR. Here's the exact workflow.

Why automate code review?

Code review is the bottleneck in most teams. A PR sits for 24 hours waiting for a human reviewer. Meanwhile, the simple stuff — naming, error handling, missing tests — could be caught instantly.

With a Claude API key, you can add a reviewer that never sleeps.

The setup

1. Get a Claude API key

You need API access. I use SimplyLouie's developer tier — it's $10/month for full Claude API access with a real API key. Much cheaper than managing Anthropic credits directly for low-volume use cases like CI.

2. Store your key in GitHub Secrets

# In your repo: Settings → Secrets → Actions → New repository secret
# Name: CLAUDE_API_KEY
# Value: your key from simplylouie.com/developers
Enter fullscreen mode Exit fullscreen mode

3. The workflow file

Create .github/workflows/ai-review.yml:

name: AI Code Review

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  ai-review:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
      contents: read

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Get PR diff
        id: diff
        run: |
          git diff origin/${{ github.base_ref }}...HEAD > pr_diff.txt
          echo "lines=$(wc -l < pr_diff.txt)" >> $GITHUB_OUTPUT

      - name: AI Review
        env:
          CLAUDE_API_KEY: ${{ secrets.CLAUDE_API_KEY }}
          PR_TITLE: ${{ github.event.pull_request.title }}
        run: |
          DIFF=$(cat pr_diff.txt | head -300)  # limit tokens

          RESPONSE=$(curl -s https://api.simplylouie.com/v1/chat \
            -H "Authorization: Bearer $CLAUDE_API_KEY" \
            -H "Content-Type: application/json" \
            -d "{
              \"model\": \"claude-3-5-sonnet-20241022\",
              \"max_tokens\": 1024,
              \"messages\": [{
                \"role\": \"user\",
                \"content\": \"Review this PR diff. Be concise. Flag: bugs, security issues, missing error handling, naming problems. PR: $PR_TITLE\\n\\nDiff:\\n$DIFF\"
              }]
            }")

          echo "$RESPONSE" | python3 -c "
import json, sys
data = json.load(sys.stdin)
print(data['choices'][0]['message']['content'])
" > review.txt

          cat review.txt

      - name: Post review comment
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs')
            const review = fs.readFileSync('review.txt', 'utf8')

            await github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## 🤖 AI Code Review\n\n${review}\n\n---\n*Powered by Claude via [SimplyLouie API](https://simplylouie.com/developers)*`
            })
Enter fullscreen mode Exit fullscreen mode

4. What it reviews

For each PR, the bot will check:

  • Bugs: off-by-one errors, null dereferences, unhandled promises
  • Security: hardcoded secrets, SQL injection patterns, XSS vectors
  • Error handling: missing try/catch, unhandled rejections
  • Code quality: function names, magic numbers, overly complex logic

Real output example

Here's what a review comment looks like:

## 🤖 AI Code Review

**Potential bug (line 47):** `user.address` could be null if the user 
hasn't set their address. Add a null check before calling `.split(',')`.

**Missing error handling (line 83):** The `fetch()` call doesn't have
a `.catch()`. If the network request fails, the promise will be 
unhandled.

**Naming (line 102):** `data2` is unclear. Consider `filteredUsers` 
or `activeUsers` based on context.

---
*Powered by Claude via SimplyLouie API*
Enter fullscreen mode Exit fullscreen mode

Cost breakdown

  • Typical PR diff: ~200 lines = ~1,500 tokens input
  • Review response: ~300 tokens output
  • Cost per review: $0.02
  • 50 PRs/month = $1.00 in API costs + $10/month for the key = $11/month total

Vs. paying a contractor for code review: easily $50-200/hour.

Customizing the prompt

You can tune the review focus:

# Security-focused
content: "Review this diff for security vulnerabilities only. Be specific about line numbers."

# Performance-focused  
content: "Review for performance issues: N+1 queries, unnecessary re-renders, memory leaks."

# Junior team
content: "Review for a junior dev team. Explain why each issue matters."
Enter fullscreen mode Exit fullscreen mode

Handling large PRs

For PRs > 300 lines, split by file:

# Review each changed file separately
git diff origin/$BASE...HEAD --name-only | while read file; do
  git diff origin/$BASE...HEAD -- "$file" | head -150 > "diff_$file.txt"
  # ... send each to API
done
Enter fullscreen mode Exit fullscreen mode

Adding it to your team

The workflow is opt-in per repo. Add it to your highest-traffic repos first. The bot comments on every PR — humans still approve/merge.

I've found it catches about 30% of issues before human review, which makes the actual review faster. The human reviewer can focus on architecture and logic instead of syntax.


API access: simplylouie.com/developers — $10/month, full Claude API, no usage caps for normal workloads.

What else would you automate with this? Commit message quality? Changelog generation? Let me know in the comments.

Top comments (0)