Target Keyword: "automated code review claude github integration"
Tags: github,code-review,ai,programming,developer-tools
Type: Tutorial
Content
Automated Code Review with Claude: A Complete GitHub Integration Guide
Manual code review doesn't scale. AI-powered automated review catches issues before humans look at code. Here's how to integrate Claude into your GitHub code review workflow.
GitHub Actions Setup
# .github/workflows/claude-review.yml
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
push:
branches: [main]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run Claude Review
uses: ./review-action
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OFOX_API_KEY: ${{ secrets.OFOX_API_KEY }}
The Review Action
#!/usr/bin/env python3
"""
GitHub Action for Claude-powered code review.
"""
import os
import json
import subprocess
from github import Github
def get_pr_diff(repo, pr_number):
"""Get the diff of a pull request."""
pr = repo.get_pull(pr_number)
return pr.get_files()
def call_claude_review(diff_content, api_key):
"""Call Claude to review the diff."""
import httpx
import asyncio
async def review():
async with httpx.AsyncClient(timeout=120.0) as client:
response = await client.post(
"https://api.ofox.ai/v1/chat/completions",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
},
json={
"model": "claude-3-5-sonnet-20241022",
"messages": [{
"role": "user",
"content": f"""You are an expert code reviewer. Review this code diff and provide feedback.
Focus on:
1. Bugs and logic errors
2. Security vulnerabilities
3. Performance issues
4. Code quality and best practices
5. Potential edge cases
Format your response as:
## Summary
[One sentence summary]
## Issues Found
- [Issue description] (Line X)
- ...
## Suggestions
- [Suggestion]
## Approval Status
APPROVE / REQUEST_CHANGES / COMMENT
Diff:
{diff_content}"""
}],
"max_tokens": 2000,
"temperature": 0.3
}
)
return response.json()["choices"][0]["message"]["content"]
return asyncio.run(review())
def post_review_comment(github_token, repo_name, pr_number, review_body):
"""Post review as a PR comment."""
g = Github(github_token)
repo = g.get_repo(repo_name)
pr = repo.get_pull(pr_number)
pr.create_issue_comment(review_body)
def main():
github_token = os.environ["GITHUB_TOKEN"]
api_key = os.environ["OFOX_API_KEY"]
# Get context from GitHub
event_path = os.environ["GITHUB_EVENT_PATH"]
with open(event_path) as f:
event = json.load(f)
repo_name = os.environ["GITHUB_REPOSITORY"]
pr_number = event.get("pull_request", {}).get("number")
if not pr_number:
print("Not a PR event, skipping")
return
# Get changed files
g = Github(github_token)
repo = g.get_repo(repo_name)
pr = repo.get_pull(pr_number)
diff_text = ""
for file in pr.get_files():
diff_text += f"\n### {file.filename}\n"
diff_text += f"```
{% endraw %}
diff\n{file.patch}\n
{% raw %}
```\n"
# Get Claude's review
review = call_claude_review(diff_text, api_key)
# Post comment
post_review_comment(github_token, repo_name, pr_number, review)
print("Review posted successfully")
if __name__ == "__main__":
main()
Handling Large Diffs
def split_diff_for_review(files, max_tokens=8000):
"""Split large diffs into reviewable chunks."""
chunks = []
current_chunk = []
current_size = 0
for file in files:
file_size = len(file.patch or "")
if current_size + file_size > max_tokens:
chunks.append(current_chunk)
current_chunk = [file]
current_size = file_size
else:
current_chunk.append(file)
current_size += file_size
if current_chunk:
chunks.append(current_chunk)
return chunks
Security Scanning Integration
# .github/workflows/security-review.yml
name: Security + AI Review
on:
pull_request:
types: [opened, synchronize]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
run: |
pip install semgrep
semgrep --config=auto --json > semgrep-results.json .
- name: Claude Security Review
env:
SEMGREP_RESULTS: semgrep-results.json
OFOX_API_KEY: ${{ secrets.OFOX_API_KEY }}
run: |
python -c "
import os, json
results = json.load(open('$SEMGREP_RESULTS'))
# Format security findings
findings = '\n'.join([
f'- {r[\"check_id\"]}: {r[\"message\"]} at {r[\"path\"]}:{r[\"start\"][\"line\"]}'
for r in results.get('results', [])[:20]
])
# Send to Claude for analysis
import httpx
async def analyze():
async with httpx.AsyncClient() as client:
resp = await client.post(
'https://api.ofox.ai/v1/chat/completions',
headers={'Authorization': 'Bearer $OFOX_API_KEY'},
json={
'model': 'claude-3-5-sonnet-20241022',
'messages': [{
'role': 'user',
'content': f'Analyze these security findings and prioritize by severity:\n{findings}'
}]
}
)
print(resp.json()['choices'][0]['message']['content'])
import asyncio
asyncio.run(analyze())
"
Review Summary Dashboard
def create_review_dashboard(repo_name, reviews):
"""Generate a markdown summary of all reviews."""
summary = f"""
# AI Code Review Summary
**Repository:** {repo_name}
**Date:** {datetime.now().strftime('%Y-%m-%d')}
## Stats
- Total PRs reviewed: {len(reviews)}
- Issues found: {sum(r.issue_count for r in reviews)}
- Suggestions made: {sum(r.suggestion_count for r in reviews)}
## Recent Reviews
"""
for review in reviews[-10:]:
summary += f"""
### PR #{review.pr_number}: {review.pr_title}
- Issues: {review.issue_count}
- Suggestions: {review.suggestion_count}
- Status: {review.approval_status}
"""
return summary
Getting Started
Power your code review with Claude via ofox.ai — their API provides reliable, fast responses perfect for automated code review workflows.
This article contains affiliate links.
Tags: github,code-review,ai,programming,developer-tools
Canonical URL: https://dev.to/zny10289
Top comments (0)