runbot/runbot_merge/views/templates.xml
Xavier Morel 974bab40ba [IMP] runbot_merge: add style for successful but unmerged staging
Currently the PR becomes successful-green as soon as CI fully passes
but before it's merged, which can be an issue as e.g. merging might be
delayed (there's no visible difference between "CI success" and
"staging merged") or it might ultimately failed (FF error).

Create an intermediate color for "successful" stagings which are still
pending merge.

Also add a fallback message for fast-forward errors instead of en
empty string.

Closes #308
2020-03-16 15:03:11 +01:00

295 lines
17 KiB
XML

<odoo>
<function model="website.page" name="write">
<value eval="ref('website.homepage_page')"/>
<value eval="{'active': False}"/>
</function>
<template id="assets_frontend" inherit_id="web.assets_frontend">
<xpath expr="link[last()]" position="after">
<link rel="stylesheet" type="text/scss" href="/runbot_merge/static/scss/runbot_merge.scss"/>
</xpath>
</template>
<template id="dashboard" name="mergebot dashboard">
<t t-call="website.layout">
<div id="wrap"><div class="container-fluid">
<div id="alerts" class="row text-center">
<t t-set="stagingcron" t-value="env(user=1).ref('runbot_merge.staging_cron')"/>
<div t-if="not stagingcron.active" class="alert alert-warning col-12" role="alert">
Staging is disabled, "ready" pull requests will not be staged.
</div>
<t t-set="mergecron" t-value="env(user=1).ref('runbot_merge.merge_cron')"/>
<div t-if="not mergecron.active" class="alert alert-warning col-12" role="alert">
Merging is disabled, stagings will not be disabled.
</div>
</div>
<section t-foreach="projects.with_context(active_test=False)" t-as="project" class="row">
<h1 class="col-md-12"><t t-esc="project.name"/></h1>
<div class="col-md-12">
key:
<ul class="list-inline">
<li class="bg-success">success (hopefully merged)</li>
<li class="bg-info">ongoing</li>
<li class="bg-danger">failure</li>
<li class="bg-gray-lighter">cancelled</li>
</ul>
</div>
<section t-foreach="project.branch_ids" t-as="branch" t-if="branch.active" class="col-md-12">
<h2>
<a t-attf-href="/runbot_merge/{{branch.id}}">
<t t-esc="branch.name"/>
</a>
</h2>
<t t-call="runbot_merge.stagings"/>
<t t-set="splits" t-value="branch.split_ids"/>
<t t-set="ready_unstaged" t-value="
project.env['runbot_merge.pull_requests'].search([
('target', '=', branch.id),
('state', '=', 'ready'),
('staging_id', '=', False),
]) - splits.mapped('batch_ids.prs')
"/>
<t t-set="ready" t-value="ready_unstaged.filtered(lambda p: not p.blocked)"/>
<t t-set="blocked" t-value="ready_unstaged.filtered(lambda p: p.blocked)"/>
<div t-if="splits" class="splits bg-warning pr-awaiting">
<h5>
Splits
<small class="text-muted">will be staged next</small>
</h5>
<ul>
<li t-foreach="splits" t-as="split">
<ul class="pr-listing list-inline list-unstyled mb0">
<li t-foreach="split.mapped('batch_ids.prs')" t-as="pr">
<a t-attf-href="https://github.com/{{ pr.repository.name }}/pull/{{ pr.number }}"
t-att-title="pr.message.split('\n')[0]">
<t t-esc="pr.repository.name"/>#<t t-esc="pr.number"/>
</a>
</li>
</ul>
</li>
</ul>
</div>
<div t-if="ready" class="pr-listing pr-awaiting bg-warning">
<h5>Awaiting</h5>
<ul class="list-inline">
<li t-foreach="ready" t-as="pr">
<a t-attf-href="https://github.com/{{ pr.repository.name }}/pull/{{ pr.number }}"
t-att-title="pr.message.split('\n')[0]">
<t t-esc="pr.repository.name"/>#<t t-esc="pr.number"/>
</a>
</li>
</ul>
</div>
<div t-if="blocked" class="pr-listing pr-blocked bg-info">
<h5>Blocked</h5>
<ul class="list-inline">
<li t-foreach="blocked" t-as="pr">
<a t-attf-href="https://github.com/{{ pr.repository.name }}/pull/{{ pr.number }}"
t-att-title="pr.blocked">
<t t-esc="pr.repository.name"/>#<t t-esc="pr.number"/>
</a>
</li>
</ul>
</div>
<t t-set="failed" t-value="
project.env['runbot_merge.pull_requests'].search([
('target', '=', branch.id),
('state', '=', 'error'),
('staging_id', '=', False),
])
"/>
<div t-if="failed" class="pr-listing pr-failed bg-danger">
<h5>Failed</h5>
<ul class="list-inline">
<li t-foreach="failed" t-as="pr">
<a t-attf-href="https://github.com/{{ pr.repository.name }}/pull/{{ pr.number }}"
t-att-title="pr.message.split('\n')[0]">
<t t-esc="pr.repository.name"/>#<t t-esc="pr.number"/>
</a>
</li>
</ul>
</div>
</section>
</section>
</div></div>
</t>
</template>
<template id="stagings" name="mergebot branch stagings">
<ul class="list-unstyled stagings">
<t t-foreach="branch.staging_ids.sorted(lambda s: s.staged_at, reverse=True)[:6]" t-as="staging">
<t t-set="success" t-value="staging.state == 'success'"/>
<t t-set="failure" t-value="staging.state == 'failure'"/>
<t t-set="pending" t-value="staging.active and (not staging.state or staging.state == 'pending')"/>
<t t-set="stateclass">
<t t-if="success">bg-success <t t-if="staging.active">bg-unmerged</t></t>
<t t-if="failure">bg-danger</t>
<t t-if="pending">bg-info</t>
<t t-if="not (success or failure or pending)">bg-gray-lighter</t>
</t>
<t t-set="decorationclass" >
<t t-if="staging_index >= 2">hidden-xs</t>
<t t-if="staging_index >= 4">visible-lg-block</t>
</t>
<t t-set="title">
<t t-if="staging.state == 'canceled'">Cancelled: <t t-esc="staging.reason"/></t>
<t t-if="staging.state == 'ff_failed'">Fast Forward Failed</t>
<t t-if="staging.state not in ('canceled', 'ff_failed')"><t t-esc="staging.reason"/></t>
</t>
<li t-attf-class="staging {{stateclass.strip()}} {{decorationclass.strip()}}" t-att-title="title.strip() or None">
<ul class="list-unstyled">
<li t-foreach="staging.batch_ids" t-as="batch" class="batch">
<t t-esc="batch.prs[:1].label"/>
<t t-foreach="batch.prs" t-as="pr">
<a t-attf-href="https://github.com/{{ pr.repository.name }}/pull/{{ pr.number }}"
t-att-title="pr.message.split('\n')[0]"><t t-esc="pr.repository.name"/>#<t t-esc="pr.number"/></a>
</t>
</li>
</ul>
<t t-if="staging.heads">
<div class="dropdown">
<button class="btn btn-link dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Staged <span t-field="staging.staged_at" t-options="{'widget': 'relative'}"/>
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li groups="runbot_merge.group_admin">
<a t-attf-href="/web#id={{staging.id}}&amp;view_type=form&amp;model=runbot_merge.stagings" target="new">
Open Staging
</a>
</li>
<li t-foreach="staging.statuses" t-as="st" t-if="st[3]"
t-att-class="
'bg-success' if st[2] == 'success'
else 'bg-danger' if st[2] in ('error', 'failure')
else 'bg-info'"
>
<a t-att-href="st[3]" target="new">
<t t-esc="st[0]"/>: <t t-esc="st[1]"/>
</a>
</li>
</ul>
</div>
</t>
</li>
</t>
</ul>
</template>
<template id="branch_stagings" name="mergebot stagings page">
<t t-call="website.layout">
<div id="wrap"><div class="container-fluid">
<section class="row">
<h1 class="col-md-12"><t t-esc="branch.project_id.name"/>: <t t-esc="branch.name"/></h1>
</section>
<table>
<t t-foreach="stagings" t-as="staging">
<t t-set="success"
t-value="staging.state == 'success'"/>
<t t-set="failure"
t-value="staging.state == 'failure'"/>
<t t-set="pending"
t-value="staging.active and (not staging.state or staging.state == 'pending')"/>
<t t-set="stateclass">
<t t-if="success">bg-success</t>
<t t-if="failure">bg-danger</t>
<t t-if="pending">bg-info</t>
<t t-if="not (success or failure or pending)">
bg-gray-lighter
</t>
</t>
<t t-set="title">
<t t-if="staging.state == 'canceled'">Cancelled:
<t t-esc="staging.reason"/>
</t>
<t t-if="staging.state == 'ff_failed'">Fast
Forward Failed
</t>
<t t-if="staging.state not in ('canceled', 'ff_failed')">
<t t-esc="staging.reason"/>
</t>
</t>
<tr t-att-class="stateclass"
style="border-bottom: 1px solid gainsboro; vertical-align: top">
<th t-att-title="title.strip() or None">
<t t-if="not staging.heads">
<span t-field="staging.staged_at"
t-options="{'widget': 'text'}"/>
</t>
<div class="dropdown" t-if="staging.heads">
<button class="btn btn-link dropdown-toggle"
type="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="true">
<span t-field="staging.staged_at"
t-options="{'widget': 'text'}"/>
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li groups="runbot_merge.group_admin">
<a t-attf-href="/web#id={{staging.id}}&amp;view_type=form&amp;model=runbot_merge.stagings"
target="new">
Open Staging
</a>
</li>
<li t-foreach="staging.statuses"
t-as="st" t-if="st[3]"
t-att-class="
'bg-success' if st[2] == 'success'
else 'bg-danger' if st[2] in ('error', 'failure')
else 'bg-info'"
>
<a t-att-href="st[3]"
target="new">
<t t-esc="st[0]"/>:
<t t-esc="st[1]"/>
</a>
</li>
</ul>
</div>
</th>
<td>
<ul class="list-inline list-unstyled mb0">
<t t-foreach="staging.batch_ids"
t-as="batch">
<t t-set="first_pr"
t-value="batch.prs[-1]"/>
<li class="dropdown">
<button class="btn btn-link dropdown-toggle"
type="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="true"
t-att-title="first_pr.message.split('\n')[0]"
>
<t t-esc="first_pr.label"/>
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li t-foreach="batch.prs"
t-as="pr">
<a t-attf-href="https://github.com/{{ pr.repository.name }}/pull/{{ pr.number }}"
t-att-title="pr.message.split('\n')[0]"
target="new">
<t t-esc="pr.repository.name"/>
#
<t t-esc="pr.number"/>
</a>
</li>
</ul>
</li>
</t>
</ul>
</td>
</tr>
</t>
</table>
<t t-if="next">
<a t-attf-href="/runbot_merge/{{branch.id}}?until={{next}}">
Next >
</a>
</t>
</div></div>
</t>
</template>
</odoo>