-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgavin_bot.py
136 lines (116 loc) · 3.94 KB
/
gavin_bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import os
import requests
from fastapi import FastAPI, Request
from github import GithubIntegration
from code_updater import (
check_issue_support,
run,
)
import shutil
import subprocess
from decouple import config
app = FastAPI()
app_id = config('GITHUB_APP_ID')
app_key_path = config('GITHUB_APP_KEY_PATH')
with open(os.path.normpath(os.path.expanduser(app_key_path)), "r") as cert_file:
app_key = cert_file.read()
gi = GithubIntegration(
app_id,
app_key,
)
installation = gi.get_installations()[0]
g = installation.get_github_for_installation()
def git_command(command, cwd):
"""
Run a Git command in the specified directory.
Args:
command (str): The Git command to run.
cwd (str): The directory to run the command in.
Returns:
str: The output of the Git command.
"""
result = subprocess.run(
command, cwd=cwd, shell=True, text=True, capture_output=True
)
if result.returncode != 0:
raise Exception(f"Git command failed: {result.stderr}")
return result.stdout
def process_issue(title, body, github_repo, issue_id):
"""
Process an issue by cloning the repository, checking if the issue is supported,
running the fix, and creating a pull request.
Args:
title (str): The title of the issue.
body (str): The body of the issue.
github_repo (str): The name of the GitHub repository.
issue_id (int): The ID of the issue.
"""
repo = g.get_repo(github_repo)
issue = repo.get_issue(number=issue_id)
issue.edit(labels=["GAVIN PROCESSING"])
try:
# Get the issue and process it
if not check_issue_support(title, body):
issue.edit(labels=["Human Action Needed"])
return
# download repo
temp_dir = "temp"
if os.path.exists(temp_dir):
print("Deleting temp directory")
shutil.rmtree(temp_dir)
os.makedirs(temp_dir)
git_command(
f"git clone https://github.com/{github_repo}.git {temp_dir}", cwd="."
)
git_command(f"git checkout -b issue-{issue_id}", cwd=temp_dir)
git_command(f"git pull origin main", cwd=temp_dir)
git_command(f"git rebase main", cwd=temp_dir)
print("Running Fix")
run(temp_dir, body)
print("Fix complete")
branch_name = f"issue-{issue_id}"
git_command(f"git add .", cwd=temp_dir)
git_command(f'git commit -m "Fix issue #{issue_id}: {title}"', cwd=temp_dir)
git_command(f"git push origin {branch_name}", cwd=temp_dir)
# Create a pull request
pr = repo.create_pull(
title=f"Fix issue #{issue_id}: {title}",
body=f"Automatically created PR to fix issue #{issue_id}",
head=branch_name,
base="main",
)
issue.edit(labels=["GAVIN PROCESSED"], state="closed")
print(f"Pull request created: {pr.html_url}")
shutil.rmtree(temp_dir)
except Exception as e:
print(e)
issue.edit(labels=["Human Action Needed"])
def label_update():
"""
Update the labels of an issue in a test repository.
"""
repo = g.get_repo("dvlpjrs/test_issue")
print(repo)
issue = repo.get_issue(number=1)
issue.edit(labels=["Human Action Needed"])
@app.post("/")
async def bot(request: Request):
"""
Handle incoming requests from GitHub.
Args:
request (Request): The incoming request.
Returns:
str: A response to the request.
"""
payload = await request.json()
if payload["action"] == "opened":
if "issue" in payload:
title = payload["issue"]["title"]
body = payload["issue"]["body"]
github_repo = payload["repository"]["full_name"]
issue_id = payload["issue"]["number"]
process_issue(title, body, github_repo, issue_id)
return "ok"
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=3000)