mirror of
https://github.com/odoo/runbot.git
synced 2025-03-24 11:55:49 +07:00
410 lines
20 KiB
XML
410 lines
20 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<odoo>
|
|
<data>
|
|
<template id="runbot.build">
|
|
<t t-call='runbot.layout'>
|
|
<t t-set="nav_form">
|
|
<form class="form-inline">
|
|
<div class="btn-group">
|
|
<t t-call="runbot.build_button">
|
|
<t t-set="bu" t-value="build"/>
|
|
<t t-set="klass" t-value="''"/>
|
|
<t t-set="show_commit_button" t-value="True"/>
|
|
</t>
|
|
</div>
|
|
</form>
|
|
</t>
|
|
<div class="row g-0">
|
|
<div class="col-md-12">
|
|
<t t-set="batches" t-value="build.top_parent.with_context(active_test=False).slot_ids.mapped('batch_id')"/>
|
|
<t t-set="bundles" t-value="batches.mapped('bundle_id')"/>
|
|
|
|
<t t-if="from_batch" t-set="unique_batch" t-value="from_batch"/>
|
|
<t t-if="from_batch" t-set="unique_bundle" t-value="from_batch.bundle_id"/>
|
|
<t t-if="not unique_batch and len(batches) == 1" t-set="unique_batch" t-value="batches"/>
|
|
<t t-if="not unique_bundle and len(bundles) == 1" t-set="unique_bundle" t-value="bundles"/>
|
|
|
|
<!-- Breadcrumbs & Previous/Next-->
|
|
<nav aria-label="breadcrumb" class="d-flex justify-content-between align-items-center">
|
|
<ol class="breadcrumb mb-0">
|
|
<li t-attf-class="breadcrumb-item">
|
|
<a t-attf-href="/runbot/{{build.params_id.project_id.id}}">
|
|
<t t-out="build.params_id.project_id.name"/>
|
|
</a>
|
|
</li>
|
|
<li t-if="unique_bundle" t-attf-class="breadcrumb-item">
|
|
<a t-att-href="unique_bundle._url()">
|
|
<t t-out="unique_bundle.name"/>
|
|
</a>
|
|
</li>
|
|
<li t-if="unique_batch" t-attf-class="breadcrumb-item">
|
|
<a t-att-href="unique_batch._url()">
|
|
batch-<t t-out="unique_batch.id"/> (<t t-out="build.params_id.trigger_id.name"/>)
|
|
</a>
|
|
</li>
|
|
<li t-foreach="build.ancestors" t-as="ancestor" t-attf-class="breadcrumb-item{{' active' if ancestor == build else ''}}">
|
|
<a t-att-href="ancestor.build_url">
|
|
<t t-out="ancestor.description or ancestor.config_id.name"/>
|
|
</a>
|
|
</li>
|
|
</ol>
|
|
<span class="btn-group pe-3">
|
|
<a t-att-href="prev_ko.build_url" role="button" t-attf-title="Previous ko {{prev_ko.display_name}}"
|
|
t-attf-class="{{'' if prev_ko else 'disabled '}}btn btn-default fa fa-angle-double-left"></a>
|
|
<a t-att-href="prev_bu.build_url" role="button" t-attf-title="Previous {{prev_bu.display_name}}"
|
|
t-attf-class="{{'' if prev_bu else 'disabled '}}btn btn-default fa fa-chevron-left"></a>
|
|
<a t-att-href="next_bu.build_url" role="button" t-attf-title="Next {{next_bu.display_name}}"
|
|
t-attf-class="{{'' if next_bu else 'disabled '}}btn btn-default fa fa-chevron-right"></a>
|
|
<a t-att-href="next_ko.build_url" role="button" t-attf-title="Next ko {{next_ko.display_name}}"
|
|
t-attf-class="{{'' if next_ko else 'disabled '}}btn btn-default fa fa-angle-double-right"></a>
|
|
</span>
|
|
</nav>
|
|
</div>
|
|
<!-- Build details-->
|
|
<t t-set="rowclass">
|
|
<t t-call="runbot.build_class">
|
|
<t t-set="build" t-value="build"/>
|
|
</t>
|
|
</t>
|
|
<div t-attf-class="bg-{{rowclass.strip()}}-subtle {{'col-md-6' if build.children_ids else 'col-md-12'}}">
|
|
<div class="build_details">
|
|
<!-- Batch/bundles links-->
|
|
<t t-if="len(bundles) > 1">
|
|
This build is referenced in <t t-out="len(bundles)"/> bundles
|
|
<ul>
|
|
<li t-foreach="bundles" t-as="bundle" ><a t-out="bundle.name" t-attf-href="/runbot/bundle/{{bundle.id}}"/></li>
|
|
</ul>
|
|
</t>
|
|
<t t-if="len(batches) > 1">
|
|
<b>First apparition:</b> <a t-out="batches[0].bundle_id.name" t-attf-href="/runbot/batch/{{batches[0].id}}"/><br/>
|
|
<b>Last apparition:</b> <a t-out="batches[-1].bundle_id.name" t-attf-href="/runbot/batch/{{batches[-1].id}}"/><br/>
|
|
</t>
|
|
<!-- Parent -->
|
|
<div t-if="build.parent_id and build.orphan_result">
|
|
<i class="fa fa-chain-broken" title="Build result ignored for parent" />
|
|
&nbsp;Orphaned build, the result does not affect parent build result
|
|
</div>
|
|
|
|
<t t-if="build.description">
|
|
<b>Description:</b>
|
|
<t t-out="build.md_description"/>
|
|
<br/>
|
|
</t>
|
|
|
|
<!-- Commits -->
|
|
<t t-foreach="build.params_id.sudo().commit_link_ids" t-as="build_commit">
|
|
<b>Commit:</b>
|
|
<a t-attf-href="/runbot/commit/{{build_commit.commit_id.id}}">
|
|
<t t-out="build_commit.commit_id.dname"/>
|
|
</a>
|
|
&nbsp;
|
|
<a t-att-href="'https://%s/commit/%s' % (build_commit.branch_id.remote_id.base_url, build_commit.commit_id.name)" title="View Commit on Github"><i class="fa fa-github"/></a>
|
|
<t t-if="build_commit.match_type in ('default', 'pr_target', 'prefix') ">
|
|
from base branch
|
|
<br/>
|
|
</t>
|
|
<div t-else="" class="ms-3">
|
|
<b>Subject:</b>
|
|
<t t-out="build_commit.commit_id.subject"/>
|
|
<br/>
|
|
<b>Author:</b>
|
|
<t t-out="build_commit.commit_id.author"/>
|
|
<br/>
|
|
<b>Committer:</b>
|
|
<t t-out="build_commit.commit_id.committer"/>
|
|
<br/>
|
|
</div>
|
|
</t>
|
|
<b>Version:</b>
|
|
<t t-out="build.params_id.version_id.name"/>
|
|
<br/>
|
|
<b>Config:</b>
|
|
<t t-out="build.params_id.config_id.name"/>
|
|
<br/>
|
|
<t t-if='more'>
|
|
<b>Trigger:</b>
|
|
<t t-out="build.params_id.trigger_id.name"/>
|
|
<br/>
|
|
<b>Config data:</b>
|
|
<t t-out="build.params_id.config_data.dict"/>
|
|
<br/>
|
|
<b>Modules:</b>
|
|
<t t-out="build.params_id.modules"/>
|
|
<br/>
|
|
<b>Extra params:</b>
|
|
<t t-out="build.params_id.extra_params"/>
|
|
<br/>
|
|
<t t-if="build.params_id.builds_reference_ids">
|
|
<b>Reference builds:</b>
|
|
<div t-foreach="build.params_id.builds_reference_ids" t-as="reference">
|
|
<a t-attf-href="/runbot/build/{{reference.id}}"><t t-esc="reference.id"/></a> - <em t-out="reference.params_id.version_id.name"/>
|
|
</div>
|
|
</t>
|
|
<t t-if="len(build.params_id.build_ids) > 1">
|
|
<b>Similar builds:</b>
|
|
<t t-foreach="build.params_id.build_ids" t-as="simbuild">
|
|
<a t-if="simbuild.id != build.id" t-attf-href="/runbot/build/#{simbuild.id}">
|
|
<span
|
|
t-attf-class="badge text-bg-{{simbuild._get_color_class()}}"
|
|
t-out="simbuild.id"/>
|
|
</a>
|
|
</t>
|
|
<br/>
|
|
</t>
|
|
<b>Host:</b>
|
|
<t t-out="build.host"/>
|
|
</t>
|
|
<div>
|
|
<b title="Execution time of this build, without child time">
|
|
Build time:
|
|
</b>
|
|
<t t-att-tile='build.build_time' t-out="s2human(build.build_time)"/>
|
|
<i t-if='more'>(<t t-out="build.build_time"/>s)</i>
|
|
</div>
|
|
<div>
|
|
<b title='Time from creation to finish (queue time + completion time)'>
|
|
Wait time:
|
|
</b>
|
|
<t t-att-tile='build.wait_time' t-out="s2human(build.wait_time)"/>
|
|
<i t-if='more'>(<t t-out="build.wait_time"/>s)</i>
|
|
</div>
|
|
<div>
|
|
<b title='Total time '>
|
|
Load time:
|
|
</b>
|
|
<t t-att-tile='build.load_time' t-out="s2human(build.load_time)"/>
|
|
<i t-if='more'>(<t t-out="build.load_time"/>s)</i>
|
|
</div>
|
|
<div>
|
|
<t t-if="build.stat_ids">
|
|
<b>Stats:</b>
|
|
<a t-attf-href="/runbot/build/stats/{{build.id}}">Build <t t-out="build.id"/></a>
|
|
<br/>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6" t-if="build.children_ids">
|
|
Children:
|
|
<table class="table table-condensed">
|
|
<t t-foreach="build.children_ids.sorted('id')" t-as="child">
|
|
<t t-set="rowclass">
|
|
<t t-call="runbot.build_class">
|
|
<t t-set="build" t-value="child"/>
|
|
</t>
|
|
</t>
|
|
<tr t-attf-class="bg-{{rowclass.strip()}}-subtle{{' line-through' if child.orphan_result else ''}}">
|
|
<td>
|
|
<a t-attf-href="/runbot/{{'batch/%s/' % from_batch.id if from_batch else ''}}build/{{child.id}}">
|
|
Build
|
|
<t t-out="child.id"/>
|
|
</a>
|
|
<t t-if="child.description">
|
|
<t t-out="child.md_description" />
|
|
</t>
|
|
<t t-else="">
|
|
with config
|
|
<t t-out="child.params_id.config_id.name"/>
|
|
</t>
|
|
<a groups="runbot.group_build_config_user" t-attf-href="/web#id={{child.params_id.config_id.id}}&view_type=form&model=runbot.build.config">...</a>
|
|
<t t-if="child.orphan_result">
|
|
<i class="fa fa-chain-broken" title="Build result ignored for parent" />
|
|
</t>
|
|
<t t-if="child.job">
|
|
Running step:
|
|
<t t-out="child.job"/>
|
|
</t>
|
|
<t t-if="child.global_state in ['testing', 'waiting']">
|
|
<i class="fa fa-spinner fa-spin"/>
|
|
<t t-out="child.global_state"/>
|
|
</t>
|
|
</td>
|
|
<td>
|
|
<span t-attf-class="badge text-bg-info" t-out="s2human(child.build_time)"/>
|
|
</td>
|
|
<td>
|
|
<t t-call="runbot.build_button">
|
|
<t t-set="bu" t-value="child"/>
|
|
<t t-set="klass" t-value="'btn-group-ssm'"/>
|
|
</t>
|
|
|
|
</td>
|
|
</tr>
|
|
</t>
|
|
</table>
|
|
</div>
|
|
<t t-set="nb_subbuild" t-value="len(build.children_ids)"/>
|
|
<div class="col-md-12">
|
|
<table class="table table-condensed">
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Level</th>
|
|
<th>Type</th>
|
|
<th>Message</th>
|
|
</tr>
|
|
|
|
<t t-set="commit_link_per_name" t-value="{commit_link.commit_id.repo_id.name:commit_link for commit_link in build.params_id.commit_link_ids}"/>
|
|
<t t-foreach="build.sudo().log_ids" t-as="l">
|
|
<t t-set="subbuild" t-value="(([child for child in build.children_ids if child.id == int(l.path)] if l.type == 'subbuild' else False) or [build.browse()])[0]"/>
|
|
<t t-set="logclass" t-value="dict(CRITICAL='danger', ERROR='danger', WARNING='warning', OK='success', SEPARATOR='separator').get(l.level)"/>
|
|
<tr t-att-class="'separator' if logclass == 'separator' else ''" t-att-title="l.active_step_id.description or ''">
|
|
<td style="white-space: nowrap; width:1%;">
|
|
<t t-out="l.create_date.strftime('%Y-%m-%d %H:%M:%S')"/>
|
|
</td>
|
|
<td style="white-space: nowrap; width:1%;">
|
|
<b t-if="l.level != 'SEPARATOR' and l.type not in ['link', 'markdown']" t-out="l.level"/>
|
|
</td>
|
|
<td style="white-space: nowrap; width:1%;">
|
|
<t t-if="l.level != 'SEPARATOR' and l.type not in ['link', 'markdown']" t-out="l.type"/>
|
|
</td>
|
|
<t t-set="message_class" t-value="''"/>
|
|
<t t-if="subbuild" t-set="message_class">
|
|
<t t-call="runbot.build_class">
|
|
<t t-set="build" t-value="subbuild"/>
|
|
</t>
|
|
</t>
|
|
<td t-attf-class="bg-{{message_class.strip() or logclass}}-subtle">
|
|
<t t-if="l.type not in ('runbot', 'link', 'markdown')">
|
|
<t t-if="l.type == 'subbuild'">
|
|
<a t-attf-href="/runbot/build/{{l.path}}">
|
|
Build #
|
|
<t t-out="l.path"/>
|
|
</a>
|
|
</t>
|
|
<t t-else="">
|
|
<t t-set="repo_name" t-value="l.path.replace('/data/build/', '').split('/')[0] "/>
|
|
<t t-set="href" t-value=""/>
|
|
<t t-if="repo_name in commit_link_per_name">
|
|
<t t-set="repo_base_url" t-value="commit_link_per_name[repo_name].branch_id.remote_id.base_url if repo_name in commit_link_per_name else ''"/>
|
|
<t t-set="commit_hash" t-value="commit_link_per_name[repo_name].commit_id.name if repo_name in commit_link_per_name else ''"/>
|
|
<t t-set="path" t-value="l.path.replace('/data/build/%s/' % repo_name, '')"/>
|
|
<t t-set="href" t-value="'https://%s/blob/%s/%s#L%s' % (repo_base_url, commit_hash, path, l.line)"/>
|
|
</t>
|
|
<a t-att-href="href" t-attf-title="Func: {{l.func}}"><t t-out="l.name"/>:<t t-out="l.line"/></a>
|
|
</t>
|
|
</t>
|
|
<!-- DEPRECATED: Will be removed once no ir.logging is concerned. -->
|
|
<span class="log_message" t-if="l.type == 'link' and len(l.message.split('$$')) == 3">
|
|
<t t-set="message" t-value="l.message.split('$$')"/>
|
|
<t t-if="message[1].startswith('fa-')">
|
|
<t t-out="message[0]"/>
|
|
<a t-attf-href="{{l.path}}">
|
|
<i t-attf-class="fa {{message[1]}}"/>
|
|
</a>
|
|
<t t-out="message[2]"/>
|
|
</t>
|
|
<t t-else="">
|
|
<t t-out="message[0]"/>
|
|
<a t-attf-href="{{l.path}}">
|
|
<t t-out="message[1]"/>
|
|
</a>
|
|
<t t-out="message[2]"/>
|
|
</t>
|
|
</span>
|
|
<span class="log_message" t-elif="l.type == 'markdown'" t-out="l._markdown()"/>
|
|
<span class="log_message" t-else="">
|
|
<t t-if="'\n' not in l.message" t-out="l.message"/>
|
|
<pre t-if="'\n' in l.message" style="margin:0;padding:0; border: none;"><t t-out="l.message"/></pre>
|
|
</span>
|
|
</td>
|
|
<td t-attf-class="bg-{{message_class.strip() or logclass}}-subtle">
|
|
<t t-if="l.level in ('CRITICAL', 'ERROR', 'WARNING') and not l.with_context(active_test=False).error_content_id">
|
|
<small>
|
|
<a groups="runbot.group_runbot_5admin" t-attf-href="/runbot/parse_log/{{l.id}}" class="sm" title="Parse this log line to follow this error.">
|
|
<i t-attf-class="fa fa-magic"/>
|
|
</a>
|
|
</small>
|
|
</t>
|
|
</td>
|
|
</tr>
|
|
<t t-if="l.error_content_id">
|
|
<t t-set="error_content" t-value="l.error_content_id"/>
|
|
<t t-set="error" t-value="error_content.error_id"/>
|
|
<tr>
|
|
<td/><td/><td/>
|
|
<td t-attf-class="bg-{{'info' if error.active else 'success'}}-subtle" colspan="2">
|
|
This error is already <em t-attf-title="{{'Was detected by runbot in nightly builds.' if error.active else 'Either the error is not properly fixed or the branch does not contain the fix.'}}"><t t-out="'known' if error.active else 'fixed'"/></em>.
|
|
<!--a groups="runbot.group_user" t-attf-href="/web#id={{error_content.id}}&view_type=form&model=runbot.build.error.content&menu_id={{env['ir.model.data']._xmlid_to_res_id('runbot.runbot_menu_root')}}" title="View in Backend" target="_blank">
|
|
<i t-attf-class="fa fa-search"/>
|
|
</a-->
|
|
<a groups="runbot.group_user" t-attf-href="/web#id={{error.id}}&view_type=form&model=runbot.build.error&menu_id={{env['ir.model.data']._xmlid_to_res_id('runbot.runbot_menu_root')}}" title="View in Backend" target="_blank">
|
|
<i t-attf-class="fa fa-list"/>
|
|
</a>
|
|
<span groups="runbot.group_runbot_admin" t-if="error.responsible or error.responsible.id == uid">(<i t-out="error.responsible.name"/>)</span>
|
|
</td>
|
|
</tr>
|
|
</t>
|
|
</t>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
</template>
|
|
<template id="runbot.build_search">
|
|
<t t-call='runbot.layout'>
|
|
<div class="row g-0">
|
|
<div class="col-md-12">
|
|
<table class="table table-condensed">
|
|
<t t-foreach="builds" t-as="build">
|
|
<t t-set="rowclass">
|
|
<t t-call="runbot.build_class">
|
|
<t t-set="build" t-value="build"/>
|
|
</t>
|
|
</t>
|
|
<tr t-attf-class="bg-{{rowclass.strip()}}-subtle{{' line-through' if build.orphan_result else ''}}">
|
|
<td>
|
|
<t t-out="build.create_date"/>
|
|
</td>
|
|
<td>
|
|
<a t-attf-href="/runbot/{{'batch/%s/' % from_batch.id if from_batch else ''}}build/{{build.id}}">
|
|
<t t-out="build.id"/>
|
|
</a>
|
|
</td>
|
|
<td>
|
|
<t t-if="build.description">
|
|
<t t-out="build.md_description" />
|
|
</t>
|
|
</td>
|
|
<td>
|
|
<t t-if="build.global_state in ['testing', 'waiting']">
|
|
<i class="fa fa-spinner fa-spin"/>
|
|
<t t-out="build.global_state"/>
|
|
</t>
|
|
</td>
|
|
<td>
|
|
<span t-out="build.params_id.config_id.name"/>
|
|
</td>
|
|
<td>
|
|
<span t-out="build.params_id.version_id.name"/>
|
|
</td>
|
|
<td>
|
|
<span t-out="s2human(build.build_time)"/>
|
|
</td>
|
|
<td>
|
|
<t t-call="runbot.build_button">
|
|
<t t-set="bu" t-value="build"/>
|
|
<t t-set="klass" t-value="'btn-group-ssm'"/>
|
|
</t>
|
|
</td>
|
|
<td>
|
|
<t t-set="commits" t-value="build.params_id.commit_link_ids.commit_id.sorted(key=lambda c: c.repo_id.id)"/>
|
|
<t t-if="build_index+1 < len(builds)" t-set="previous_commits" t-value="list(builds[build_index+1].params_id.commit_link_ids.commit_id.sorted(key=lambda c: c.repo_id.id))"/>
|
|
<t t-else="" t-set="previous_commits" t-value="[]"/>
|
|
<t t-foreach="zip(previous_commits, commits)" t-as="compare">
|
|
<t t-set="previous_commit" t-value="compare[0]"/>
|
|
<t t-set="commit" t-value="compare[1]"/>
|
|
<a t-attf-href="https://{{commit.repo_id.main_remote_id.base_url}}/compare/{{previous_commit.name}}..{{commit.name}}" t-att-title="commit.repo_id.name">
|
|
<i class="fa fa-plus"/>
|
|
</a>
|
|
</t>
|
|
</td>
|
|
</tr>
|
|
</t>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
</template>
|
|
</data>
|
|
</odoo>
|