[FIX] runbot_merge: correctly handle emptying PR body

The previous version of the code assumed `pr['body']` is always a
string, which is not correct, when the PR body is emptied the body
itself is removed (its value is `None`).

Add a case for this in the PR edition test, and avoid blowing up (or
adding empty newlines) when the PR body is empty. For PR creation this
issue was fixed in c2db5659d8 but
apparently I missed that the exact same issue occurs just a few lines
above.

Also turns out github does *not* send change information when the body
is updated from (or to?) `None`, so don't even bother with that, just
check every time if the overall message has been updated.

Fixes #629
This commit is contained in:
Xavier Morel 2022-07-11 14:00:35 +02:00
parent b86092de83
commit 3da1874196
4 changed files with 30 additions and 18 deletions

View File

@ -826,6 +826,12 @@ mutation setDraft($pid: ID!) {
}
}
'''
def state_prop(name: str) -> property:
@property
def _prop(self):
return self._pr[name]
return _prop.setter(lambda self, v: self._set_prop(name, v))
class PR:
def __init__(self, repo, number):
self.repo = repo
@ -850,15 +856,9 @@ class PR:
caching['If-Modified-Since']= r.headers['Last-Modified']
return contents
@property
def title(self):
return self._pr['title']
title = title.setter(lambda self, v: self._set_prop('title', v))
@property
def base(self):
return self._pr['base']
base = base.setter(lambda self, v: self._set_prop('base', v))
title = state_prop('title')
body = state_prop('body')
base = state_prop('base')
@property
def draft(self):
@ -888,10 +888,6 @@ class PR:
def state(self):
return self._pr['state']
@property
def body(self):
return self._pr['body']
@property
def comments(self):
r = self.repo._session.get('https://api.github.com/repos/{}/issues/{}/comments'.format(self.repo.name, self.number))

View File

@ -0,0 +1,4 @@
FIX: correctly handle PR empty PR descriptions
Github's webhook for this case are weird, and weren't handled correctly,
updating a PR's description to *or from* empty might be mishandled.

View File

@ -120,15 +120,25 @@ def handle_pr(env, event):
if not source_branch:
return handle_pr(env, dict(event, action='opened'))
pr_obj = find(source_branch)
updates = {}
if source_branch != branch:
if branch != pr_obj.target:
updates['target'] = branch.id
updates['squash'] = pr['commits'] == 1
if event['changes'].keys() & {'title', 'body'}:
updates['message'] = "{}\n\n{}".format(pr['title'].strip(), pr['body'].strip())
# turns out github doesn't bother sending a change key if the body is
# changing from empty (None), therefore ignore that entirely, just
# generate the message and check if it changed
message = pr['title'].strip()
body = (pr['body'] or '').strip()
if body:
message += f"\n\n{body}"
if message != pr_obj.message:
updates['message'] = message
_logger.info("update: %s#%d = %s (by %s)", repo.name, pr['number'], updates, event['sender']['login'])
if updates:
pr_obj = find(source_branch)
pr_obj.write(updates)
return 'Updated {}'.format(pr_obj.id)
return "Nothing to update ({})".format(event['changes'].keys())

View File

@ -728,6 +728,8 @@ class TestPREdition:
assert pr.message == 'title\n\nbody'
with repo: prx.title = "title 2"
assert pr.message == 'title 2\n\nbody'
with repo: prx.body = None
assert pr.message == "title 2"
assert pr.staging_id, \
"message edition does not affect staging of rebased PRs"
with repo: prx.base = '1.0'