From 6061d786a894960eb55c0f0cc3cea8707876d40e Mon Sep 17 00:00:00 2001 From: Xavier-Do Date: Thu, 10 Feb 2022 11:38:30 +0100 Subject: [PATCH] [FIX] better base bundle computation --- runbot/models/batch.py | 8 +++----- runbot/models/bundle.py | 26 +++++++++++++++----------- runbot/models/repo.py | 22 ++++++++++++++++++++++ 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/runbot/models/batch.py b/runbot/models/batch.py index 5f0228104..1ce68cc1b 100644 --- a/runbot/models/batch.py +++ b/runbot/models/batch.py @@ -306,7 +306,6 @@ def _fill_missing(branch_commits, match_type): 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 = {} @@ -341,11 +340,10 @@ def _fill_missing(branch_commits, match_type): 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 + + if trigger.should_build(bundle, trigger_custom): link_type, build = self._create_build(params) + self.env['runbot.batch.slot'].create({ 'batch_id': self.id, 'trigger_id': trigger.id, diff --git a/runbot/models/bundle.py b/runbot/models/bundle.py index 9ea1b4cc5..446e9d152 100644 --- a/runbot/models/bundle.py +++ b/runbot/models/bundle.py @@ -87,7 +87,7 @@ def _compute_to_upgrade(self): for bundle in self: bundle.to_upgrade = bundle.is_base - @api.depends('name', 'is_base', 'defined_base_id', 'base_id.is_base', 'project_id') + @api.depends('name', 'is_base', 'defined_base_id', 'base_id.is_base', 'project_id', 'branch_ids.target_branch_name', 'branch_ids.alive', 'branch_ids.is_pr') def _compute_base_id(self): for bundle in self: if bundle.is_base: @@ -98,17 +98,19 @@ def _compute_base_id(self): continue project_id = bundle.project_id.id master_base = False - fallback = False - for bid, bname in self._get_base_ids(project_id): - if bundle.name.startswith('%s-' % bname): - bundle.base_id = self.browse(bid) + fallback_id = False + pr = bundle.branch_ids.sorted('id desc').filtered(lambda branch: branch.alive and branch.is_pr) + + for base_id, base_name in self._get_base_ids(project_id): + if (pr and base_name == pr.target_branch_name) or bundle.name.startswith(f'{base_name}-'): + bundle.base_id = self.browse(base_id) break - elif bname == 'master': - master_base = self.browse(bid) - elif not fallback or fallback.id < bid: - fallback = self.browse(bid) + elif base_name == 'master': + master_base = self.browse(base_id) + elif not fallback_id or fallback_id < base_id: + fallback_id = base_id else: - bundle.base_id = master_base or fallback + bundle.base_id = bundle.base_id or master_base or self.browse(fallback_id) @tools.ormcache('project_id') def _get_base_ids(self, project_id): @@ -241,11 +243,13 @@ def _consistency_warning(self): warnings.append(('warning', 'No base defined on this bundle')) else: for branch in self.branch_ids: + if not branch.alive: + continue if branch.is_pr and branch.target_branch_name != self.base_id.name: if branch.target_branch_name.startswith(self.base_id.name): warnings.append(('info', 'PR %s targeting a non base branch: %s' % (branch.dname, branch.target_branch_name))) else: - warnings.append(('warning' if branch.alive else 'info', 'PR %s targeting wrong version: %s (expecting %s)' % (branch.dname, branch.target_branch_name, self.base_id.name))) + warnings.append(('warning', 'PR %s targeting wrong version: %s (expecting %s)' % (branch.dname, branch.target_branch_name, self.base_id.name))) elif not branch.is_pr and not branch.name.startswith(self.base_id.name) and not self.defined_base_id: warnings.append(('warning', 'Branch %s not starting with version name (%s)' % (branch.dname, self.base_id.name))) return warnings diff --git a/runbot/models/repo.py b/runbot/models/repo.py index a30b3486f..925edaca6 100644 --- a/runbot/models/repo.py +++ b/runbot/models/repo.py @@ -37,6 +37,7 @@ 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") + pr_only = fields.Boolean("Only start trigger if bundle has PR alive") 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") @@ -90,6 +91,27 @@ def _get_version_domain(self): return safe_eval(self.version_domain) return [] + def should_build(self, bundle, trigger_custom): + if trigger_custom and trigger_custom.start_mode == 'force': + return True + + if self.manual: + return False + + if (trigger_custom and trigger_custom.start_mode == 'disabled'): + return False + + if bundle.build_all or bundle.sticky: + return True + + if self.repo_ids & bundle.branch_ids.remote_id.repo_id: + if not self.pr_only: + return True + if any(branch.alive and branch.is_pr for branch in bundle.branch_ids): + return True + + return False + class Remote(models.Model): """