-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgm.py
165 lines (139 loc) · 5.05 KB
/
gm.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
from datetime import datetime, timedelta
from os import environ
from typing import Dict, Optional
import openai
from github import AuthenticatedUser, Event, Github, NamedUser
openai.api_key = environ.get("OPENAI_API_KEY")
OPENAI_MODEL = environ.get("OPENAI_MODEL", "gpt-4")
def hey_gpt(events: list[dict]) -> str:
# @TODO: update to stream response back
prompt = f"""
Hi! Can you write an engineering stand up for me?
I'd like it to be a list and include details.
Here's what I did yesterday:
{events}
"""
completion = openai.ChatCompletion.create(
model=OPENAI_MODEL, messages=[{"role": "user", "content": prompt}]
)
output = completion.choices[0].message["content"].strip()
return output
# only care about code related events
GH_EVENTS = [
# "CommitCommentEvent",
# "CreateEvent",
# "DeleteEvent",
# "ForkEvent",
# "GollumEvent",
"IssueCommentEvent",
# "IssuesEvent",
# "MemberEvent",
# "PublicEvent",
"PullRequestEvent",
"PullRequestReviewEvent",
"PullRequestReviewCommentEvent",
"PullRequestReviewThreadEvent",
"PushEvent",
# "ReleaseEvent",
# "SponsorshipEvent",
# "WatchEvent",
]
def github_user(
token: str, user: str
) -> NamedUser.NamedUser | AuthenticatedUser.AuthenticatedUser:
g = Github(token)
u = g.get_user(user)
return u
def event_dict(event: Event.Event) -> Dict[str, str]:
E = {}
E["repo"] = event.repo.full_name
E["type"] = event.type
E["created_at"] = event.created_at.date().isoformat()
return E
def github_event(event: Event.Event) -> Optional[Dict[str, str]]:
# @TODO: probably a better way to do this
if (
event.type == "PullRequestReviewEvent"
and event.payload["review"]["state"] == "approved"
):
E = event_dict(event)
E["pull_request"] = event.payload["pull_request"]["head"]["ref"]
E["pull_request_title"] = event.payload["pull_request"]["title"]
E["review"] = event.payload["review"]["state"]
return E
elif event.type == "PushEvent" and len(event.payload["commits"]) > 0:
E = event_dict(event)
E["branch"] = event.payload["ref"]
E["commits"] = []
commits = event.payload["commits"]
for i in range(len(commits)):
E["commits"].append(strip_commit_message(commits[i]["message"]))
return E
elif event.type == "PullRequestReviewCommentEvent":
E = event_dict(event)
E["pull_request"] = event.payload["pull_request"]["head"]["ref"]
E["pull_request_title"] = event.payload["pull_request"]["title"]
E["comment"] = event.payload["comment"]["body"]
E["comment_code"] = event.payload["comment"]["diff_hunk"]
E["comment_file"] = event.payload["comment"]["path"]
return E
elif event.type == "PullRequestEvent" and event.payload["action"] == "opened":
E = event_dict(event)
E["pull_request"] = event.payload["pull_request"]["head"]["ref"]
E["pull_request_title"] = event.payload["pull_request"]["title"]
E["action"] = event.payload["action"]
E["body"] = event.payload["pull_request"]["body"]
return E
elif event.type == "IssueCommentEvent":
E = event_dict(event)
E["issue"] = event.payload["issue"]["title"]
E["comment"] = event.payload["comment"]["body"]
return E
else:
return None
def strip_commit_message(message: str) -> str:
# remove lines starting with 'Signed-off-by:'
lines = message.splitlines()
lines = [line for line in lines if not line.startswith("Signed-off-by:")]
return "\n".join(lines)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--user", type=str, help="GitHub username", required=True)
parser.add_argument(
"-o", "--org", type=str, help="GitHub organization", required=True
)
parser.add_argument(
"-t", "--token", type=str, help="GitHub access token", required=False
)
parser.add_argument("-d", "--days", type=int, help="Days back", default=1)
args = parser.parse_args()
if not args.token:
args.token = environ.get("GITHUB_TOKEN")
if not args.token:
raise Exception(
"No GitHub token provided, use --token <token> or GITHUB_TOKEN env var"
)
u = github_user(args.token, args.user)
gh_event_log = []
for e in u.get_events():
# make this more configurable
# use for organization or personal events
if (
e.org is not None
# belongs to the `--org`
and e.org.login == args.org
# events within last `--days`
and (
e.created_at.date()
>= (datetime.today() - timedelta(days=args.days)).date()
)
# only certain events
and e.type in GH_EVENTS
):
E = github_event(e)
if E is not None:
gh_event_log.append(E)
print(hey_gpt(gh_event_log))