[IMP] runbot_merge: tag PRs with a pseudo-branch on merge to master

If a PR got merged to master (or whatever the current development
branch is), there's no easy way to know what maintenance branch it
ended up landing in, except by asking git which branches contain the
commit (which can be rather slow).

Add a special case on merge which labels the PR with a pseudo-branch
patterned after the second-to-last branch of the project:

* if the branch ends with a number, increment the number by one
  e.g. 2.0 -> 2.1, 5 -> 5.1
* otherwise, just prefix with `post-` e.g. "maint" ->
  "post-maint" (that one doesn't sound very helpful, but I guess it's
  nice for the weirdoes who call their branches "natty narwhal" and
  shit)

Fixes #450
This commit is contained in:
Xavier Morel 2021-03-01 16:18:14 +01:00
parent 60af69b69f
commit 318803d7bb
2 changed files with 80 additions and 0 deletions

View File

@ -1843,6 +1843,15 @@ class Stagings(models.Model):
self, prs
)
prs.write({'state': 'merged'})
pseudobranch = None
if self.target == project.branch_ids[:1] and project.branch_ids[1:2]:
prev = project.branch_ids[1:2].name
m = re.search(r'(\d+)(?:\.(\d+))?$', prev)
if m:
pseudobranch = "%s.%d" % (m[1], (int(m[2] or 0) + 1))
else:
pseudobranch = 'post-' + prev
for pr in prs:
self.env['runbot_merge.pull_requests.feedback'].create({
'repository': pr.repository.id,
@ -1852,6 +1861,12 @@ class Stagings(models.Model):
}),
'close': True,
})
if pseudobranch:
self.env['runbot_merge.pull_requests.tagging'].create({
'repository': pr.repository.id,
'pull_request': pr.number,
'tags_add': json.dumps([pseudobranch]),
})
finally:
self.batch_ids.write({'active': False})
self.write({'active': False})

View File

@ -111,3 +111,68 @@ def test_status_skipped(env, project, repo, config):
repo.post_status('staging.maintenance', 'success', 'ci')
env.run_crons('runbot_merge.process_updated_commits')
assert st.state == 'success'
def test_pseudo_version_tag(env, project, make_repo, setreviewers, config):
""" Because the last branch in the sequence is "live", if a PR's merged in
it it's hard to know where it landed in terms of other branches.
Therefore if a PR is merged in one such branch, tag it using the previous
branch of the sequence:
* if that ends with a number, increment the number by 1
* otherwise add 'post-' prefix (I guess)
"""
repo = make_repo('repo')
project.branch_ids.sequence = 1
project.write({
'repo_ids': [(0, 0, {'name': repo.name, 'required_statuses': 'ci'})],
'branch_ids': [
(0, 0, {'name': '2.0', 'sequence': 11}),
(0, 0, {'name': '1.0', 'sequence': 21})
],
})
setreviewers(*project.repo_ids)
with repo:
[m] = repo.make_commits(None, Commit('c1', tree={'a': '1'}), ref='heads/master')
repo.make_ref('heads/1.0', m)
repo.make_ref('heads/2.0', m)
repo.make_ref('heads/bonk', m)
with repo:
repo.make_commits(m, Commit('pr1', tree={'b': '1'}), ref='heads/change')
pr = repo.make_pr(target='master', head='change')
repo.post_status(pr.ref, 'success', 'ci')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons() # should create staging
pr_id = env['runbot_merge.pull_requests'].search([
('repository.name', '=', repo.name),
('number', '=', pr.number)
])
assert pr_id.state == 'ready'
assert pr_id.staging_id
with repo:
repo.post_status('staging.master', 'success', 'ci')
env.run_crons() # should merge staging
assert pr_id.state == 'merged'
assert pr.labels >= {'2.1'}
# now the second branch is non-numeric, therefore the label should just be prefixed by "post-"
project.write({'branch_ids': [(0, 0, {'name': 'bonk', 'sequence': 6})]})
with repo:
repo.make_commits(m, Commit('pr2', tree={'c': '1'}), ref='heads/change2')
pr = repo.make_pr(target='master', head='change2')
repo.post_status(pr.ref, 'success', 'ci')
pr.post_comment('hansen r+', config['role_reviewer']['token'])
env.run_crons() # should create staging
pr_id = env['runbot_merge.pull_requests'].search([
('repository.name', '=', repo.name),
('number', '=', pr.number)
])
assert pr_id.state == 'ready', pr.comments
assert pr_id.staging_id
with repo:
repo.post_status('staging.master', 'success', 'ci')
env.run_crons() # should merge staging
assert pr_id.state == 'merged'
assert pr.labels >= {'post-bonk'}