diff --git a/forwardport/tests/test_weird.py b/forwardport/tests/test_weird.py
index 8ce88f77..ab077c05 100644
--- a/forwardport/tests/test_weird.py
+++ b/forwardport/tests/test_weird.py
@@ -847,6 +847,11 @@ def test_freeze(env, config, make_repo, users):
assert not w_id.errors
w_id.action_freeze()
+
+ # re-enable forward-port cron after freeze
+ _, cron_id = env['ir.model.data'].check_object_reference('forwardport', 'port_forward', context={'active_test': False})
+ env['ir.cron'].browse([cron_id]).active = True
+
# run crons to process the feedback, run a second time in case of e.g.
# forward porting
env.run_crons()
diff --git a/runbot_merge/models/project_freeze/__init__.py b/runbot_merge/models/project_freeze/__init__.py
index 73889ae7..4e513be6 100644
--- a/runbot_merge/models/project_freeze/__init__.py
+++ b/runbot_merge/models/project_freeze/__init__.py
@@ -9,8 +9,9 @@ from collections import Counter
from markupsafe import Markup
from odoo import models, fields, api, Command
-from odoo.exceptions import UserError
from odoo.addons.runbot_merge.exceptions import FastForwardError
+from odoo.exceptions import UserError
+from odoo.tools import drop_view_if_exists
_logger = logging.getLogger(__name__)
class FreezeWizard(models.Model):
@@ -38,11 +39,7 @@ class FreezeWizard(models.Model):
if v
)
- release_label = fields.Char(
- string="Find by label",
- help="Setting a (complete) PR label will automatically find and "
- "configure the corresponding PRs as release",
- )
+ release_label = fields.Many2one('runbot_merge.freeze.labels', store=False, string="Release label", help="Find release PRs by label")
release_pr_ids = fields.One2many(
'runbot_merge.project.freeze.prs', 'wizard_id',
string="Release pull requests",
@@ -50,11 +47,7 @@ class FreezeWizard(models.Model):
"one per repository",
)
- bump_label = fields.Char(
- string="Find by label",
- help="Setting a (complete) PR label will automatically find and "
- "configure the corresponding PRs as bump",
- )
+ bump_label = fields.Many2one('runbot_merge.freeze.labels', store=False, string="Bump label", help="Find bump PRs by label")
bump_pr_ids = fields.One2many(
'runbot_merge.project.freeze.bumps', 'wizard_id',
string="Bump pull requests",
@@ -73,42 +66,51 @@ class FreezeWizard(models.Model):
return
prs = self.env['runbot_merge.pull_requests'].search([
- ('label', '=', self.release_label)
+ ('label', '=', self.release_label.label),
+ ('state', 'not in', ('merged', 'closed')),
])
for release_pr in self.release_pr_ids:
- release_pr.pr_id = prs.filtered(lambda p: p.repository == release_pr.repository_id)
+ p = prs.filtered(lambda p: p.repository == release_pr.repository_id)
+ if len(p) < 2:
+ release_pr.pr_id = p
@api.onchange('release_pr_ids')
def _onchange_release_prs(self):
labels = {p.pr_id.label for p in self.release_pr_ids if p.pr_id}
- self.release_label = len(labels) == 1 and labels.pop()
+ self.release_label = len(labels) == 1 and self.env['runbot_merge.freeze.labels'].search([
+ ('label', '=', labels.pop()),
+ ])
@api.onchange('bump_label')
def _onchange_bump_label(self):
- if not self.release_label:
+ if not self.bump_label:
return
-
prs = self.env['runbot_merge.pull_requests'].search([
- ('label', '=', self.bump_label)
+ ('label', '=', self.bump_label.label),
+ ('state', 'not in', ('merged', 'closed')),
])
-
- commands = [Command.clear()]
- for pr in prs:
- current = self.bump_pr_ids.filtered(lambda bump_pr: bump_pr.repository_id == pr.repository)
- if current:
- commands.append(Command.update(current.id, {'pr_id': pr.id}))
+ commands = []
+ for bump_pr in self.bump_pr_ids:
+ p = prs.filtered(lambda p: p.repository == bump_pr.repository_id)
+ if len(p) == 1:
+ commands.append(Command.update(bump_pr.id, {'pr_id': p.id}))
else:
- commands.append(Command.create({
- 'repository_id': pr.repository.id,
- 'pr_id': pr.id
- }))
+ commands.append(Command.delete(bump_pr.id))
+ prs -= p
- self.write({'bump_pr_ids': commands})
+ commands.extend(
+ Command.create({'repository_id': pr.repository.id, 'pr_id': pr.id})
+ for pr in prs
+ )
+
+ self.bump_pr_ids = commands
@api.onchange('bump_pr_ids')
def _onchange_bump_prs(self):
labels = {p.pr_id.label for p in self.bump_pr_ids if p.pr_id}
- self.bump_label = len(labels) == 1 and labels.pop()
+ self.bump_label = len(labels) == 1 and self.env['runbot_merge.freeze.labels'].search([
+ ('label', '=', labels.pop()),
+ ])
@api.depends('release_pr_ids.pr_id.label', 'required_pr_ids.state')
def _compute_errors(self):
@@ -433,3 +435,38 @@ class PullRequest(models.Model):
def _compute_state_color(self):
for p in self:
p.state_color = STATE_COLORMAP[p.state]
+
+class OpenPRLabels(models.Model):
+ """Hacking around using contextual display_name to try and autocomplete
+ labels through PRs doesn't work because the client fucks up the display_name
+ (apparently they're not keyed on the context), therefore the behaviour
+ is inconsistent as the label shown in the autocomplete will result in the
+ PR being shown as its label in the o2m, and the other way around (if a PR
+ is selected directly in the o2m, then the PR's base display_name will be
+ shown in the label lookup field).
+
+ Therefore create a dumbshit view of label records.
+
+ Under the assumption that we'll have less than 256 repositories, the id of a
+ label record is the PR's id shifted as the high 24 bits, and the repo id as
+ the low 8.
+ """
+ _name = 'runbot_merge.freeze.labels'
+ _description = "view representing labels for open PRs so they can autocomplete properly"
+ _rec_name = "label"
+ _auto = False
+
+ def init(self):
+ super().init()
+ drop_view_if_exists(self.env.cr, "runbot_merge_freeze_labels");
+ self.env.cr.execute("""
+ CREATE VIEW runbot_merge_freeze_labels AS (
+ SELECT DISTINCT ON (label)
+ id << 8 | repository as id,
+ label
+ FROM runbot_merge_pull_requests
+ WHERE state != 'merged' AND state != 'closed'
+ ORDER BY label, repository, id
+ )""")
+
+ label = fields.Char()
diff --git a/runbot_merge/models/project_freeze/views.xml b/runbot_merge/models/project_freeze/views.xml
index 6fc466e0..a2f8bfc3 100644
--- a/runbot_merge/models/project_freeze/views.xml
+++ b/runbot_merge/models/project_freeze/views.xml
@@ -29,7 +29,7 @@
-
+
diff --git a/runbot_merge/security/ir.model.access.csv b/runbot_merge/security/ir.model.access.csv
index 65f02444..a6cb79ba 100644
--- a/runbot_merge/security/ir.model.access.csv
+++ b/runbot_merge/security/ir.model.access.csv
@@ -1,8 +1,9 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_runbot_merge_project_admin,Admin access to project,model_runbot_merge_project,runbot_merge.group_admin,1,1,1,1
access_runbot_merge_project_freeze,Admin access to freeze wizard,model_runbot_merge_project_freeze,runbot_merge.group_admin,1,1,0,0
-access_runbot_merge_project_freeze_prs,Admin access to freeze wizard release prs,model_runbot_merge_project_freeze_prs,runbot_merge.group_admin,1,1,0,1
+access_runbot_merge_project_freeze_prs,Admin access to freeze wizard release prs,model_runbot_merge_project_freeze_prs,runbot_merge.group_admin,1,1,1,1
access_runbot_merge_project_freeze_bumps,Admin access to freeze wizard bump prs,model_runbot_merge_project_freeze_bumps,runbot_merge.group_admin,1,1,1,1
+access_runbot_merge_pr_labels,Admin access to labels view,model_runbot_merge_freeze_labels,runbot_merge.group_admin,1,0,0,0
access_runbot_merge_repository_admin,Admin access to repo,model_runbot_merge_repository,runbot_merge.group_admin,1,1,1,1
access_runbot_merge_repository_status_admin,Admin access to repo statuses,model_runbot_merge_repository_status,runbot_merge.group_admin,1,1,1,1
access_runbot_merge_branch_admin,Admin access to branches,model_runbot_merge_branch,runbot_merge.group_admin,1,1,1,1