[CHG] runbot_merge: branch_ids -> branch_filter

On per-repo status configurations, convert the "branch_ids" filter to
a domain on branches. Since the selection is generally
binary (statuses either apply to the master branch or apply to
non-master branch) this avoids error-prone missed updates where we
forget to enable statuses pretty much every time we fork off a new
branch.

Fixes #404
This commit is contained in:
Xavier Morel 2020-10-02 10:48:25 +02:00
parent 2fafd5419a
commit c78ffb9e3f
5 changed files with 31 additions and 5 deletions

View File

@ -1,6 +1,6 @@
{
'name': 'merge bot',
'version': '1.4',
'version': '1.5',
'depends': ['contacts', 'website'],
'data': [
'security/security.xml',

View File

@ -0,0 +1,22 @@
def migrate(cr, version):
""" copy required status filters from an m2m to branches to a domain
"""
cr.execute("""
ALTER TABLE runbot_merge_repository_status
ADD COLUMN branch_filter varchar
""")
cr.execute('''
SELECT status_id, array_agg(branch_id)
FROM runbot_merge_repository_status_branch
GROUP BY status_id
''')
for st, brs in cr.fetchall():
cr.execute("""
UPDATE runbot_merge_repository_status
SET branch_filter = %s
WHERE id = %s
""", [
repr([('id', 'in', brs)]),
st
])
cr.execute("DROP TABLE runbot_merge_repository_status_branch")

View File

@ -236,14 +236,18 @@ class StatusConfiguration(models.Model):
context = fields.Char(required=True)
repo_id = fields.Many2one('runbot_merge.repository', required=True, ondelete='cascade')
branch_ids = fields.Many2many('runbot_merge.branch', 'runbot_merge_repository_status_branch', 'status_id', 'branch_id')
branch_filter = fields.Char(help="branches this status applies to")
# FIXME: migrate branch_ids -> branch_filter = [('id', 'in', branch_ids.ids)]
prs = fields.Boolean(string="Applies to pull requests", default=True)
stagings = fields.Boolean(string="Applies to stagings", default=True)
def _for_branch(self, branch):
assert branch._name == 'runbot_merge.branch', \
f'Expected branch, got {branch}'
return self.filtered(lambda st: not st.branch_ids or branch in st.branch_ids)
return self.filtered(lambda st: (
not st.branch_filter
or branch.filtered_domain(ast.literal_eval(st.branch_filter))
))
def _for_pr(self, pr):
assert pr._name == 'runbot_merge.pull_requests', \
f'Expected pull request, got {pr}'

View File

@ -14,7 +14,7 @@ def repo(env, project, make_repo, users, setreviewers):
# require the lint status on master
(0, 0, {
'context': 'lint',
'branch_ids': [(4, project.branch_ids.id, False)]
'branch_filter': [('id', '=', project.branch_ids.id)]
}),
(0, 0, {'context': 'pr', 'stagings': False}),
(0, 0, {'context': 'staging', 'prs': False}),

View File

@ -64,7 +64,7 @@
<field name="status_ids">
<tree editable="bottom">
<field name="context"/>
<field name="branch_ids" widget="many2many_tags"/>
<field name="branch_filter" widget="domain"/>
<field name="prs"/>
<field name="stagings"/>
</tree>