Skip to content

Commit a0d4f32

Browse files
committed
github: fix ai review action (third time's the charm)
Inline python in yaml is a footgun. Restore the file and checkout the base code. Fixes: 4cd3417 ("github: fix ai review action") Signed-off-by: Robin Jarry <[email protected]>
1 parent 558b6af commit a0d4f32

File tree

2 files changed

+100
-96
lines changed

2 files changed

+100
-96
lines changed

.github/workflows/ai-review.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env python3
2+
# SPDX-License-Identifier: BSD-3-Clause
3+
# Copyright (c) 2025 Robin Jarry
4+
5+
import json
6+
import os
7+
import sys
8+
9+
import openai
10+
import requests
11+
12+
openai.api_key = os.environ["OPENAI_API_KEY"]
13+
REPO = os.environ["REPO"]
14+
PR_NUMBER = os.environ["PR_NUMBER"]
15+
GITHUB_TOKEN = os.environ["GITHUB_TOKEN"]
16+
COMMIT_ID = os.environ["COMMIT_ID"]
17+
DIFF_FILE = os.environ["DIFF_FILE"]
18+
19+
with open(DIFF_FILE) as f:
20+
diff = f.read()
21+
22+
# Split into file hunks
23+
comments = []
24+
25+
prompt = f"""You are an expert C developer reviewing a GitHub pull request.
26+
27+
Focus on:
28+
- Memory safety (e.g., buffer overflows, pointer misuse)
29+
- Correctness (null checks, type safety, missing error handling)
30+
- Code clarity and clean style
31+
- Use of standard idioms and conventions (C23)
32+
33+
Only provide helpful, relevant comments.
34+
Be brief but clear.
35+
Only include issues worth commenting.
36+
Never suggest to add code comments.
37+
38+
**IMPORTANT: OUTPUT PURE JSON WITHOUT MARKDOWN SYNTAX.**
39+
40+
Provide a list of concise per-file inline comments in JSON format. Example:
41+
42+
[{{"path": "modules/infra/control/nexthop.c", "line": 42, "comment": "Return value of malloc is not checked."}}, {{"path": "main/dpdk.c", "line": 666, "comment": "Reset to NULL to avoid double-free."}}]
43+
44+
Here is the diff to review:
45+
46+
```diff
47+
{diff}
48+
```
49+
"""
50+
51+
response = openai.chat.completions.create(
52+
model="o4-mini",
53+
messages=[
54+
{"role": "user", "content": prompt},
55+
],
56+
temperature=0.2,
57+
max_tokens=800,
58+
)
59+
60+
result = response.choices[0].message.content.strip()
61+
result = result.removeprefix("```json")
62+
result = result.removesuffix("```")
63+
parsed = json.loads(result.strip())
64+
for c in parsed:
65+
comments.append(
66+
{
67+
"path": c["path"],
68+
"line": c["line"],
69+
"body": c["comment"],
70+
"commit_id": COMMIT_ID,
71+
}
72+
)
73+
74+
if comments:
75+
for c in comments:
76+
print(f"adding comment on {c['path']}:{c['line']}: {c['body']}")
77+
r = requests.post(
78+
f"https://api.github.com/repos/{REPO}/pulls/{PR_NUMBER}/comments",
79+
headers={
80+
"Authorization": f"Bearer {GITHUB_TOKEN}",
81+
"Accept": "application/vnd.github+json",
82+
},
83+
json=c,
84+
)
85+
if r.status_code >= 300:
86+
print(
87+
"error: failed to post comment:", r.status_code, r.text, file=sys.stderr
88+
)
89+
os.exit(1)
90+
else:
91+
print("no actionable review comments.")

.github/workflows/review.yml

Lines changed: 9 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ jobs:
1616
runs-on: ubuntu-latest
1717

1818
steps:
19+
- uses: actions/setup-python@v5
20+
with:
21+
python-version: '3.13'
22+
23+
- run: pip install openai requests
24+
25+
- uses: actions/checkout@v4
26+
1927
- name: Download PR diff
2028
env:
2129
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -25,12 +33,6 @@ jobs:
2533
-L "${{ github.event.pull_request.diff_url }}" \
2634
-o pr.diff
2735
28-
- uses: actions/setup-python@v5
29-
with:
30-
python-version: '3.13'
31-
32-
- run: pip install openai requests
33-
3436
- name: Run GPT inline review
3537
env:
3638
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
@@ -39,93 +41,4 @@ jobs:
3941
PR_NUMBER: ${{ github.event.pull_request.number }}
4042
COMMIT_ID: ${{ github.event.pull_request.head.sha }}
4143
DIFF_FILE: pr.diff
42-
run: |
43-
python3 <<EOF
44-
import json
45-
import os
46-
import sys
47-
48-
import openai
49-
import requests
50-
51-
openai.api_key = os.environ["OPENAI_API_KEY"]
52-
REPO = os.environ["REPO"]
53-
PR_NUMBER = os.environ["PR_NUMBER"]
54-
GITHUB_TOKEN = os.environ["GITHUB_TOKEN"]
55-
COMMIT_ID = os.environ["COMMIT_ID"]
56-
DIFF_FILE = os.environ["DIFF_FILE"]
57-
58-
with open(DIFF_FILE) as f:
59-
diff = f.read()
60-
61-
# Split into file hunks
62-
comments = []
63-
64-
prompt = f"""You are an expert C developer reviewing a GitHub pull request.
65-
66-
Focus on:
67-
- Memory safety (e.g., buffer overflows, pointer misuse)
68-
- Correctness (null checks, type safety, missing error handling)
69-
- Code clarity and clean style
70-
- Use of standard idioms and conventions (C23)
71-
72-
Only provide helpful, relevant comments.
73-
Be brief but clear.
74-
Only include issues worth commenting.
75-
Never suggest to add code comments.
76-
77-
**IMPORTANT: OUTPUT PURE JSON WITHOUT MARKDOWN SYNTAX.**
78-
79-
Provide a list of concise per-file inline comments in JSON format. Example:
80-
81-
[{{"path": "modules/infra/control/nexthop.c", "line": 42, "comment": "Return value of malloc is not checked."}}, {{"path": "main/dpdk.c", "line": 666, "comment": "Reset to NULL to avoid double-free."}}]
82-
83-
Here is the diff to review:
84-
85-
```diff
86-
{diff}
87-
```
88-
"""
89-
90-
response = openai.chat.completions.create(
91-
model="o4-mini",
92-
messages=[
93-
{"role": "user", "content": prompt},
94-
],
95-
temperature=0.2,
96-
max_tokens=800,
97-
)
98-
99-
result = response.choices[0].message.content.strip()
100-
result = result.removeprefix("```json")
101-
result = result.removesuffix("```")
102-
parsed = json.loads(result.strip())
103-
for c in parsed:
104-
comments.append(
105-
{
106-
"path": c["path"],
107-
"line": c["line"],
108-
"body": c["comment"],
109-
"commit_id": COMMIT_ID,
110-
}
111-
)
112-
113-
if comments:
114-
for c in comments:
115-
print(f"adding comment on {c['path']}:{c['line']}: {c['body']}")
116-
r = requests.post(
117-
f"https://api.github.com/repos/{REPO}/pulls/{PR_NUMBER}/comments",
118-
headers={
119-
"Authorization": f"Bearer {GITHUB_TOKEN}",
120-
"Accept": "application/vnd.github+json",
121-
},
122-
json=c,
123-
)
124-
if r.status_code >= 300:
125-
print(
126-
"error: failed to post comment:", r.status_code, r.text, file=sys.stderr
127-
)
128-
os.exit(1)
129-
else:
130-
print("no actionable review comments.")
131-
EOF
44+
run: python3 .github/workflows/ai-review.py

0 commit comments

Comments
 (0)