Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 118 additions & 14 deletions .github/workflows/review.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,126 @@
name: GPTcode-reviewer

name: PR Summary and Inline Issues Check
on:
pull_request:
types:
- opened
- synchronize
permissions: write-all
types: [opened, synchronize, reopened]

jobs:
review:
summarize_and_check:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Checkout Code
uses: actions/checkout@v3

- name: GPTcode-reviewer
uses: PierreGode/GPTcode-reviewer@PR-LOG
- name: Set Up Python
uses: actions/setup-python@v4
with:
GITHUB_TOKEN: ${{ secrets.G_TOKEN }}
python-version: '3.9'

- name: Install Python Dependencies
run: |
python -m pip install --upgrade pip
pip install requests

- name: Run AI Analysis
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
OPENAI_API_MODEL: "gpt-4o-mini" # Optional: defaults to "gpt-4"
exclude: "**/*.json, **/*.md" # Optional: exclude patterns separated by commas
GITHUB_TOKEN: ${{ secrets.G_TOKEN }}
run: |
python - <<EOF
import os
import requests
import json

# Gather GitHub event details
event_path = os.environ.get('GITHUB_EVENT_PATH')
with open(event_path, 'r') as f:
event = json.load(f)

# Extract PR and repo details
pr_number = event['pull_request']['number']
repo_full_name = event['repository']['full_name']
token = os.environ.get('GITHUB_TOKEN')
openai_key = os.environ.get('OPENAI_API_KEY')

# Get PR diff
headers = {
'Authorization': f'token {token}',
'Accept': 'application/vnd.github.v3.diff',
}
diff_url = event['pull_request']['url'] + "/files"
pr_files = requests.get(diff_url, headers=headers).json()

diff_text = ""
inline_comments = [] # Collect inline comments to post

for fdata in pr_files:
filename = fdata['filename']
patch = fdata.get('patch', '')
diff_text += f"File: {filename}\\nPatch:\\n{patch}\\n\\n"

# Call OpenAI for inline code analysis
issues_prompt = f"Review the following code changes for critical issues (e.g., syntax errors, undefined variables, broken imports). Provide specific inline comments for each issue with the corresponding line number from this diff:\n\n{patch}"
ai_headers = {"Content-Type": "application/json", "Authorization": f"Bearer {openai_key}"}
data_issues = {
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": issues_prompt}],
"temperature": 0.7
}
issues_response = requests.post("https://api.openai.com/v1/chat/completions", headers=ai_headers, json=data_issues)
issues_response.raise_for_status()
issues = issues_response.json()['choices'][0]['message']['content'].strip()

# Parse issues for inline comments
if issues and "no issues found" not in issues.lower():
for issue in issues.split("\\n- "):
if issue.strip():
# Example issue format: "Line X: Description of issue"
if "Line " in issue:
parts = issue.split(":")
line_info = parts[0].strip()
description = ":".join(parts[1:]).strip()

if "Line" in line_info:
line_number = int(line_info.split(" ")[1]) # Extract line number
inline_comments.append({
"path": filename,
"line": line_number,
"side": "RIGHT", # Changes are always on the "RIGHT" side in the diff
"body": f"**AI Code Issue Check:**\n{description}"
})

# Post inline comments as a single review
if inline_comments:
review_data = {
"body": "AI-generated review comments for code issues.",
"event": "COMMENT",
"comments": inline_comments
}
review_response = requests.post(f"https://api.github.com/repos/{repo_full_name}/pulls/{pr_number}/reviews",
headers={'Authorization': f'token {token}', 'Accept': 'application/vnd.github.v3+json'},
json=review_data)
review_response.raise_for_status()
print("Review comments posted successfully.")
else:
print("No critical issues found in the code.")

# Always post PR summary
summary_prompt = f"Summarize the following pull request changes in a concise, technical manner:\\n\\n{diff_text}"
data_summary = {
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": summary_prompt}],
"temperature": 0.7
}
summary_response = requests.post("https://api.openai.com/v1/chat/completions", headers=ai_headers, json=data_summary)
summary_response.raise_for_status()
summary = summary_response.json()['choices'][0]['message']['content'].strip()

# Post AI Pull Request Summary
comment_url = f"https://api.github.com/repos/{repo_full_name}/issues/{pr_number}/comments"
summary_comment = {
"body": f"**AI Pull Request Summary:**\\n{summary}"
}
summary_comment_response = requests.post(comment_url, headers={'Authorization': f'token {token}', 'Accept': 'application/vnd.github.v3+json'}, json=summary_comment)
summary_comment_response.raise_for_status()

print("PR Summary posted successfully.")
EOF
Loading