Skip to content

Commit f0e6b8d

Browse files
committed
feat(PR): Add AI-powered PR review and labeling
- Update README with new ai-commit, ai-pr, and ai-review commands - Enhance make_pull_request.py with automatic PR labeling (minor/patch/major) - Add pull_request_review.py for AI-generated PR reviews - Update setup.py with new command aliases
1 parent 3a6d820 commit f0e6b8d

File tree

4 files changed

+137
-5
lines changed

4 files changed

+137
-5
lines changed

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,20 @@ To generate automated commit messages:
2222
# Add your files like normal
2323
git add -u
2424
# Ai-generate commit messages
25-
how-commit
25+
ai-commit
2626
```
2727
![image](./images/image.png)
2828

2929

3030
Then, you can push your changes and use AI to auto-generate you a description
3131

32+
```bash
33+
ai-pr
3234
```
33-
how-pr
35+
36+
To then review:
37+
```bash
38+
ai-review
3439
```
3540

3641
See example PR: https://github.com/j2nullify/ai-git-commit/pull/2
37-

app/make_pull_request.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,39 @@ def main():
3838
prompt_body = f"Generate a concise and informative pull request description based on the following diff. Include key changes and their impact:\n\n{pr_diff}"
3939
pr_description = query_bedrock(prompt_body)
4040
pr_description = extract_bash_commands_no_line_split(pr_description)[0]
41+
prompt_label = f"""Based on the following diff, suggest the most appropriate label for this pull request based on SemVer2.
42+
Choose only one of: "minor", "patch", or "major". Respond with only the label.
43+
44+
<example>minor</example>
45+
<example>patch</example>
46+
<example>major</example>
47+
Diff:
48+
{pr_diff}
49+
"""
50+
pr_label = query_bedrock(prompt_label).strip()
51+
52+
for labels in pr_label:
53+
if "minor" in labels:
54+
pr_label = "minor"
55+
elif "patch" in labels:
56+
pr_label = "patch"
57+
elif "major" in labels:
58+
pr_label = "major"
59+
60+
# Validate the label
61+
if pr_label not in ["minor", "patch", "major"]:
62+
print(f"Warning: Invalid label '{pr_label}' generated. Defaulting to 'minor'.")
63+
pr_label = "minor"
64+
65+
# Create pull request using GitHub CLI with label
66+
result = subprocess.run([
67+
"gh", "pr", "create", "--title", pr_title, "--body", pr_description,
68+
"--label", pr_label])
69+
if result.returncode != 0:
70+
result = subprocess.run([
71+
"gh", "pr", "edit", "--title", pr_title, "--body", pr_description,
72+
"--label", pr_label])
73+
4174

4275
# Create pull request using GitHub CLI
4376
# Check if GitHub CLI (gh) is installed

app/pull_request_review.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
"""Make a pull request
2+
"""
3+
import subprocess
4+
from app.query_bedrock import query_bedrock
5+
from app.extract_bash import extract_bash_commands_no_line_split
6+
7+
def get_current_branch():
8+
return subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).decode().strip()
9+
10+
def get_pr_number():
11+
try:
12+
pr_info = subprocess.check_output(["gh", "pr", "view", "--json", "number"]).decode()
13+
return int(pr_info.split(":")[1].strip()[:-1])
14+
except subprocess.CalledProcessError:
15+
return None
16+
17+
def get_pr_diff(pr_number):
18+
try:
19+
diff = subprocess.check_output(["gh", "pr", "diff", str(pr_number)]).decode()
20+
return diff
21+
except subprocess.CalledProcessError:
22+
print(f"Error: Unable to get the diff for PR #{pr_number}.")
23+
return None
24+
25+
def review_pull_request(pr_number):
26+
pr_diff = get_pr_diff(pr_number)
27+
if not pr_diff:
28+
return
29+
prompt = f"""Review the following pull request diff and provide a concise review comment.
30+
Include any potential issues, suggestions for improvement, and overall assessment.
31+
If you have any specific code change suggestions, please include them as well.
32+
33+
{pr_diff}
34+
35+
Respond with only the review comment, enclosed in triple backticks (```). For example:
36+
```
37+
The changes look good overall. Consider adding more unit tests for the new functionality.
38+
39+
Suggestion for improvement:
40+
In file.py, line 42, consider changing:
41+
if x == None:
42+
to:
43+
if x is None:
44+
45+
This is more idiomatic Python and avoids potential issues with custom __eq__ methods.
46+
```
47+
"""
48+
49+
review_comment = query_bedrock(prompt)
50+
review_comment = extract_bash_commands_no_line_split(review_comment)[0]
51+
52+
try:
53+
result = subprocess.run([
54+
"gh", "pr", "review", str(pr_number),
55+
"--body", review_comment,
56+
"--comment"
57+
])
58+
59+
if result.returncode == 0:
60+
print(f"✅ Review submitted successfully for PR #{pr_number}!")
61+
else:
62+
print(f"❌ Failed to submit review for PR #{pr_number}. Please try again.")
63+
except subprocess.CalledProcessError:
64+
print(f"Error: Unable to submit review for PR #{pr_number}.")
65+
66+
def main():
67+
# Check if GitHub CLI (gh) is installed
68+
try:
69+
subprocess.run(["gh", "--version"], check=True, capture_output=True)
70+
except (subprocess.CalledProcessError, FileNotFoundError):
71+
print("GitHub CLI (gh) is not installed or not found. Please install it to review pull requests.")
72+
print("Visit https://cli.github.com/ for installation instructions.")
73+
return
74+
75+
current_branch = get_current_branch()
76+
pr_number = get_pr_number()
77+
78+
if pr_number is None:
79+
print(f"No pull request found for the current branch '{current_branch}'.")
80+
create_pr = input("Would you like to create a pull request? (y/n): ").lower()
81+
if create_pr == 'y':
82+
subprocess.run(["python", "app/make_pull_request.py"])
83+
pr_number = get_pr_number()
84+
else:
85+
print("Exiting without creating a pull request.")
86+
return
87+
88+
if pr_number:
89+
review_pull_request(pr_number)
90+
else:
91+
print("Unable to find or create a pull request. Please check your branch and try again.")
92+
93+
if __name__ == "__main__":
94+
main()

setup.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@
3232
entry_points={
3333
"console_scripts": [
3434
"how=app.cli:main",
35-
"how-commit=app.commit:main",
36-
"how-pr=app.make_pull_request:main",
35+
"ai-commit=app.commit:main",
36+
"ai-pr=app.make_pull_request:main",
37+
"ai-review=app.pull_request_review:main",
3738
],
3839
},
3940
)

0 commit comments

Comments
 (0)