mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 15:35:46 +07:00
--wip-- [skip ci]
This commit is contained in:
parent
075e6a99b0
commit
ac3038e664
@ -15,7 +15,7 @@
|
||||
])"/>
|
||||
<div t-if="outstanding != 0" class="alert col-md-12 alert-warning mb-0">
|
||||
<a href="/forwardport/outstanding">
|
||||
<t t-esc="outstanding"/> outstanding forward-ports (>1 week)
|
||||
<t t-out="outstanding"/> outstanding forward-ports (>1 week)
|
||||
</a>
|
||||
</div>
|
||||
</t>
|
||||
|
@ -36,6 +36,11 @@
|
||||
'templates/git.xml',
|
||||
'templates/nginx.xml',
|
||||
'templates/build_error.xml',
|
||||
'templates/new/page.xml',
|
||||
'templates/new/bundle.xml',
|
||||
'templates/new/batch.xml',
|
||||
'templates/new/build.xml',
|
||||
'templates/new/slot.xml',
|
||||
|
||||
'views/branch_views.xml',
|
||||
'views/build_error_views.xml',
|
||||
@ -65,6 +70,16 @@
|
||||
'runbot/static/src/libs/diff_match_patch/diff_match_patch.js',
|
||||
'runbot/static/src/js/fields/*',
|
||||
],
|
||||
'runbot.assets_frontend_new': [
|
||||
# TODO: compile bootstrap scss from /web without reviews and copy custom_utilities.scss
|
||||
'/runbot/static/src/libs/bootstrap/css/bootstrap.css',
|
||||
'/runbot/static/src/libs/fontawesome/css/font-awesome.css',
|
||||
'/runbot/static/src/css/runbot.scss',# TODO: Check what is necessary from here
|
||||
'/runbot/static/src/libs/jquery/jquery.js',
|
||||
'/runbot/static/src/libs/popper/popper.js',
|
||||
'/runbot/static/src/libs/bootstrap/js/bootstrap.bundle.js',
|
||||
'/runbot/static/src/js/runbot.js',
|
||||
],
|
||||
'runbot.assets_frontend': [
|
||||
'/web/static/lib/bootstrap/dist/css/bootstrap.css',
|
||||
'/web/static/src/libs/fontawesome/css/font-awesome.css',
|
||||
|
@ -3,6 +3,7 @@ import datetime
|
||||
import werkzeug
|
||||
import logging
|
||||
import functools
|
||||
from typing import TypedDict, Optional, List, NamedTuple
|
||||
|
||||
import werkzeug.utils
|
||||
import werkzeug.urls
|
||||
@ -19,6 +20,32 @@ from odoo.osv import expression
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Breadcrumb(NamedTuple):
|
||||
url: str
|
||||
name: str
|
||||
|
||||
Breadcrumbs = List[Breadcrumb]
|
||||
|
||||
class ToolbarContext(TypedDict):
|
||||
"""
|
||||
Context used by 'runbot.layout_toolbar', should be provided through the 'toolbar' context key.
|
||||
"""
|
||||
sticky: Optional[bool] # Defines if the toolbar is sticky or not, defaults to true
|
||||
|
||||
start_template: Optional[str] # Default to 'runbot.layout_toolbar_start_section'
|
||||
# start_template default expected values
|
||||
breadcrumbs: Optional[Breadcrumbs]
|
||||
middle_template: Optional[str] # Defaults to 'runbot.layout_toolbar_middle_section'
|
||||
# middle_template default expected values
|
||||
message: Optional[str]
|
||||
end_template: Optional[str] # Defaults to 'runbot.layout_toolbar_end_section'
|
||||
# end_template expected values
|
||||
pending_count: Optional[int]
|
||||
pending_level: Optional[int]
|
||||
pending_assigned_count: Optional[int]
|
||||
# hosts_data: Optional[request.env['runbot.host']]
|
||||
|
||||
|
||||
def route(routes, **kw):
|
||||
def decorator(f):
|
||||
@o_route(routes, **kw)
|
||||
@ -73,6 +100,22 @@ def route(routes, **kw):
|
||||
|
||||
class Runbot(Controller):
|
||||
|
||||
def _get_default_toolbar(self, *, include_message=False):
|
||||
pending_count, level, _, pending_assigned_count = self._pending()
|
||||
|
||||
if include_message:
|
||||
message = request.env['ir.config_parameter'].sudo().get_param('runbot.runbot_message')
|
||||
else:
|
||||
message = None
|
||||
|
||||
return ToolbarContext(
|
||||
pending_count=pending_count,
|
||||
pending_level=level,
|
||||
pending_assigned_count=pending_assigned_count,
|
||||
hosts_data=request.env['runbot.host'].search([('assigned_only', '=', False)]),
|
||||
message=message,
|
||||
)
|
||||
|
||||
def _pending(self):
|
||||
ICP = request.env['ir.config_parameter'].sudo().get_param
|
||||
warn = int(ICP('runbot.pending.warning', 5))
|
||||
@ -108,22 +151,17 @@ class Runbot(Controller):
|
||||
'/runbot',
|
||||
'/runbot/<model("runbot.project"):project>',
|
||||
'/runbot/<model("runbot.project"):project>/search/<search>'], website=True, auth='public', type='http')
|
||||
def bundles(self, project=None, search='', projects=False, refresh=False, for_next_freeze=False, limit=40, has_pr=None, **kwargs):
|
||||
def bundles(self, project=None, search='', projects=False, refresh=False, for_next_freeze=False, limit=40, has_pr=None, old=None, **kwargs):
|
||||
search = search if len(search) < 60 else search[:60]
|
||||
env = request.env
|
||||
categories = env['runbot.category'].search([])
|
||||
if not project and projects:
|
||||
project = projects[0]
|
||||
|
||||
pending_count, level, scheduled_count, pending_assigned_count = self._pending()
|
||||
context = {
|
||||
'categories': categories,
|
||||
'search': search,
|
||||
'message': request.env['ir.config_parameter'].sudo().get_param('runbot.runbot_message'),
|
||||
'pending_count': pending_count,
|
||||
'pending_assigned_count': pending_assigned_count,
|
||||
'pending_level': level,
|
||||
'scheduled_count': scheduled_count,
|
||||
'toolbar': self._get_default_toolbar(include_message=True),
|
||||
'hosts_data': request.env['runbot.host'].search([('assigned_only', '=', False)]),
|
||||
}
|
||||
if project:
|
||||
@ -186,28 +224,32 @@ class Runbot(Controller):
|
||||
'search': search,
|
||||
})
|
||||
|
||||
context.update({'message': request.env['ir.config_parameter'].sudo().get_param('runbot.runbot_message')})
|
||||
# request.is_frontend = False # remove inherit branding
|
||||
return request.render('runbot.bundles', context)
|
||||
return request.render(f'runbot.bundles{"_new" if not old else ""}', context)
|
||||
|
||||
@route([
|
||||
'/runbot/bundle/<model("runbot.bundle"):bundle>',
|
||||
'/runbot/bundle/<model("runbot.bundle"):bundle>/page/<int:page>',
|
||||
'/runbot/bundle/<string:bundle>',
|
||||
], website=True, auth='public', type='http', sitemap=False)
|
||||
def bundle(self, bundle=None, page=1, limit=50, **kwargs):
|
||||
def bundle(self, bundle=None, page=1, limit=50, old=None, **kwargs):
|
||||
if isinstance(bundle, str):
|
||||
bundle = request.env['runbot.bundle'].search([('name', '=', bundle)], limit=1, order='id')
|
||||
if not bundle:
|
||||
raise NotFound
|
||||
return werkzeug.utils.redirect(f'/runbot/bundle/{slug(bundle)}')
|
||||
if isinstance(limit, str):
|
||||
limit = int(limit)
|
||||
domain = [('bundle_id', '=', bundle.id), ('hidden', '=', False)]
|
||||
batch_count = request.env['runbot.batch'].search_count(domain)
|
||||
pager = request.website.pager(
|
||||
url='/runbot/bundle/%s' % bundle.id,
|
||||
total=batch_count,
|
||||
page=page,
|
||||
step=50,
|
||||
step=limit,
|
||||
url_args={
|
||||
'limit': limit,
|
||||
}
|
||||
)
|
||||
batchs = request.env['runbot.batch'].search(domain, limit=limit, offset=pager.get('offset', 0), order='id desc')
|
||||
|
||||
@ -218,9 +260,16 @@ class Runbot(Controller):
|
||||
'project': bundle.project_id,
|
||||
'title': 'Bundle %s' % bundle.name,
|
||||
'page_info_state': bundle.last_batch._get_global_result(),
|
||||
'toolbar': ToolbarContext(
|
||||
breadcrumbs=[
|
||||
Breadcrumb('/runbot/%s' % bundle.project_id, bundle.project_id.display_name),
|
||||
Breadcrumb('/runbot/bundle/%s' % bundle.id, bundle.display_name),
|
||||
],
|
||||
middle_template='runbot.bundle_toolbar_middle_section',
|
||||
end_template='website.pager',
|
||||
)
|
||||
}
|
||||
|
||||
return request.render('runbot.bundle', context)
|
||||
return request.render(f'runbot.bundle{"_new" if not old else ""}', context)
|
||||
|
||||
@o_route([
|
||||
'/runbot/bundle/<model("runbot.bundle"):bundle>/force',
|
||||
@ -237,15 +286,25 @@ class Runbot(Controller):
|
||||
return werkzeug.utils.redirect('/runbot/batch/%s' % batch.id)
|
||||
|
||||
@route(['/runbot/batch/<int:batch_id>'], website=True, auth='public', type='http', sitemap=False)
|
||||
def batch(self, batch_id=None, **kwargs):
|
||||
def batch(self, batch_id=None, old=None, **kwargs):
|
||||
batch = request.env['runbot.batch'].browse(batch_id)
|
||||
bundle = batch.bundle_id
|
||||
project = bundle.project_id
|
||||
context = {
|
||||
'batch': batch,
|
||||
'project': batch.bundle_id.project_id,
|
||||
'project': project,
|
||||
'title': 'Batch %s (%s)' % (batch.id, batch.bundle_id.name),
|
||||
'page_info_state': batch._get_global_result(),
|
||||
'toolbar': ToolbarContext(
|
||||
breadcrumbs=[
|
||||
Breadcrumb('/runbot/%s' % project, project.display_name),
|
||||
Breadcrumb('/runbot/bundle/%s' % bundle.id, bundle.display_name),
|
||||
Breadcrumb('/runbot/bundle/batch/%s' % batch.id, batch.display_name),
|
||||
],
|
||||
middle_template='runbot.batch_toolbar_middle_section',
|
||||
),
|
||||
}
|
||||
return request.render('runbot.batch', context)
|
||||
return request.render(f'runbot.batch{"_new" if not old else ""}', context)
|
||||
|
||||
@o_route(['/runbot/batch/slot/<model("runbot.batch.slot"):slot>/build'], auth='user', type='http')
|
||||
def slot_create_build(self, slot=None, **kwargs):
|
||||
@ -312,7 +371,7 @@ class Runbot(Controller):
|
||||
'/runbot/build/<int:build_id>',
|
||||
'/runbot/batch/<int:from_batch>/build/<int:build_id>'
|
||||
], type='http', auth="public", website=True, sitemap=False)
|
||||
def build(self, build_id, search=None, from_batch=None, **post):
|
||||
def build(self, build_id, search=None, from_batch=None, old=None, **post):
|
||||
"""Events/Logs"""
|
||||
|
||||
if from_batch:
|
||||
@ -328,10 +387,34 @@ class Runbot(Controller):
|
||||
if not build.exists():
|
||||
return request.not_found()
|
||||
siblings = (build.parent_id.children_ids if build.parent_id else from_batch.slot_ids.build_id if from_batch else build).sorted('id')
|
||||
project = build.params_id.trigger_id.project_id
|
||||
breadcrumbs: Breadcrumbs = [Breadcrumb('/runbot/%s' % project, project.display_name)]
|
||||
batch = bundle = None
|
||||
if from_batch:
|
||||
batch = from_batch
|
||||
batches = batch
|
||||
bundle = batch.bundle_id
|
||||
bundles = bundle
|
||||
else:
|
||||
batches = build.top_parent.with_context(active_test=False).slot_ids.batch_id
|
||||
bundles = batches.bundle_id
|
||||
if len(batches) == 1:
|
||||
batch = batches
|
||||
if len(bundles) == 1:
|
||||
bundle = bundles
|
||||
if bundle:
|
||||
breadcrumbs.append(Breadcrumb(bundle._url(), bundle.display_name))
|
||||
if batch:
|
||||
breadcrumbs.append(Breadcrumb(batch._url(), batch.display_name))
|
||||
breadcrumbs.extend(
|
||||
Breadcrumb(ancestor.build_url, ancestor.description or ancestor.config_id.name) for ancestor in build.ancestors
|
||||
)
|
||||
context = {
|
||||
'build': build,
|
||||
'batches': batches,
|
||||
'bundles': bundles,
|
||||
'from_batch': from_batch,
|
||||
'project': build.params_id.trigger_id.project_id,
|
||||
'project': project,
|
||||
'title': 'Build %s' % build.id,
|
||||
'siblings': siblings,
|
||||
'page_info_state': build.global_result,
|
||||
@ -340,8 +423,13 @@ class Runbot(Controller):
|
||||
'prev_bu': next((b for b in reversed(siblings) if b.id < build.id), Build),
|
||||
'next_bu': next((b for b in siblings if b.id > build.id), Build),
|
||||
'next_ko': next((b for b in siblings if b.id > build.id and b.global_result != 'ok'), Build),
|
||||
'toolbar': ToolbarContext(
|
||||
breadcrumbs=breadcrumbs,
|
||||
middle_template='runbot.build_toolbar_middle_section',
|
||||
end_template='runbot.build_toolbar_end_section',
|
||||
)
|
||||
}
|
||||
return request.render("runbot.build", context)
|
||||
return request.render(f'runbot.build{"_new" if not old else ""}', context)
|
||||
|
||||
@route([
|
||||
'/runbot/build/search',
|
||||
|
@ -34,6 +34,10 @@ class Batch(models.Model):
|
||||
column2='referenced_batch_id',
|
||||
)
|
||||
|
||||
def _compute_display_name(self):
|
||||
for batch in self:
|
||||
batch.display_name = f'Batch #{batch.id}'
|
||||
|
||||
@api.depends('slot_ids.build_id')
|
||||
def _compute_all_build_ids(self):
|
||||
all_builds = self.env['runbot.build'].search([('id', 'child_of', self.slot_ids.build_id.ids)])
|
||||
|
@ -1269,3 +1269,22 @@ class BuildResult(models.Model):
|
||||
|
||||
def _parse_config(self):
|
||||
return set(findall(self._server("tools/config.py"), r'--[\w-]+', ))
|
||||
|
||||
def _get_view_class(self):
|
||||
"""
|
||||
Returns the color class to use according to bootstrap (+ killed).
|
||||
"""
|
||||
self.ensure_one()
|
||||
|
||||
if self.global_state in ('running', 'done'):
|
||||
if self.global_result == 'ok':
|
||||
return 'success'
|
||||
elif self.global_result == 'skipped':
|
||||
return 'skipped'
|
||||
elif self.global_result in ('killed', 'manually_killed'):
|
||||
return 'killed'
|
||||
if self.global_result == 'ko':
|
||||
return 'danger'
|
||||
elif self.global_result == 'warn':
|
||||
return 'warning'
|
||||
return 'info'
|
||||
|
@ -12,18 +12,51 @@
|
||||
--bs-warning-bg-subtle: #fff9e6;
|
||||
--bs-info-bg-subtle: #d9edf7;
|
||||
--bs-info-rgb: 23, 162, 184;
|
||||
// TODO: move to batch section
|
||||
.o_runbot_batch_card > .card-header {
|
||||
--bs-success-rgb: 223, 240, 216;
|
||||
--bs-info-rgb: 217, 237, 247;
|
||||
--bs-danger-rgb: 242, 222, 222;
|
||||
--bs-warning-rgb: 255, 249, 230;
|
||||
&.text-bg-info, &.text-bg-danger {
|
||||
color: #000 !important;
|
||||
}
|
||||
.badge {
|
||||
--bs-warning-rgb: 255, 193, 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
:root[data-bs-theme=red404] {
|
||||
:root[data-bs-theme=red404] {
|
||||
--bs-success-bg-subtle: #cdffb9;
|
||||
--bs-danger-bg-subtle: #e67ecf;
|
||||
--bs-warning-bg-subtle: #fae9b1;
|
||||
--bs-info-bg-subtle: #b6e2f8;
|
||||
--bs-info-rgb: 23, 162, 184;
|
||||
--bs-success-bg: #cdffb9;
|
||||
// TODO: move to batch section
|
||||
.o_runbot_batch_card > .card-header {
|
||||
--bs-success-rgb: 205, 255, 185;
|
||||
--bs-info-rgb: 182, 226, 248;
|
||||
--bs-danger-rgb: 230, 126, 207;
|
||||
--bs-warning-rgb: 250, 233, 177;
|
||||
&.text-bg-danger {
|
||||
color: #fff !important;
|
||||
}
|
||||
&.text-bg-success {
|
||||
color: #000 !important;
|
||||
}
|
||||
.badge {
|
||||
--bs-warning-rgb: 255, 193, 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-bs-theme=legacy] .text-bg-info {
|
||||
color: #fff !important; /* black by default, changes from previous version, color forced to fit with --bs-info-rgb*/
|
||||
}
|
||||
[data-bs-theme=legacy] .text-bg-success {
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
[data-bs-theme=legacy] .btn-success {
|
||||
--bs-btn-color: #fff;
|
||||
@ -85,7 +118,7 @@
|
||||
--bs-btn-focus-shadow-rgb: 60, 153, 110;
|
||||
--bs-btn-active-color: var(--btn-default-color);
|
||||
--bs-btn-active-bg: var(--bs-body-bg);
|
||||
--bs-btn-active-border-color: var(--bs-body-bg);
|
||||
--bs-btn-active-border-color: var(--btn-default-border);
|
||||
--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
||||
--bs-btn-disabled-color: var(--btn-default-color);
|
||||
--bs-btn-disabled-bg: var(--bs-body-bg);
|
||||
@ -221,6 +254,9 @@ body, .table {
|
||||
.dropdown-toggle:after {
|
||||
content: none;
|
||||
}
|
||||
.dropdown-toggle-caret:after {
|
||||
content: ' ';
|
||||
}
|
||||
|
||||
.one_line {
|
||||
white-space: nowrap;
|
||||
@ -249,12 +285,13 @@ body, .table {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.bg-killed {
|
||||
background-color: #aaa;
|
||||
.bg-killed, .bg-killed-subtle, .bg-skipped, .bg-skipped-subtle {
|
||||
background-color: var(--bs-tertiary-bg);
|
||||
}
|
||||
|
||||
.text-bg-killed {
|
||||
background-color: #aaa;
|
||||
color: var(--bs-body-color) !important;
|
||||
background-color: var(--bs-tertiary-bg);
|
||||
}
|
||||
|
||||
.table-condensed td {
|
||||
@ -425,4 +462,178 @@ body, .table {
|
||||
|
||||
code {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* NEW STUFF */
|
||||
|
||||
.o_runbot_sticky_star {
|
||||
color: #f0ad4e;
|
||||
}
|
||||
|
||||
/* Layout */
|
||||
.o_runbot_main_container > .row {
|
||||
padding: .5rem 0;
|
||||
}
|
||||
|
||||
.o_runbot_main_container > .row:not(:last-child) {
|
||||
border-bottom: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;
|
||||
}
|
||||
|
||||
/* Navbar */
|
||||
.o_runbot_navbar_username {
|
||||
max-width: 16rem;
|
||||
}
|
||||
|
||||
.o_runbot_btn_haspr {
|
||||
color: var(--bs-btn-color) !important;
|
||||
background-color: var(--bs-btn-bg) !important;
|
||||
border-color: var(--bs-btn-border-color) !important;
|
||||
}
|
||||
|
||||
.o_runbot_btn_haspr:has(input:checked) {
|
||||
color: var(--bs-btn-active-color) !important;
|
||||
background-color: var(--bs-btn-active-bg) !important;
|
||||
border-color: var(--bs-btn-active-border-color) !important;
|
||||
}
|
||||
|
||||
/* Bundles */
|
||||
@media (min-width: 768px) {
|
||||
.o_runbot_bundle_info {
|
||||
width: 16rem;
|
||||
max-width: 16rem;
|
||||
}
|
||||
}
|
||||
|
||||
.o_runbot_bundle_row .o_runbot_batch_card > .o_runbot_batch_card_content > .o_runbot_batch_card_slots > .o_runbot_batch_card_slot {
|
||||
min-width: 50%;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.o_runbot_bundle .o_runbot_batch_card > .o_runbot_batch_card_content > .o_runbot_batch_card_slots > .o_runbot_batch_card_slot {
|
||||
min-width: 50%;
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
@media (min-width: 576px) {
|
||||
.o_runbot_bundle .o_runbot_batch_card > .o_runbot_batch_card_content > .o_runbot_batch_card_slots > .o_runbot_batch_card_slot {
|
||||
flex-basis: 200px;
|
||||
flex-grow: 1;
|
||||
max-width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
.o_runbot_bundle > .col-12 {
|
||||
--bs-gutter-x: 0.5rem;
|
||||
--bs-gutter-y: 0.5rem;
|
||||
}
|
||||
|
||||
/* Batch */
|
||||
:root[data-bs-theme="legacy"] .o_runbot_batch_card {
|
||||
/* In legacy theme we want to keep the card's border color */
|
||||
border: var(--bs-card-border-width) solid var(--bs-card-border-color) !important;
|
||||
}
|
||||
|
||||
.o_runbot_batch_card > .o_runbot_batch_card_content > .o_runbot_batch_card_slots > .o_runbot_batch_card_slot > .o_runbot_slot_btn_group {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.o_runbot_batch_card > .o_runbot_batch_card_content > .o_runbot_batch_card_commits {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
.o_runbot_batch > .o_runbot_batch_slots .o_runbot_slot_btn_group {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Slot */
|
||||
// .btn-group-ssm > * {
|
||||
// align-items: center;
|
||||
// }
|
||||
.btn-group-ssm {
|
||||
> * {
|
||||
align-content: center;
|
||||
}
|
||||
.o_runbot_slot_btn_small, .o_runbot_build_menu {
|
||||
flex: 0 0 25px;
|
||||
}
|
||||
}
|
||||
.o_runbot_slot_btn_group .o_runbot_slot_btn_small, .o_runbot_slot_btn_group > .o_runbot_build_menu {
|
||||
flex: 0 0 25px;
|
||||
}
|
||||
|
||||
.o_runbot_log_grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, fit-content(200px)) 1fr;
|
||||
line-height: normal;
|
||||
min-width: 0;
|
||||
|
||||
&> *:not(.separator) {
|
||||
// Same as .border-bottom;
|
||||
border-bottom: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;
|
||||
}
|
||||
|
||||
&> .separator {
|
||||
grid-column: span 4;
|
||||
}
|
||||
|
||||
&> .o_runbot_log_grid_header {
|
||||
font-weight: bold;
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
&> .o_runbot_log_grid_date {
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
|
||||
&> *:not(.o_runbot_log_grid_message) {
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
&> .o_runbot_log_grid_message {
|
||||
overflow: hidden;
|
||||
|
||||
&> * {
|
||||
overflow: auto;
|
||||
text-wrap: nowrap;
|
||||
}
|
||||
|
||||
.o_runbot_log_message_toolbox {
|
||||
opacity: 0.8;
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
|
||||
// .btn.disabled has a different opacity
|
||||
&> * {
|
||||
--bs-btn-disabled-opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: remove if not used */
|
||||
.bg-danger-subtle-hover:hover {
|
||||
background-color: var(--bs-danger) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.bg-success-subtle-hover:hover {
|
||||
background-color: var(--bs-success) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.bg-warning-subtle-hover:hover {
|
||||
background-color: var(--bs-warning) !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.bg-info-subtle-hover:hover {
|
||||
background-color: var(--bs-info) !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.bg-killed-subtle-hover:hover {
|
||||
background-color: var(--body-secondary-bg);
|
||||
color: var(--body-secondary-color);
|
||||
}
|
@ -23,7 +23,7 @@ function stringify(obj) {
|
||||
export class JsonField extends TextField {
|
||||
static template = xml`
|
||||
<t t-if="props.readonly">
|
||||
<span t-esc="value"/>
|
||||
<span t-out="value"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div t-ref="div">
|
||||
@ -64,7 +64,7 @@ registry.category("fields").add("runbotjsonb", {
|
||||
|
||||
export class FrontendUrl extends Component {
|
||||
static template = xml`
|
||||
<div><a t-att-href="route" target="_blank"><t t-esc="displayValue"/></a></div>
|
||||
<div><a t-att-href="route" target="_blank"><t t-out="displayValue"/></a></div>
|
||||
`;
|
||||
|
||||
static components = { Many2OneField };
|
||||
|
@ -9,24 +9,24 @@
|
||||
<button class="btn btn-sm btn-outline-primary" t-on-click="toggleKept">Toggle context</button>
|
||||
<button class="btn btn-sm btn-outline-primary" t-on-click="copyNewToClipboard(trackingValue)">Copy new value to clipboard</button>
|
||||
</div>
|
||||
<div class="o-mail-Message-trackingField ms-1 fst-italic text-muted">(<t t-esc="trackingValue.changedField"/>)</div>
|
||||
<div class="o-mail-Message-trackingField ms-1 fst-italic text-muted">(<t t-out="trackingValue.changedField"/>)</div>
|
||||
<div class="code_diff">
|
||||
<table>
|
||||
<t t-foreach="lines(trackingValue)" t-as="line" t-key="line_index">
|
||||
<tr t-if="kept or line.type!=='kept'">
|
||||
<td class="col_number" t-esc="line.pre_line_counter"/>
|
||||
<td class="col_number" t-esc="line.post_line_counter"/>
|
||||
<td class="code" t-att-class="line.type" t-esc="line.line"/>
|
||||
<td class="col_number" t-out="line.pre_line_counter"/>
|
||||
<td class="col_number" t-out="line.post_line_counter"/>
|
||||
<td class="code" t-att-class="line.type" t-out="line.line"/>
|
||||
</tr>
|
||||
</t>
|
||||
</table>
|
||||
</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span class="o-mail-Message-trackingOld me-1 px-1 text-muted fw-bold" t-esc="formatTrackingOrNone(trackingValue.fieldType, trackingValue.oldValue)"/>
|
||||
<span class="o-mail-Message-trackingOld me-1 px-1 text-muted fw-bold" t-out="formatTrackingOrNone(trackingValue.fieldType, trackingValue.oldValue)"/>
|
||||
<i class="o-mail-Message-trackingSeparator fa fa-long-arrow-right mx-1 text-600"/>
|
||||
<span class="o-mail-Message-trackingNew me-1 fw-bold text-info" t-esc="formatTrackingOrNone(trackingValue.fieldType, trackingValue.newValue)"/>
|
||||
<span class="o-mail-Message-trackingField ms-1 fst-italic text-muted">(<t t-esc="trackingValue.changedField"/>)</span>
|
||||
<span class="o-mail-Message-trackingNew me-1 fw-bold text-info" t-out="formatTrackingOrNone(trackingValue.fieldType, trackingValue.newValue)"/>
|
||||
<span class="o-mail-Message-trackingField ms-1 fst-italic text-muted">(<t t-out="trackingValue.changedField"/>)</span>
|
||||
</t>
|
||||
</li>
|
||||
</xpath>
|
||||
|
@ -37,3 +37,40 @@ function copyToClipboard(text) {
|
||||
}
|
||||
navigator.clipboard.writeText(text);
|
||||
}
|
||||
|
||||
const copyHashToClipboard = (hash) => {
|
||||
if (!navigator.clipboard) {
|
||||
return
|
||||
}
|
||||
navigator.clipboard.writeText(location.origin + location.pathname + `#${hash}`);
|
||||
}
|
||||
|
||||
const switchTheme = (theme) => {
|
||||
document.documentElement.dataset.bsTheme = theme;
|
||||
}
|
||||
|
||||
// setInterval(() => {
|
||||
// if (document.documentElement.dataset.bsTheme === 'dark') {
|
||||
// switchTheme('light');
|
||||
// } else {
|
||||
// switchTheme('dark');
|
||||
// }
|
||||
// }, 2000)
|
||||
|
||||
const dark = switchTheme.bind(null, 'dark');
|
||||
const legacy = switchTheme.bind(null, 'legacy');
|
||||
const light = switchTheme.bind(null, 'light');
|
||||
const red404 = switchTheme.bind(null, 'red404');
|
||||
|
||||
setTimeout(() => {
|
||||
const navbarElem = document.querySelector('nav.navbar');
|
||||
const toolbarElem = document.querySelector('.o_runbot_toolbar.position-sticky');
|
||||
|
||||
if (navbarElem && toolbarElem) {
|
||||
toolbarElem.style.top = navbarElem.getBoundingClientRect().height;
|
||||
new ResizeObserver(() => {
|
||||
console.log('resize')
|
||||
toolbarElem.style.top = navbarElem.getBoundingClientRect().height;
|
||||
}).observe(navbarElem);
|
||||
}
|
||||
}, 150);
|
||||
|
@ -15,10 +15,10 @@
|
||||
<rect t-att-x="left.width" width="4" height="18" t-att-fill="right.color"/>
|
||||
<rect rx="4" t-attf-width="{{ left.width + right.width }}" height="18" fill="url(#smooth)"/>
|
||||
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
||||
<text t-attf-x="{{left.width/2+1}}" y="13" fill="#010101" fill-opacity=".3"><t t-esc="left.text"/></text>
|
||||
<text t-attf-x="{{left.width/2+1}}" y="12"><t t-esc="left.text"/></text>
|
||||
<text t-attf-x="{{left.width+right.width/2-1}}" y="13" fill="#010101" fill-opacity=".3"><t t-esc="right.text"/></text>
|
||||
<text t-attf-x="{{left.width+right.width/2-1}}" y="12"><t t-esc="right.text"/></text>
|
||||
<text t-attf-x="{{left.width/2+1}}" y="13" fill="#010101" fill-opacity=".3"><t t-out="left.text"/></text>
|
||||
<text t-attf-x="{{left.width/2+1}}" y="12"><t t-out="left.text"/></text>
|
||||
<text t-attf-x="{{left.width+right.width/2-1}}" y="13" fill="#010101" fill-opacity=".3"><t t-out="right.text"/></text>
|
||||
<text t-attf-x="{{left.width+right.width/2-1}}" y="12"><t t-out="right.text"/></text>
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
@ -36,10 +36,10 @@
|
||||
<rect t-att-x="left.width" width="4" height="20" t-att-fill="right.color"/>
|
||||
<rect rx="3" t-attf-width="{{ left.width + right.width }}" height="20" fill="url(#smooth)"/>
|
||||
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
||||
<text t-attf-x="{{left.width/2+1}}" y="15" fill="#010101" fill-opacity=".3"><t t-esc="left.text"/></text>
|
||||
<text t-attf-x="{{left.width/2+1}}" y="14"><t t-esc="left.text"/></text>
|
||||
<text t-attf-x="{{left.width+right.width/2-1}}" y="15" fill="#010101" fill-opacity=".3"><t t-esc="right.text"/></text>
|
||||
<text t-attf-x="{{left.width+right.width/2-1}}" y="14"><t t-esc="right.text"/></text>
|
||||
<text t-attf-x="{{left.width/2+1}}" y="15" fill="#010101" fill-opacity=".3"><t t-out="left.text"/></text>
|
||||
<text t-attf-x="{{left.width/2+1}}" y="14"><t t-out="left.text"/></text>
|
||||
<text t-attf-x="{{left.width+right.width/2-1}}" y="15" fill="#010101" fill-opacity=".3"><t t-out="right.text"/></text>
|
||||
<text t-attf-x="{{left.width+right.width/2-1}}" y="14"><t t-out="right.text"/></text>
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
|
@ -10,7 +10,7 @@
|
||||
<tr>
|
||||
<td>Bundle</td>
|
||||
<td>
|
||||
<a t-esc="batch.bundle_id.name" t-attf-href="/runbot/bundle/{{batch.bundle_id.id}}"/>
|
||||
<a t-out="batch.bundle_id.name" t-attf-href="/runbot/bundle/{{batch.bundle_id.id}}"/>
|
||||
&emsp;
|
||||
<a groups="runbot.group_runbot_advanced_user" t-attf-href="/web/#id={{batch.id}}&view_type=form&model=runbot.batch&menu_id={{env['ir.model.data']._xmlid_to_res_id('runbot.runbot_menu_root')}}" class="btn btn-default btn-sm" target="new" title="View Batch in Backend">
|
||||
<i class="fa fa-list"/>
|
||||
@ -19,28 +19,28 @@
|
||||
</tr>
|
||||
<tr t-if="batch.category_id.id != default_category">
|
||||
<td>Category</td>
|
||||
<td t-esc="batch.category_id.name"></td>
|
||||
<td t-out="batch.category_id.name"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td t-esc="batch.slot_ids[0].params_id.version_id.name if batch.slot_ids else batch.bundle_id.version_id.name"/>
|
||||
<td t-out="batch.slot_ids[0].params_id.version_id.name if batch.slot_ids else batch.bundle_id.version_id.name"/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Create date</td>
|
||||
<td t-esc="batch.create_date"/>
|
||||
<td t-out="batch.create_date"/>
|
||||
</tr>
|
||||
<tr t-if="more">
|
||||
<td>Last update</td>
|
||||
<td>
|
||||
<t t-esc="batch.last_update"/>
|
||||
<span class="badge text-bg-info" t-esc="s2human(batch.last_update - batch.create_date)"/>
|
||||
<t t-out="batch.last_update"/>
|
||||
<span class="badge text-bg-info" t-out="s2human(batch.last_update - batch.create_date)"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr t-if="more and batch.reference_batch_ids">
|
||||
<td>Version reference batches (for upgrade)</td>
|
||||
<td>
|
||||
<t t-foreach="batch.reference_batch_ids" t-as="reference_batch"/>
|
||||
<div><a t-attf-href="/runbot/batch/{{reference_batch.id}}"><t t-esc="reference_batch.bundle_id.version_id.name"/> (<t t-esc="reference_batch.id"/>)</a></div>
|
||||
<div><a t-attf-href="/runbot/batch/{{reference_batch.id}}"><t t-out="reference_batch.bundle_id.version_id.name"/> (<t t-out="reference_batch.id"/>)</a></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -54,63 +54,63 @@
|
||||
<i class="fa fa-fw fa-link" t-if="commit_link.match_type == 'head'" title="This commit is an existing head from bundle branches"/>
|
||||
<i class="fa fa-fw fa-code-fork" t-if="commit_link.match_type == 'base_match'" title="This commit is matched from a base batch with matching merge_base"/>
|
||||
<i class="fa fa-fw fa-clock-o" t-if="commit_link.match_type == 'base_head'" title="This commit is the head of a base branch"/>
|
||||
<span class="label" t-esc="commit.dname"/>
|
||||
<span class="label" t-out="commit.dname"/>
|
||||
</a>
|
||||
<a t-att-href="'https://%s/commit/%s' % (commit_link.branch_id.remote_id.base_url, commit_link.commit_id.name)" title="View Commit on Github"><i class="fa fa-github"/></a>
|
||||
<small t-if="commit_link.match_type and commit_link.match_type.startswith('base')">
|
||||
from base:
|
||||
<span t-esc="commit_link.branch_id.name"/>
|
||||
<span t-out="commit_link.branch_id.name"/>
|
||||
<br/>
|
||||
</small>
|
||||
<small t-else="">
|
||||
found in branch
|
||||
<span t-esc="commit_link.branch_id.name"/>
|
||||
<span t-out="commit_link.branch_id.name"/>
|
||||
<t t-if="batch.state != 'preparing'">
|
||||
<span t-esc="'+%s' % commit_link.diff_add" class="text-success"/>
|
||||
<span t-esc="'-%s' % commit_link.diff_remove" class="text-danger"/>
|
||||
<span t-out="'+%s' % commit_link.diff_add" class="text-success"/>
|
||||
<span t-out="'-%s' % commit_link.diff_remove" class="text-danger"/>
|
||||
<span class="text-info">
|
||||
(
|
||||
<span t-esc="commit_link.file_changed"/>
|
||||
<span t-out="commit_link.file_changed"/>
|
||||
<i class="fa fa-file"/>
|
||||
)
|
||||
<span io="behind">(
|
||||
<span t-esc="'%s ahead' % commit_link.base_ahead" class="text-success"/>
|
||||
<span t-out="'%s ahead' % commit_link.base_ahead" class="text-success"/>
|
||||
,
|
||||
<span t-esc="'%s behind' % commit_link.base_behind" class="text-danger"/>
|
||||
<span t-out="'%s behind' % commit_link.base_behind" class="text-danger"/>
|
||||
)</span>
|
||||
</span>
|
||||
</t>
|
||||
<br/>
|
||||
<t t-if="more">
|
||||
Base head:
|
||||
<span t-esc="commit_link.base_commit_id.name"/>
|
||||
<span t-out="commit_link.base_commit_id.name"/>
|
||||
<br/>
|
||||
Merge base:
|
||||
<span t-esc="commit_link.merge_base_commit_id.name"/>
|
||||
<span t-out="commit_link.merge_base_commit_id.name"/>
|
||||
<br/>
|
||||
</t>
|
||||
</small>
|
||||
<b t-if="commit.rebase_on_id">Automatic rebase on <t t-esc="commit.rebase_on_id.name"/><br/></b>
|
||||
<b t-if="commit.rebase_on_id">Automatic rebase on <t t-out="commit.rebase_on_id.name"/><br/></b>
|
||||
<t t-if="more or not (commit_link.match_type and commit_link.match_type.startswith('base'))">
|
||||
Subject:
|
||||
<span t-esc="commit.subject"/>
|
||||
<span t-out="commit.subject"/>
|
||||
<br/>
|
||||
Author:
|
||||
<span t-esc="commit.author"/>
|
||||
<span t-out="commit.author"/>
|
||||
(
|
||||
<span t-esc="commit.author_email"/>
|
||||
<span t-out="commit.author_email"/>
|
||||
)
|
||||
<br/>
|
||||
<t t-if="commit.author != commit.committer">
|
||||
Committer:
|
||||
<span t-esc="commit.committer"/>
|
||||
<span t-out="commit.committer"/>
|
||||
(
|
||||
<span t-esc="commit.committer_email"/>
|
||||
<span t-out="commit.committer_email"/>
|
||||
)
|
||||
<br/>
|
||||
</t>
|
||||
Commit date:
|
||||
<span t-esc="commit.date"/>
|
||||
<span t-out="commit.date"/>
|
||||
<br/>
|
||||
</t>
|
||||
<hr/>
|
||||
@ -155,7 +155,7 @@
|
||||
<t t-foreach="batch.log_ids" t-as="log">
|
||||
<t t-set="logclass" t-value="dict(ERROR='danger', WARNING='warning', INFO='info').get(log.level, 'warning')"/>
|
||||
<div t-attf-class="alert alert-{{logclass}}">
|
||||
<b t-esc="log.level"/>
|
||||
<b t-out="log.level"/>
|
||||
--
|
||||
<t t-out="log._markdown()"/>
|
||||
</div>
|
||||
|
@ -8,7 +8,7 @@
|
||||
<div class='col-md-12'>
|
||||
<div class="navbar navbar-default">
|
||||
<h3>
|
||||
<span class="text-muted"><t t-esc="branch.remote_id.short_name"/>:</span><t t-esc="branch.name"/> <i t-if="not branch.alive" title="deleted/closed" class="fa fa-ban text-danger"/>
|
||||
<span class="text-muted"><t t-out="branch.remote_id.short_name"/>:</span><t t-out="branch.name"/> <i t-if="not branch.alive" title="deleted/closed" class="fa fa-ban text-danger"/>
|
||||
<div class="btn-group" role="group">
|
||||
<a t-att-href="branch.branch_url" class="btn btn-sm text-start" title="View Branch on Github"><i class="fa fa-github"/></a>
|
||||
<a groups="runbot.group_runbot_admin" class="btn btn-sm fa fa-list text-start" t-attf-href="/web/#id={{branch.id}}&view_type=form&model=runbot.branch" target="new" title="View Branch in Backend"/>
|
||||
@ -18,11 +18,11 @@
|
||||
<table class="table table-condensed table-responsive table-stripped">
|
||||
<tr>
|
||||
<td>Remote:</td>
|
||||
<td t-esc="branch.remote_id.name"></td>
|
||||
<td t-out="branch.remote_id.name"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Head:</td>
|
||||
<td t-esc="branch.head_name"></td>
|
||||
<td t-out="branch.head_name"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Bundle:</td>
|
||||
@ -30,7 +30,7 @@
|
||||
<small>
|
||||
<div class="btn-toolbar mb-1" role="toolbar">
|
||||
<div class="btn-group btn-group-ssm w-100" role="group">
|
||||
<a t-attf-href="/runbot/bundle/{{branch.bundle_id.id}}" t-esc="branch.bundle_id.name" class="btn btn-default text-start" title="View Bundle Details"/>
|
||||
<a t-attf-href="/runbot/bundle/{{branch.bundle_id.id}}" t-out="branch.bundle_id.name" class="btn btn-default text-start" title="View Bundle Details"/>
|
||||
</div>
|
||||
</div>
|
||||
</small>
|
||||
@ -39,21 +39,21 @@
|
||||
<t t-if="branch.is_pr">
|
||||
<tr t-if="pr_branch">
|
||||
<td>Pull Head Name</td>
|
||||
<td><a t-attf-href="/runbot/branch/{{pr_branch.id}}" t-esc="branch.pull_head_name" title="View PR Details"/></td>
|
||||
<td><a t-attf-href="/runbot/branch/{{pr_branch.id}}" t-out="branch.pull_head_name" title="View PR Details"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Target Branch</td>
|
||||
<td t-esc="branch.target_branch_name"></td>
|
||||
<td t-out="branch.target_branch_name"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pr title</td>
|
||||
<td t-esc="branch.pr_title"/>
|
||||
<td t-out="branch.pr_title"/>
|
||||
</tr>
|
||||
</t>
|
||||
<t t-elif="branch_pr">
|
||||
<tr>
|
||||
<td>Pull Request:</td>
|
||||
<td><a t-attf-href="/runbot/branch/{{branch_pr.id}}" t-esc="branch_pr.name" title="View Branch Details"/></td>
|
||||
<td><a t-attf-href="/runbot/branch/{{branch_pr.id}}" t-out="branch_pr.name" title="View Branch Details"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
</table>
|
||||
@ -68,11 +68,11 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tr t-foreach='branch.reflog_ids' t-as='reflog'>
|
||||
<td t-esc="reflog.date"/>
|
||||
<td><a t-attf-href="/runbot/commit/{{reflog.commit_id.id}}" t-esc="reflog.commit_id.name"/></td>
|
||||
<td t-esc="reflog.commit_id.date"/>
|
||||
<td t-esc="reflog.commit_id.author"/>
|
||||
<td t-esc="reflog.commit_id.subject"/>
|
||||
<td t-out="reflog.date"/>
|
||||
<td><a t-attf-href="/runbot/commit/{{reflog.commit_id.id}}" t-out="reflog.commit_id.name"/></td>
|
||||
<td t-out="reflog.commit_id.date"/>
|
||||
<td t-out="reflog.commit_id.author"/>
|
||||
<td t-out="reflog.commit_id.subject"/>
|
||||
</tr>
|
||||
</table>
|
||||
<h4 t-else="">No Reflogs Found</h4>
|
||||
|
@ -29,22 +29,22 @@
|
||||
<ol class="breadcrumb mb-0">
|
||||
<li t-attf-class="breadcrumb-item">
|
||||
<a t-attf-href="/runbot/{{build.params_id.project_id.id}}">
|
||||
<t t-esc="build.params_id.project_id.name"/>
|
||||
<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-esc="unique_bundle.name"/>
|
||||
<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-esc="unique_batch.id"/> (<t t-esc="build.params_id.trigger_id.name"/>)
|
||||
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-esc="ancestor.description or ancestor.config_id.name"/>
|
||||
<t t-out="ancestor.description or ancestor.config_id.name"/>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
@ -70,14 +70,14 @@
|
||||
<div class="build_details">
|
||||
<!-- Batch/bundles links-->
|
||||
<t t-if="len(bundles) > 1">
|
||||
This build is referenced in <t t-esc="len(bundles)"/> bundles
|
||||
This build is referenced in <t t-out="len(bundles)"/> bundles
|
||||
<ul>
|
||||
<li t-foreach="bundles" t-as="bundle" ><a t-esc="bundle.name" t-attf-href="/runbot/bundle/{{bundle.id}}"/></li>
|
||||
<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-esc="batches[0].bundle_id.name" t-attf-href="/runbot/batch/{{batches[0].id}}"/><br/>
|
||||
<b>Last apparition:</b> <a t-esc="batches[-1].bundle_id.name" t-attf-href="/runbot/batch/{{batches[-1].id}}"/><br/>
|
||||
<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">
|
||||
@ -95,7 +95,7 @@
|
||||
<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-esc="build_commit.commit_id.dname"/>
|
||||
<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>
|
||||
@ -105,40 +105,40 @@
|
||||
</t>
|
||||
<div t-else="" class="ms-3">
|
||||
<b>Subject:</b>
|
||||
<t t-esc="build_commit.commit_id.subject"/>
|
||||
<t t-out="build_commit.commit_id.subject"/>
|
||||
<br/>
|
||||
<b>Author:</b>
|
||||
<t t-esc="build_commit.commit_id.author"/>
|
||||
<t t-out="build_commit.commit_id.author"/>
|
||||
<br/>
|
||||
<b>Committer:</b>
|
||||
<t t-esc="build_commit.commit_id.committer"/>
|
||||
<t t-out="build_commit.commit_id.committer"/>
|
||||
<br/>
|
||||
</div>
|
||||
</t>
|
||||
<b>Version:</b>
|
||||
<t t-esc="build.params_id.version_id.name"/>
|
||||
<t t-out="build.params_id.version_id.name"/>
|
||||
<br/>
|
||||
<b>Config:</b>
|
||||
<t t-esc="build.params_id.config_id.name"/>
|
||||
<t t-out="build.params_id.config_id.name"/>
|
||||
<br/>
|
||||
<t t-if='more'>
|
||||
<b>Trigger:</b>
|
||||
<t t-esc="build.params_id.trigger_id.name"/>
|
||||
<t t-out="build.params_id.trigger_id.name"/>
|
||||
<br/>
|
||||
<b>Config data:</b>
|
||||
<t t-esc="build.params_id.config_data.dict"/>
|
||||
<t t-out="build.params_id.config_data.dict"/>
|
||||
<br/>
|
||||
<b>Modules:</b>
|
||||
<t t-esc="build.params_id.modules"/>
|
||||
<t t-out="build.params_id.modules"/>
|
||||
<br/>
|
||||
<b>Extra params:</b>
|
||||
<t t-esc="build.params_id.extra_params"/>
|
||||
<t t-out="build.params_id.extra_params"/>
|
||||
<br/>
|
||||
|
||||
<t t-if="len(build.params_id.builds_reference_ids) > 1">
|
||||
<b>Reference builds:</b>
|
||||
<t t-foreach="build.params_id.builds_reference_ids" t-as="reference">
|
||||
<span t-esc="reference.id"/>
|
||||
<span t-out="reference.id"/>
|
||||
</t>
|
||||
<br/>
|
||||
</t>
|
||||
@ -149,39 +149,39 @@
|
||||
<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-esc="simbuild.id"/>
|
||||
t-out="simbuild.id"/>
|
||||
</a>
|
||||
</t>
|
||||
<br/>
|
||||
</t>
|
||||
<b>Host:</b>
|
||||
<t t-esc="build.host"/>
|
||||
<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-esc="s2human(build.build_time)"/>
|
||||
<i t-if='more'>(<t t-esc="build.build_time"/>s)</i>
|
||||
<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-esc="s2human(build.wait_time)"/>
|
||||
<i t-if='more'>(<t t-esc="build.wait_time"/>s)</i>
|
||||
<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-esc="s2human(build.load_time)"/>
|
||||
<i t-if='more'>(<t t-esc="build.load_time"/>s)</i>
|
||||
<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-esc="build.id"/></a>
|
||||
<a t-attf-href="/runbot/build/stats/{{build.id}}">Build <t t-out="build.id"/></a>
|
||||
<br/>
|
||||
</t>
|
||||
</div>
|
||||
@ -200,14 +200,14 @@
|
||||
<td>
|
||||
<a t-attf-href="/runbot/{{'batch/%s/' % from_batch.id if from_batch else ''}}build/{{child.id}}">
|
||||
Build
|
||||
<t t-esc="child.id"/>
|
||||
<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-esc="child.params_id.config_id.name"/>
|
||||
<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">
|
||||
@ -215,15 +215,15 @@
|
||||
</t>
|
||||
<t t-if="child.job">
|
||||
Running step:
|
||||
<t t-esc="child.job"/>
|
||||
<t t-out="child.job"/>
|
||||
</t>
|
||||
<t t-if="child.global_state in ['testing', 'waiting']">
|
||||
<i class="fa fa-spinner fa-spin"/>
|
||||
<t t-esc="child.global_state"/>
|
||||
<t t-out="child.global_state"/>
|
||||
</t>
|
||||
</td>
|
||||
<td>
|
||||
<span t-attf-class="badge text-bg-info" t-esc="s2human(child.build_time)"/>
|
||||
<span t-attf-class="badge text-bg-info" t-out="s2human(child.build_time)"/>
|
||||
</td>
|
||||
<td>
|
||||
<t t-call="runbot.build_button">
|
||||
@ -252,13 +252,13 @@
|
||||
<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-esc="l.create_date.strftime('%Y-%m-%d %H:%M:%S')"/>
|
||||
<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-esc="l.level"/>
|
||||
<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-esc="l.type"/>
|
||||
<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">
|
||||
@ -271,7 +271,7 @@
|
||||
<t t-if="l.type == 'subbuild'">
|
||||
<a t-attf-href="/runbot/build/{{l.path}}">
|
||||
Build #
|
||||
<t t-esc="l.path"/>
|
||||
<t t-out="l.path"/>
|
||||
</a>
|
||||
</t>
|
||||
<t t-else="">
|
||||
@ -283,31 +283,31 @@
|
||||
<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-esc="l.name"/>:<t t-esc="l.line"/></a>
|
||||
<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-esc="message[0]"/>
|
||||
<t t-out="message[0]"/>
|
||||
<a t-attf-href="{{l.path}}">
|
||||
<i t-attf-class="fa {{message[1]}}"/>
|
||||
</a>
|
||||
<t t-esc="message[2]"/>
|
||||
<t t-out="message[2]"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-esc="message[0]"/>
|
||||
<t t-out="message[0]"/>
|
||||
<a t-attf-href="{{l.path}}">
|
||||
<t t-esc="message[1]"/>
|
||||
<t t-out="message[1]"/>
|
||||
</a>
|
||||
<t t-esc="message[2]"/>
|
||||
<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-esc="l.message"/>
|
||||
<pre t-if="'\n' in l.message" style="margin:0;padding:0; border: none;"><t t-esc="l.message"/></pre>
|
||||
<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">
|
||||
@ -326,14 +326,14 @@
|
||||
<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-esc="'known' if error.active else 'fixed'"/></em>.
|
||||
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="new">
|
||||
<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="new">
|
||||
<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-esc="error.responsible.name"/>)</span>
|
||||
<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>
|
||||
@ -356,11 +356,11 @@
|
||||
</t>
|
||||
<tr t-attf-class="bg-{{rowclass.strip()}}-subtle{{' line-through' if build.orphan_result else ''}}">
|
||||
<td>
|
||||
<t t-esc="build.create_date"/>
|
||||
<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-esc="build.id"/>
|
||||
<t t-out="build.id"/>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
@ -371,17 +371,17 @@
|
||||
<td>
|
||||
<t t-if="build.global_state in ['testing', 'waiting']">
|
||||
<i class="fa fa-spinner fa-spin"/>
|
||||
<t t-esc="build.global_state"/>
|
||||
<t t-out="build.global_state"/>
|
||||
</t>
|
||||
</td>
|
||||
<td>
|
||||
<span t-esc="build.params_id.config_id.name"/>
|
||||
<span t-out="build.params_id.config_id.name"/>
|
||||
</td>
|
||||
<td>
|
||||
<span t-esc="build.params_id.version_id.name"/>
|
||||
<span t-out="build.params_id.version_id.name"/>
|
||||
</td>
|
||||
<td>
|
||||
<span t-esc="s2human(build.build_time)"/>
|
||||
<span t-out="s2human(build.build_time)"/>
|
||||
</td>
|
||||
<td>
|
||||
<t t-call="runbot.build_button">
|
||||
|
@ -18,27 +18,27 @@
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col"><t t-esc="build_error.last_seen_date" t-options='{"widget": "datetime"}'/></div>
|
||||
<div class="col"><t t-out="build_error.last_seen_date" t-options='{"widget": "datetime"}'/></div>
|
||||
<div class="col col-md-8">
|
||||
<button class="btn accordion-button collapsed" type="button" data-bs-toggle="collapse" t-attf-data-bs-target="#collapse{{build_error.id}}" aria-expanded="true" aria-controls="collapseOne">
|
||||
<code><t t-esc="build_error.name"/></code>
|
||||
<code><t t-out="build_error.name"/></code>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<t t-foreach="build_error.trigger_ids" t-as="trigger">
|
||||
<span class="badge text-bg-pill text-bg-info small"><t t-esc="trigger.name"/></span>
|
||||
<span class="badge text-bg-pill text-bg-info small"><t t-out="trigger.name"/></span>
|
||||
</t>
|
||||
</div>
|
||||
<div class="col">
|
||||
<t t-if="build_error.responsible" t-esc="build_error.responsible.name"/>
|
||||
<t t-if="build_error.responsible" t-out="build_error.responsible.name"/>
|
||||
<a t-else="" t-attf-href="/runbot/errors/assign/{{build_error.id}}" data-runbot="action" role="button" class="btn btn-primary btn-sm">Assign to me</a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<a t-att-href="build_error.last_seen_build_id.build_url" t-attf-title="View last affected build ({{build_error.last_seen_build_id.id}})"><i class="fa fa-external-link"/></a>
|
||||
<a groups="base.group_user" t-attf-href="/web/#id={{build_error.id}}&view_type=form&model=runbot.build.error&menu_id={{env['ir.model.data']._xmlid_to_res_id('runbot.runbot_menu_root')}}" target="new" title="View in Backend">
|
||||
<span class="badge text-bg-info" t-esc="build_error.build_count" t-attf-title="This error was seen {{build_error.build_count}} View in backend"/>
|
||||
<span class="badge text-bg-info" t-out="build_error.build_count" t-attf-title="This error was seen {{build_error.build_count}} View in backend"/>
|
||||
</a>
|
||||
<span groups="!base.group_user" class="badge text-bg-info" t-esc="build_error.build_count" t-attf-title="This error was seen {{build_error.build_count}}"/>
|
||||
<span groups="!base.group_user" class="badge text-bg-info" t-out="build_error.build_count" t-attf-title="This error was seen {{build_error.build_count}}"/>
|
||||
<span class="fa fa-random" t-if="build_error.random"/>
|
||||
</div>
|
||||
</div>
|
||||
@ -46,7 +46,7 @@
|
||||
|
||||
<div t-attf-id="collapse{{build_error.id}}" class="collapse" aria-labelledby="headingOne" t-attf-data-parent="#accordion_{{accordion_id}}">
|
||||
<div class="card-body">
|
||||
<pre class="pre-scrollable bg-danger-subtle"><t t-esc="build_error.content.strip()" /></pre>
|
||||
<pre class="pre-scrollable bg-danger-subtle"><t t-out="build_error.content.strip()" /></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -79,11 +79,11 @@
|
||||
<span class="ms-auto">
|
||||
<span class="dropdown me-auto">
|
||||
<a role="button" href="#" class="dropdown-toggle btn btn-secondary" data-bs-toggle="dropdown">
|
||||
Sort By: <t t-esc="request.params.get('sort', '')"/>
|
||||
Sort By: <t t-out="request.params.get('sort', '')"/>
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="sortMenuButton" role="menu">
|
||||
<t t-foreach="sort_order_choices" t-as="sort_choice">
|
||||
<a role="menuitem" class="dropdown-item" t-attf-href="/runbot/errors?sort={{sort_choice}}"><t t-esc="sort_order_choices[sort_choice]"/></a>
|
||||
<a role="menuitem" class="dropdown-item" t-attf-href="/runbot/errors?sort={{sort_choice}}"><t t-out="sort_order_choices[sort_choice]"/></a>
|
||||
</t>
|
||||
</div>
|
||||
</span>
|
||||
@ -110,7 +110,7 @@
|
||||
<div class="row">
|
||||
<div t-if="team" class='col-md-12'>
|
||||
<div class="col-lg-12 text-center mb16">
|
||||
<h2>Team <t t-esc="team.name.capitalize()"/>
|
||||
<h2>Team <t t-out="team.name.capitalize()"/>
|
||||
<a groups="base.group_user" t-attf-href="/web/#id={{team.id}}&view_type=form&model=runbot.team&menu_id={{env['ir.model.data']._xmlid_to_res_id('runbot.runbot_menu_root')}}" target="new" title="View in Backend">
|
||||
<i class="fa fa-list"/>
|
||||
</a>
|
||||
@ -140,7 +140,7 @@
|
||||
<div class="row">
|
||||
<div class="list-group list-group-horizontal">
|
||||
<t t-foreach="teams" t-as="team">
|
||||
<a t-attf-href="/runbot/teams/{{ team.id }}" class="list-group-item list-group-item-action"><t t-esc="team.name"/></a>
|
||||
<a t-attf-href="/runbot/teams/{{ team.id }}" class="list-group-item list-group-item-action"><t t-out="team.name"/></a>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -8,22 +8,22 @@
|
||||
<div class="row g-0">
|
||||
<div class="col-md-4">
|
||||
<div class="bg-success-subtle">
|
||||
<b>Build: </b><a t-attf-href="/runbot/build/{{build.id}}"><t t-esc="build.id"/></a><br/>
|
||||
<b>Build: </b><a t-attf-href="/runbot/build/{{build.id}}"><t t-out="build.id"/></a><br/>
|
||||
<t t-if="build.description">
|
||||
<b>Description:</b>
|
||||
<t t-out="build.md_description"/>
|
||||
<br/>
|
||||
</t>
|
||||
<b>Date: </b><t t-esc="build.create_date" /><br/>
|
||||
<b>Config: </b><t t-esc="build.params_id.config_id.name" /><br/>
|
||||
<b>Date: </b><t t-out="build.create_date" /><br/>
|
||||
<b>Config: </b><t t-out="build.params_id.config_id.name" /><br/>
|
||||
<b>Bundle(s): </b>
|
||||
<t t-foreach="bundles" t-as="bundle">
|
||||
<a t-attf-href="/runbot/bundle/{{bundle.id}}"><t t-esc="bundle.name" /></a>
|
||||
<a t-attf-href="/runbot/bundle/{{bundle.id}}"><t t-out="bundle.name" /></a>
|
||||
</t><br/>
|
||||
<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-esc="build_commit.commit_id.dname"/>
|
||||
<t t-out="build_commit.commit_id.dname"/>
|
||||
</a>
|
||||
<a t-att-href="'https://%s/commit/%s' % (build_commit.branch_id.remote_id.base_url, build_commit.commit_id.name)" class="btn btn-sm text-start" title="View Commit on Github"><i class="fa fa-github"/></a>
|
||||
<t t-if="build_commit.match_type in ('default', 'pr_target', 'prefix') ">
|
||||
@ -32,27 +32,27 @@
|
||||
</t>
|
||||
<div t-else="" class="ms-3">
|
||||
<b>Subject:</b>
|
||||
<t t-esc="build_commit.commit_id.subject"/>
|
||||
<t t-out="build_commit.commit_id.subject"/>
|
||||
<br/>
|
||||
<b>Author:</b>
|
||||
<t t-esc="build_commit.commit_id.author"/>
|
||||
<t t-out="build_commit.commit_id.author"/>
|
||||
<br/>
|
||||
<b>Committer:</b>
|
||||
<t t-esc="build_commit.commit_id.committer"/>
|
||||
<t t-out="build_commit.commit_id.committer"/>
|
||||
<br/>
|
||||
</div>
|
||||
</t>
|
||||
<b>Version:</b>
|
||||
<t t-esc="build.params_id.version_id.name"/>
|
||||
<t t-out="build.params_id.version_id.name"/>
|
||||
<br/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-foreach="sorted(build_stats.keys())" t-as="category" class="col-md-4">
|
||||
<h3><t t-esc="category.title().replace('_', ' ')"/></h3>
|
||||
<h3><t t-out="category.title().replace('_', ' ')"/></h3>
|
||||
<table class="table table-condensed table-responsive table-stripped">
|
||||
<tr t-foreach="build_stats[category].keys()" t-as="module">
|
||||
<td><t t-esc="module"/></td>
|
||||
<td><t t-esc="build_stats[category][module]"/></td>
|
||||
<td><t t-out="module"/></td>
|
||||
<td><t t-out="build_stats[category][module]"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
@ -69,11 +69,11 @@
|
||||
<div class="container-fluid">
|
||||
<nav class="navbar navbar-light">
|
||||
<div class="container">
|
||||
<b>Bundle:</b><t t-esc="bundle.name"/>
|
||||
<b>Trigger:</b><t t-esc="trigger.name"/>
|
||||
<b>Bundle:</b><t t-out="bundle.name"/>
|
||||
<b>Trigger:</b><t t-out="trigger.name"/>
|
||||
<b>Stat Category:</b>
|
||||
<select id="key_category_selector" class="form-select" aria-label="Stat Category">
|
||||
<option t-foreach="stats_categories" t-as="category" t-attf-value="{{category}}"><t t-esc="category.replace('_',' ').title()"/></option>
|
||||
<option t-foreach="stats_categories" t-as="category" t-attf-value="{{category}}"><t t-out="category.replace('_',' ').title()"/></option>
|
||||
</select>
|
||||
<b>Nb of builds:</b>
|
||||
<select id="limit_selector" class="form-select" aria-label="Number Of Builds">
|
||||
|
@ -8,7 +8,7 @@
|
||||
<div class='col-md-12'>
|
||||
<div class="navbar navbar-default">
|
||||
<span class="text-center" style="font-size: 18px;">
|
||||
<t t-esc="bundle.name"/>
|
||||
<t t-out="bundle.name"/>
|
||||
<i t-if="bundle.sticky" class="fa fa-star" style="color: #f0ad4e" />
|
||||
<div class="btn-group" role="group">
|
||||
<a groups="runbot.group_runbot_advanced_user" t-attf-href="/web/#id={{bundle.id}}&view_type=form&model=runbot.bundle&menu_id={{env['ir.model.data']._xmlid_to_res_id('runbot.runbot_menu_root')}}" class="btn btn-default" target="new" title="View in Backend">
|
||||
@ -55,7 +55,7 @@
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td>
|
||||
<t t-esc="bundle.version_id.name"/>
|
||||
<t t-out="bundle.version_id.name"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -68,8 +68,8 @@
|
||||
<div class="btn-group btn-group-ssm" role="group">
|
||||
<a t-att-href="branch.branch_url" class="btn btn-default text-left" title="View Branch on Github"><i class="fa fa-github"/></a>
|
||||
<a groups="runbot.group_runbot_admin" class="btn btn-default fa fa-list text-left" t-attf-href="/web/#id={{branch.id}}&view_type=form&model=runbot.branch" target="new" title="View Branch in Backend"/>
|
||||
<a href="#" t-esc="branch.remote_id.short_name" class="btn btn-default disabled text-left"/>
|
||||
<a t-attf-href="/runbot/branch/{{branch.id}}" class="btn btn-default text-left" title="View Branch Details"><span t-att-class="'' if branch.alive else 'line-through'" t-esc="branch.name"/> <i t-if="not branch.alive" title="deleted/closed" class="fa fa-ban text-danger"/></a>
|
||||
<a href="#" t-out="branch.remote_id.short_name" class="btn btn-default disabled text-left"/>
|
||||
<a t-attf-href="/runbot/branch/{{branch.id}}" class="btn btn-default text-left" title="View Branch Details"><span t-att-class="'' if branch.alive else 'line-through'" t-out="branch.name"/> <i t-if="not branch.alive" title="deleted/closed" class="fa fa-ban text-danger"/></a>
|
||||
<t t-if="not any (b.is_pr and b.alive for b in group[1]) and not branch.is_pr">
|
||||
<a t-attf-href="https://{{group[0].main_remote_id.base_url}}/compare/{{bundle.version_id.name}}...{{branch.remote_id.owner}}:{{branch.name}}?expand=1" class="btn btn-default text-left" title="Create pr"><i class="fa fa-code-fork"/> Create pr</a>
|
||||
</t>
|
||||
@ -83,7 +83,7 @@
|
||||
|
||||
<tr t-if="more">
|
||||
<td>Project</td>
|
||||
<td t-esc="bundle.project_id.name"/>
|
||||
<td t-out="bundle.project_id.name"/>
|
||||
</tr>
|
||||
<tr t-if="more">
|
||||
<td>New build enabled</td>
|
||||
@ -93,11 +93,11 @@
|
||||
</tr>
|
||||
<tr t-if="more">
|
||||
<td>Modules</td>
|
||||
<td t-esc="bundle.modules or '/'"/>
|
||||
<td t-out="bundle.modules or '/'"/>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div t-foreach="bundle._consistency_warning()" t-as="warning" t-esc="warning[1]" t-attf-class="alert alert-{{warning[0]}}"/>
|
||||
<div t-foreach="bundle._consistency_warning()" t-as="warning" t-out="warning[1]" t-attf-class="alert alert-{{warning[0]}}"/>
|
||||
<div class="batch_row" t-foreach="batchs" t-as="batch">
|
||||
<t t-call="runbot.batch_tile"/>
|
||||
</div>
|
||||
|
@ -6,17 +6,17 @@
|
||||
<td t-if="state=='pending'">
|
||||
<i class="fa fa-circle text-warning"/>
|
||||
&nbsp;
|
||||
<t t-esc="state"/>
|
||||
<t t-out="state"/>
|
||||
</td>
|
||||
<td t-if="state=='success'">
|
||||
<i class="fa fa-check text-success"/>
|
||||
&nbsp;
|
||||
<t t-esc="state"/>
|
||||
<t t-out="state"/>
|
||||
</td>
|
||||
<td t-if="state in ('failure', 'error')">
|
||||
<i class="fa fa-times text-danger"/>
|
||||
&nbsp;
|
||||
<t t-esc="state"/>
|
||||
<t t-out="state"/>
|
||||
</td>
|
||||
</template>
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>
|
||||
<t t-esc="commit.name"/>
|
||||
<t t-out="commit.name"/>
|
||||
<div class="btn-group" role="group">
|
||||
<a t-att-href="'' if not reflogs else 'https://%s/commit/%s' % (reflogs[0].branch_id.remote_id.base_url, commit.name)" class="btn btn-sm text-start" title="View Commit on Github"><i class="fa fa-github"/></a>
|
||||
<a groups="runbot.group_runbot_admin" class="btn btn-sm fa fa-list text-start" t-attf-href="/web/#id={{commit.id}}&view_type=form&model=runbot.commit" target="new" title="View Commit in Backend"/>
|
||||
@ -39,33 +39,33 @@
|
||||
<tr>
|
||||
<td>Tree hash</td>
|
||||
<td>
|
||||
<t t-esc="commit.tree_hash"/>
|
||||
<t t-out="commit.tree_hash"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Repo</td>
|
||||
<td t-esc="commit.repo_id.name"/>
|
||||
<td t-out="commit.repo_id.name"/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Subject</td>
|
||||
<td t-esc="commit.subject"/>
|
||||
<td t-out="commit.subject"/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Date</td>
|
||||
<td t-esc="commit.date"/>
|
||||
<td t-out="commit.date"/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Author</td>
|
||||
<td>
|
||||
<t t-esc="commit.author"/>
|
||||
<small t-esc="commit.author_email"/>
|
||||
<t t-out="commit.author"/>
|
||||
<small t-out="commit.author_email"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr t-if="commit.author != commit.committer">
|
||||
<td>Commiter</td>
|
||||
<td>
|
||||
<t t-esc="commit.committer"/>
|
||||
<small t-esc="commit.committer_email"/>
|
||||
<t t-out="commit.committer"/>
|
||||
<small t-out="commit.committer_email"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -76,15 +76,15 @@
|
||||
<table class="table table-sm table-borderless">
|
||||
<tr t-foreach='last_status_by_context' t-as='context'>
|
||||
<t t-set="status" t-value="last_status_by_context[context]"/>
|
||||
<td t-esc="status.sent_date and status.sent_date.strftime('%Y-%m-%d %H:%M:%S') or '—'"/>
|
||||
<td t-esc="context"/>
|
||||
<td t-out="status.sent_date and status.sent_date.strftime('%Y-%m-%d %H:%M:%S') or '—'"/>
|
||||
<td t-out="context"/>
|
||||
<t t-call="runbot.commit_status_state_td">
|
||||
<t t-set="state" t-value="status.state"/>
|
||||
</t>
|
||||
<td>
|
||||
<a t-att-href="status.target_url">
|
||||
build
|
||||
<t t-if="status.target_url" t-esc="status.target_url.split('/')[-1]" />
|
||||
<t t-if="status.target_url" t-out="status.target_url.split('/')[-1]" />
|
||||
</a>
|
||||
</td>
|
||||
<td groups="base.group_user">
|
||||
@ -101,9 +101,9 @@
|
||||
<h3>Branch presence history</h3>
|
||||
<table class="table table-stripped">
|
||||
<tr t-foreach='reflogs' t-as='reflog'>
|
||||
<td t-esc="reflog.date"/>
|
||||
<td t-esc="reflog.branch_id.remote_id.short_name"/>
|
||||
<td><a t-attf-href="/runbot/branch/{{reflog.branch_id.id}}" t-esc="reflog.branch_id.name" title="View Branch Details"/></td>
|
||||
<td t-out="reflog.date"/>
|
||||
<td t-out="reflog.branch_id.remote_id.short_name"/>
|
||||
<td><a t-attf-href="/runbot/branch/{{reflog.branch_id.id}}" t-out="reflog.branch_id.name" title="View Branch Details"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
@ -111,15 +111,15 @@
|
||||
<h3>Status history</h3>
|
||||
<table class="table table-stripped">
|
||||
<tr t-foreach='status_list' t-as='status'>
|
||||
<td t-esc="status.sent_date and status.sent_date.strftime('%Y-%m-%d %H:%M:%S') or '—'"/>
|
||||
<td t-esc="status.context"/>
|
||||
<td t-out="status.sent_date and status.sent_date.strftime('%Y-%m-%d %H:%M:%S') or '—'"/>
|
||||
<td t-out="status.context"/>
|
||||
<t t-call="runbot.commit_status_state_td">
|
||||
<t t-set="state" t-value="status.state"/>
|
||||
</t>
|
||||
<td>
|
||||
<a t-attf-href="/runbot/build/{{status.build_id.id}}">
|
||||
build
|
||||
<t t-esc="status.build_id.id" />
|
||||
<t t-out="status.build_id.id" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@ -129,4 +129,4 @@
|
||||
</t>
|
||||
</template>
|
||||
</data>
|
||||
</odoo>
|
||||
</odoo>
|
||||
|
@ -14,20 +14,20 @@
|
||||
<div>
|
||||
<span t-attf-class="badge text-bg-{{pending_level}}">
|
||||
Pending:
|
||||
<t t-esc="pending_count"/><span title="Assigned build (reserved host)" t-if="pending_assigned_count">(<t t-esc="pending_assigned_count"/>)</span>
|
||||
<t t-out="pending_count"/><span title="Assigned build (reserved host)" t-if="pending_assigned_count">(<t t-out="pending_assigned_count"/>)</span>
|
||||
</span>
|
||||
</div>
|
||||
<t t-set="project_id"/>
|
||||
<t t-set="nb_project" t-value="len(bundles.mapped('project_id'))"/>
|
||||
<t t-foreach="bundles.sorted(lambda b: (-b.project_id.id, b.version_id.number), reverse=True)" t-as="bundle">
|
||||
<h3 t-if="nb_project > 1 and project_id != bundle.project_id.id" t-esc="bundle.project_id.name"/>
|
||||
<h3 t-if="nb_project > 1 and project_id != bundle.project_id.id" t-out="bundle.project_id.name"/>
|
||||
<t t-set="project_id" t-value="bundle.project_id.id"/>
|
||||
<h4>
|
||||
<t t-esc="bundle.name"/>
|
||||
<t t-out="bundle.name"/>
|
||||
</h4>
|
||||
<t t-foreach="bundle.last_done_batch.slot_ids" t-as="slot">
|
||||
<span t-attf-class="badge text-bg-{{slot.build_id._get_color_class()}}">
|
||||
<t t-esc="slot.trigger_id.name"/>
|
||||
<t t-out="slot.trigger_id.name"/>
|
||||
</span>
|
||||
</t>
|
||||
</t>
|
||||
@ -74,7 +74,7 @@
|
||||
</div>
|
||||
<t t-foreach="hosts_data.sorted(key=lambda h:h.name)" t-as="host">
|
||||
<div>
|
||||
<span t-esc="host.name.split('.')[0]"/>
|
||||
<span t-out="host.name.split('.')[0]"/>
|
||||
<t t-if="host.nb_testing == 0">
|
||||
<t t-set="klass">success</t>
|
||||
</t>
|
||||
@ -88,11 +88,11 @@
|
||||
<t t-set="klass">danger</t>
|
||||
</t>
|
||||
<span t-attf-class="badge text-bg-{{klass}}">
|
||||
<span t-esc="host.nb_testing"/>
|
||||
<span t-out="host.nb_testing"/>
|
||||
/
|
||||
<span t-esc="host.nb_worker"/>
|
||||
<span t-out="host.nb_worker"/>
|
||||
</span>
|
||||
<t t-esc="host.nb_running"/>
|
||||
<t t-out="host.nb_running"/>
|
||||
<t t-set="succes_time" t-value="int(datetime.datetime.now().timestamp() - host.last_success.timestamp())"/>
|
||||
<t t-set="start_time" t-value="int(datetime.datetime.now().timestamp() - host.last_start_loop.timestamp())"/>
|
||||
<t t-set="end_time" t-value="int(datetime.datetime.now().timestamp() - host.last_end_loop.timestamp())"/>
|
||||
@ -106,7 +106,7 @@
|
||||
</t>
|
||||
|
||||
<span t-attf-class="badge text-bg-{{klass}}">
|
||||
<span t-esc="succes_time"/>
|
||||
<span t-out="succes_time"/>
|
||||
</span>
|
||||
|
||||
<t t-set="klass">success</t>
|
||||
@ -118,7 +118,7 @@
|
||||
</t>
|
||||
|
||||
<span t-attf-class="badge text-bg-{{klass}}">
|
||||
<span t-esc="start_time"/>
|
||||
<span t-out="start_time"/>
|
||||
</span>
|
||||
|
||||
<t t-set="klass">success</t>
|
||||
@ -130,7 +130,7 @@
|
||||
</t>
|
||||
|
||||
<span t-attf-class="badge text-bg-{{klass}}">
|
||||
<span t-esc="end_time"/>
|
||||
<span t-out="end_time"/>
|
||||
</span>
|
||||
|
||||
<t t-set="cron_time" t-value="end_time-start_time"/>
|
||||
@ -142,7 +142,7 @@
|
||||
<t t-set="klass">danger</t>
|
||||
</t>
|
||||
<span t-attf-class="badge text-bg-{{klass}}">
|
||||
<span t-esc="cron_time"/>
|
||||
<span t-out="cron_time"/>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
@ -151,7 +151,7 @@
|
||||
<table>
|
||||
<tr t-foreach="bundles.sorted(lambda b: b.version_id.number, reverse=True)" t-as="bundle">
|
||||
<td>
|
||||
<t t-esc="bundle.version_id.number"/>
|
||||
<t t-out="bundle.version_id.number"/>
|
||||
</td>
|
||||
<td>
|
||||
<t t-set='batch' t-value="bundle.with_context({'category_id': category.id}).last_done_batch"/>
|
||||
@ -159,7 +159,7 @@
|
||||
<t t-foreach="batch.slot_ids" t-as='slot'>
|
||||
<tr>
|
||||
<td>
|
||||
<t t-esc="slot.trigger_id.name[:4]"/>
|
||||
<t t-out="slot.trigger_id.name[:4]"/>
|
||||
</td>
|
||||
<t t-set="build" t-value="slot.build_id"/>
|
||||
<td>
|
||||
@ -169,7 +169,7 @@
|
||||
</td>
|
||||
<td t-foreach="build.children_ids" t-as="child">
|
||||
<span t-attf-class="badge text-bg-{{slot.build_id._get_color_class()}}">
|
||||
<t t-esc="child.params_id.config_id.name[:4]"/>
|
||||
<t t-out="child.params_id.config_id.name[:4]"/>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
@ -188,16 +188,16 @@
|
||||
<div class="col-md-3 col-lg-2 p-2">
|
||||
<div class="card">
|
||||
<div class="card-header limited-height-toggle" t-attf-onclick="$('#tile_{{tile.id}}').toggleClass('limited-height')">
|
||||
<t t-esc="tile.display_name"/> <t t-if="tile.build_ids"> (<t t-esc="len(tile.build_ids)"/>)</t>
|
||||
<t t-out="tile.display_name"/> <t t-if="tile.build_ids"> (<t t-out="len(tile.build_ids)"/>)</t>
|
||||
</div>
|
||||
<div class="card-body limited-height" t-attf-id="tile_{{tile.id}}">
|
||||
<p t-if="not tile.build_ids" class="text-success my-0">No build found 👍</p>
|
||||
<t t-foreach="tile.sticky_bundle_ids.sorted(lambda b: b.version_id.number, reverse=True)" t-as="bundle">
|
||||
<t t-set="failed_builds" t-value="tile.build_ids.filtered(lambda b: b.top_parent.slot_ids.batch_id.bundle_id == bundle)"/>
|
||||
<h4 class="card-title" t-if="failed_builds" t-esc="bundle.name"/>
|
||||
<h4 class="card-title" t-if="failed_builds" t-out="bundle.name"/>
|
||||
<p t-foreach="failed_builds" t-as="build" class="my-0">
|
||||
<a class="text-danger" t-attf-href="/runbot/build/{{build.id}}" target="new">
|
||||
<t t-esc="build.description or build.id"/>
|
||||
<t t-out="build.description or build.id"/>
|
||||
</a>
|
||||
</p>
|
||||
</t>
|
||||
@ -243,7 +243,7 @@
|
||||
<div class="one_line">
|
||||
<i t-if="bundle.sticky" class="fa fa-star" style="color: #f0ad4e" />
|
||||
<a t-attf-href="/runbot/bundle/#{bundle.id}" title="View Bundle">
|
||||
<b t-esc="bundle.name"/>
|
||||
<b t-out="bundle.name"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="badge text-bg-info" t-out="len(builds)"/>
|
||||
|
@ -26,7 +26,7 @@
|
||||
</div>
|
||||
<div class='col-md-12'>
|
||||
<div t-if="message" class="alert alert-warning" role="alert">
|
||||
<t t-esc="message" />
|
||||
<t t-out="message" />
|
||||
</div>
|
||||
<div t-if="not project" class="mb32">
|
||||
<h3>No project</h3>
|
||||
@ -37,7 +37,7 @@
|
||||
<div class="one_line">
|
||||
<i t-if="bundle.sticky" class="fa fa-star" style="color: #f0ad4e" />
|
||||
<a t-attf-href="/runbot/bundle/#{bundle.id}" t-attf-title="View Bundle #{bundle.name}">
|
||||
<b t-esc="bundle.name"/>
|
||||
<b t-out="bundle.name"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">
|
||||
@ -62,7 +62,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="bundle.host_id">
|
||||
<span class="badge text-bg-info" t-esc="bundle.host_id.name"></span>
|
||||
<span class="badge text-bg-info" t-out="bundle.host_id.name"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-9 col-lg-10">
|
||||
@ -91,7 +91,7 @@
|
||||
<a t-attf-href="/runbot/batch/#{batch.id}" title="View Batch">
|
||||
<div class="batch_header">
|
||||
<span t-attf-class="badge text-bg-{{'warning' if batch.has_warning else 'default'}}">
|
||||
<t t-esc="batch._get_formated_age()"/>
|
||||
<t t-out="batch._get_formated_age()"/>
|
||||
<i class="fa fa-exclamation-triangle" t-if="batch.has_warning"/>
|
||||
</span>
|
||||
<span class="float-end header_hover">View batch...</span>
|
||||
@ -118,10 +118,10 @@
|
||||
<i class="fa fa-fw fa-link" t-if="commit_link.match_type == 'head'" title="This commit is an existing head from bundle branches"/>
|
||||
<i class="fa fa-fw fa-code-fork" t-if="commit_link.match_type == 'base_match'" title="This commit is matched from a base batch with matching merge_base"/>
|
||||
<i class="fa fa-fw fa-clock-o" t-if="commit_link.match_type == 'base_head'" title="This commit is the head of a base branch"/>
|
||||
<t t-esc="commit_link.commit_id.dname"/>
|
||||
<t t-out="commit_link.commit_id.dname"/>
|
||||
</a>
|
||||
<a t-att-href="'https://%s/commit/%s' % (commit_link.branch_id.remote_id.base_url, commit_link.commit_id.name)" t-attf-class="badge text-bg-{{match_class}}" title="View Commit on Github"><i class="fa fa-github"/></a>
|
||||
<span t-esc="commit_link.commit_id.subject"/>
|
||||
<span t-out="commit_link.commit_id.subject"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,10 +6,10 @@
|
||||
filemode = true
|
||||
bare = true
|
||||
<t t-foreach="repo.remote_ids" t-as="remote_id">
|
||||
[remote "<t t-esc="remote_id.remote_name"/>"]
|
||||
url = <t t-esc="remote_id.name"/>
|
||||
<t t-if = "remote_id.fetch_heads"> fetch = +refs/heads/*:refs/<t t-esc='remote_id.remote_name'/>/heads/*</t>
|
||||
<t t-if = "remote_id.fetch_pull"> fetch = +refs/pull/*/head:refs/<t t-esc='remote_id.remote_name'/>/pull/*</t>
|
||||
[remote "<t t-out="remote_id.remote_name"/>"]
|
||||
url = <t t-out="remote_id.name"/>
|
||||
<t t-if = "remote_id.fetch_heads"> fetch = +refs/heads/*:refs/<t t-out='remote_id.remote_name'/>/heads/*</t>
|
||||
<t t-if = "remote_id.fetch_pull"> fetch = +refs/pull/*/head:refs/<t t-out='remote_id.remote_name'/>/pull/*</t>
|
||||
</t></template>
|
||||
</data>
|
||||
</odoo>
|
||||
|
226
runbot/templates/new/batch.xml
Normal file
226
runbot/templates/new/batch.xml
Normal file
@ -0,0 +1,226 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<template id="runbot.batch_card">
|
||||
<t t-set="klass">info</t>
|
||||
<t t-if="batch.state=='skipped'" t-set="klass">killed</t>
|
||||
<t t-if="batch.state=='done' and all(slot.build_id.global_result == 'ok' for slot in batch.slot_ids if slot.build_id)" t-set="klass">success</t>
|
||||
<t t-if="batch.state=='done' and any(slot.build_id.global_result in ('ko', 'warn') for slot in batch.slot_ids)" t-set="klass">danger</t>
|
||||
<div t-attf-class="o_runbot_batch_card card w-100 h-100">
|
||||
<a t-attf-class="card-header px-2 d-flex justify-content-between alig-items-center text-bg-{{klass}}"
|
||||
t-attf-href="/runbot/batch/#{batch.id}" title="View Batch"
|
||||
>
|
||||
<span class="lh-sm">Batch #<t t-out="batch.id"/></span>
|
||||
<span t-attf-class="badge text-bg-{{'warning' if batch.has_warning else 'default'}}">
|
||||
<t t-out="batch._get_formated_age()"/>
|
||||
<i t-if="batch.has_warning" class="fa fa-exclamation-triangle"/>
|
||||
</span>
|
||||
</a>
|
||||
<div class="o_runbot_batch_card_content d-flex flex-column justify-content-between h-100">
|
||||
<div class="o_runbot_batch_card_slots card-body row g-1 p-1">
|
||||
<div t-if="batch.state == 'preparing'" class="col-12 btn-group btn-group-ssm">
|
||||
<span class="btn btn-default disabled" titled="Preparing">
|
||||
<i class="fa fa-cog fa-spin fa-fw"/> Preparing
|
||||
</span>
|
||||
</div>
|
||||
<t t-foreach="batch.slot_ids" t-as="slot">
|
||||
<t t-if="slot.build_id">
|
||||
<div class="o_runbot_batch_card_slot col-auto">
|
||||
<t t-if="((not slot.trigger_id.hide and trigger_display is None) or (trigger_display and slot.trigger_id.id in trigger_display)) or slot.build_id.global_result != 'ok'"
|
||||
t-call="runbot.slot_btn_group"/>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
<div class="o_runbot_batch_card_commits row g-0 card-footer p-1" t-if="more">
|
||||
<div t-foreach="batch.commit_link_ids.sorted(lambda cl: (cl.commit_id.repo_id.sequence, cl.commit_id.repo_id.id))" t-as="commit_link"
|
||||
class="col-12 text-truncate"
|
||||
>
|
||||
<t t-set="match_class" t-value="'info' if commit_link.match_type == 'new' else 'secondary'"/>
|
||||
<a
|
||||
title="View Commit on Github"
|
||||
t-att-href="'https://%s/commit/%s' % (commit_link.branch_id.remote_id.base_url, commit_link.commit_id.name)"
|
||||
t-attf-class="badge text-bg-{{match_class}}"
|
||||
>
|
||||
<i class="fa fa-github"/>
|
||||
</a>
|
||||
<a t-attf-href="/runbot/commit/#{commit_link.commit_id.id}" t-attf-class="badge text-bg-{{match_class}}">
|
||||
<i class="fa fa-fw fa-hashtag" t-if="commit_link.match_type == 'new'" title="This commit is a new head"/>
|
||||
<i class="fa fa-fw fa-link" t-if="commit_link.match_type == 'head'" title="This commit is an existing head from bundle branches"/>
|
||||
<i class="fa fa-fw fa-code-fork" t-if="commit_link.match_type == 'base_match'" title="This commit is matched from a base batch with matching merge_base"/>
|
||||
<i class="fa fa-fw fa-clock-o" t-if="commit_link.match_type == 'base_head'" title="This commit is the head of a base branch"/>
|
||||
<t t-out="commit_link.commit_id.dname"/>
|
||||
</a>
|
||||
<span class="font-monospace text-nowrap text-truncate overflow-hidden" t-att-title="commit_link.commit_id.subject" t-out="commit_link.commit_id.subject"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="runbot.batch_commit_link_cell">
|
||||
<t t-set="commit" t-value="commit_link.commit_id"/>
|
||||
<div class="row">
|
||||
<div>
|
||||
<a t-attf-href="/runbot/commit/#{commit.id}">
|
||||
<i class="fa fa-fw fa-hashtag" t-if="commit_link.match_type == 'new'" title="This commit is a new head"/>
|
||||
<i class="fa fa-fw fa-link" t-if="commit_link.match_type == 'head'" title="This commit is an existing head from bundle branches"/>
|
||||
<i class="fa fa-fw fa-code-fork" t-if="commit_link.match_type == 'base_match'" title="This commit is matched from a base batch with matching merge_base"/>
|
||||
<i class="fa fa-fw fa-clock-o" t-if="commit_link.match_type == 'base_head'" title="This commit is the head of a base branch"/>
|
||||
<span class="label" t-out="commit.dname"/>
|
||||
</a>
|
||||
<a t-att-href="'https://%s/commit/%s' % (commit_link.branch_id.remote_id.base_url, commit_link.commit_id.name)" title="View Commit on Github"><i class="fa fa-github"/></a>
|
||||
<small>
|
||||
<t t-if="commit_link.match_type and commit_link.match_type.startswith('base')">
|
||||
from base: <t t-out="commit_link.branch_id.name"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
found in branch <t t-out="commit_link.branch_id.name"/>
|
||||
<t t-if="batch.state != 'preparing'">
|
||||
<span t-out="'+%s' % commit_link.diff_add" class="text-success"/>
|
||||
<span t-out="'-%s' % commit_link.diff_remove" class="text-danger"/>
|
||||
<span class="text-info">
|
||||
(
|
||||
<t t-out="commit_link.file_changed"/>
|
||||
<i class="fa fa-file"/>
|
||||
)
|
||||
<span>(
|
||||
<span t-out="'%s ahead' % commit_link.base_ahead" class="text-success"/>
|
||||
,
|
||||
<span t-out="'%s behind' % commit_link.base_behind" class="text-danger"/>
|
||||
)</span>
|
||||
</span>
|
||||
</t>
|
||||
</t>
|
||||
</small>
|
||||
</div>
|
||||
<small class="d-block">Base head: <t t-out="commit_link.base_commit_id.name"/></small>
|
||||
<small class="d-block">Merge head: <t t-out="commit_link.merge_base_commit_id.name"/></small>
|
||||
<b t-if="commit.rebase_on_id">Automatic rebase on <t t-out="commit.rebase_on_id.name"/><br/></b>
|
||||
<t t-if="more or not (commit_link.match_type and commit_link.match_type.startswith('base'))">
|
||||
<span class="d-block">
|
||||
Subject: <t t-out="commit.subject"/>
|
||||
</span>
|
||||
<span class="d-block">
|
||||
Author: <t t-out="commit.author"/> (<t t-out="commit.author_email"/>)
|
||||
</span>
|
||||
<span class="d-block" t-if="commit.author != commit.committer">
|
||||
Committer: <t t-out="commit.committer"/> (<t t-out="commit.committer_email"/>)
|
||||
</span>
|
||||
<span class="d-block">
|
||||
Commit date: <t t-out="commit.date"/>
|
||||
</span>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="runbot.batch_toolbar_middle_section">
|
||||
<div class="btn-group btn-group-sm" role="group" groups="runbot.group_runbot_advanced_user">
|
||||
<a t-attf-href="/web/#id={{batch.id}}&view_type=form&model=runbot.batch&menu_id={{env['ir.model.data']._xmlid_to_res_id('runbot.runbot_menu_root')}}" class="btn btn-default" target="new" title="View Batch in Backend">
|
||||
<i class="fa fa-list"/>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="runbot.batch_new">
|
||||
<t t-call="runbot.layout_new">
|
||||
<div class="o_runbot_batch row">
|
||||
<div class="o_runbot_batch_details col-12 col-lg-6">
|
||||
<t t-set="batch_class" t-value="'bg-info-subtle' if batch.state=='preparing' else 'bg-success-subtle' if not any(log.level != 'INFO' for log in batch.log_ids) else 'bg-warning-subtle'"/>
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<td>Bundle</td>
|
||||
<td>
|
||||
<a t-out="batch.bundle_id.name" t-attf-href="/runbot/bundle/{{batch.bundle_id.id}}"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr t-if="batch.category_id.id != default_category">
|
||||
<td>Category</td>
|
||||
<td t-out="batch.category_id.name"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td t-out="batch.slot_ids[0].params_id.version_id.name if batch.slot_ids else batch.bundle_id.version_id.name"/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Create date</td>
|
||||
<td t-out="batch.create_date"/>
|
||||
</tr>
|
||||
<tr t-if="more">
|
||||
<td>Last update</td>
|
||||
<td>
|
||||
<t t-out="batch.last_update"/>
|
||||
<span class="badge text-bg-info pull-right" t-out="s2human_long(batch.last_update - batch.create_date)"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr t-if="more and batch.reference_batch_ids">
|
||||
<td>Version reference batches (for upgrade)</td>
|
||||
<td>
|
||||
<t t-foreach="batch.reference_batch_ids" t-as="reference_batch"/>
|
||||
<div><a t-attf-href="/runbot/batch/{{reference_batch.id}}"><t t-out="reference_batch.bundle_id.version_id.name"/> (<t t-out="reference_batch.id"/>)</a></div>
|
||||
</td>
|
||||
</tr>
|
||||
<t t-set="commit_links" t-value="batch.commit_link_ids.sorted(key=lambda lc: (lc.commit_id.repo_id.sequence, lc.commit_id.repo_id.id))"/>
|
||||
<tr>
|
||||
<td t-att-class="batch_class" t-att-rowspan="len(batch.commit_link_ids)">Commits</td>
|
||||
<!-- TODO: dedup -->
|
||||
<td t-att-class="batch_class">
|
||||
<t t-call="runbot.batch_commit_link_cell">
|
||||
<t t-set="commit_link" t-value="commit_links[0]"/>
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
<tr t-foreach="commit_links[1:]" t-as="commit_link">
|
||||
<td t-att-class="batch_class">
|
||||
<t t-call="runbot.batch_commit_link_cell"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="o_runbot_batch_slots col-12 col-lg-6">
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<td>Builds</td>
|
||||
<td>
|
||||
<div class="row g-1">
|
||||
<t t-foreach="batch.slot_ids.filtered(lambda s: not s.trigger_id.manual)" t-as="slot" t-call="runbot.slot_btn_group"/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Manual</td>
|
||||
<td>
|
||||
<div class="row g-1">
|
||||
<t t-foreach="batch.slot_ids.filtered(lambda s: s.trigger_id.manual)" t-as="slot">
|
||||
<t t-if="slot.build_id or (not slot.trigger_id.team_ids) or (user_id in slot.trigger_id.team_ids.user_ids)">
|
||||
<t t-call="runbot.slot_btn_group"/>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr t-if="more">
|
||||
<td>Old builds</td>
|
||||
<td>
|
||||
<div class="row g-1 text-decoration-line-through">
|
||||
<t t-foreach="batch.with_context(active_test=False).slot_ids.filtered(lambda s: not s.active)" t-as="slot">
|
||||
<t t-call="runbot.slot_btn_group"/>
|
||||
</t>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="o_runbot_batch_logs col-12">
|
||||
<t t-foreach="batch.log_ids" t-as="log">
|
||||
<t t-set="logclass" t-value="dict(ERROR='danger', WARNING='warning', INFO='info').get(log.level, 'warning')"/>
|
||||
<div t-attf-class="alert alert-{{logclass}}">
|
||||
<b t-out="log.level"/>
|
||||
--
|
||||
<t t-out="log._markdown()"/>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
271
runbot/templates/new/build.xml
Normal file
271
runbot/templates/new/build.xml
Normal file
@ -0,0 +1,271 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<template id="runbot.build_buttons">
|
||||
<a t-if="build.local_state == 'running' and build.database_ids" t-attf-href="/runbot/run/{{build.id}}" class="btn btn-info o_runbot_slot_btn_small" title="Sign in on this build" aria-label="Sign in on this build">
|
||||
<i class="fa fa-sign-in"/>
|
||||
</a>
|
||||
<a t-if="build.static_run" t-att-href="build.static_run" class="btn btn-info o_runbot_slot_btn_small" title="View result" aria-label="View result">
|
||||
<i class="fa fa-sign-in"/>
|
||||
</a>
|
||||
<a groups="base.group_user" t-if="build.local_state=='done' and (not build.parent_id.database_ids or user_id.has_group('runbot.group_runbot_advanced_user')) and build.requested_action != 'wake_up' and build.database_ids"
|
||||
href="#" data-runbot="wakeup" t-att-data-runbot-build="build.id" class="btn btn-default o_runbot_slot_btn_small" title="Wake up this build" aria-label="Wake up this build">
|
||||
<i class="fa fa-coffee"/>
|
||||
</a>
|
||||
<a t-attf-href="/runbot/build/{{build.id}}" class="btn btn-default o_runbot_slot_btn_small" title="Build details" aria-label="Build details">
|
||||
<i class="fa fa-file-text-o"/>
|
||||
</a>
|
||||
<t t-call="runbot.build_menu">
|
||||
<t t-set="bu" t-value="build"/>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="runbot.build_toolbar_middle_section">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<t t-call="runbot.build_buttons"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="runbot.build_toolbar_end_section">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="runbot.build_new">
|
||||
<t t-call="runbot.layout_new">
|
||||
<div class="o_runbot_build row gy-2">
|
||||
<t t-set="rowclass" t-value="build._get_view_class()"/>
|
||||
<div class="o_runbot_build_information col-12 col-md-6">
|
||||
<div t-attf-class="bg-{{rowclass}}-subtle card p-2">
|
||||
<!-- Batch/bundles links-->
|
||||
<div 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>
|
||||
</div>
|
||||
<t t-if="len(batches) > 1">
|
||||
<div><b>First apparition:</b> <a t-out="batches[0].bundle_id.name" t-att-href="batches[0]._url()"/><br/></div>
|
||||
<div><b>Last apparition:</b> <a t-out="batches[-1].bundle_id.name" t-att-href="batches[-1]._url()"/><br/></div>
|
||||
</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">
|
||||
<div>
|
||||
<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>
|
||||
</div>
|
||||
<div t-if="build_commit.match_type in ('default', 'pr_target', 'prefix')">
|
||||
<div>from base branch</div>
|
||||
</div>
|
||||
<div t-else="" class="ms-3">
|
||||
<div><b>Subject:</b> <span class="font-monospace" t-out="build_commit.commit_id.subject"/></div>
|
||||
<div><b>Author:</b> <t t-out="build_commit.commit_id.author"/></div>
|
||||
<div><b>Committer:</b> <t t-out="build_commit.commit_id.committer"/></div>
|
||||
</div>
|
||||
</t>
|
||||
<div><b>Version:</b> <t t-out="build.params_id.version_id.name"/></div>
|
||||
<div><b>Config:</b> <t t-out="build.params_id.config_id.name"/></div>
|
||||
<t t-if="more">
|
||||
<div><b>Trigger:</b> <t t-out="build.params_id.trigger_id.name"/></div>
|
||||
<div><b>Config data:</b> <span class="font-monospace" t-out="build.params_id.config_data.dict"/></div>
|
||||
<div><b>Modules:</b> <t t-out="build.params_id.modules"/></div>
|
||||
<div><b>Extra params:</b> <span class="font-monospace" t-out="build.params_id.extra_params"/></div>
|
||||
<div t-if="len(build.params_id.builds_reference_ids) > 1">
|
||||
<b>Reference builds:</b>
|
||||
<span t-foreach="build.params_id.builds_reference_ids" t-as="reference" t-out="reference.id"/>
|
||||
</div>
|
||||
<div 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>
|
||||
</div>
|
||||
<div><b>Host:</b> <t t-out="build.host"/></div>
|
||||
</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-if="build.stat_ids">
|
||||
<b>Stats: <a t-attf-href="/runbot/build/stats/{{build.id}}">Build <t t-out="build.id"/></a></b>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_runbot_build_child_information col-12 col-md-6" t-if="build.children_ids">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Children
|
||||
</div>
|
||||
<ul class="list-group list-group-flush">
|
||||
<li t-foreach="build.children_ids" t-as="child"
|
||||
t-attf-class="list-group-item bg-{{child._get_view_class()}}-subtle{{' text-decoration-line-through' if child.orphan_result else ''}}">
|
||||
<div class="btn-group btn-group-ssm d-flex flex-grow-1">
|
||||
<a t-attf-href="/runbot/{{'batch/%s/' % from_batch.id if from_batch else ''}}build/{{child.id}}"
|
||||
class="btn btn-default flex-grow-1 text-start text-truncate">
|
||||
<div class="d-flex flex-row align-items-center gap-2">
|
||||
<div>
|
||||
Build <t t-out="child.id"/>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<t t-if="child.description" t-out="child.md_description"/>
|
||||
<t t-else="">
|
||||
with config <t t-out="child.params_id.config_id.name"/>
|
||||
</t>
|
||||
<i t-if="child.orphan_result" class="fa fa-chain-broken" title="Build result ignored for parent"/>
|
||||
</div>
|
||||
<div>
|
||||
<t t-if="child.job">
|
||||
<small>Running step: <t t-out="child.job"/></small>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="child.global_state in ('testing', 'waiting') or True">
|
||||
<i class="fa fa-spinner fa-spin"/>
|
||||
<t t-out="child.global_state"/>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<t t-call="runbot.build_buttons">
|
||||
<t t-set="build" t-value="child"/>
|
||||
</t>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_runbot_logs row">
|
||||
<div class="o_runbot_log_grid gx-0">
|
||||
<div class="o_runbot_log_grid_header o_runbot_log_grid_date">Date</div>
|
||||
<div class="o_runbot_log_grid_header">Level</div>
|
||||
<div class="o_runbot_log_grid_header">Type</div>
|
||||
<div class="o_runbot_log_grid_header o_runbot_log_grid_message">Message</div>
|
||||
<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">
|
||||
<div t-if="l.level == 'SEPARATOR'" class="separator"/>
|
||||
<div class="o_runbot_log_grid_date text-truncate">
|
||||
<t t-out="str(l.id) + ' ' + l.create_date.strftime('%Y-%m-%d %H:%M:%S')"/>
|
||||
<span t-attf-id="log_line_{{l.id}}" style="scroll-margin-top: 120px;"/>
|
||||
</div>
|
||||
<div class="fw-bold" t-out="l.level if l.type not in ('link', 'markdown') and l.level != 'SEPARATOR' else ''"/>
|
||||
<div t-out="l.type if l.type not in ('link', 'markdown') and l.level != 'SEPARATOR' else ''"/>
|
||||
<div class="o_runbot_log_grid_message">
|
||||
<!-- TODO: check logic exact logic -->
|
||||
<t t-set="subbuild" t-value="build.children_ids & build.browse(int(l.path)) if l.type == 'subbuild' else build.browse()"/>
|
||||
<!-- <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)"/>
|
||||
<t t-set="message_class" t-value="subbuild and subbuild._get_view_class() or ''"/>
|
||||
<div t-attf-class="bg-{{message_class or logclass}}-subtle p-1">
|
||||
|
||||
<div class="o_runbot_log_message_toolbox btn-group btn-group-ssm" role="group" t-if="l.level in ('CRITICAL', 'ERROR', 'WARNING')">
|
||||
<t t-set="error_content" t-value="l.error_content_id"/>
|
||||
<t t-set="error" t-value="error_content.error_id"/>
|
||||
<a t-if="error" class="btn btn-default" 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')}}" target="new">
|
||||
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>
|
||||
<span groups="runbot.group_runbot_admin" t-if="error.responsible or error.responsible.id == uid">(<i t-out="error.responsible.name"/>)</span>
|
||||
</a>
|
||||
<a t-if="error" t-attf-class="btn btn-default bg-{{'info' if error.active else 'success'}}-subtle fa fa-list"
|
||||
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="new"
|
||||
/>
|
||||
<a t-if="not error" groups="runbot.group_runbot_admin" t-attf-href="/runbot/parse_log/{{l.id}}" class="btn btn-default fa fa-magic sm"
|
||||
title="Parse this log line to follow this error."/>
|
||||
<a class="btn btn-default fa fa-link" t-attf-onclick="copyHashToClipboard('log_line_{{l.id}}')"
|
||||
title="Copy link to line"
|
||||
/>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
150
runbot/templates/new/bundle.xml
Normal file
150
runbot/templates/new/bundle.xml
Normal file
@ -0,0 +1,150 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<!-- Homepage and bundles searc -->
|
||||
<template id="runbot.bundles_new">
|
||||
<t t-call="runbot.layout_new">
|
||||
<div class="o_runbot_bundle_row row" t-foreach="bundles" t-as="bundle">
|
||||
<!-- TODO: missing style -->
|
||||
<div class="o_runbot_bundle_info col-12 col-md-auto me-1 mb-2">
|
||||
<!-- TODO: use css for style -->
|
||||
<div class="text-truncate">
|
||||
<i t-if="bundle.sticky" class="o_runbot_sticky_star fa fa-star"/>
|
||||
<a t-attf-href="/runbot/bundle/#{bundle.id}" t-attf-title="View Bundle ${bundle.name}" class="fw-bold" t-out="bundle.name"/>
|
||||
</div>
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<!-- Fetch last batch for each category -->
|
||||
<t t-set="categories_and_batch"
|
||||
t-value="[(category, bundle.with_context(category_id=category.id).last_done_batch) for category in categories if category.id != active_category_id]"
|
||||
/>
|
||||
<t t-set="categories_and_batch" t-value="[tpl for tpl in categories_and_batch if tpl[1]]"/>
|
||||
<div class="btn-group" role="group" t-if="categories_and_batch">
|
||||
<t t-foreach="categories_and_batch" t-as="category_and_batch">
|
||||
<t t-if="category_and_batch[0].view_id" t-call="{{category.view_id.sudo().key}}"/>
|
||||
<a t-else=""
|
||||
t-attf-title="View last {{category_and_batch[0].name}} batch"
|
||||
t-attf-href="/runbot/batch/{{category_and_batch[1].id}}"
|
||||
t-attf-class="fa fa-{{category_and_batch[0].icon}}"
|
||||
/>
|
||||
</t>
|
||||
</div>
|
||||
<div class="btn-group" role="group">
|
||||
<t t-if="not bundle.sticky" t-call="runbot.branch_copy_button"/>
|
||||
<!-- TODO: check branch_github_menu -->
|
||||
<t t-call="runbot.branch_github_menu"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="bundle.host_id">
|
||||
<span class="badge text-bg-info" t-out="bundle.host_id.name"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_runbot_bundle_batch_row col">
|
||||
<div class="row g-2">
|
||||
<t t-foreach="enumerate(bundle.last_batchs)" t-as="e_batch">
|
||||
<t t-set="index" t-value="e_batch[0]"/>
|
||||
<div t-att-class="'col-12 col-sm-6 col-xl-3' if index < 2 else 'col-xl-3 d-none d-xl-block'">
|
||||
<t t-call="runbot.batch_card">
|
||||
<t t-set="batch" t-value="e_batch[1]"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Bundle "form" view -->
|
||||
<template id="runbot.bundle_toolbar_middle_section">
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<a groups="runbot.group_runbot_advanced_user" t-attf-href="/web/#id={{bundle.id}}&view_type=form&model=runbot.bundle&menu_id={{env['ir.model.data']._xmlid_to_res_id('runbot.runbot_menu_root')}}" class="btn btn-default" target="new" title="View in Backend">
|
||||
<i class="fa fa-list"/>
|
||||
</a>
|
||||
<a groups="runbot.group_runbot_advanced_user" class="btn btn-default" t-attf-href="/runbot/bundle/{{bundle.id}}/force" title="Force A New Batch">
|
||||
<i class="fa fa-refresh"/>
|
||||
</a>
|
||||
<a t-if="bundle.env.user.has_group('runbot.group_runbot_advanced_user') or (bundle.env.user.has_group('runbot.group_user') and ':' in bundle.name)" class="btn btn-default" t-attf-href="/runbot/bundle/{{bundle.id}}/force/1" title="Force A New Batch with automatic rebase">
|
||||
<i class="fa fa-fast-forward"/>
|
||||
</a>
|
||||
<t t-call="runbot.branch_copy_button">
|
||||
<t t-set="btn_size" t-value="'btn'"/>
|
||||
</t>
|
||||
<t t-call="runbot.bundle_stats_dropdown"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="runbot.bundle_new">
|
||||
<t t-call="runbot.layout_new">
|
||||
<div class="o_runbot_bundle row p-2">
|
||||
<div class="col-12">
|
||||
<table class="table table-condensed table-responsive table-stripped table-bordered">
|
||||
<tbody>
|
||||
<tr groups="base.group_user" t-if="not bundle.sticky and not bundle.is_base">
|
||||
<t t-if="bundle.no_build">
|
||||
<td class="text-danger">Build disabled</td>
|
||||
<td>
|
||||
<a class="btn btn-primary btn-ssm"
|
||||
t-attf-href="/runbot/bundle/toggle_no_build/{{bundle.id}}/0">
|
||||
Enable builds
|
||||
</a>
|
||||
</td>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<td>Build enabled</td>
|
||||
<td>
|
||||
<a class="btn btn-secondary btn-ssm"
|
||||
t-attf-href="/runbot/bundle/toggle_no_build/{{bundle.id}}/1">
|
||||
Disable builds
|
||||
</a>
|
||||
</td>
|
||||
</t>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td>
|
||||
<t t-out="bundle.version_id.name"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Branches</td>
|
||||
<td>
|
||||
<div class="row gx-0 gy-1">
|
||||
<t t-foreach="bundle._branch_groups().items()" t-as="group">
|
||||
<div t-foreach="group[1]" t-as="branch" class="btn-group btn-group-ssm" role="group">
|
||||
<a t-att-href="branch.branch_url" class="o_runbot_slot_btn_small btn btn-default text-start" title="View Branch on Github"><i class="fa fa-github"/></a>
|
||||
<a groups="runbot.group_runbot_admin" class="o_runbot_slot_btn_small btn btn-default fa fa-list text-start" t-attf-href="/web/#id={{branch.id}}&view_type=form&model=runbot.branch" target="new" title="View Branch in Backend"/>
|
||||
<a href="#" t-out="branch.remote_id.short_name" class="btn btn-default disabled text-start flex-grow-1"/>
|
||||
<a t-attf-href="/runbot/branch/{{branch.id}}" class="btn btn-default text-start flex-grow-0" title="View Branch Details"><span t-att-class="'' if branch.alive else 'line-through'" t-out="branch.name"/> <i t-if="not branch.alive" title="deleted/closed" class="fa fa-ban text-danger"/></a>
|
||||
<t t-if="not any (b.is_pr and b.alive for b in group[1]) and not branch.is_pr">
|
||||
<a t-attf-href="https://{{group[0].main_remote_id.base_url}}/compare/{{bundle.version_id.name}}...{{branch.remote_id.owner}}:{{branch.name}}?expand=1" class="btn btn-default text-start flex-grow-0" title="Create pr"><i class="fa fa-code-fork"/> Create pr</a>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr t-if="more">
|
||||
<td>Project</td>
|
||||
<td t-out="bundle.project_id.name"/>
|
||||
</tr>
|
||||
<tr t-if="more">
|
||||
<td>New build enabled</td>
|
||||
<td>
|
||||
<i t-attf-class="fa fa-{{'times' if bundle.no_build else 'check'}}"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr t-if="more">
|
||||
<td>Modules</td>
|
||||
<td t-out="bundle.modules or '/'"/>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div t-foreach="bundle._consistency_warning()" t-as="warning" t-out="warning[1]" t-attf-class="col-12 alert alert-{{warning[0]}}"/>
|
||||
<div class="col-12" t-foreach="batchs" t-as="batch">
|
||||
<t t-call="runbot.batch_card"/>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
246
runbot/templates/new/page.xml
Normal file
246
runbot/templates/new/page.xml
Normal file
@ -0,0 +1,246 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- TODO: figure out proper keepquery logic -->
|
||||
|
||||
<!-- Basic page layout, this is just assets -->
|
||||
<template id="runbot.base_page_new">
|
||||
<html t-att-data-bs-theme="theme or 'light'">
|
||||
<title t-out="title or 'Runbot'"/>
|
||||
|
||||
<!-- <t t-call-assets="runbot.assets_frontend_new"/> -->
|
||||
<!-- <t t-call-assets="web.assets_frontend"/> -->
|
||||
<t t-call-assets="runbot.assets_frontend_new"/>
|
||||
|
||||
<t t-if="refresh">
|
||||
<!-- TODO: replace this with javascript code -->
|
||||
<meta http-equiv="refresh" t-att-content="refresh"/>
|
||||
</t>
|
||||
|
||||
<t t-if="not page_info_state or page_info_state == 'ok' or page_info_state not in ('warn', 'ko', 'skipped', 'killed', 'manually_killed')">
|
||||
<link rel="icon" type="image/png" href="/runbot/static/src/img/icon_ok.png"/>
|
||||
<link rel="icon" type="image/svg+xml" href="/runbot/static/src/img/icon_ok.svg"/>
|
||||
</t>
|
||||
<t t-elif="page_info_state == 'ko'">
|
||||
<link rel="icon" type="image/png" href="/runbot/static/src/img/icon_ko.png"/>
|
||||
<link rel="icon" type="image/svg+xml" href="/runbot/static/src/img/icon_ko.svg"/>
|
||||
</t>
|
||||
<t t-elif="page_info_state == 'warn'">
|
||||
<link rel="icon" type="image/png" href="/runbot/static/src/img/icon_warn.png"/>
|
||||
<link rel="icon" type="image/svg+xml" href="/runbot/static/src/img/icon_warn.svg"/>
|
||||
</t>
|
||||
<t t-elif="page_info_state == 'skipped'">
|
||||
<link rel="icon" type="image/png" href="/runbot/static/src/img/icon_skipped.png"/>
|
||||
<link rel="icon" type="image/svg+xml" href="/runbot/static/src/img/icon_skipped.svg"/>
|
||||
</t>
|
||||
<t t-elif="page_info_state == 'killed' or page_info_state == 'manually_killed'">
|
||||
<link rel="icon" type="image/png" href="/runbot/static/src/img/icon_killed.png"/>
|
||||
<link rel="icon" type="image/svg+xml" href="/runbot/static/src/img/icon_killed.svg"/>
|
||||
</t>
|
||||
|
||||
</html>
|
||||
<body>
|
||||
<t t-out="0"/>
|
||||
</body>
|
||||
</template>
|
||||
|
||||
<template id="runbot.layout_navbar">
|
||||
<!--
|
||||
Context used;
|
||||
class Navbar(TypedDict):
|
||||
project: self.env['runbot.project']
|
||||
projects: Optional[self.env['runbot.project']]
|
||||
qu: QueryURL object
|
||||
nb_assigned_errors: int
|
||||
nb_team_errors: int
|
||||
nb_build_errors: int
|
||||
has_pr: Optional[bool]
|
||||
-->
|
||||
<nav class="navbar navbar-expand-sm sticky-top shadow-sm bg-body-tertiary">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-brand">
|
||||
<a class="text-reset text-decoration-none text-initial" t-out="project.name" t-att-href="qu('/runbot/%s' % slug(project))"/>
|
||||
<span t-if="projects and len(projects) > 1" class="dropdown-toggle dropdown-toggle-caret d-none d-sm-inline" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false"/>
|
||||
<ul t-if="projects and len(projects) > 1" class="dropdown-menu">
|
||||
<li><h6 class="dropdown-header">Change Project</h6></li>
|
||||
<li><a class="dropdown-item active" t-out="project.name" t-att-href="qu('/runbot/%s' % slug(project))"/></li>
|
||||
<li><hr class="dropdown-divider"/></li>
|
||||
<t t-foreach="projects" t-as="_project">
|
||||
<li t-if="project.id != _project.id">
|
||||
<a class="dropdown-item" t-att-href="qu('/runbot/%s' % slug(_project))" t-out="_project.name"/>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</div>
|
||||
<button
|
||||
class="navbar-toggler"
|
||||
type="button"
|
||||
data-bs-toggle="offcanvas"
|
||||
data-bs-target="#navbarOffCanvas"
|
||||
aria-label="Toggle navigation"
|
||||
>
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="offcanvas offcanvas-end" tabindex="-1" id="navbarOffCanvas">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" t-out="project.name"/>
|
||||
<button
|
||||
type="button"
|
||||
class="btn-close"
|
||||
data-bs-dismiss="offcanvas"
|
||||
aria-label="Close"
|
||||
/>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<ul class="navbar-nav justify-content-end flex-grow-1 pe-3">
|
||||
<li class="nav-item d-sm-none"><a class="nav-link active" aria-current="page" t-att-href="qu('/runbot/%s' % slug(project))" t-out="project.name"/></li>
|
||||
<t t-foreach="projects" t-as="_project">
|
||||
<li t-if="project.id != _project.id" class="nav-item d-sm-none">
|
||||
<a class="nav-link" t-att-href="qu('/runbot/%s' % slug(_project))" t-out="_project.name"/>
|
||||
</li>
|
||||
</t>
|
||||
<!-- TODO: js code to open preferences -->
|
||||
<li class="nav-item divider"/>
|
||||
<li class="nav-item"><a class="o_runbot_preferences nav-link" href="#"><i class="fa fa-gear"/></a></li>
|
||||
<li class="nav-item divider"/>
|
||||
<t t-if="not user_id._is_public()">
|
||||
<li class="nav-item" t-if="nb_assigned_errors">
|
||||
<a href="/runbot/errors" class="nav-link text-danger" t-attf-title="You have {{nb_assigned_errors}} random bug assigned">
|
||||
<i class="fa fa-bug"/>
|
||||
<t t-out="nb_assigned_errors"/>
|
||||
<span class="text-warning" t-if="nb_team_errors" t-out="'+ ' + nb_team_errors"/>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" t-elif="nb_team_errors">
|
||||
<a href="/runbot/errors" class="nav-link text-warning" t-attf-title="Your team has {{nb_team_errors}} random bug assigned">
|
||||
<i class="fa fa-bug"/>
|
||||
<t t-out="nb_team_errors"/>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item" t-elif="nb_build_errors">
|
||||
<a href="/runbot/errors" class="nav-link" title="Random Bugs"><i class="fa fa-bug"/></a>
|
||||
</li>
|
||||
<li class="nav-item dropdown" t-ignore="true">
|
||||
<a href="#" class="o_runbot_navbar_username nav-link fw-bold text-truncate" data-bs-toggle="dropdown" t-out="user_id.name"/>
|
||||
<div class="dropdown-menu dropdown-menu-end" role="menu">
|
||||
<a class="dropdown-item" id="o_logout" role="menuitem" t-attf-href="/web/session/logout?redirect=/">Logout</a>
|
||||
<a class="dropdown-item" role="menuitem" t-attf-href="/web">Web</a>
|
||||
<div t-if="user_id.runbot_team_ids" class="dropdown-divider"/>
|
||||
<div t-if="user_id.runbot_team_ids" class="dropdown-header">Teams</div>
|
||||
<a t-foreach="user_id.runbot_team_ids" t-as="team" class="dropdown-item" role="menuitem" t-attf-href="/runbot/teams/{{team.id}}">
|
||||
<t t-out="team.name.capitalize()"/>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
</t>
|
||||
<li class="nav-item" t-else="" t-ignore="true">
|
||||
<a class="nav-link fw-bold" t-attf-href="/web/login?redirect={{request.httprequest.path}}">Login</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<div class="btn-group" role="group">
|
||||
<a class="btn btn-outline-secondary" onclick="legacy()">a</a>
|
||||
<a class="btn btn-outline-secondary" onclick="light()">b</a>
|
||||
<a class="btn btn-outline-secondary" onclick="dark()">c</a>
|
||||
<a class="btn btn-outline-secondary" onclick="red404()">d</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="mt-3 mb-0 mt-sm-0 d-flex">
|
||||
<!-- TODO: style -> has pr button shows as primary if input is checked-->
|
||||
<div class="input-group me-2 flex-grow-1">
|
||||
<input class="form-control" type="search" name="search" placeholder="Search" aria-label="Search"/>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<div class="input-group-text o_runbot_btn_haspr btn btn-outline-primary p-0" type="button" tabindex="0">
|
||||
<!-- TODO: js component -->
|
||||
<input type="checkbox" tabindex="0" id="searchHasPr" name="has_pr" class="d-none" t-att-checked="bool(request.params.get('has_pr'))"></input>
|
||||
<label for="searchHasPr" class="py-2 px-3 w-100 h-100 align-content-center" role="button">
|
||||
<i class="fa fa-github"></i>
|
||||
</label>
|
||||
</div>
|
||||
<button class="btn btn-outline-success" type="submit">Search</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<template id="runbot.layout_toolbar_start_section">
|
||||
<div t-if="toolbar.get('breadcrumbs') and len(toolbar.get('breadcrumbs')) > 1" class="o_runbot_toolbar_breadcrumbs d-flex">
|
||||
<t t-set="breadcrumbs" t-value="toolbar.get('breadcrumbs')"/>
|
||||
<ol class="breadcrumb flex-nowrap text-nowrap lh-sm">
|
||||
<li
|
||||
t-foreach="breadcrumbs" t-as="breadcrumb"
|
||||
t-attf-class="breadcrumb-item d-inline-flex{{' active' if breadcrumb == breadcrumbs[-1] else None}}"
|
||||
t-att-aria-current="'page' if breadcrumb == breadcrumbs[-1] else None"
|
||||
>
|
||||
<a t-if="breadcrumb != breadcrumbs[-1]" t-att-href="breadcrumb.url" t-out="breadcrumb.name"/>
|
||||
<t t-else="" t-out="breadcrumb.name"/>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="runbot.layout_toolbar_middle_section">
|
||||
<div t-if="toolbar.get('message')" class="alert alert-warning m-0" role="alert" t-out="toolbar.get('message')"/>
|
||||
</template>
|
||||
|
||||
<template id="runbot.layout_toolbar_end_section">
|
||||
<a t-if="toolbar.get('pending_count')" href="/runbot/load_info" class="text-decoration-none">
|
||||
<span t-attf-class="badge text-bg-{{toolbar.get('pending_level')}}">
|
||||
Pending: <t t-out="toolbar.get('pending_count')"/>
|
||||
<span t-if="toolbar.get('pending_assigned_count')" title="Assigned build (reserved host)">
|
||||
(<t t-out="toolbar.get('pending_assigned_count')"/>)
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
<a href="/runbot/load_info" t-if="toolbar.get('hosts_data') is not None" class="slots_infos text-decoration-none">
|
||||
<t t-set="testing" t-value="toolbar.get('hosts_data')._total_testing()"/>
|
||||
<t t-set="workers" t-value="toolbar.get('hosts_data')._total_workers()"/>
|
||||
<t t-set="klass">success</t>
|
||||
<t t-if="not workers" t-set="klass">danger</t>
|
||||
<t t-else="">
|
||||
<t t-if="int(testing)/workers > 0" t-set="klass">info</t>
|
||||
<t t-if="int(testing)/workers > 0.75" t-set="klass">warning</t>
|
||||
<t t-if="int(testing)/workers >= 1" t-set="klass">danger</t>
|
||||
</t>
|
||||
<span t-attf-class="badge text-bg-{{klass}}">
|
||||
Testing:
|
||||
<t t-out="testing"/>
|
||||
/
|
||||
<t t-out="workers"/>
|
||||
</span>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<template id="runbot.layout_toolbar">
|
||||
<t t-set="toolbar" t-value="toolbar or {}"/>
|
||||
<!-- TODO: js code to have top value take the height of the navbar -->
|
||||
<div t-att-class="'o_runbot_toolbar row bg-body' + (' position-sticky z-1' if toolbar.get('sticky', True) else '')">
|
||||
<div class="d-flex flex-wrap flex-md-nowrap justify-content-between align-items-center gap-md-3">
|
||||
<!-- Toolbar is made of left middle and right part -->
|
||||
<div class="d-flex d-empty-none order-0" style="flex: 1;">
|
||||
<t t-call="{{toolbar.get('start_template', 'runbot.layout_toolbar_start_section')}}"/>
|
||||
</div>
|
||||
<div class="d-flex d-empty-none justify-content-start justify-content-md-around order-2 order-md-1 w-100 w-md-auto mw-100" style="flex: 1;">
|
||||
<t t-call="{{toolbar.get('middle_template', 'runbot.layout_toolbar_middle_section')}}"/>
|
||||
</div>
|
||||
<div class="d-flex d-empty-none justify-content-end order-1 order-md-2 flex-grow-1 gap-1" style="flex: 1;">
|
||||
<t t-call="{{toolbar.get('end_template', 'runbot.layout_toolbar_end_section')}}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="runbot.layout_new">
|
||||
<t t-call="runbot.base_page_new">
|
||||
<t t-call="{{layout_nav_template or 'runbot.layout_navbar'}}"/>
|
||||
<div class="container-fluid o_runbot_main_container d-flex flex-column">
|
||||
<t t-call="{{layout_nav_toolbar or 'runbot.layout_toolbar'}}"/>
|
||||
<t t-out="0"/>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
23
runbot/templates/new/slot.xml
Normal file
23
runbot/templates/new/slot.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<template id="runbot.slot_btn_group">
|
||||
<t t-set="bu" t-value="slot.build_id"/>
|
||||
<t t-set="color" t-value="bu._get_color_class()"/>
|
||||
<div class="o_runbot_slot_btn_group btn-group btn-group-ssm">
|
||||
<span t-attf-class="o_runbot_slot_btn_small btn btn-{{color}} disabled" t-att-title="slot.link_type">
|
||||
<i t-attf-class="fa fa-{{slot._fa_link_type()}}"/>
|
||||
</span>
|
||||
<a t-att-href="'/runbot/batch/%s/build/%s' % (slot.batch_id.id, bu.id) if bu else None"
|
||||
t-attf-class="btn btn-default text-start text-nowrap text-truncate flex-grow-1{{' disabled' if not bu else ''}}"
|
||||
t-out="slot.trigger_id.name"
|
||||
/>
|
||||
<a t-if="slot.trigger_id.report_view_id" title="View last trigger report" t-attf-href="/runbot/trigger/report/{{slot.trigger_id.id}}" class="o_runbot_slot_btn_small fa fa-eye btn btn-info"/>
|
||||
<a t-if="bu.local_state == 'running' and bu.database_ids" t-attf-href="/runbot/run/{{bu.id}}" class="o_runbot_slot_btn_small fa fa-sign-in btn btn-info"/>
|
||||
<a t-if="bu.static_run" t-att-href="bu.static_run" class="o_runbot_slot_btn_small fa fa-sign-in btn btn-info"/>
|
||||
<t t-if="bu" t-call="runbot.build_menu"/>
|
||||
<a t-if="not bu" groups="base.group_user" class="o_runbot_slot_btn_small btn btn-default" title="Create build" t-attf-href="/runbot/batch/slot/{{slot.id}}/build">
|
||||
<i class="fa fa-play fa-fw"/>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
</odoo>
|
@ -2,8 +2,8 @@
|
||||
<odoo>
|
||||
<data>
|
||||
<template id="runbot.nginx_config">
|
||||
pid <t t-esc="nginx_dir"/>/nginx.pid;
|
||||
error_log <t t-esc="nginx_dir"/>/error.log;
|
||||
pid <t t-out="nginx_dir"/>/nginx.pid;
|
||||
error_log <t t-out="nginx_dir"/>/error.log;
|
||||
worker_processes 1;
|
||||
events { worker_connections 1024; }
|
||||
http {
|
||||
@ -16,10 +16,10 @@ index index.html;
|
||||
log_format full '$remote_addr - $remote_user [$time_local] '
|
||||
'"$request" $status $body_bytes_sent '
|
||||
'"$http_referer" "$http_user_agent" $request_time';
|
||||
access_log <t t-esc="nginx_dir"/>/access.log full;
|
||||
error_log <t t-esc="nginx_dir"/>/error.log;
|
||||
client_body_temp_path <t t-esc="nginx_dir"/>;
|
||||
fastcgi_temp_path <t t-esc="nginx_dir"/>;
|
||||
access_log <t t-out="nginx_dir"/>/access.log full;
|
||||
error_log <t t-out="nginx_dir"/>/error.log;
|
||||
client_body_temp_path <t t-out="nginx_dir"/>;
|
||||
fastcgi_temp_path <t t-out="nginx_dir"/>;
|
||||
|
||||
autoindex on;
|
||||
|
||||
@ -33,7 +33,7 @@ map $http_x_forwarded_proto $real_scheme {
|
||||
'' $scheme;
|
||||
}
|
||||
|
||||
proxy_temp_path <t t-esc="nginx_dir"/>;
|
||||
proxy_temp_path <t t-out="nginx_dir"/>;
|
||||
proxy_read_timeout 600;
|
||||
proxy_connect_timeout 600;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
@ -43,20 +43,20 @@ proxy_set_header Host $host;
|
||||
server {
|
||||
listen 8080 default;
|
||||
location /runbot/static/ {
|
||||
alias <t t-esc="runbot_static"/>;
|
||||
alias <t t-out="runbot_static"/>;
|
||||
autoindex off;
|
||||
return 404;
|
||||
location /runbot/static/src { }
|
||||
location ~ /runbot/static/build/[^/]+/(logs|tests|coverage)/ {
|
||||
autoindex on;
|
||||
add_header 'Access-Control-Allow-Origin' '<t t-esc="base_url"/>';
|
||||
add_header 'Access-Control-Allow-Origin' '<t t-out="base_url"/>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 8080;
|
||||
server_name ~^dockerhub\.<t t-esc="re_escape(host_name)"/>$;
|
||||
server_name ~^dockerhub\.<t t-out="re_escape(host_name)"/>$;
|
||||
|
||||
location /v2/ {
|
||||
limit_except GET HEAD OPTIONS {
|
||||
@ -77,22 +77,22 @@ server {
|
||||
<t id="server_build_anchor"/>
|
||||
server {
|
||||
listen 8080;
|
||||
server_name ~^<t t-out="re_escape(build.dest)"/>(-[a-z0-9_-]+)?-<t t-esc="build._get_run_token()[0]"/>(-[a-z0-9_]+)\.<t t-esc="re_escape(build.host)"/>$;
|
||||
server_name ~^<t t-out="re_escape(build.dest)"/>(-[a-z0-9_-]+)?-<t t-out="build._get_run_token()[0]"/>(-[a-z0-9_]+)\.<t t-out="re_escape(build.host)"/>$;
|
||||
<t id="build_anchor_authenticated"/>
|
||||
location / {
|
||||
<t id="build_anchor_authenticated_side_effect"/>
|
||||
return 307 http://<t t-out="build.dest"/>$1.<t t-esc="build.host"/>;
|
||||
return 307 http://<t t-out="build.dest"/>$1.<t t-out="build.host"/>;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 8080;
|
||||
server_name ~^<t t-out="re_escape(build.dest)"/>(-[a-z0-9_-]+)?\.<t t-esc="re_escape(build.host)"/>$;
|
||||
server_name ~^<t t-out="re_escape(build.dest)"/>(-[a-z0-9_-]+)?\.<t t-out="re_escape(build.host)"/>$;
|
||||
<t id="build_anchor"/>
|
||||
location / { proxy_pass http://127.0.0.1:<t t-esc="build.port"/>; }
|
||||
location /longpolling { proxy_pass http://127.0.0.1:<t t-esc="build.port + 1"/>; }
|
||||
location / { proxy_pass http://127.0.0.1:<t t-out="build.port"/>; }
|
||||
location /longpolling { proxy_pass http://127.0.0.1:<t t-out="build.port + 1"/>; }
|
||||
location /websocket {
|
||||
proxy_pass http://127.0.0.1:<t t-esc="build.port + 1"/>;
|
||||
proxy_pass http://127.0.0.1:<t t-out="build.port + 1"/>;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Proto $real_scheme;
|
||||
proxy_set_header Host $host;
|
||||
|
@ -5,7 +5,7 @@
|
||||
<template id="runbot.base_page">
|
||||
<html t-att-data-bs-theme="theme">
|
||||
<head>
|
||||
<title t-esc="title or 'Runbot'"/>
|
||||
<title t-out="title or 'Runbot'"/>
|
||||
<link rel="stylesheet" type="text/css" href="/runbot/static/src/libs/bootstrap/css/bootstrap.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/runbot/static/src/libs/fontawesome/css/font-awesome.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/runbot/static/src/css/runbot.css"/>
|
||||
@ -53,7 +53,7 @@
|
||||
<nav class="navbar navbar-expand-md bg-body-tertiary">
|
||||
<a t-if="project" t-att-href="qu(search=search)">
|
||||
<b class="active_project">
|
||||
<t t-esc="project.name"/>
|
||||
<t t-out="project.name"/>
|
||||
</b>
|
||||
</a>
|
||||
<button type="button" class="navbar-toggler" data-bs-toggle="collapse" data-bs-target="#top_menu_collapse">
|
||||
@ -65,7 +65,7 @@
|
||||
<t t-foreach="projects" t-as="l_project">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" t-att-href="qu('/runbot/%s' % slug(l_project), search=search)">
|
||||
<t t-esc="l_project.name"/>
|
||||
<t t-out="l_project.name"/>
|
||||
</a>
|
||||
</li>
|
||||
</t>
|
||||
@ -82,7 +82,7 @@
|
||||
<li class="nav-item dropdown" t-ignore="true">
|
||||
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown">
|
||||
<b>
|
||||
<span t-esc="user_id.name[:23] + '...' if user_id.name and len(user_id.name) > 25 else user_id.name"/>
|
||||
<span t-out="user_id.name[:23] + '...' if user_id.name and len(user_id.name) > 25 else user_id.name"/>
|
||||
</b>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-end js_usermenu" role="menu">
|
||||
@ -91,7 +91,7 @@
|
||||
<div t-if="user_id.runbot_team_ids" class="dropdown-divider"/>
|
||||
<div t-if="user_id.runbot_team_ids" class="dropdown-header">Teams</div>
|
||||
<a t-foreach="user_id.runbot_team_ids" t-as="team" class="dropdown-item" role="menuitem" t-attf-href="/runbot/teams/{{team.id}}">
|
||||
<t t-esc="team.name.capitalize()"/>
|
||||
<t t-out="team.name.capitalize()"/>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
@ -136,7 +136,7 @@
|
||||
|
||||
<div class="text-nowrap btn-group btn-group-sm" role="group">
|
||||
<t t-foreach="categories" t-as="category">
|
||||
<button t-attf-onclick="document.cookie = 'category={{category.id}}; expires=Thu, 1 Dec 2942 12:00:00 UTC; path=/'; location.reload();" type="button" t-attf-class="btn btn-{{'primary' if category.id == active_category_id else 'secondary'}}" t-esc="category.name"/>
|
||||
<button t-attf-onclick="document.cookie = 'category={{category.id}}; expires=Thu, 1 Dec 2942 12:00:00 UTC; path=/'; location.reload();" type="button" t-attf-class="btn btn-{{'primary' if category.id == active_category_id else 'secondary'}}" t-out="category.name"/>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
@ -146,12 +146,12 @@
|
||||
<t t-foreach="categories" t-as="category">
|
||||
<t t-set="category_triggers" t-value="triggers.filtered(lambda t: not t.manual and t.category_id == category)"/>
|
||||
<t t-if="category_triggers">
|
||||
<h3 t-esc="category.name"/>
|
||||
<h3 t-out="category.name"/>
|
||||
<div class="row">
|
||||
<t t-foreach="category_triggers" t-as="trigger">
|
||||
<div class="col-md-3 text-nowrap">
|
||||
<input t-attf-class="trigger_selection {{'trigger_selection_hide' if trigger.hide else 'trigger_selection_show'}}" type="checkbox" t-attf-name="trigger_{{trigger.id}}" t-attf-id="trigger_{{trigger.id}}" t-att-checked="trigger_display is None or trigger.id in trigger_display"/>
|
||||
<label t-attf-for="trigger_{{trigger.id}}" t-esc="trigger.name"/>
|
||||
<label t-attf-for="trigger_{{trigger.id}}" t-out="trigger.name"/>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
@ -181,8 +181,8 @@
|
||||
<li class="nav-item">
|
||||
<a href="/runbot/errors" class="nav-link text-danger" t-attf-title="You have {{nb_assigned_errors}} random bug assigned">
|
||||
<i class="fa fa-bug"/>
|
||||
<t t-esc="nb_assigned_errors"/>
|
||||
<span class="text-warning" t-if="nb_team_errors">+<t t-esc="nb_team_errors"/></span>
|
||||
<t t-out="nb_assigned_errors"/>
|
||||
<span class="text-warning" t-if="nb_team_errors">+<t t-out="nb_team_errors"/></span>
|
||||
</a>
|
||||
</li>
|
||||
</t>
|
||||
@ -191,7 +191,7 @@
|
||||
<li class="nav-item">
|
||||
<a href="/runbot/errors" class="nav-link text-warning" t-attf-title="Your team has {{nb_team_errors}} random bug assigned">
|
||||
<i class="fa fa-bug"/>
|
||||
<t t-esc="nb_team_errors"/>
|
||||
<t t-out="nb_team_errors"/>
|
||||
</a>
|
||||
</li>
|
||||
</t>
|
||||
@ -207,7 +207,7 @@
|
||||
<a href="/runbot/load_info" class="slots_infos">
|
||||
<span t-attf-class="badge text-bg-{{pending_level}}">
|
||||
Pending:
|
||||
<t t-esc="pending_count"/><span title="Assigned build (reserved host)" t-if="pending_assigned_count">(<t t-esc="pending_assigned_count"/>)</span>
|
||||
<t t-out="pending_count"/><span title="Assigned build (reserved host)" t-if="pending_assigned_count">(<t t-out="pending_assigned_count"/>)</span>
|
||||
</span>
|
||||
<t t-set="testing" t-value="hosts_data._total_testing()"/>
|
||||
<t t-set="workers" t-value="hosts_data._total_workers()"/>
|
||||
@ -220,9 +220,9 @@
|
||||
</t>
|
||||
<span t-attf-class="badge text-bg-{{klass}}">
|
||||
Testing:
|
||||
<t t-esc="testing"/>
|
||||
<t t-out="testing"/>
|
||||
/
|
||||
<t t-esc="workers"/>
|
||||
<t t-out="workers"/>
|
||||
</span>
|
||||
</a>
|
||||
</template>
|
||||
@ -235,10 +235,10 @@
|
||||
<i t-attf-class="fa fa-{{slot._fa_link_type()}}"/>
|
||||
</span>
|
||||
<a t-if="bu" t-attf-href="/runbot/batch/{{slot.batch_id.id}}/build/#{bu.id}" t-attf-class="btn btn-default slot_name">
|
||||
<span t-esc="slot.trigger_id.name"/>
|
||||
<span t-out="slot.trigger_id.name"/>
|
||||
</a>
|
||||
<span t-else="" t-attf-class="btn btn-default disabled slot_name">
|
||||
<span t-esc="slot.trigger_id.name"/>
|
||||
<span t-out="slot.trigger_id.name"/>
|
||||
</span>
|
||||
<a t-if="slot.trigger_id.report_view_id" title="View last trigger report" t-attf-href="/runbot/trigger/report/{{slot.trigger_id.id}}" class="fa fa-eye btn btn-info"/>
|
||||
<a t-if="bu.local_state == 'running' and bu.database_ids" t-attf-href="/runbot/run/{{bu.id}}" class="fa fa-sign-in btn btn-info"/>
|
||||
@ -290,102 +290,106 @@
|
||||
<t t-if="build.global_result == 'warn'">
|
||||
<t t-set="rowclass">warning</t>
|
||||
</t>
|
||||
<t t-esc="rowclass"/>
|
||||
<t t-out="rowclass"/>
|
||||
</template>
|
||||
|
||||
<template id="runbot.build_menu">
|
||||
<button t-attf-class="btn btn-default dropdown-toggle" data-bs-toggle="dropdown" title="Build options" aria-label="Build options" aria-expanded="false">
|
||||
<button t-attf-class="o_runbot_build_menu btn btn-default dropdown-toggle" data-bs-toggle="dropdown" title="Build options" aria-label="Build options" aria-expanded="false">
|
||||
<i t-attf-class="fa {{'fa-spinner' if bu.global_state == 'pending' else 'fa-cog'}} {{'' if bu.global_state in ('done', 'running') else 'fa-spin'}} fa-fw"/>
|
||||
<span class="caret"/>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-end" role="menu">
|
||||
<a t-if="bu.global_result=='skipped'" groups="runbot.group_runbot_admin" class="dropdown-item" href="#" data-runbot="rebuild" t-att-data-runbot-build="bu['id']">
|
||||
<i class="fa fa-level-up"/>
|
||||
Force Build
|
||||
</a>
|
||||
<t t-if="bu.local_state=='running'">
|
||||
<t t-foreach="bu.database_ids[1:].sorted('name')" t-as="db">
|
||||
<a class="dropdown-item" t-attf-href="/runbot/run/{{bu.id}}/{{db.db_suffix}}">
|
||||
<div class="dropdown-menu dropdown-menu-end" role="menu">
|
||||
<a t-if="bu.global_result=='skipped'" groups="runbot.group_runbot_admin" class="dropdown-item" href="#" data-runbot="rebuild" t-att-data-runbot-build="bu['id']">
|
||||
<i class="fa fa-level-up"/>
|
||||
Force Build
|
||||
</a>
|
||||
<t t-if="bu.local_state=='running'">
|
||||
<t t-foreach="bu.database_ids[1:].sorted('name')" t-as="db">
|
||||
<a class="dropdown-item" t-attf-href="/runbot/run/{{bu.id}}/{{db.db_suffix}}">
|
||||
<i class="fa fa-sign-in"/>
|
||||
Connect <t t-out="db.db_suffix"></t>
|
||||
</a>
|
||||
</t>
|
||||
<a class="dropdown-item" t-attf-href="http://{{bu.domain}}/web/database/selector">
|
||||
<i class="fa fa-sign-in"/>
|
||||
Connect <t t-esc="db.db_suffix"></t>
|
||||
Database selector
|
||||
</a>
|
||||
</t>
|
||||
<a class="dropdown-item" t-attf-href="http://{{bu.domain}}/web/database/selector">
|
||||
<i class="fa fa-sign-in"/>
|
||||
Database selector
|
||||
<a class="dropdown-item" t-if="bu.global_state in ['done','running'] or bu.requested_action == 'deathrow'" groups="base.group_user" href="#" data-runbot="rebuild" t-att-data-runbot-build="bu['id']" title="Retry this build, usefull for false positive">
|
||||
<i class="fa fa-refresh"/>
|
||||
Rebuild
|
||||
</a>
|
||||
</t>
|
||||
<a class="dropdown-item" t-if="bu.global_state in ['done','running'] or bu.requested_action == 'deathrow'" groups="base.group_user" href="#" data-runbot="rebuild" t-att-data-runbot-build="bu['id']" title="Retry this build, usefull for false positive">
|
||||
<i class="fa fa-refresh"/>
|
||||
Rebuild
|
||||
</a>
|
||||
<t t-if="bu.global_state != 'done'">
|
||||
<t t-if="bu.requested_action != 'deathrow'">
|
||||
<a groups="base.group_user" href="#" data-runbot="kill" class="dropdown-item" t-att-data-runbot-build="bu['id']">
|
||||
<i class="fa fa-crosshairs"/>
|
||||
Kill
|
||||
<t t-if="bu.global_state != 'done'">
|
||||
<t t-if="bu.requested_action != 'deathrow'">
|
||||
<a groups="base.group_user" href="#" data-runbot="kill" class="dropdown-item" t-att-data-runbot-build="bu['id']">
|
||||
<i class="fa fa-crosshairs"/>
|
||||
Kill
|
||||
</a>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<a groups="base.group_user" class="dropdown-item disabled">
|
||||
<i class="fa fa-spinner fa-spin"/>
|
||||
Killing
|
||||
<i class="fa fa-crosshairs"/>
|
||||
</a>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="bu.global_state == 'done'">
|
||||
<t t-if="bu.requested_action != 'wake_up' and bu.database_ids">
|
||||
<a groups="base.group_user" class="dropdown-item" href="#" data-runbot="wakeup" t-att-data-runbot-build="bu['id']">
|
||||
<i class="fa fa-coffee"/>
|
||||
Wake up
|
||||
</a>
|
||||
</t>
|
||||
<t t-if="bu.requested_action == 'wake_up'">
|
||||
<a groups="base.group_user" class="dropdown-item disabled">
|
||||
<i class="fa fa-spinner fa-spin"/>
|
||||
Waking up
|
||||
<i class="fa fa-crosshairs"/>
|
||||
</a>
|
||||
</t>
|
||||
</t>
|
||||
<div t-if="bu.global_state not in ('testing', 'waiting', 'pending')" groups="base.group_user" class="dropdown-divider"/>
|
||||
<t t-set="log_url" t-value="'http://%s' % bu.host if bu.host != fqdn else ''"/>
|
||||
<t t-if="bu.host" t-foreach="bu.log_list.split(',') if bu.log_list else []" t-as="log_name">
|
||||
<a class="dropdown-item" t-attf-href="{{log_url}}/runbot/static/build/#{bu.dest}/logs/#{log_name}.txt">
|
||||
<i class="fa fa-file-text-o"/>
|
||||
Full
|
||||
<t t-out="log_name"/>
|
||||
logs
|
||||
</a>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<a groups="base.group_user" class="dropdown-item disabled">
|
||||
<i class="fa fa-spinner fa-spin"/>
|
||||
Killing
|
||||
<i class="fa fa-crosshairs"/>
|
||||
<div class="dropdown-divider" groups="runbot.group_runbot_admin,runbot.group_build_config_user"/>
|
||||
<t groups="runbot.group_runbot_admin">
|
||||
<a class="dropdown-item" t-attf-href="/runbot/build/search?config_id={{bu.params_id.config_id.id}}&trigger_id={{bu.params_id.trigger_id.id}}&version_id={{bu.params_id.version_id.id}}&create_batch_id.bundle_id={{bu.params_id.create_batch_id.bundle_id.id}}&description={{bu.description or ''}}">
|
||||
<i class="fa fa-search"/>
|
||||
Find similar builds
|
||||
</a>
|
||||
<a class="dropdown-item" t-attf-href="/web/#id={{bu['id']}}&view_type=form&model=runbot.build&menu_id={{env['ir.model.data']._xmlid_to_res_id('runbot.runbot_menu_root')}}" target="new">
|
||||
<i class="fa fa-list"/>
|
||||
View in backend
|
||||
</a>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="bu.global_state == 'done'">
|
||||
<t t-if="bu.requested_action != 'wake_up' and bu.database_ids">
|
||||
<a groups="base.group_user" class="dropdown-item" href="#" data-runbot="wakeup" t-att-data-runbot-build="bu['id']">
|
||||
<i class="fa fa-coffee"/>
|
||||
Wake up
|
||||
</a>
|
||||
</t>
|
||||
<t t-if="bu.requested_action == 'wake_up'">
|
||||
<a groups="base.group_user" class="dropdown-item disabled">
|
||||
<i class="fa fa-spinner fa-spin"/>
|
||||
Waking up
|
||||
<i class="fa fa-crosshairs"/>
|
||||
</a>
|
||||
</t>
|
||||
</t>
|
||||
<div t-if="bu.global_state not in ('testing', 'waiting', 'pending')" groups="base.group_user" class="dropdown-divider"/>
|
||||
<t t-set="log_url" t-value="'http://%s' % bu.host if bu.host != fqdn else ''"/>
|
||||
<t t-if="bu.host" t-foreach="bu.log_list.split(',') if bu.log_list else []" t-as="log_name">
|
||||
<a class="dropdown-item" t-attf-href="{{log_url}}/runbot/static/build/#{bu.dest}/logs/#{log_name}.txt">
|
||||
<i class="fa fa-file-text-o"/>
|
||||
Full
|
||||
<t t-esc="log_name"/>
|
||||
logs
|
||||
</a>
|
||||
</t>
|
||||
<t groups="runbot.group_runbot_admin">
|
||||
<div class="dropdown-divider"/>
|
||||
<a class="dropdown-item" t-attf-href="/runbot/build/search?config_id={{bu.params_id.config_id.id}}&trigger_id={{bu.params_id.trigger_id.id}}&version_id={{bu.params_id.version_id.id}}&create_batch_id.bundle_id={{bu.params_id.create_batch_id.bundle_id.id}}&description={{bu.description or ''}}">
|
||||
<i class="fa fa-search"/>
|
||||
Find similar builds
|
||||
</a>
|
||||
<a class="dropdown-item" t-attf-href="/web/#id={{bu['id']}}&view_type=form&model=runbot.build&menu_id={{env['ir.model.data']._xmlid_to_res_id('runbot.runbot_menu_root')}}" target="new">
|
||||
<a groups="runbot.group_build_config_user" class="dropdown-item" t-attf-href="/web/#id={{bu.params_id.config_id.id}}&view_type=form&model=runbot.build.config&menu_id={{env['ir.model.data']._xmlid_to_res_id('runbot.runbot_menu_root')}}" target="new">
|
||||
<i class="fa fa-list"/>
|
||||
View in backend
|
||||
View config in backend
|
||||
</a>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<template id="runbot.branch_github_menu">
|
||||
<button t-attf-class="btn btn-default btn-ssm" data-bs-toggle="dropdown" title="Github links" aria-label="Github links" aria-expanded="false">
|
||||
<i t-attf-class="fa fa-github {{'text-primary' if any(branch_id.is_pr and branch_id.alive for branch_id in bundle.branch_ids) else 'text-secondary' if all(not branch_id.alive for branch_id in bundle.branch_ids) else ''}}"/>
|
||||
<span class="caret"/>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<t t-foreach="bundle.branch_ids.sorted(key=lambda b: (not b.alive, b.remote_id.repo_id.sequence, b.remote_id.repo_id.id, b.is_pr, b.id))" t-as="branch">
|
||||
<t t-set="link_title" t-value="'View %s %s on Github' % ('PR' if branch.is_pr else 'Branch', branch.name)"/>
|
||||
<a t-att-href="branch.branch_url" class="dropdown-item" t-att-title="link_title">
|
||||
<span class="font-italic text-muted" t-out="branch.remote_id.short_name"/> <span t-att-class="'' if branch.alive else 'line-through'" t-out="branch.name"/> <i t-if="not branch.alive" title="deleted/closed" class="fa fa-ban text-danger"/>
|
||||
</a>
|
||||
</t>
|
||||
</div>
|
||||
</button>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<t t-foreach="bundle.branch_ids.sorted(key=lambda b: (not b.alive, b.remote_id.repo_id.sequence, b.remote_id.repo_id.id, b.is_pr, b.id))" t-as="branch">
|
||||
<t t-set="link_title" t-value="'View %s %s on Github' % ('PR' if branch.is_pr else 'Branch', branch.name)"/>
|
||||
<a t-att-href="branch.branch_url" class="dropdown-item" t-att-title="link_title">
|
||||
<span class="font-italic text-muted" t-esc="branch.remote_id.short_name"/> <span t-att-class="'' if branch.alive else 'line-through'" t-esc="branch.name"/> <i t-if="not branch.alive" title="deleted/closed" class="fa fa-ban text-danger"/>
|
||||
</a>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="runbot.branch_copy_button">
|
||||
@ -396,7 +400,7 @@
|
||||
|
||||
|
||||
<template id="runbot.bundle_stats_dropdown">
|
||||
<button t-attf-class="btn btn-default dropdown-toggle" data-bs-toggle="dropdown" title="Bundle Stats" aria-label="Bundle Stats" aria-expanded="false">
|
||||
<button t-attf-class="btn btn-default btn-sm dropdown-toggle" data-bs-toggle="dropdown" title="Bundle Stats" aria-label="Bundle Stats" aria-expanded="false">
|
||||
<i t-attf-class="fa fa-bar-chart"/>
|
||||
<span class="caret"/>
|
||||
</button>
|
||||
@ -404,11 +408,11 @@
|
||||
<t t-foreach="project.trigger_ids.sorted(lambda t: (t.category_id.id, t.sequence, t.id))" t-as="trigger">
|
||||
<t t-if="trigger.has_stats and not trigger.manual" >
|
||||
<t t-if="current_category != trigger.category_id">
|
||||
<span class="dropdown-item"><b><t t-esc="trigger.category_id.name"/></b></span>
|
||||
<span class="dropdown-item"><b><t t-out="trigger.category_id.name"/></b></span>
|
||||
<t t-set="current_category" t-value="trigger.category_id"/>
|
||||
</t>
|
||||
<a class="dropdown-item" t-attf-href="/runbot/stats/{{bundle.id}}/{{trigger.id}}">
|
||||
<t t-esc="trigger.name" />
|
||||
<t t-out="trigger.name" />
|
||||
</a>
|
||||
</t>
|
||||
</t>
|
||||
|
@ -19,7 +19,7 @@
|
||||
t-att-title="title.strip()"
|
||||
t-att-target="target or None"
|
||||
t-att-class="classes or None"
|
||||
><t t-esc="pr.display_name"/></a>
|
||||
><t t-out="pr.display_name"/></a>
|
||||
</template>
|
||||
|
||||
<template id="staging-statuses" name="dropdown statuses list of stagings">
|
||||
@ -50,7 +50,7 @@
|
||||
else 'bg-danger' if st[0] in ('error', 'failure')
|
||||
else 'bg-info' if st[0]
|
||||
else 'bg-light'}}">
|
||||
<t t-esc="req.repo_id.name"/>: <t t-esc="req.context"/>
|
||||
<t t-out="req.repo_id.name"/>: <t t-out="req.context"/>
|
||||
</a>
|
||||
</t>
|
||||
</div>
|
||||
@ -78,7 +78,7 @@
|
||||
<div id="wrap"><div class="container-fluid">
|
||||
<t t-call="runbot_merge.alerts"/>
|
||||
<section t-foreach="projects" t-as="project" class="row">
|
||||
<h1 class="col-md-12"><t t-esc="project.name"/></h1>
|
||||
<h1 class="col-md-12"><t t-out="project.name"/></h1>
|
||||
<div class="col-md-12">
|
||||
key:
|
||||
<ul class="list-inline">
|
||||
@ -91,7 +91,7 @@
|
||||
<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"/>
|
||||
<t t-out="branch.name"/>
|
||||
</a>
|
||||
</h2>
|
||||
<t t-call="runbot_merge.stagings"/>
|
||||
@ -185,7 +185,7 @@
|
||||
<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-out="batch.prs[:1].label"/>
|
||||
<t t-foreach="batch.prs" t-as="pr">
|
||||
<t t-call="runbot_merge.link-pr"/>
|
||||
</t>
|
||||
@ -208,7 +208,7 @@
|
||||
<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>
|
||||
<h1 class="col-md-12"><t t-out="branch.project_id.name"/>: <t t-out="branch.name"/></h1>
|
||||
</section>
|
||||
<form method="get">
|
||||
<label for="until">Staged before:</label>
|
||||
@ -279,7 +279,7 @@
|
||||
aria-haspopup="true"
|
||||
aria-expanded="true"
|
||||
>
|
||||
<t t-esc="first_pr.label"/>
|
||||
<t t-out="first_pr.label"/>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
@ -310,7 +310,7 @@
|
||||
<div id="wrap"><div class="container-fluid">
|
||||
<h1>Changelog</h1>
|
||||
<section t-foreach="entries" t-as="entry">
|
||||
<h3 t-if="not entry_first" t-esc="entry"/>
|
||||
<h3 t-if="not entry_first" t-out="entry"/>
|
||||
<ul>
|
||||
<li t-foreach="sorted(entry_value)" t-as="item">
|
||||
<t t-out="item"/>
|
||||
@ -325,14 +325,14 @@
|
||||
<div class="alert alert-success">
|
||||
Merged
|
||||
<t t-if="merged_head">
|
||||
at <a t-attf-href="https://github.com/{{pr.repository.name}}/commit/{{merged_head}}"><t t-esc="merged_head"/></a>
|
||||
at <a t-attf-href="https://github.com/{{pr.repository.name}}/commit/{{merged_head}}"><t t-out="merged_head"/></a>
|
||||
</t>
|
||||
<p>Statuses:</p>
|
||||
<ul>
|
||||
<t t-foreach="pr.repository.status_ids._for_pr(pr)" t-as="ci">
|
||||
<t t-set="st" t-value="statuses.get(ci.context.strip())"/>
|
||||
<li t-if="st">
|
||||
<a t-att-href="st.get('target_url') if st else None"><t t-esc="ci.context.strip()"/></a><t t-if="st and st.get('description')">: <t t-esc="st['description']"/></t>
|
||||
<a t-att-href="st.get('target_url') if st else None"><t t-out="ci.context.strip()"/></a><t t-if="st and st.get('description')">: <t t-out="st['description']"/></t>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
@ -356,7 +356,7 @@
|
||||
<template id="view_pull_request_info_error">
|
||||
<div class="alert alert-danger">
|
||||
Error:
|
||||
<span t-esc="pr.with_context(active_test=False).batch_id.staging_ids[-1:].reason">
|
||||
<span t-out="pr.with_context(active_test=False).batch_id.staging_ids[-1:].reason">
|
||||
Unable to stage PR
|
||||
</span>
|
||||
</div>
|
||||
@ -399,7 +399,7 @@
|
||||
<t t-else="">ok</t>
|
||||
</t>
|
||||
<li t-att-class="result">
|
||||
<a t-att-href="st.get('target_url') if st else None"><t t-esc="ci.context.strip()"/></a><t t-if="st and st.get('description')">: <t t-esc="st['description']"/></t>
|
||||
<a t-att-href="st.get('target_url') if st else None"><t t-out="ci.context.strip()"/></a><t t-if="st and st.get('description')">: <t t-out="st['description']"/></t>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
@ -432,7 +432,7 @@
|
||||
</h1>
|
||||
<h6>Created by <span t-field="pr.author.display_name"/></h6>
|
||||
<t t-set="tmpl">
|
||||
<t t-if="pr.state in ('merged', 'closed', 'error')"><t t-esc="pr.state"/></t>
|
||||
<t t-if="pr.state in ('merged', 'closed', 'error')"><t t-out="pr.state"/></t>
|
||||
<t t-elif="pr.staging_id">staging</t>
|
||||
<t t-else="">open</t>
|
||||
</t>
|
||||
|
Loading…
Reference in New Issue
Block a user