Skip to content

Commit 182b7cd

Browse files
committed
Uses labels as filters for notification
Addresses PR reviews
1 parent 64b131b commit 182b7cd

File tree

1 file changed

+69
-24
lines changed

1 file changed

+69
-24
lines changed

bin/lib/notify.py

Lines changed: 69 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
OWNER_REPO = "compiler-explorer/compiler-explorer"
77
USER_AGENT = "CE Live Now Notification Bot"
88

9+
NOW_LIVE_LABEL = "live"
10+
NOW_LIVE_MESSAGE = "This is now live"
11+
912

1013
def post(entity: str, token: str, query: dict = None, dry=False) -> dict:
1114
if query is None:
@@ -74,25 +77,33 @@ def list_inbetween_commits(end_commit: str, new_commit: str, token: str) -> List
7477

7578

7679
def get_linked_pr(commit: str, token: str) -> dict:
80+
"""Returns a list whose items are the PR associated to each commit"""
7781
pr = get(f"repos/{OWNER_REPO}/commits/{commit}/pulls", token=token)
78-
return pr
82+
return pr[0] if len(pr) == 1 else {}
7983

8084

8185
def get_linked_issues(pr: str, token: str):
8286
query = """
83-
query {
84-
repository(owner: "compiler-explorer", name: "compiler-explorer") {
85-
pullRequest(number: %s) {
86-
closingIssuesReferences(first: 10) {
87-
edges {
88-
node {
89-
number
90-
}
87+
query {
88+
repository(owner: "compiler-explorer", name: "compiler-explorer") {
89+
pullRequest(number: %s) {
90+
closingIssuesReferences(first: 10) {
91+
edges {
92+
node {
93+
labels(first: 10) {
94+
edges {
95+
node {
96+
name
9197
}
9298
}
9399
}
100+
number
101+
}
94102
}
103+
}
95104
}
105+
}
106+
}
96107
""" % pr
97108
return post("graphql", token, {"query": query})
98109

@@ -102,33 +113,67 @@ def get_issue_comments(issue: str, token: str) -> List[dict]:
102113

103114

104115
def comment_on_issue(issue: str, msg: str, token: str):
105-
result = post(f"repos/{OWNER_REPO}/issues/{issue}/comments", token, {"body": msg}, dry=True)
116+
result = post(f"repos/{OWNER_REPO}/issues/{issue}/comments", token, {"body": msg})
106117
return result
107118

108119

120+
def set_issue_labels(issue: str, labels: List[str], token: str):
121+
post(f"repos/{OWNER_REPO}/issues/{issue}/labels", token, {"labels": labels})
122+
123+
124+
def should_send_comment_to_issue(issue: str, token: str):
125+
"""Only send a comment to the issue if nothing like the live message is there already"""
126+
comments = get_issue_comments(issue, token)
127+
return all([NOW_LIVE_MESSAGE not in comment["body"] for comment in comments])
128+
129+
109130
def send_live_message(issue: str, token: str):
110-
comment_on_issue(issue, "This is now live", token=token)
131+
set_issue_labels(issue, [NOW_LIVE_LABEL], token)
132+
if should_send_comment_to_issue(issue, token):
133+
comment_on_issue(issue, NOW_LIVE_MESSAGE, token)
111134

112135

113136
def get_edges(issue: dict) -> List[dict]:
114137
return issue["data"]["repository"]["pullRequest"]["closingIssuesReferences"]["edges"]
115138

116139

140+
def should_process_pr(pr_labels):
141+
"""Only process PRs that do not have the live label already set"""
142+
return all([label["name"] != NOW_LIVE_LABEL for label in pr_labels])
143+
144+
145+
def should_notify_issue(edge) -> bool:
146+
"""We want to notify the issue if:
147+
- there's one linked ("number" in edge) AND
148+
- either:
149+
- the linked issue has no labels ("labels" not in edge["node"]) OR
150+
- the NOW_LIVE_LABEL label is not among its labels"""
151+
return "number" in edge and (("labels" not in edge) or all(
152+
[label["node"]["name"] != NOW_LIVE_LABEL for label in edge["labels"]["edges"]]))
153+
154+
117155
def handle_notify(base, new, token):
118-
print(f'Notifying from {base} to {new}')
156+
print(f'Checking for live notifications from {base} to {new}')
119157

120158
commits = list_inbetween_commits(base, new, token)
121-
122159
prs = [get_linked_pr(commit["sha"], token) for commit in commits]
123-
ids = [pr[0]["number"] for pr in prs]
124-
linked_issues = [get_linked_issues(pr, token) for pr in ids]
125-
issues_ids = [get_edges(issue) for issue in linked_issues if len(get_edges(issue)) > 0]
126-
127-
for edge in issues_ids:
128-
for node in edge:
129-
issue = node["node"]["number"]
130-
comments = get_issue_comments(issue, token)
131-
if not any(["This is now live" in comment["body"] for comment in comments]):
132-
send_live_message(issue, token)
160+
161+
for pr_data in prs:
162+
pr_id = pr_data["number"]
163+
if should_process_pr(pr_data["labels"]):
164+
print(f"Notifying PR {pr_id}")
165+
send_live_message(pr_id, token)
166+
167+
linked_issues = get_linked_issues(pr_id, token)
168+
issues_edges = get_edges(linked_issues)
169+
if len(issues_edges) == 1 and "node" in issues_edges[0]:
170+
edge = issues_edges[0]["node"]
171+
if should_notify_issue(edge):
172+
print(f"Notifying issue {edge['number']}")
173+
send_live_message(edge['number'], token)
174+
else:
175+
print(f"Skipping notifying issue {edge['number']}")
133176
else:
134-
print(f"Skipping notifying {issue}, it's already been done")
177+
print(f"No issues in which to notify for PR {pr_id}")
178+
else:
179+
print(f"Skipping notifying PR {pr_id}")

0 commit comments

Comments
 (0)