1- name : Code Review Pipeline
1+ name : PR Summary and Code Review
22
33on :
44 pull_request :
5- types : [opened, synchronize, reopened]
5+ types :
6+ - opened
7+ - synchronize
8+ - reopened
9+
10+ permissions :
11+ contents : read
12+ pull-requests : write
13+ issues : write
614
715jobs :
8- code_review :
16+ pr_summary :
917 runs-on : ubuntu-latest
1018 steps :
19+ # Checkout repository
1120 - name : Checkout Code
1221 uses : actions/checkout@v3
1322
23+ # Set up Python for PR summaries
1424 - name : Set Up Python
1525 uses : actions/setup-python@v4
1626 with :
1727 python-version : ' 3.9'
1828
29+ # Install Python dependencies
1930 - name : Install Python Dependencies
2031 run : |
2132 python -m pip install --upgrade pip
2233 pip install requests
2334
24- - name : Run Code Review
35+ # Run AI Analysis (PR Summary Only)
36+ - name : Generate PR Summary
2537 env :
2638 OPENAI_API_KEY : ${{ secrets.OPENAI_API_KEY }}
2739 GITHUB_TOKEN : ${{ secrets.G_TOKEN }}
@@ -31,99 +43,66 @@ jobs:
3143 import requests
3244 import json
3345
34- # Helper function to extract line numbers
35- def extract_line_number(issue_text):
36- try:
37- if "Line" in issue_text:
38- line_part = issue_text.split("Line")[1].split(":")[0].strip()
39- return int(line_part)
40- except (ValueError, IndexError):
41- pass
42- return None
43-
44- # Load GitHub event data
45- event_path = os.getenv("GITHUB_EVENT_PATH")
46+ # Gather GitHub event details
47+ event_path = os.environ.get('GITHUB_EVENT_PATH')
4648 with open(event_path, 'r') as f:
4749 event = json.load(f)
4850
49- pr_number = event["pull_request"]["number"]
50- repo_full_name = event["repository"]["full_name"]
51+ # Extract PR and repo details
52+ pr_number = event['pull_request']['number']
53+ repo_full_name = event['repository']['full_name']
54+ token = os.environ.get('GITHUB_TOKEN')
55+ openai_key = os.environ.get('OPENAI_API_KEY')
5156
52- # Fetch PR diff
57+ # Get PR diff
5358 headers = {
54- " Authorization" : f'token {os.getenv("GITHUB_TOKEN") }',
55- " Accept": " application/vnd.github.v3.diff" ,
59+ ' Authorization' : f'token {token }',
60+ ' Accept': ' application/vnd.github.v3.diff' ,
5661 }
57- diff_url = event[" pull_request"][" url" ] + "/files"
62+ diff_url = event[' pull_request'][' url' ] + "/files"
5863 pr_files = requests.get(diff_url, headers=headers).json()
5964
60- # Prepare inline comments
61- inline_comments = []
62-
63- for file in pr_files:
64- filename = file["filename"]
65- patch = file.get("patch", "")
66-
67- if not patch.strip():
68- continue
69-
70- # Send patch to OpenAI for review
71- prompt = f"""
72- Analyze the following code patch and find:
73- - Syntax errors
74- - Logical issues
75- - Security vulnerabilities
76- For each issue, specify:
77- - Line number
78- - Problem description
79- - Suggested fix
65+ diff_text = ""
66+ for fdata in pr_files:
67+ filename = fdata['filename']
68+ patch = fdata.get('patch', '')
69+ diff_text += f"File: {filename}\\nPatch:\\n{patch}\\n\\n"
70+
71+ # Generate PR summary using OpenAI
72+ summary_prompt = f"Summarize the following pull request changes in a concise, technical manner:\\n\\n{diff_text}"
73+ ai_headers = {"Content-Type": "application/json", "Authorization": f"Bearer {openai_key}"}
74+ data_summary = {
75+ "model": "gpt-4o-mini",
76+ "messages": [{"role": "user", "content": summary_prompt}],
77+ "temperature": 0.7
78+ }
79+ summary_response = requests.post("https://api.openai.com/v1/chat/completions", headers=ai_headers, json=data_summary)
80+ summary_response.raise_for_status()
81+ summary = summary_response.json()['choices'][0]['message']['content'].strip()
82+
83+ # Post AI Pull Request Summary
84+ comment_url = f"https://api.github.com/repos/{repo_full_name}/issues/{pr_number}/comments"
85+ summary_comment = {
86+ "body": f"**AI Pull Request Summary:**\\n{summary}"
87+ }
88+ summary_comment_response = requests.post(comment_url, headers={'Authorization': f'token {token}', 'Accept': 'application/vnd.github.v3+json'}, json=summary_comment)
89+ summary_comment_response.raise_for_status()
8090
81- Patch:
82- {patch}
83- """
84- openai_headers = {
85- "Authorization": f'Bearer {os.getenv("OPENAI_API_KEY")}',
86- "Content-Type": "application/json",
87- }
88- openai_payload = {
89- "model": "gpt-4o-mini",
90- "messages": [{"role": "user", "content": prompt}],
91- "temperature": 0.3,
92- }
93- response = requests.post(
94- "https://api.openai.com/v1/chat/completions",
95- headers=openai_headers,
96- json=openai_payload,
97- )
98- response.raise_for_status()
99- ai_output = response.json()["choices"][0]["message"]["content"]
91+ print("PR Summary posted successfully.")
92+ EOF
10093
101- # Process AI output
102- for issue in ai_output.split("\n"):
103- if "Line" in issue:
104- line_number = extract_line_number(issue)
105- if line_number:
106- description = issue.split(": ", 1)[-1].strip()
107- inline_comments.append(
108- {
109- "path": filename,
110- "line": line_number,
111- "side": "RIGHT",
112- "body": f"**AI Code Review:**\n{description}",
113- }
114- )
94+ code_review :
95+ runs-on : ubuntu-latest
96+ steps :
97+ # Checkout repository
98+ - name : Checkout Repository
99+ uses : actions/checkout@v4
115100
116- # Submit review comments
117- if inline_comments:
118- review_url = f"https://api.github.com/repos/{repo_full_name}/pulls/{pr_number}/reviews"
119- review_data = {
120- "event": "COMMENT",
121- "body": "AI-generated inline comments for code review.",
122- "comments": inline_comments,
123- }
124- review_response = requests.post(review_url, headers=headers, json=review_data)
125- review_response.raise_for_status()
126- print("Code review comments posted successfully.")
127- else:
128- print("No issues found in the code.")
129- EOF
101+ # Run GPT Code Reviewer (handles all code review tasks)
102+ - name : Run GPT Code Reviewer
103+ uses : PierreGode/GPTcode-reviewer@main
104+ with :
105+ GITHUB_TOKEN : ${{ secrets.G_TOKEN }}
106+ OPENAI_API_KEY : ${{ secrets.OPENAI_API_KEY }}
107+ OPENAI_API_MODEL : " gpt-4o-mini"
108+ exclude : " **/*.json, **/*.md"
0 commit comments