mirror of
https://github.com/odoo/runbot.git
synced 2025-03-30 23:05:44 +07:00
[ADD] forwardport: views of outstanding forwardports
Though the forwardport posts regular reminders that an fw is outdated, it can be easy to miss for the non-subject (and apparently the subjects often just ignore the information entirely). Add a few relevant links there: * on PR pages, add a link to either the source or the forward-ports (if applicable), as well as the merge date * add a new page which lists all the PRs with outstanding forwardports, as well as the forwardports in question Fixes #474
This commit is contained in:
parent
ca2742a12c
commit
670f56b491
@ -6,6 +6,101 @@
|
|||||||
Forward-port is disabled, merged pull requests will not be forward-ported.
|
Forward-port is disabled, merged pull requests will not be forward-ported.
|
||||||
</div>
|
</div>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
<!-- key block (hopefully) -->
|
||||||
|
<xpath expr="//div[@id='alerts']" position="inside">
|
||||||
|
<t t-if="env['runbot_merge.pull_requests'].check_access_rights('read', False)">
|
||||||
|
<t t-set="outstanding" t-value="env['runbot_merge.pull_requests'].search_count([
|
||||||
|
('source_id', '!=', False),
|
||||||
|
('state', 'not in', ['merged', 'closed']),
|
||||||
|
])"/>
|
||||||
|
<div t-if="outstanding != 0" class="alert col-md-12 bg-warning">
|
||||||
|
<a href="/forwardport/outstanding">
|
||||||
|
<t t-esc="outstanding"/> outstanding forward-ports
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="pr_background">
|
||||||
|
<t t-if="p.state == 'merged'">bg-success</t>
|
||||||
|
<t t-elif="p.state == 'closed'">bg-light</t>
|
||||||
|
<t t-elif="p.state == 'error'">bg-danger</t>
|
||||||
|
<t t-else="">bg-warning</t>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<record id="forwardport.outstanding_fp" model="website.page">
|
||||||
|
<field name="name">Outstanding forward ports</field>
|
||||||
|
<field name="type">qweb</field>
|
||||||
|
<field name="url">/forwardport/outstanding</field>
|
||||||
|
<field name="website_indexed" eval="False"/>
|
||||||
|
<field name="is_published">True</field>
|
||||||
|
<field name="key">forwardport.outstanding_fp</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<t name="Outstanding forward ports" t-name="forwardport.outstanding_fp">
|
||||||
|
<t t-call="website.layout">
|
||||||
|
<div id="wrap" class="oe_structure oe_empty"><div class="container-fluid">
|
||||||
|
<h1>List of pull requests with outstanding forward ports</h1>
|
||||||
|
<dl><t t-foreach="env['runbot_merge.pull_requests']._outstanding()" t-as="x">
|
||||||
|
<t t-set="source" t-value="x[0]"/>
|
||||||
|
<t t-set="prs" t-value="x[1]"/>
|
||||||
|
<dt>
|
||||||
|
<a t-att-href="source.url"><span t-field="source.display_name"/></a>
|
||||||
|
by <span t-field="source.author.display_name"
|
||||||
|
t-attf-title="@{{source.author.github_login}}"/>
|
||||||
|
merged <span t-field="source.merge_date"
|
||||||
|
t-options="{'widget': 'relative'}"
|
||||||
|
t-att-title="source.merge_date"/>
|
||||||
|
by <span t-field="source.reviewed_by.display_name"
|
||||||
|
t-attf-title="@{{source.reviewed_by.github_login}}"/>
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
Outstanding forward-ports:
|
||||||
|
<ul>
|
||||||
|
<li t-foreach="prs" t-as="p">
|
||||||
|
<a t-att-href="p.url"><span t-field="p.display_name"/></a>
|
||||||
|
(<span t-field="p.state"/>)
|
||||||
|
targeting <span t-field="p.target.name"/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</dd>
|
||||||
|
</t></dl>
|
||||||
|
</div></div>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<template id="view_pull_request" inherit_id="runbot_merge.view_pull_request">
|
||||||
|
<xpath expr="//dl[hasclass('runbot-merge-fields')]" position="inside">
|
||||||
|
<t t-if="pr.state == 'merged'">
|
||||||
|
<dt>merged</dt>
|
||||||
|
<dd>
|
||||||
|
<span t-field="pr.merge_date" t-options="{'widget': 'relative'}"
|
||||||
|
t-att-title="pr.merge_date"/>
|
||||||
|
</dd>
|
||||||
|
</t>
|
||||||
|
<t t-if="pr.source_id">
|
||||||
|
<dt>forward-port of</dt>
|
||||||
|
<dd>
|
||||||
|
<a t-att-href="pr.source_id.url">
|
||||||
|
<span t-field="pr.source_id.display_name"/>
|
||||||
|
</a>
|
||||||
|
</dd>
|
||||||
|
</t>
|
||||||
|
<t t-if="pr.forwardport_ids">
|
||||||
|
<dt>forward-ports</dt>
|
||||||
|
<dd><ul>
|
||||||
|
<t t-foreach="pr.forwardport_ids" t-as="p">
|
||||||
|
<t t-set="bgsignal"><t t-call="forwardport.pr_background"/></t>
|
||||||
|
<li t-att-class="bgsignal">
|
||||||
|
<a t-att-href="p.url"><span t-field="p.display_name"/></a>
|
||||||
|
targeting <span t-field="p.target.name"/>
|
||||||
|
</li>
|
||||||
|
</t>
|
||||||
|
</ul></dd>
|
||||||
|
</t>
|
||||||
|
</xpath>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<record model="ir.ui.view" id="project">
|
<record model="ir.ui.view" id="project">
|
||||||
|
@ -34,7 +34,6 @@ from odoo.exceptions import UserError
|
|||||||
from odoo.tools import topological_sort, groupby
|
from odoo.tools import topological_sort, groupby
|
||||||
from odoo.tools.appdirs import user_cache_dir
|
from odoo.tools.appdirs import user_cache_dir
|
||||||
from odoo.addons.runbot_merge import utils
|
from odoo.addons.runbot_merge import utils
|
||||||
from odoo.addons.runbot_merge.models.pull_requests import RPLUS
|
|
||||||
|
|
||||||
footer = '\nMore info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port\n'
|
footer = '\nMore info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port\n'
|
||||||
|
|
||||||
@ -192,6 +191,7 @@ class PullRequests(models.Model):
|
|||||||
help="a PR with a parent is an automatic forward port"
|
help="a PR with a parent is an automatic forward port"
|
||||||
)
|
)
|
||||||
source_id = fields.Many2one('runbot_merge.pull_requests', index=True, help="the original source of this FP even if parents were detached along the way")
|
source_id = fields.Many2one('runbot_merge.pull_requests', index=True, help="the original source of this FP even if parents were detached along the way")
|
||||||
|
forwardport_ids = fields.One2many('runbot_merge.pull_requests', 'source_id')
|
||||||
reminder_backoff_factor = fields.Integer(default=-4)
|
reminder_backoff_factor = fields.Integer(default=-4)
|
||||||
merge_date = fields.Datetime()
|
merge_date = fields.Datetime()
|
||||||
|
|
||||||
@ -1039,19 +1039,31 @@ stderr:
|
|||||||
repo.config('--add', 'remote.origin.fetch', '+refs/pull/*/head:refs/heads/pull/*')
|
repo.config('--add', 'remote.origin.fetch', '+refs/pull/*/head:refs/heads/pull/*')
|
||||||
return repo
|
return repo
|
||||||
|
|
||||||
def _reminder(self):
|
def _outstanding(self, cutoff=None):
|
||||||
now = datetime.datetime.now()
|
""" Returns "outstanding" (unmerged and unclosed) forward-ports whose
|
||||||
cutoff = self.env.context.get('forwardport_updated_before') or fields.Datetime.to_string(now - DEFAULT_DELTA)
|
source was merged before ``cutoff`` (all of them if not provided).
|
||||||
cutoff_dt = fields.Datetime.from_string(cutoff)
|
|
||||||
|
|
||||||
for source, prs in groupby(self.env['runbot_merge.pull_requests'].search([
|
:param str cutoff: a datetime (ISO-8601 formatted)
|
||||||
|
:returns: an iterator of (source, forward_ports)
|
||||||
|
"""
|
||||||
|
cutoff_terms = []
|
||||||
|
if cutoff:
|
||||||
|
# original merged more than <cutoff> ago
|
||||||
|
cutoff_terms = [('source_id.merge_date', '<', cutoff)]
|
||||||
|
return groupby(self.env['runbot_merge.pull_requests'].search([
|
||||||
# only FP PRs
|
# only FP PRs
|
||||||
('source_id', '!=', False),
|
('source_id', '!=', False),
|
||||||
# active
|
# active
|
||||||
('state', 'not in', ['merged', 'closed']),
|
('state', 'not in', ['merged', 'closed']),
|
||||||
# original merged more than <cutoff> ago
|
*cutoff_terms,
|
||||||
('source_id.merge_date', '<', cutoff),
|
], order='source_id, id'), lambda p: p.source_id)
|
||||||
], order='source_id, id'), lambda p: p.source_id):
|
|
||||||
|
def _reminder(self):
|
||||||
|
cutoff = self.env.context.get('forwardport_updated_before') \
|
||||||
|
or fields.Datetime.to_string(datetime.datetime.now() - DEFAULT_DELTA)
|
||||||
|
cutoff_dt = fields.Datetime.from_string(cutoff)
|
||||||
|
|
||||||
|
for source, prs in self._outstanding(cutoff):
|
||||||
backoff = dateutil.relativedelta.relativedelta(days=2**source.reminder_backoff_factor)
|
backoff = dateutil.relativedelta.relativedelta(days=2**source.reminder_backoff_factor)
|
||||||
prs = list(prs)
|
prs = list(prs)
|
||||||
if source.merge_date > (cutoff_dt - backoff):
|
if source.merge_date > (cutoff_dt - backoff):
|
||||||
|
Loading…
Reference in New Issue
Block a user