From 0ea9c4aefed42e6620c0fb0d20c6d1489ce0848c Mon Sep 17 00:00:00 2001 From: Christophe Monniez Date: Thu, 8 Sep 2022 23:12:40 +0200 Subject: [PATCH] [IMP] runbot: add a simpler bundle page * add the possibility to tag bundles * add a owner to the bundle A new bundle page is added in order to filter and search bundles easily. The bundles can be filtered by Pull Requests being open or closed. They can be filtered by teams and tags and searched by names. --- runbot/__manifest__.py | 1 + runbot/controllers/frontend.py | 50 +++++++++++ runbot/models/bundle.py | 65 +++++++++++++++ runbot/security/ir.model.access.csv | 4 + runbot/templates/bundle_list.xml | 123 ++++++++++++++++++++++++++++ runbot/templates/frontend.xml | 2 +- runbot/views/bundle_views.xml | 3 + 7 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 runbot/templates/bundle_list.xml diff --git a/runbot/__manifest__.py b/runbot/__manifest__.py index d7d25f9f..3f366e90 100644 --- a/runbot/__manifest__.py +++ b/runbot/__manifest__.py @@ -29,6 +29,7 @@ 'templates/build.xml', 'templates/build_stats.xml', 'templates/bundle.xml', + 'templates/bundle_list.xml', 'templates/commit.xml', 'templates/dashboard.xml', 'templates/frontend.xml', diff --git a/runbot/controllers/frontend.py b/runbot/controllers/frontend.py index a9fcf053..52638b2f 100644 --- a/runbot/controllers/frontend.py +++ b/runbot/controllers/frontend.py @@ -197,6 +197,56 @@ class Runbot(Controller): return request.render('runbot.bundle', context) + @route(['/runbot/bundle', '/runbot/bundle/page/'], website=True, auth='user', type='http', sitemap=False) + def bundle_list(self, project_id=None, is_base='0', pr_filter=None, team_id=None, tag_id=None, search=None, page=1, **kwargs): + if not project_id: + project_id = request.env.ref('runbot.main_project').id + + is_base = bool(int(is_base)) + + pr_filters = { + 'all': { 'text': 'All', 'domain': False}, + 'has_pr': { 'text': 'With Pull Request(s)', 'domain': ('pr_count', '>', 0)}, + 'has_no_pr': { 'text': 'Without Pull Request(s)', 'domain': ('pr_count', '=', 0)}, + 'has_open_pr': { 'text': 'With Open Pull Request(s)', 'domain': ('pr_open_count', '>', 0)}, + 'has_no_open_pr': { 'text': 'Without Open Pull Request(s)', 'domain': ('pr_open_count', '=', 0)}, + } + teams = request.env['runbot.team'].search([], order='name') + tags = request.env['runbot.bundle.tag'].search([], order='name') + domain = [('project_id', '=', project_id), ('is_base', '=', is_base)] + + if pr_filter: + domain.append(pr_filters.get(pr_filter, {}).get('domain', ())) + if team_id: + team = request.env['runbot.team'].browse(int(team_id)) + domain.append(('owner_id', 'in', team.user_ids.ids)) + if tag_id: + tag_name = request.env['runbot.bundle.tag'].browse(int(tag_id)).name + domain.append(('tags', 'like', f'%{tag_name}%')) + + if search: + search = search if len(search) < 60 else search[:60] + domain.append(('name', 'like', f'%{search}%')) + + bundle_count = request.env['runbot.bundle.pr'].search_count(domain) + pager = request.website.pager( + url='/runbot/bundle', + url_args={'is_base': '1' if is_base else 0, 'pr_filter': pr_filter, 'team_id': team_id}, + total=bundle_count, + page=page, + step=20, + ) + bundle_ids = request.env['runbot.bundle.pr'].search(domain, limit=20, offset=pager.get('offset', 0), order='id desc').ids + + context = { + 'pager': pager, + 'pr_filters': pr_filters, + 'teams': teams, + 'tags': tags, + 'bundles': request.env['runbot.bundle'].browse(bundle_ids), + } + return request.render('runbot.bundle_list', context) + @o_route([ '/runbot/bundle//force', '/runbot/bundle//force/', diff --git a/runbot/models/bundle.py b/runbot/models/bundle.py index 4578658c..c5c3b706 100644 --- a/runbot/models/bundle.py +++ b/runbot/models/bundle.py @@ -50,6 +50,10 @@ class Bundle(models.Model): commit_limit = fields.Integer("Commit limit") file_limit = fields.Integer("File limit") + # Administrative fields + owner_id = fields.Many2one('res.users', 'Bundle Owner') + tag_ids = fields.Many2many('runbot.bundle.tag', string='Tags') + @api.depends('name') def _compute_host_id(self): assigned_only = None @@ -241,3 +245,64 @@ class Bundle(models.Model): for branch in self.branch_ids.sorted(key=lambda b: (b.is_pr)): branch_groups[branch.remote_id.repo_id].append(branch) return branch_groups + + +class BundleTag(models.Model): + + _name = "runbot.bundle.tag" + _description = "Bundle tag" + + _sql_constraints = [ + ('unique_bundle_tag_nam', 'unique (name)', 'avoid duplicate tags'), + ] + + name = fields.Char('Tag', ) + bundle_ids = fields.Many2many('runbot.bundle', string='Bundles') + + +class BundlePr(models.Model): + + _name = "runbot.bundle.pr" + _description = "Bundle PR Link" + _auto = False + _order = 'id desc' + + id = fields.Many2one('runbot.bundle', string='Bundle', readonly=True) + name = fields.Char(string='Bundle Name', readonly=True) + project_id = fields.Many2one('runbot.project', readonly=True) + is_base = fields.Boolean('Is base', readonly=True) + owner_id = fields.Many2one('res.users', string='Bundle Owner', readonly=True) + tags = fields.Char('Comma Separated Tags', readonly=True) + branch_count = fields.Integer('Branch count', readonly=True) + pr_count = fields.Integer('PR count', readonly=True) + pr_open_count = fields.Integer('Open PR count', readonly=True) + pr_closed_count = fields.Integer('Closed PR count', readonly=True) + + def init(self): + """ Create an SQL view for bundle """ + tools.drop_view_if_exists(self._cr, 'runbot_bundle_pr') + self._cr.execute(""" + CREATE VIEW runbot_bundle_pr AS ( + SELECT + runbot_bundle.id AS id, + runbot_bundle.name AS name, + runbot_bundle.project_id AS project_id, + runbot_bundle.is_base AS is_base, + runbot_bundle.owner_id AS owner_id, + STRING_AGG(runbot_bundle_tag.name,',') AS tags, + count(runbot_branch.id) AS branch_count, + SUM(CASE WHEN runbot_branch.is_pr THEN 1 ELSE 0 END) AS pr_count, + SUM(CASE WHEN runbot_branch.is_pr AND runbot_branch.alive THEN 1 ELSE 0 END) AS pr_open_count, + SUM(CASE WHEN runbot_branch.is_pr AND NOT runbot_branch.alive THEN 1 ELSE 0 END) AS pr_closed_count + FROM + runbot_bundle + JOIN + runbot_branch ON runbot_branch.bundle_id = runbot_bundle.id + LEFT JOIN + runbot_bundle_runbot_bundle_tag_rel ON runbot_bundle_runbot_bundle_tag_rel.runbot_bundle_id = runbot_bundle.id + LEFT JOIN + runbot_bundle_tag ON runbot_bundle_tag.id = runbot_bundle_runbot_bundle_tag_rel.runbot_bundle_tag_id + GROUP BY + runbot_bundle.id + )""" + ) diff --git a/runbot/security/ir.model.access.csv b/runbot/security/ir.model.access.csv index c2227dc8..99bb3347 100644 --- a/runbot/security/ir.model.access.csv +++ b/runbot/security/ir.model.access.csv @@ -73,6 +73,10 @@ access_runbot_project_runbot_admin,access_runbot_project_runbot_admin,runbot.mod access_runbot_bundle_user,access_runbot_bundle_user,runbot.model_runbot_bundle,runbot.group_user,1,0,0,0 access_runbot_bundle_runbot_admin,access_runbot_bundle_runbot_admin,runbot.model_runbot_bundle,runbot.group_runbot_admin,1,1,1,1 +access_runbot_bundle_pr_user,access_runbot_bundle_pr_usr,runbot.model_runbot_bundle_pr,runbot.group_user,1,0,0,0 +access_runbot_bundle_tag_admin,access_runbot_bundle_tag_admin,runbot.model_runbot_bundle_tag,runbot.group_runbot_admin,1,1,1,1 +access_runbot_bundle_tag_user,access_runbot_bundle_tag_user,runbot.model_runbot_bundle_tag,runbot.group_user,1,0,0,0 + access_runbot_batch_user,access_runbot_batch_user,runbot.model_runbot_batch,runbot.group_user,1,0,0,0 access_runbot_batch_runbot_admin,access_runbot_batch_runbot_admin,runbot.model_runbot_batch,runbot.group_runbot_admin,1,1,1,1 diff --git a/runbot/templates/bundle_list.xml b/runbot/templates/bundle_list.xml new file mode 100644 index 00000000..d5a9d34b --- /dev/null +++ b/runbot/templates/bundle_list.xml @@ -0,0 +1,123 @@ + + + + + + + + diff --git a/runbot/templates/frontend.xml b/runbot/templates/frontend.xml index 863e750c..ead3ecbe 100644 --- a/runbot/templates/frontend.xml +++ b/runbot/templates/frontend.xml @@ -90,7 +90,7 @@ - View batch... + diff --git a/runbot/views/bundle_views.xml b/runbot/views/bundle_views.xml index 03f205a5..5dfe0cf9 100644 --- a/runbot/views/bundle_views.xml +++ b/runbot/views/bundle_views.xml @@ -37,6 +37,8 @@ + + @@ -122,6 +124,7 @@ +