From 060709ac42a4cbf431a644f9af60a84df3f82cb4 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 13 Jan 2020 08:39:47 +0100 Subject: [PATCH 01/11] [ADD] forwardport: missing access rights --- forwardport/data/security.xml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/forwardport/data/security.xml b/forwardport/data/security.xml index 3f7b8248..d25ae794 100644 --- a/forwardport/data/security.xml +++ b/forwardport/data/security.xml @@ -17,7 +17,33 @@ 1 1 + + Admin access to tagging + + + 1 + 1 + 1 + 1 + + + Admin access to branch remover + + + 1 + 1 + 1 + 1 + + + No normal access to tagging + + 1 + 0 + 0 + 0 + No normal access to batches From a30a1c08e710637760902b460191abb27372caec Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 13 Jan 2020 08:40:12 +0100 Subject: [PATCH 02/11] [FIX] runbot_merge, forwardport: missing model descriptions Really can't be arsed to care, just want to remove the warning. --- forwardport/models/project.py | 1 + runbot_merge/models/pull_requests.py | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/forwardport/models/project.py b/forwardport/models/project.py index 46c7c0fc..43f9f667 100644 --- a/forwardport/models/project.py +++ b/forwardport/models/project.py @@ -886,6 +886,7 @@ class Feedback(models.Model): class Tagging(models.Model): _name = 'forwardport.tagging' + _description = "ad-hoc forwardport tagging commands" token_field = fields.Selection([ ('github_token', 'Mergebot'), diff --git a/runbot_merge/models/pull_requests.py b/runbot_merge/models/pull_requests.py index 4b942add..8ff699da 100644 --- a/runbot_merge/models/pull_requests.py +++ b/runbot_merge/models/pull_requests.py @@ -26,7 +26,7 @@ WAIT_FOR_VISIBILITY = [10, 10, 10, 10] _logger = logging.getLogger(__name__) class Project(models.Model): - _name = 'runbot_merge.project' + _name = _description = 'runbot_merge.project' name = fields.Char(required=True, index=True) repo_ids = fields.One2many( @@ -213,7 +213,7 @@ class Project(models.Model): return bool(self.env.cr.rowcount) class Repository(models.Model): - _name = 'runbot_merge.repository' + _name = _description = 'runbot_merge.repository' name = fields.Char(required=True) project_id = fields.Many2one('runbot_merge.project', required=True) @@ -285,7 +285,7 @@ class Repository(models.Model): }) class Branch(models.Model): - _name = 'runbot_merge.branch' + _name = _description = 'runbot_merge.branch' _order = 'sequence, name' name = fields.Char(required=True) @@ -507,7 +507,7 @@ class Branch(models.Model): ACL = collections.namedtuple('ACL', 'is_admin is_reviewer is_author') class PullRequests(models.Model): - _name = 'runbot_merge.pull_requests' + _name = _description = 'runbot_merge.pull_requests' _order = 'number desc' target = fields.Many2one('runbot_merge.branch', required=True, index=True) @@ -1259,7 +1259,7 @@ class Tagging(models.Model): way of that. Instead, queue tagging changes into this table whose execution can be cron-driven. """ - _name = 'runbot_merge.pull_requests.tagging' + _name = _description = 'runbot_merge.pull_requests.tagging' repository = fields.Many2one('runbot_merge.repository', required=True) # store the PR number (not id) as we need a Tagging for PR objects @@ -1290,7 +1290,7 @@ class Tagging(models.Model): class Feedback(models.Model): """ Queue of feedback comments to send to PR users """ - _name = 'runbot_merge.pull_requests.feedback' + _name = _description = 'runbot_merge.pull_requests.feedback' repository = fields.Many2one('runbot_merge.repository', required=True) # store the PR number (not id) as we may want to send feedback to PR @@ -1310,7 +1310,7 @@ class Commit(models.Model): independent of everything else as commits can be created by statuses only, by PR pushes, by branch updates, ... """ - _name = 'runbot_merge.commit' + _name = _description = 'runbot_merge.commit' sha = fields.Char(required=True) statuses = fields.Char(help="json-encoded mapping of status contexts to states", default="{}") @@ -1366,7 +1366,7 @@ class Commit(models.Model): return res class Stagings(models.Model): - _name = 'runbot_merge.stagings' + _name = _description = 'runbot_merge.stagings' target = fields.Many2one('runbot_merge.branch', required=True) @@ -1691,7 +1691,7 @@ class Stagings(models.Model): return repo_name class Split(models.Model): - _name = 'runbot_merge.split' + _name = _description = 'runbot_merge.split' target = fields.Many2one('runbot_merge.branch', required=True) batch_ids = fields.One2many('runbot_merge.batch', 'split_id', context={'active_test': False}) @@ -1703,7 +1703,7 @@ class Batch(models.Model): repositories e.g. change an API in repo1, this breaks use of that API in repo2 which now needs to be updated. """ - _name = 'runbot_merge.batch' + _name = _description = 'runbot_merge.batch' target = fields.Many2one('runbot_merge.branch', required=True) staging_id = fields.Many2one('runbot_merge.stagings') @@ -1796,7 +1796,7 @@ class Batch(models.Model): }) class FetchJob(models.Model): - _name = 'runbot_merge.fetch_job' + _name = _description = 'runbot_merge.fetch_job' active = fields.Boolean(default=True) repository = fields.Many2one('runbot_merge.repository', required=True) From 99d2d426eba8cf970eb9a700c730463788abab1c Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 13 Jan 2020 08:41:07 +0100 Subject: [PATCH 03/11] [FIX] runbot_merge: api.multi decorator removed --- runbot_merge/models/pull_requests.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/runbot_merge/models/pull_requests.py b/runbot_merge/models/pull_requests.py index 8ff699da..5b57e984 100644 --- a/runbot_merge/models/pull_requests.py +++ b/runbot_merge/models/pull_requests.py @@ -965,7 +965,6 @@ class PullRequests(models.Model): 'message': message, }) - @api.multi def write(self, vals): oldstate = { pr: pr._tagstate for pr in self } @@ -988,7 +987,6 @@ class PullRequests(models.Model): }) return w - @api.multi def unlink(self): for pr in self: self.env['runbot_merge.pull_requests.tagging'].create({ @@ -1466,7 +1464,6 @@ class Stagings(models.Model): vals['timeout_limit'] = fields.Datetime.to_string(datetime.datetime.now() + datetime.timedelta(minutes=s.target.project_id.ci_timeout)) s.write(vals) - @api.multi def action_cancel(self): self.cancel("explicitly cancelled by %s", self.env.user.display_name) return { 'type': 'ir.actions.act_window_close' } From 0bdc824c2ed8ce54415a58cdedc4fba96f57b534 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 13 Jan 2020 08:42:25 +0100 Subject: [PATCH 04/11] [FIX] runbot_merge: incorrect name_get implementation It's supposed to return a list of pairs, not a dict. --- runbot_merge/models/pull_requests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runbot_merge/models/pull_requests.py b/runbot_merge/models/pull_requests.py index 5b57e984..eaedbb00 100644 --- a/runbot_merge/models/pull_requests.py +++ b/runbot_merge/models/pull_requests.py @@ -574,10 +574,10 @@ class PullRequests(models.Model): return super(PullRequests, self)._compute_display_name() def name_get(self): - return { - p.id: '%s#%s' % (p.repository.name, p.number) + return [ + (p.id, '%s#%d' % (p.repository.name, p.number)) for p in self - } + ] def __str__(self): if len(self) == 0: From 27e9a4f9eec988222f0e705979caa5042631834d Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 13 Jan 2020 08:43:10 +0100 Subject: [PATCH 05/11] [FIX] runbot_merge: provide explicit labels on fields Two fields can't have the same label, because of the field names, there were field label conflicts. --- runbot_merge/models/pull_requests.py | 4 ++-- runbot_merge/models/res_partner.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/runbot_merge/models/pull_requests.py b/runbot_merge/models/pull_requests.py index eaedbb00..8ee7cb50 100644 --- a/runbot_merge/models/pull_requests.py +++ b/runbot_merge/models/pull_requests.py @@ -554,8 +554,8 @@ class PullRequests(models.Model): status = fields.Char(compute='_compute_statuses') previous_failure = fields.Char(default='{}') - batch_id = fields.Many2one('runbot_merge.batch',compute='_compute_active_batch', store=True) - batch_ids = fields.Many2many('runbot_merge.batch') + batch_id = fields.Many2one('runbot_merge.batch', string="Active Batch", compute='_compute_active_batch', store=True) + batch_ids = fields.Many2many('runbot_merge.batch', string="Batches") staging_id = fields.Many2one(related='batch_id.staging_id', store=True) commits_map = fields.Char(help="JSON-encoded mapping of PR commits to actually integrated commits. The integration head (either a merge commit or the PR's topmost) is mapped from the 'empty' pr commit (the key is an empty string, because you can't put a null key in json maps).", default='{}') diff --git a/runbot_merge/models/res_partner.py b/runbot_merge/models/res_partner.py index e170e80c..6fddbb06 100644 --- a/runbot_merge/models/res_partner.py +++ b/runbot_merge/models/res_partner.py @@ -8,7 +8,7 @@ class Partner(models.Model): reviewer = fields.Boolean(default=False, help="Can review PRs (maybe m2m to repos/branches?)") self_reviewer = fields.Boolean(default=False, help="Can review own PRs (independent from reviewer)") delegate_reviewer = fields.Many2many('runbot_merge.pull_requests') - formatted_email = fields.Char(compute='_rfc5322_formatted') + formatted_email = fields.Char(string="commit email", compute='_rfc5322_formatted') def _auto_init(self): res = super(Partner, self)._auto_init() From 08f73ea3d30c75f62035906b30f78e084ecd4d75 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 13 Jan 2020 08:43:57 +0100 Subject: [PATCH 06/11] [FIX] runbot_merge: convert priority field to a regular integer In 13.0, the value of a selection field can't be an integer anymore. --- runbot_merge/models/pull_requests.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/runbot_merge/models/pull_requests.py b/runbot_merge/models/pull_requests.py index 8ee7cb50..911d4048 100644 --- a/runbot_merge/models/pull_requests.py +++ b/runbot_merge/models/pull_requests.py @@ -544,11 +544,7 @@ class PullRequests(models.Model): reviewed_by = fields.Many2one('res.partner') delegates = fields.Many2many('res.partner', help="Delegate reviewers, not intrinsically reviewers but can review this PR") - priority = fields.Selection([ - (0, 'Urgent'), - (1, 'Pressing'), - (2, 'Normal'), - ], default=2, index=True) + priority = fields.Integer(default=2, index=True) statuses = fields.Text(compute='_compute_statuses') status = fields.Char(compute='_compute_statuses') From f91629f693d0f8e89e87335a61e79ff4fe2e2ad1 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 13 Jan 2020 08:45:10 +0100 Subject: [PATCH 07/11] [FIX] runbot_merge: v13 computed field compatibility In v13, computed fields *must* have their value set on all records. --- runbot_merge/models/pull_requests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/runbot_merge/models/pull_requests.py b/runbot_merge/models/pull_requests.py index 911d4048..f174f391 100644 --- a/runbot_merge/models/pull_requests.py +++ b/runbot_merge/models/pull_requests.py @@ -604,6 +604,7 @@ class PullRequests(models.Model): for s in self: c = Commits.search([('sha', '=', s.head)]) if not (c and c.statuses): + s.status = s.statuses = False continue statuses = json.loads(c.statuses) From 63271cd82e20f284cc037fa57d87eda4be2d84ce Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 13 Jan 2020 08:47:58 +0100 Subject: [PATCH 08/11] [IMP] runbot_merge: better notification of stored field update Using `modified` seems safer than just blowing the cache with respect to stored computed fields depending on PR state (not sure there are any but it's likely). --- runbot_merge/models/pull_requests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runbot_merge/models/pull_requests.py b/runbot_merge/models/pull_requests.py index f174f391..9612c5eb 100644 --- a/runbot_merge/models/pull_requests.py +++ b/runbot_merge/models/pull_requests.py @@ -1207,7 +1207,7 @@ class PullRequests(models.Model): WHERE id = %s AND state != 'merged' ''', [self.id]) self.env.cr.commit() - self.invalidate_cache(fnames=['state'], ids=[self.id]) + self.modified(['state']) if self.env.cr.rowcount: self.env['runbot_merge.pull_requests.tagging'].create({ 'pull_request': self.number, From 3f44bb5c9e4c468994ab1163b40e2b8af35cfece Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 21 Jan 2020 11:21:14 +0100 Subject: [PATCH 09/11] [FIX] runbot_merge: styling crap bs4 yields complete vomit on the template as-is (see: https://imgur.com/a/XIMn7MX). Add a bunch of color and styling overrides to get something closer to the original, and move the existing styles to a "proper" scss file while at it. --- runbot_merge/static/scss/runbot_merge.scss | 61 ++++++++++++++++++++++ runbot_merge/views/templates.xml | 34 +++--------- 2 files changed, 67 insertions(+), 28 deletions(-) create mode 100644 runbot_merge/static/scss/runbot_merge.scss diff --git a/runbot_merge/static/scss/runbot_merge.scss b/runbot_merge/static/scss/runbot_merge.scss new file mode 100644 index 00000000..33d60d86 --- /dev/null +++ b/runbot_merge/static/scss/runbot_merge.scss @@ -0,0 +1,61 @@ +// FIX: bs4 shit-heap colors and styles +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #666666; +} +h1, h2, h3, h4, h5, h6{ + color: inherit; + margin-top: 0.66em; + margin-bottom: 0.33em; +} +h5 { font-size: 1em; } +.bg-success, .bg-info, .bg-warning, .bg-danger, .bg-gray-lighter { + color: inherit; +} +.dropdown-item, .dropdown-menu, .dropdown-menu a { + color: inherit; +} +.bg-success { + background-color: #dff0d8 !important; +} +.bg-info { + background-color: #d9edf7 !important; +} +.bg-warning { + background-color: #fcf8e3 !important; +} +.bg-danger { + background-color: #f2dede !important; +} +.list-inline { + margin-bottom: 10px; +} +.list-inline > li { + padding: 0 5px; + margin-right: 0; +} + +// mergebot layouting +.stagings { + display: flex; + align-items: stretch; +} +.stagings > li { + flex: 1; + + padding: 0.1em; + padding-left: 0.5em; +} +.stagings > li:not(:last-child) { + border-right: 1px solid lightgray; +} +.batch:not(:last-child) { + border-bottom: 1px solid lightgray; +} +.batch a:not(:last-of-type) a:after { + content: ","; +} +.pr-listing > * { display: inline-block; } +.pr-awaiting { opacity: 0.8; } +.pr-blocked { opacity: 0.6; } +.pr-failed { opacity: 0.9; } diff --git a/runbot_merge/views/templates.xml b/runbot_merge/views/templates.xml index e6c13f22..3fafd5d2 100644 --- a/runbot_merge/views/templates.xml +++ b/runbot_merge/views/templates.xml @@ -1,34 +1,12 @@ -