mirror of
https://github.com/odoo/runbot.git
synced 2025-03-27 13:25:47 +07:00
[FIX] runbot: add the dasboard view for sticky branches
During the runbot migration to Odoo 11.0, the dashboard was lost in Limbo.
This commit is contained in:
parent
5b8184890e
commit
0b1ff4dd49
@ -19,6 +19,7 @@
|
|||||||
'templates/frontend.xml',
|
'templates/frontend.xml',
|
||||||
'templates/build.xml',
|
'templates/build.xml',
|
||||||
'templates/assets.xml',
|
'templates/assets.xml',
|
||||||
|
'templates/dashboard.xml',
|
||||||
'templates/nginx.xml',
|
'templates/nginx.xml',
|
||||||
'data/runbot_cron.xml'
|
'data/runbot_cron.xml'
|
||||||
],
|
],
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import operator
|
||||||
import werkzeug
|
import werkzeug
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
from odoo import http
|
from odoo import http
|
||||||
from odoo.addons.http_routing.models.ir_http import slug
|
from odoo.addons.http_routing.models.ir_http import slug
|
||||||
@ -217,3 +219,60 @@ class Runbot(http.Controller):
|
|||||||
else:
|
else:
|
||||||
return request.not_found()
|
return request.not_found()
|
||||||
return werkzeug.utils.redirect(url)
|
return werkzeug.utils.redirect(url)
|
||||||
|
|
||||||
|
@http.route(['/runbot/dashboard'], type='http', auth="public", website=True)
|
||||||
|
def dashboard(self, refresh=None):
|
||||||
|
cr = request.cr
|
||||||
|
RB = request.env['runbot.build']
|
||||||
|
repos = request.env['runbot.repo'].search([]) # respect record rules
|
||||||
|
|
||||||
|
cr.execute("""SELECT bu.id
|
||||||
|
FROM runbot_branch br
|
||||||
|
JOIN LATERAL (SELECT *
|
||||||
|
FROM runbot_build bu
|
||||||
|
WHERE bu.branch_id = br.id
|
||||||
|
ORDER BY id DESC
|
||||||
|
LIMIT 3
|
||||||
|
) bu ON (true)
|
||||||
|
JOIN runbot_repo r ON (r.id = br.repo_id)
|
||||||
|
WHERE br.sticky
|
||||||
|
AND br.repo_id in %s
|
||||||
|
ORDER BY r.sequence, r.name, br.branch_name, bu.id DESC
|
||||||
|
""", [tuple(repos._ids)])
|
||||||
|
|
||||||
|
builds = RB.browse(map(operator.itemgetter(0), cr.fetchall()))
|
||||||
|
|
||||||
|
count = RB.search_count
|
||||||
|
qctx = {
|
||||||
|
'refresh': refresh,
|
||||||
|
'host_stats': [],
|
||||||
|
'pending_total': count([('state', '=', 'pending')]),
|
||||||
|
}
|
||||||
|
|
||||||
|
repos_values = qctx['repo_dict'] = OrderedDict()
|
||||||
|
for build in builds:
|
||||||
|
repo = build.repo_id
|
||||||
|
branch = build.branch_id
|
||||||
|
r = repos_values.setdefault(repo.id, {'branches': OrderedDict()})
|
||||||
|
if 'name' not in r:
|
||||||
|
r.update({
|
||||||
|
'name': repo.name,
|
||||||
|
'base': repo.base,
|
||||||
|
'testing': count([('repo_id', '=', repo.id), ('state', '=', 'testing')]),
|
||||||
|
'running': count([('repo_id', '=', repo.id), ('state', '=', 'running')]),
|
||||||
|
'pending': count([('repo_id', '=', repo.id), ('state', '=', 'pending')]),
|
||||||
|
})
|
||||||
|
b = r['branches'].setdefault(branch.id, {'name': branch.branch_name, 'builds': list()})
|
||||||
|
b['builds'].append(self.build_info(build))
|
||||||
|
|
||||||
|
# consider host gone if no build in last 100
|
||||||
|
build_threshold = max(builds.ids or [0]) - 100
|
||||||
|
for result in RB.read_group([('id', '>', build_threshold)], ['host'], ['host']):
|
||||||
|
if result['host']:
|
||||||
|
qctx['host_stats'].append({
|
||||||
|
'host': result['host'],
|
||||||
|
'testing': count([('state', '=', 'testing'), ('host', '=', result['host'])]),
|
||||||
|
'running': count([('state', '=', 'running'), ('host', '=', result['host'])]),
|
||||||
|
})
|
||||||
|
|
||||||
|
return request.render("runbot.sticky-dashboard", qctx)
|
||||||
|
78
runbot/templates/dashboard.xml
Normal file
78
runbot/templates/dashboard.xml
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<template id="runbot.sticky-dashboard">
|
||||||
|
<t t-call='website.layout'>
|
||||||
|
<t t-set="head">
|
||||||
|
<t t-if="refresh">
|
||||||
|
<meta http-equiv="refresh" t-att-content="refresh"/>
|
||||||
|
</t>
|
||||||
|
<style>
|
||||||
|
.bg-killed {
|
||||||
|
background-color: #aaa;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
padding: 3px 0;
|
||||||
|
border-bottom: 1px solid grey;
|
||||||
|
}
|
||||||
|
.r-mb02 { margin-bottom: 0.2em; }
|
||||||
|
</style>
|
||||||
|
</t>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class='col-md-12'>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<p class="text-center">
|
||||||
|
<t t-foreach="host_stats" t-as="hs">
|
||||||
|
<span class="label label-default">
|
||||||
|
<t t-esc="hs['host']"/>: <t t-esc="hs['testing']"/> testing, <t t-esc="hs['running']"/> running
|
||||||
|
</span>&nbsp;
|
||||||
|
</t>
|
||||||
|
<span class="label label-info">Pending: <t t-esc="pending_total"/></span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<t t-foreach="repo_dict.values()" t-as="repo">
|
||||||
|
<h4><span><t t-esc="repo['name']"/></span>
|
||||||
|
<small class="pull-right">
|
||||||
|
<t t-esc="repo['testing']"/> testing,
|
||||||
|
<t t-esc="repo['running']"/> running,
|
||||||
|
<t t-esc="repo['pending']"/> pending.
|
||||||
|
</small></h4>
|
||||||
|
<div t-foreach="repo['branches'].values()" t-as="br">
|
||||||
|
<div class="col-md-1">
|
||||||
|
<b t-esc="br['name']"/><br/>
|
||||||
|
<small><t t-esc="br['builds'][0]['job_age']"/></small>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-11 r-mb02">
|
||||||
|
<t t-foreach="br['builds']" t-as="bu">
|
||||||
|
<t t-if="bu['state']=='pending'"><t t-set="klass">default</t></t>
|
||||||
|
<t t-if="bu['state']=='testing'"><t t-set="klass">info</t></t>
|
||||||
|
<t t-if="bu['state']=='deathrow'"><t t-set="klass">default</t></t>
|
||||||
|
<t t-if="bu['state'] in ['running','done'] and bu['result'] == 'ko'"><t t-set="klass">danger</t></t>
|
||||||
|
<t t-if="bu['state'] in ['running','done'] and bu['result'] == 'warn'"><t t-set="klass">warning</t></t>
|
||||||
|
<t t-if="bu['state'] in ['running','done'] and bu['result'] == 'ok'"><t t-set="klass">success</t></t>
|
||||||
|
<t t-if="bu['state'] in ['running','done'] and bu['result'] == 'skipped'"><t t-set="klass">default</t></t>
|
||||||
|
<t t-if="bu['state'] in ['running','done'] and bu['result'] in ['killed', 'manually_killed']"><t t-set="klass">killed</t></t>
|
||||||
|
<div t-attf-class="bg-{{klass}} col-md-4">
|
||||||
|
<i class="fa fa-at"></i>
|
||||||
|
<t t-esc="bu['author']"/>
|
||||||
|
<t t-if="bu['committer'] and bu['author'] != bu['committer']" t-id="bu['committer']">
|
||||||
|
(<i class="fa fa-sign-out"></i>&nbsp;<t t-esc="bu['committer']"/>)
|
||||||
|
</t>
|
||||||
|
<br/>
|
||||||
|
<i class="fa fa-envelope-o"></i>
|
||||||
|
<a t-attf-href="https://#{repo['base']}/commit/#{bu['name']}"><t t-esc="bu['subject'][:32] + ('...' if bu['subject'][32:] else '') " t-att-title="bu['subject']"/></a>
|
||||||
|
<br/>
|
||||||
|
<t t-call="runbot.build_name"/> — <small><a t-attf-href="/runbot/build/{{bu['id']}}"><t t-esc="bu['dest']"/></a> on <t t-esc="bu['host']"/> <a t-if="bu['state'] == 'running'" t-attf-href="http://{{bu['domain']}}/?db={{bu['dest']}}-all"><i class="fa fa-sign-in"></i></a></small>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</template>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
Loading…
Reference in New Issue
Block a user