Skip to content

Commit 5283a54

Browse files
authored
Comment on backport PR when status checks are done. (GH-27)
Leave a comment when status checks for the backport PR are done. Only leave the comment on backports made by @miss-islington. Mention the original PR author and the core dev who merged the original PR. Closes python/miss-islington#26
1 parent 2aa60bd commit 5283a54

File tree

5 files changed

+89
-6
lines changed

5 files changed

+89
-6
lines changed

backport/__main__.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,12 @@
1414
from . import tasks
1515
from . import backport_pr
1616
from . import delete_branch
17+
from . import status_change
18+
19+
router = routing.Router(backport_pr.router,
20+
delete_branch.router,
21+
status_change.router)
1722

18-
router = routing.Router(backport_pr.router, delete_branch.router)
1923
cache = cachetools.LRUCache(maxsize=500)
2024

2125

backport/backport_pr.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ async def backport_pr(event, gh, *args, **kwargs):
4343

4444
util.comment_on_pr(issue_number, message)
4545

46-
for branch in branches:
46+
sorted_branches = sorted(branches,
47+
reverse=True,
48+
key=lambda v: tuple(map(int, v.split('.'))))
49+
50+
for branch in sorted_branches:
4751
tasks.backport_task.delay(commit_hash,
4852
branch,
4953
issue_number=issue_number,

backport/status_change.py

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import requests
2+
import os
3+
import re
4+
5+
from gidgethub import sansio, routing
6+
7+
from . import util
8+
9+
router = routing.Router()
10+
11+
TITLE_RE = re.compile(r'\[(?P<branch>\d+\.\d+)\].+?(?P<pr>\d+)\)')
12+
13+
14+
15+
@router.register("status")
16+
async def check_status(event, gh, *args, **kwargs):
17+
"""
18+
Check the state change
19+
"""
20+
if event.data["commit"]["committer"]["login"] == "miss-islington":
21+
sha = event.data["sha"]
22+
status_url = f"https://github.com/api/repos/python/cpython/commits/{sha}/status"
23+
request_headers = sansio.create_headers(
24+
"miss-islington",
25+
oauth_token=os.getenv('GH_AUTH'))
26+
response = requests.get(status_url,
27+
headers=request_headers)
28+
result = response.json()
29+
30+
if result["state"] != "pending":
31+
url = "https://github.com/api/repos/miss-islington/cpython/git/refs/heads/"
32+
response = requests.get(url, headers=request_headers)
33+
for ref in response.json():
34+
print("ref obj")
35+
print(ref)
36+
if "backport-" in ref["ref"] and ref["object"]["sha"] == sha:
37+
backport_branch_name = ref["ref"].split("/")[-1]
38+
pr_url = f"https://github.com/api/repos/python/cpython/pulls?state=open&head=miss-islington:{backport_branch_name}"
39+
pr_response = requests.get(pr_url, headers=request_headers).json()
40+
print("pr respponse")
41+
print(pr_response)
42+
if pr_response:
43+
pr_number = pr_response[0]["number"]
44+
normalized_pr_title = util.normalize_title(pr_response[0]["title"],
45+
pr_response[0]["body"])
46+
47+
title_match = TITLE_RE.match(normalized_pr_title)
48+
if title_match:
49+
original_pr_number = title_match.group('pr')
50+
original_pr_url = f"https://github.com/api/repos/python/cpython/pulls/{original_pr_number}"
51+
original_pr_result = requests.get(original_pr_url,
52+
headers=request_headers).json()
53+
pr_author = original_pr_result["user"]["login"]
54+
committer = original_pr_result["merged_by"]["login"]
55+
56+
participants = util.get_participants(
57+
pr_author, committer)
58+
emoji = "✅" if result['state'] == "success" else "❌"
59+
util.comment_on_pr(
60+
pr_number,
61+
message=f"{participants}: Backport status check is done, and it's a {result['state']} {emoji} .")

backport/tasks.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,13 @@ def backport_task(commit_hash, branch, *, issue_number, created_by, merged_by):
3030
"""Backport a commit into a branch."""
3131
if not util.is_cpython_repo():
3232
# cd to cpython if we're not already in it
33-
34-
os.chdir('./cpython')
33+
if "cpython" in os.listdir('.'):
34+
os.chdir('./cpython')
35+
else:
36+
print(f"pwd: {os.pwd()}, listdir: {os.listdir('.')}")
37+
util.comment_on_pr(issue_number,
38+
f"""{util.get_participants(created_by, merged_by)}, Something is wrong... I can't backport for now.
39+
Please backport using [cherry_picker](https://pypi.org/project/cherry-picker/) on command line.""")
3540
cp = cherry_picker.CherryPicker('origin', commit_hash, [branch])
3641
try:
3742
cp.backport()

backport/util.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def comment_on_pr(issue_number, message):
2020
headers=request_headers,
2121
json=data)
2222
if response.status_code == requests.codes.created:
23-
print(f"Commented at {response.json()['html_url']}")
23+
print(f"Commented at {response.json()['html_url']}, message: {message}")
2424
else:
2525
print(response.status_code)
2626
print(response.text)
@@ -60,4 +60,13 @@ def delete_branch(branch_name):
6060
if response.status_code == 204:
6161
print(f"{branch_name} branch deleted.")
6262
else:
63-
print(f"Couldn't delete the branch {branch_name}")
63+
print(f"Couldn't delete the branch {branch_name}")
64+
65+
66+
def normalize_title(title, body):
67+
"""Normalize the title if it spills over into the PR's body."""
68+
if not (title.endswith('…') and body.startswith('…')):
69+
return title
70+
else:
71+
# Being paranoid in case \r\n is used.
72+
return title[:-1] + body[1:].partition('\r\n')[0]

0 commit comments

Comments
 (0)