[IMP] runbot_merge: ping commenter when fetching PR due to comment

If a comment causes an unknown PR to be fetched, it's a bit odd to
ping the author (and possibly reviewer) anyway as they're not super
concerned (and technically we could be ignoring the purported /
attempted reviewer).

So if a fetch job was created because of a comment, remember the
comment author and ping *them* instead of using the default ping
policy.

Fixes #981
This commit is contained in:
Xavier Morel 2024-11-18 13:52:27 +01:00
parent c974f51036
commit fbfb96be53
4 changed files with 35 additions and 8 deletions

View File

@ -431,7 +431,9 @@ def _handle_comment(env, repo, issue, comment, target=None):
if not repository.project_id._find_commands(comment['body'] or ''):
return "No commands, ignoring"
pr = env['runbot_merge.pull_requests']._get_or_schedule(repo, issue, target=target)
pr = env['runbot_merge.pull_requests']._get_or_schedule(
repo, issue, target=target, commenter=comment['user']['login'],
)
if not pr:
return "Unknown PR, scheduling fetch"

View File

@ -16,7 +16,7 @@ runbot_merge.pr.load.unmanaged,"Branch `{pr[base][ref]}` is not within my remit,
pr: pull request (github object)
Repository: repository object (???)"
runbot_merge.pr.load.fetched,"{pr.ping}I didn't know about this PR and had to retrieve its information, you may have to re-approve it as I didn't see previous commands.","Notifies that we did retrieve an unknown PR (either by request or as side effect of an interaction).
runbot_merge.pr.load.fetched,"{ping}I didn't know about this PR and had to retrieve its information, you may have to re-approve it as I didn't see previous commands.","Notifies that we did retrieve an unknown PR (either by request or as side effect of an interaction).
Pr: pr object we just created"
runbot_merge.pr.branch.disabled,"{pr.ping}the target branch {pr.target.name!r} has been disabled, you may want to close this PR.","Notifies that the target branch for this PR was deactivated.

1 id template help
16 runbot_merge.pr.linked.not_ready {pr.ping}linked pull request(s) {siblings} not ready. Linked PRs are not staged until all of them are ready. Comment when a PR is ready (approved & validated) but it is linked to other PRs which are not. pr: pr we're looking at siblings: its siblings, as a single comma-separated list of PR links
17 runbot_merge.pr.merge_method {pr.ping}because this PR has multiple commits, I need to know how to merge it: {methods} Comment when a PR is ready but doesn't have a merge method set pr: the pr we can't stage methods: a markdown-formatted list of valid merge methods
18 runbot_merge.pr.staging.mismatch {pr.ping}we apparently missed updates to this PR and tried to stage it in a state which might not have been approved. The properties {mismatch} were not correctly synchronized and have been updated. <details><summary>differences</summary> ```diff {diff}``` </details> Note that we are unable to check the properties {unchecked}. Please check and re-approve. Comment when staging was attempted but a sanity check revealed the github state and the mergebot state differ. pr: the pr we tried to stage mismatch: comma separated list of mismatched property names diff: patch-style view of the differing properties unchecked: comma-separated list of properties which can't be checked
19 runbot_merge.pr.staging.fail {pr.ping}staging failed: {message} Comment when a PR caused a staging to fail (normally only sent if the staging has a single batch, may be sent on multiple PRs depending whether the heuristic to guess the problematic PR of a batch succeeded) pr: the pr message: staging failure information (error message, build link, etc...)
20 runbot_merge.forwardport.updates.closed {pr.ping}ancestor PR {parent.display_name} has been updated but this PR is {pr.state} and can't be updated to match. You may want or need to manually update any followup PR. Comment when a PR is updated and on of its followups is already merged or closed. Sent to the followup. pr: the closed or merged PR parent: the modified ancestor PR
21 runbot_merge.forwardport.updates.conflict.parent {pr.ping}WARNING: the latest change ({pr.head}) triggered a conflict when updating the next forward-port ({next.display_name}), and has been ignored. You will need to update this pull request differently, or fix the issue by hand on {next.display_name}. Comment when a PR update triggers a conflict in a child. pr: updated parent PR next: child PR in conflict
22 runbot_merge.forwardport.updates.conflict.child {pr.ping}WARNING: the update of {previous.display_name} to {previous.head} has caused a conflict in this pull request, data may have been lost.{stdout}{stderr} Comment when a PR update followup is in conflict. pr: PR where update followup conflict happened previous: parent PR which triggered the followup stdout: markdown-formatted stdout of git, if any stderr: markdown-formatted stderr of git, if any

View File

@ -107,7 +107,14 @@ All substitutions are tentatively applied sequentially to the input.
self._cr, 'runbot_merge_unique_repo', self._table, ['name'])
return res
def _load_pr(self, number, *, closing=False, squash=False):
def _load_pr(
self,
number: int,
*,
closing: bool = False,
squash: bool = False,
ping: str | None = None,
):
gh = self.github()
# fetch PR object and handle as *opened*
@ -238,7 +245,10 @@ All substitutions are tentatively applied sequentially to the input.
self.env.ref('runbot_merge.pr.load.fetched')._send(
repository=self,
pull_request=number,
format_args={'pr': pr_id},
format_args={
'pr': pr_id,
'ping': ping or pr_id.ping,
},
)
def having_branch(self, branch):
@ -635,7 +645,15 @@ class PullRequests(models.Model):
return json.loads(self.overrides)
return {}
def _get_or_schedule(self, repo_name, number, *, target=None, closing=False) -> PullRequests | None:
def _get_or_schedule(
self,
repo_name: str,
number: int,
*,
target: str | None = None,
closing: bool = False,
commenter: str | None = None,
) -> PullRequests | None:
repo = self.env['runbot_merge.repository'].search([('name', '=', repo_name)])
if not repo:
source = self.env['runbot_merge.events_sources'].search([('repository', '=', repo_name)])
@ -682,6 +700,7 @@ class PullRequests(models.Model):
'repository': repo.id,
'number': number,
'closing': closing,
'commenter': commenter,
})
def _iter_ancestors(self) -> Iterator[PullRequests]:
@ -2518,6 +2537,7 @@ class FetchJob(models.Model):
number = fields.Integer(required=True, group_operator=None)
closing = fields.Boolean(default=False)
commits_at = fields.Datetime(index="btree_not_null")
commenter = fields.Char()
@api.model_create_multi
def create(self, vals_list):
@ -2545,7 +2565,12 @@ class FetchJob(models.Model):
f.active = False
self.env.cr.execute("SAVEPOINT runbot_merge_before_fetch")
try:
f.repository._load_pr(f.number, closing=f.closing, squash=bool(f.commits_at))
f.repository._load_pr(
f.number,
closing=f.closing,
squash=bool(f.commits_at),
ping=f.commenter and f'@{f.commenter} ',
)
except Exception:
self.env.cr.execute("ROLLBACK TO SAVEPOINT runbot_merge_before_fetch")
_logger.exception("Failed to load pr %s, skipping it", f.number)

View File

@ -3414,7 +3414,7 @@ class TestUnknownPR:
(users['reviewer'], 'hansen r+'),
(users['reviewer'], 'hansen r+'),
seen(env, prx, users),
(users['user'], f"@{users['user']} I didn't know about this PR and had to "
(users['user'], f"@{users['reviewer']} I didn't know about this PR and had to "
"retrieve its information, you may have to "
"re-approve it as I didn't see previous commands."),
]
@ -3470,7 +3470,7 @@ class TestUnknownPR:
# reviewer is set because fetch replays all the comments (thus
# setting r+ and reviewer) but then syncs the head commit thus
# unsetting r+ but leaving the reviewer
(users['user'], f"@{users['user']} I didn't know about this PR and had to retrieve "
(users['user'], f"@{users['reviewer']} I didn't know about this PR and had to retrieve "
"its information, you may have to re-approve it "
"as I didn't see previous commands."),
]