[FIX] runbot_merge: backport wizard

- fix incorrect view specs (the action id comes first)
- add a wizard form and hook it into the PR, completely forgot to do
  that
- usability improvements: filter branches to be in the same project as
  the PR being backported, and older than the current PR's branch

The latter is a somewhat incomplete condition: ideally we'd want to
only allow selecting branches preceding the target of the *source* of
the PR being backported, that way we don't risk errors when
backporting forward-ports (the condition should be checked in the
final action but still).

Also we're only filtering by sequence, so we're missing the name part
of the ordering, hence if multiple branches have the same sequence we
may not allow selecting some of the preceding branches.
This commit is contained in:
Xavier Morel 2024-11-18 09:48:48 +01:00
parent 5b94dcce35
commit a12e593fba
3 changed files with 32 additions and 4 deletions

View File

@ -19,6 +19,7 @@
'views/templates.xml',
'models/project_freeze/views.xml',
'models/staging_cancel/views.xml',
'models/backport/views.xml',
],
'assets': {
'web.assets_frontend': [

View File

@ -1,7 +1,6 @@
import logging
import re
import secrets
import subprocess
import requests
@ -44,7 +43,7 @@ class PullRequest(models.Model):
return {
'type': 'ir.actions.act_window',
'name': f"Backport of {self.display_name}",
'views': [('form', False)],
'views': [(False, 'form')],
'target': 'new',
'res_model': w._name,
'res_id': w.id,
@ -56,7 +55,12 @@ class PullRequestBackport(models.TransientModel):
_rec_name = 'pr_id'
pr_id = fields.Many2one('runbot_merge.pull_requests', required=True)
target = fields.Many2one('runbot_merge.branch')
project_id = fields.Many2one(related='pr_id.repository.project_id')
source_seq = fields.Integer(related='pr_id.target.sequence')
target = fields.Many2one(
'runbot_merge.branch',
domain="[('project_id', '=', project_id), ('sequence', '>', source_seq)]",
)
def action_apply(self) -> dict:
if not self.target:
@ -135,7 +139,7 @@ class PullRequestBackport(models.TransientModel):
return {
'type': 'ir.actions.act_window',
'name': "new backport",
'views': [('form', False)],
'views': [(False, 'form')],
'res_model': backport._name,
'res_id': backport.id,
}

View File

@ -0,0 +1,23 @@
<odoo>
<record id="runbot_merge_backport_form" model="ir.ui.view">
<field name="name">Backport Wizard</field>
<field name="model">runbot_merge.pull_requests.backport</field>
<field name="arch" type="xml">
<form>
<field name="pr_id" invisible="1"/>
<field name="project_id" invisible="1"/>
<field name="source_seq" invisible="1"/>
<field name="target" class="w-100"/>
</form>
</field>
</record>
<record id="runbot_merge_backport_pr_action" model="ir.actions.server">
<field name="name">Perform backport from current PR</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_runbot_merge_pull_requests"/>
<field name="binding_model_id" ref="model_runbot_merge_pull_requests"/>
<field name="state">code</field>
<field name="code">action = record.backport()</field>
</record>
</odoo>