From 9eb7f0d5772c235c133dc3159a75091e0094fee4 Mon Sep 17 00:00:00 2001 From: Xavier-Do Date: Fri, 29 Mar 2024 11:12:27 +0100 Subject: [PATCH] [IMP] runbot: add trigger cross dependency --- runbot/__manifest__.py | 2 +- runbot/controllers/frontend.py | 1 + runbot/migrations/17.0.5.6/pre-migration.py | 7 ++ runbot/models/batch.py | 48 ++++++++----- runbot/models/build.py | 1 + runbot/models/repo.py | 22 ++++++ runbot/models/runbot.py | 2 +- runbot/security/ir.model.access.csv | 5 ++ runbot/tests/common.py | 4 +- runbot/tests/test_build.py | 76 +++++++++++++++++++-- runbot/tests/test_build_config_step.py | 9 ++- runbot/tests/test_repo.py | 11 ++- runbot/tests/test_upgrade.py | 26 ++++--- runbot/views/menus.xml | 8 ++- runbot/views/repo_views.xml | 59 ++++++++++++++-- runbot_populate/models/runbot.py | 3 +- 16 files changed, 237 insertions(+), 47 deletions(-) create mode 100644 runbot/migrations/17.0.5.6/pre-migration.py diff --git a/runbot/__manifest__.py b/runbot/__manifest__.py index 863e1245..1288b4b3 100644 --- a/runbot/__manifest__.py +++ b/runbot/__manifest__.py @@ -6,7 +6,7 @@ 'author': "Odoo SA", 'website': "http://runbot.odoo.com", 'category': 'Website', - 'version': '5.5', + 'version': '5.6', 'application': True, 'depends': ['base', 'base_automation', 'website'], 'data': [ diff --git a/runbot/controllers/frontend.py b/runbot/controllers/frontend.py index 04014618..27bf105e 100644 --- a/runbot/controllers/frontend.py +++ b/runbot/controllers/frontend.py @@ -232,6 +232,7 @@ class Runbot(Controller): batch = bundle.sudo()._force() batch._log('Batch forced by %s', request.env.user.name) batch._prepare(auto_rebase) + batch._process() return werkzeug.utils.redirect('/runbot/batch/%s' % batch.id) @route(['/runbot/batch/'], website=True, auth='public', type='http', sitemap=False) diff --git a/runbot/migrations/17.0.5.6/pre-migration.py b/runbot/migrations/17.0.5.6/pre-migration.py new file mode 100644 index 00000000..11790e32 --- /dev/null +++ b/runbot/migrations/17.0.5.6/pre-migration.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +import logging + + +def migrate(cr, version): + cr.execute('ALTER TABLE runbot_build ADD COLUMN create_batch_id INT') diff --git a/runbot/models/batch.py b/runbot/models/batch.py index 5f828fee..fad30b49 100644 --- a/runbot/models/batch.py +++ b/runbot/models/batch.py @@ -109,14 +109,16 @@ class Batch(models.Model): def _process(self): processed = self.browse() for batch in self: - if batch.state == 'preparing' and batch.last_update < fields.Datetime.now() - datetime.timedelta(seconds=60): + if batch.state == 'preparing' and batch.last_update <= fields.Datetime.now() - datetime.timedelta(seconds=60): batch._prepare() processed |= batch - elif batch.state == 'ready' and all(slot.build_id.global_state in (False, 'running', 'done') for slot in batch.slot_ids): - _logger.info('Batch %s is done', self.id) - batch._log('Batch done') - batch.state = 'done' - processed |= batch + if batch.state == 'ready': + self._start_builds() + if all(slot.build_id.global_state in (False, 'running', 'done') for slot in batch.slot_ids): + _logger.info('Batch %s is done', self.id) + batch._log('Batch done') + batch.state = 'done' + processed |= batch return processed def _create_build(self, params): @@ -326,7 +328,6 @@ class Batch(models.Model): for commit_link in self.commit_link_ids: commit_link.commit_id = commit_link.commit_id._rebase_on(commit_link.base_commit_id) commit_link_by_repos = {commit_link.commit_id.repo_id.id: commit_link for commit_link in self.commit_link_ids} - bundle_repos = bundle.branch_ids.mapped('remote_id.repo_id') version_id = self.bundle_id.version_id.id project_id = self.bundle_id.project_id.id trigger_customs = {} @@ -360,19 +361,11 @@ class Batch(models.Model): params = self.env['runbot.build.params'].create(params_value) - build = self.env['runbot.build'] - link_type = 'created' - force_trigger = trigger_custom and trigger_custom.start_mode == 'force' - skip_trigger = (trigger_custom and trigger_custom.start_mode == 'disabled') or trigger.manual - should_start = ((trigger.repo_ids & bundle_repos) or bundle.build_all or bundle.sticky) - if force_trigger or (should_start and not skip_trigger): # only auto link build if bundle has a branch for this trigger - link_type, build = self._create_build(params) self.env['runbot.batch.slot'].create({ 'batch_id': self.id, 'trigger_id': trigger.id, - 'build_id': build.id, 'params_id': params.id, - 'link_type': link_type, + 'link_type': 'created', }) ###################################### @@ -388,6 +381,29 @@ class Batch(models.Model): ]) skippable._skip() + def _start_builds(self): + self.ensure_one() + bundle = self.bundle_id + bundle_repos = bundle.branch_ids.mapped('remote_id.repo_id') + success_trigger = self.slot_ids.filtered(lambda s: s.build_id.global_state in ('running', 'done') and s.build_id.global_result == "ok").trigger_id + trigger_customs = {} + for trigger_custom in self.bundle_id.trigger_custom_ids: + trigger_customs[trigger_custom.trigger_id] = trigger_custom + for slot in self.slot_ids: + if slot.build_id: + continue + trigger = slot.trigger_id + if trigger.starts_after_ids - success_trigger: # some required triggers are missing + continue + + trigger_custom = trigger_customs.get(trigger, self.env['runbot.bundle.trigger.custom']) + force_trigger = trigger_custom and trigger_custom.start_mode == 'force' + skip_trigger = (trigger_custom and trigger_custom.start_mode == 'disabled') or trigger.manual + should_start = ((trigger.repo_ids & bundle_repos) or bundle.build_all or bundle.sticky) + if force_trigger or (should_start and not skip_trigger): + slot.link_type, slot.build_id = self._create_build(slot.params_id) + + def _update_commits_infos(self, base_head_per_repo): for link_commit in self.commit_link_ids: commit = link_commit.commit_id diff --git a/runbot/models/build.py b/runbot/models/build.py index dd98f8d6..044d94e6 100644 --- a/runbot/models/build.py +++ b/runbot/models/build.py @@ -158,6 +158,7 @@ class BuildResult(models.Model): version_id = fields.Many2one('runbot.version', related='params_id.version_id', store=True, index=True) config_id = fields.Many2one('runbot.build.config', related='params_id.config_id', store=True, index=True) trigger_id = fields.Many2one('runbot.trigger', related='params_id.trigger_id', store=True, index=True) + create_batch_id = fields.Many2one('runbot.batch', related='params_id.create_batch_id', store=True, index=True) # state machine global_state = fields.Selection(make_selection(state_order), string='Status', compute='_compute_global_state', store=True, recursive=True) diff --git a/runbot/models/repo.py b/runbot/models/repo.py index a7441c74..11bdd8aa 100644 --- a/runbot/models/repo.py +++ b/runbot/models/repo.py @@ -29,6 +29,13 @@ class ModuleFilter(models.Model): description = fields.Char(string="Description") +class TriggerDependency(models.Model): + _name = 'runbot.trigger.dependency' + _description = 'Trigger Dependency' + + dependency_id = fields.Many2one('runbot.trigger', string="Dependency", required=True) + dependant_id = fields.Many2one('runbot.trigger', string="Dependant", required=True) + class Trigger(models.Model): """ List of repo parts that must be part of the same bundle @@ -46,6 +53,21 @@ class Trigger(models.Model): project_id = fields.Many2one('runbot.project', string="Project id", required=True) repo_ids = fields.Many2many('runbot.repo', relation='runbot_trigger_triggers', string="Triggers", domain="[('project_id', '=', project_id)]") dependency_ids = fields.Many2many('runbot.repo', relation='runbot_trigger_dependencies', string="Dependencies") + + starts_before_ids = fields.Many2many( + 'runbot.trigger', + string="Start before", + relation='runbot_trigger_dependency', + column1='dependency_id', + column2='dependant_id', + ) + starts_after_ids = fields.Many2many( + 'runbot.trigger', + string="Start after", + relation='runbot_trigger_dependency', + column2='dependency_id', + column1='dependant_id', + ) module_filters = fields.One2many('runbot.module.filter', 'trigger_id', string="Module filters", help='Will be combined with repo module filters when used with this trigger') config_id = fields.Many2one('runbot.build.config', string="Config", required=True) batch_dependent = fields.Boolean('Batch Dependent', help="Force adding batch in build parameters to make it unique and give access to bundle") diff --git a/runbot/models/runbot.py b/runbot/models/runbot.py index ed17fdf4..51ebc039 100644 --- a/runbot/models/runbot.py +++ b/runbot/models/runbot.py @@ -139,7 +139,7 @@ class Runbot(models.AbstractModel): non_allocated_domain = expression.AND([non_allocated_domain, domain]) e = expression.expression(non_allocated_domain, self.env['runbot.build']) query = e.query - query.order = '"runbot_build".parent_path' + query.order = 'runbot_build.create_batch_id' select_query, select_params = query.select() # self-assign to be sure that another runbot batch cannot self assign the same builds query = """UPDATE diff --git a/runbot/security/ir.model.access.csv b/runbot/security/ir.model.access.csv index 34c07cc4..67f6ec7e 100644 --- a/runbot/security/ir.model.access.csv +++ b/runbot/security/ir.model.access.csv @@ -67,6 +67,9 @@ access_runbot_build_stat_regex_admin,access_runbot_build_stat_regex_admin,runbot access_runbot_trigger_user,access_runbot_trigger_user,runbot.model_runbot_trigger,runbot.group_user,1,0,0,0 access_runbot_trigger_runbot_admin,access_runbot_trigger_runbot_admin,runbot.model_runbot_trigger,runbot.group_runbot_admin,1,1,1,1 +access_runbot_trigger_dependency_user,access_runbot_trigger_dependency_user,runbot.model_runbot_trigger_dependency,runbot.group_user,1,0,0,0 +access_runbot_trigger_dependency_runbot_admin,access_runbot_trigger_dependency_runbot_admin,runbot.model_runbot_trigger_dependency,runbot.group_runbot_admin,1,1,1,1 + access_runbot_module_filter_user,access_runbot_module_filter_user,runbot.model_runbot_module_filter,runbot.group_user,1,0,0,0 access_runbot_module_filter_runbot_admin,access_runbot_module_filter_runbot_admin,runbot.model_runbot_module_filter,runbot.group_runbot_admin,1,1,1,1 @@ -135,3 +138,5 @@ access_runbot_trigger_custom_wizard,access_runbot_trigger_custom_wizard,model_ru access_runbot_build_stat_regex_wizard,access_runbot_build_stat_regex_wizard,model_runbot_build_stat_regex_wizard,runbot.group_runbot_admin,1,1,1,1 access_runbot_host_message,access_runbot_host_message,runbot.model_runbot_host_message,runbot.group_runbot_admin,1,0,0,0 + + diff --git a/runbot/tests/common.py b/runbot/tests/common.py index 3406f5e9..d695e951 100644 --- a/runbot/tests/common.py +++ b/runbot/tests/common.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import datetime import time +from odoo import fields from odoo.tests.common import TransactionCase from unittest.mock import patch, DEFAULT @@ -249,7 +250,8 @@ class RunbotCase(TransactionCase): self.assertEqual(triggers.repo_ids + triggers.dependency_ids, self.remote_addons.repo_id + self.remote_server.repo_id) batch = self.branch_addons.bundle_id._force() - batch._prepare() + batch.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + batch._process() class RunbotCaseMinimalSetup(RunbotCase): diff --git a/runbot/tests/test_build.py b/runbot/tests/test_build.py index 99de400c..73c2c2c5 100644 --- a/runbot/tests/test_build.py +++ b/runbot/tests/test_build.py @@ -90,7 +90,8 @@ class TestBuildParams(RunbotCaseMinimalSetup): # prepare last_batch bundle = self.env['runbot.bundle'].search([('name', '=', branch_a_name), ('project_id', '=', self.project.id)]) - bundle.last_batch._prepare() + bundle.last_batch.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + bundle.last_batch._process() build_slot = bundle.last_batch.slot_ids.filtered(lambda rec: rec.trigger_id == self.trigger_server) self.assertEqual(build_slot.build_id.params_id.config_id, self.trigger_server.config_id) self.assertEqual(build_slot.build_id.description, expected_description, "A build description should reflect the trigger description") @@ -118,11 +119,68 @@ class TestBuildParams(RunbotCaseMinimalSetup): 'bundle_id': bundle.id, 'config_id': custom_config.id }) - - bundle.last_batch._prepare() + bundle.last_batch.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + bundle.last_batch._process() build_slot = bundle.last_batch.slot_ids.filtered(lambda rec: rec.trigger_id == self.trigger_server) self.assertEqual(build_slot.build_id.params_id.config_id, custom_config) + def test_trigger_dependency(self): + self.start_patchers() + self.additionnal_setup() + self.assertEqual(self.project.trigger_ids, self.trigger_server | self.trigger_addons) + minimal_config = self.env['runbot.build.config'].create({'name': 'Minimal Check'}) + other_triggers = self.project.trigger_ids + self.assertEqual(other_triggers.mapped('name'), ['Server trigger', 'Addons trigger']) + trigger_minimal_check = self.Trigger.create({ + 'sequence': 0, + 'name': 'minimal_check', + 'repo_ids': [(4, self.repo_addons.id), (4, self.repo_server.id)], + 'config_id': minimal_config.id, + 'project_id': self.project.id, + 'starts_before_ids': other_triggers.ids, + }) + self.assertEqual(self.trigger_server.starts_after_ids, trigger_minimal_check) + self.assertEqual(self.trigger_addons.starts_after_ids, trigger_minimal_check) + + branch_a_name = 'master-test-something' + self.push_commit(self.remote_server_dev, branch_a_name, 'nice subject', sha='d0d0caca') + self.repo_server._update_batches() + bundle = self.Bundle.search([('name', '=', branch_a_name), ('project_id', '=', self.project.id)]) + batch = bundle.last_batch + batch.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + batch._process() + self.assertEqual(batch.slot_ids.mapped('trigger_id.name'), ['minimal_check', 'Server trigger', 'Addons trigger'], 'All three slot should have been created') + minimal_check_build = batch.slot_ids.build_id + self.assertEqual(len(minimal_check_build), 1, 'Only minimal check should have started') + self.assertEqual(minimal_check_build.trigger_id.name, 'minimal_check', 'Only minimal check should have started') + + with self.env.cr.savepoint() as sp: + minimal_check_build.local_result = 'ko' + minimal_check_build.local_state = 'done' + batch._process() + all_builds = batch.slot_ids.build_id + self.assertEqual(len(all_builds), 1, 'Only minimal check should have started') + self.assertEqual(batch.state, 'done') + sp.rollback() + + minimal_check_build.local_result = 'ok' + minimal_check_build.local_state = 'done' + batch._process() + all_builds = batch.slot_ids.build_id + + self.assertEqual( + all_builds.trigger_id.mapped('name'), + ['minimal_check', 'Server trigger'], + 'Other builds should have started (server only since addons was not updated)', + ) + self.assertEqual(batch.state, 'ready') + self.assertEqual(all_builds.mapped('local_state'), ['done', 'pending']) + server_builds = all_builds[1] + server_builds.local_result = 'ok' + server_builds.local_state = 'done' + batch._process() + self.assertEqual(batch.state, 'done') + class TestBuildResult(RunbotCase): @@ -558,11 +616,14 @@ class TestGc(RunbotCaseMinimalSetup): # prepare last_batch bundle_a = self.env['runbot.bundle'].search([('name', '=', branch_a_name)]) - bundle_a.last_batch._prepare() + bundle_a.last_batch.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + bundle_a.last_batch._process() # now we should have a build in pending state in the bundle self.assertEqual(len(bundle_a.last_batch.slot_ids), 2) build_a = bundle_a.last_batch.slot_ids[0].build_id + self.assertEqual(build_a.local_state, 'pending') + self.assertEqual(build_a.local_state, 'pending') self.assertEqual(build_a.global_state, 'pending') # now another commit is found in another branch @@ -570,7 +631,9 @@ class TestGc(RunbotCaseMinimalSetup): self.push_commit(self.remote_server_dev, branch_b_name, 'other subject', sha='cacad0d0') self.repo_server._update_batches() bundle_b = self.env['runbot.bundle'].search([('name', '=', branch_b_name)]) - bundle_b.last_batch._prepare() + bundle_b.last_batch.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + bundle_b.last_batch._process() + build_b = bundle_b.last_batch.slot_ids[0].build_id @@ -588,7 +651,8 @@ class TestGc(RunbotCaseMinimalSetup): self.push_commit(self.remote_server_dev, branch_a_name, 'new subject', sha='d0cad0ca') self.repo_server._update_batches() bundle_a = self.env['runbot.bundle'].search([('name', '=', branch_a_name)]) - bundle_a.last_batch._prepare() + bundle_a.last_batch.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + bundle_a.last_batch._process() build_a_last = bundle_a.last_batch.slot_ids[0].build_id self.assertEqual(build_a_last.local_state, 'pending') self.assertTrue(build_a.killable, 'The previous build in the batch should be killable') diff --git a/runbot/tests/test_build_config_step.py b/runbot/tests/test_build_config_step.py index 0922f97d..819afd01 100644 --- a/runbot/tests/test_build_config_step.py +++ b/runbot/tests/test_build_config_step.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- +import datetime from unittest.mock import patch, mock_open -from odoo import Command +from odoo import Command, fields from odoo.tools import mute_logger from odoo.exceptions import UserError from odoo.addons.runbot.common import RunbotException @@ -219,7 +220,8 @@ class TestBuildConfigStepRestore(TestBuildConfigStepCommon): # setup master branch master_batch = self.master_bundle._force() with mute_logger('odoo.addons.runbot.models.batch'): - master_batch._prepare() + master_batch.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + master_batch._process() reference_slot = master_batch.slot_ids trigger = reference_slot.trigger_id self.assertEqual(trigger.name, 'Server trigger', 'Just checking that we have a single slot') @@ -246,7 +248,8 @@ class TestBuildConfigStepRestore(TestBuildConfigStepCommon): # create dev build dev_batch = self.dev_bundle._force() with mute_logger('odoo.addons.runbot.models.batch'): - dev_batch._prepare() + dev_batch.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + dev_batch._process() dev_batch.base_reference_batch_id = master_batch # not tested, this is not the purpose of this test dev_build = dev_batch.slot_ids.build_id self.assertEqual(dev_build.params_id.config_data, config_data) diff --git a/runbot/tests/test_repo.py b/runbot/tests/test_repo.py index ff2ad23e..f962d827 100644 --- a/runbot/tests/test_repo.py +++ b/runbot/tests/test_repo.py @@ -1,12 +1,16 @@ # -*- coding: utf-8 -*- +import datetime +import logging +import time import re + from unittest import skip from unittest.mock import patch, Mock from subprocess import CalledProcessError + +from odoo import fields from odoo.tests import common, TransactionCase from odoo.tools import mute_logger -import logging -import time from .common import RunbotCase, RunbotCaseMinimalSetup @@ -248,7 +252,8 @@ class TestRepo(RunbotCaseMinimalSetup): return {} self.patchers['github_patcher'].side_effect = github2 - last_batch._prepare() + bundle.last_batch.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + bundle.last_batch._process() self.assertEqual(last_batch.commit_link_ids.commit_id.mapped('subject'), ['Server subject', 'Addons subject']) self.assertEqual(last_batch.state, 'ready') diff --git a/runbot/tests/test_upgrade.py b/runbot/tests/test_upgrade.py index 10d2713a..67e8e49f 100644 --- a/runbot/tests/test_upgrade.py +++ b/runbot/tests/test_upgrade.py @@ -1,5 +1,7 @@ +import datetime import getpass import logging +from odoo import fields from unittest.mock import patch, mock_open from odoo.exceptions import UserError from odoo.tools import mute_logger @@ -206,7 +208,8 @@ class TestUpgradeFlow(RunbotCase): # create nightly batch_nigthly = bundle._force(self.nightly_category.id) - batch_nigthly._prepare() + batch_nigthly.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + batch_nigthly._process() self.assertEqual(batch_nigthly.category_id, self.nightly_category) builds_nigthly = {} host = self.env['runbot.host']._get_current() @@ -232,7 +235,8 @@ class TestUpgradeFlow(RunbotCase): batch_nigthly.state = 'done' batch_weekly = bundle._force(self.weekly_category.id) - batch_weekly._prepare() + batch_weekly.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + batch_weekly._process() self.assertEqual(batch_weekly.category_id, self.weekly_category) builds_weekly = {} build = batch_weekly.slot_ids.filtered(lambda s: s.trigger_id == self.trigger_addons_weekly).build_id @@ -249,7 +253,8 @@ class TestUpgradeFlow(RunbotCase): batch_weekly.state = 'done' batch_default = bundle._force() - batch_default._prepare() + batch_default.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + batch_default._process() build = batch_default.slot_ids.filtered(lambda s: s.trigger_id == self.trigger_server).build_id build.local_state = 'done' batch_default.state = 'done' @@ -268,7 +273,8 @@ class TestUpgradeFlow(RunbotCase): self.trigger_upgrade_server.flush_recordset(['upgrade_step_id']) batch = self.master_bundle._force() - batch._prepare() + batch.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + batch._process() upgrade_current_build = batch.slot_ids.filtered(lambda slot: slot.trigger_id == self.trigger_upgrade_server).build_id #host = self.env['runbot.host']._get_current() #upgrade_current_build.host = host.name @@ -334,7 +340,8 @@ class TestUpgradeFlow(RunbotCase): }) batch = self.master_bundle._force(self.nightly_category.id) - batch._prepare() + batch.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + batch._process() upgrade_nightly = batch.slot_ids.filtered(lambda slot: slot.trigger_id == trigger_upgrade_addons_nightly).build_id #upgrade_nightly.host = host.name upgrade_nightly._schedule() @@ -484,7 +491,8 @@ class TestUpgradeFlow(RunbotCase): # test_build_references batch = self.master_bundle._force() - batch._prepare() + batch.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + batch._process() upgrade_slot = batch.slot_ids.filtered(lambda slot: slot.trigger_id == self.trigger_upgrade_server) self.assertTrue(upgrade_slot) upgrade_build = upgrade_slot.build_id @@ -501,7 +509,8 @@ class TestUpgradeFlow(RunbotCase): self.trigger_upgrade_server.upgrade_step_id.upgrade_from_all_intermediate_version = True batch = self.master_bundle._force() - batch._prepare() + batch.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + batch._process() upgrade_build = batch.slot_ids.filtered(lambda slot: slot.trigger_id == self.trigger_upgrade_server).build_id self.assertEqual( upgrade_build.params_id.builds_reference_ids, @@ -539,7 +548,8 @@ class TestUpgradeFlow(RunbotCase): self.assertEqual(bundle_133.name, 'saas-13.3') batch13 = bundle_13._force() - batch13._prepare() + batch13.last_update = fields.Datetime.now() - datetime.timedelta(seconds=60) + batch13._process() upgrade_complement_build_13 = batch13.slot_ids.filtered(lambda slot: slot.trigger_id == trigger_upgrade_complement).build_id # upgrade_complement_build_13.host = host.name self.assertEqual(upgrade_complement_build_13.params_id.config_id, config_upgrade_complement) diff --git a/runbot/views/menus.xml b/runbot/views/menus.xml index f01f49ad..37f7938f 100644 --- a/runbot/views/menus.xml +++ b/runbot/views/menus.xml @@ -14,8 +14,14 @@ - + + + + + + + diff --git a/runbot/views/repo_views.xml b/runbot/views/repo_views.xml index 9d930c7f..93782ee4 100644 --- a/runbot/views/repo_views.xml +++ b/runbot/views/repo_views.xml @@ -33,6 +33,20 @@ + + + + + + + + @@ -85,12 +99,40 @@ + + + + runbot.trigger.dependency.form + runbot.trigger.dependency + +
+ + + + + + +
+
+
- + + runbot.trigger.dependency.tree + runbot.trigger.dependency + + + + + + + + + + runbot.category.form runbot.category @@ -224,10 +266,17 @@ - Triggers - runbot.trigger - tree,form - + Triggers + runbot.trigger + tree,form + + + + Triggers dependency + runbot.trigger.dependency + tree,form + + Remotes runbot.remote diff --git a/runbot_populate/models/runbot.py b/runbot_populate/models/runbot.py index 77305230..9c437366 100644 --- a/runbot_populate/models/runbot.py +++ b/runbot_populate/models/runbot.py @@ -115,8 +115,7 @@ class Runbot(models.AbstractModel): mock_git.side_effect = git with mute_logger('odoo.addons.runbot.models.batch'): - batch._prepare() - + batch._process() if i != nb_batch - 1: for slot in batch.slot_ids: if slot.build_id: