From 669f2be60c0761e6d008b9c2a21d54920f140447 Mon Sep 17 00:00:00 2001 From: William Braeckman Date: Wed, 5 Mar 2025 13:34:38 +0100 Subject: [PATCH] [IMP] runbot: inherit pr target custom triggers When teams want to work by merging many branches into a singular dev branch before targetting master, they often require custom triggers which we have to copy by hand. With this change we hope to be able to set the custom trigger on the target branch instead and inherit the custom triggers on the children branches automatically. --- runbot/models/batch.py | 4 ++-- runbot/models/bundle.py | 12 ++++++++++++ runbot/tests/test_build.py | 22 ++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/runbot/models/batch.py b/runbot/models/batch.py index bd6f496d..1469d9e0 100644 --- a/runbot/models/batch.py +++ b/runbot/models/batch.py @@ -366,7 +366,7 @@ class Batch(models.Model): version_id = self.bundle_id.version_id.id project_id = self.bundle_id.project_id.id trigger_customs = {} - for trigger_custom in self.bundle_id.trigger_custom_ids: + for trigger_custom in self.bundle_id.all_trigger_custom_ids: trigger_customs[trigger_custom.trigger_id] = trigger_custom for trigger in triggers: trigger_custom = trigger_customs.get(trigger, self.env['runbot.bundle.trigger.custom']) @@ -427,7 +427,7 @@ class Batch(models.Model): bundle_repos = bundle.branch_ids.filtered('alive').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: + for trigger_custom in self.bundle_id.all_trigger_custom_ids: trigger_customs[trigger_custom.trigger_id] = trigger_custom for slot in self.slot_ids: if slot.build_id: diff --git a/runbot/models/bundle.py b/runbot/models/bundle.py index ae097a0a..9cab8493 100644 --- a/runbot/models/bundle.py +++ b/runbot/models/bundle.py @@ -48,6 +48,7 @@ class Bundle(models.Model): # Custom parameters trigger_custom_ids = fields.One2many('runbot.bundle.trigger.custom', 'bundle_id') + all_trigger_custom_ids = fields.Many2many('runbot.bundle.trigger.custom', compute='_compute_all_trigger_custom_ids', recursive=True) host_id = fields.Many2one('runbot.host', compute="_compute_host_id", store=True) dockerfile_id = fields.Many2one('runbot.dockerfile', index=True, help="Use a custom Dockerfile") commit_limit = fields.Integer("Commit limit") @@ -194,6 +195,17 @@ class Bundle(models.Model): for bundle_id, batch_id in self.env.cr.fetchall(): self.browse(bundle_id).last_done_batch = self.env['runbot.batch'].browse(batch_id) + @api.depends('branch_ids.target_branch_name', 'branch_ids.is_pr') + def _compute_all_trigger_custom_ids(self): + for bundle in self: + pr_branches = bundle.branch_ids.filtered('is_pr') + targets = set(pr_branches.mapped('target_branch_name')) + if len(targets) != 1 or targets == {bundle.base_id.name} or bundle.trigger_custom_ids: + bundle.all_trigger_custom_ids = bundle.trigger_custom_ids + else: + parent_bundle = self.env['runbot.bundle'].search([('name', '=', targets.pop())]) + bundle.all_trigger_custom_ids = parent_bundle.all_trigger_custom_ids + def _url(self): self.ensure_one() return "/runbot/bundle/%s" % self.id diff --git a/runbot/tests/test_build.py b/runbot/tests/test_build.py index b55d89b7..467d7707 100644 --- a/runbot/tests/test_build.py +++ b/runbot/tests/test_build.py @@ -125,6 +125,28 @@ class TestBuildParams(RunbotCaseMinimalSetup): 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) + # Test custom trigger if targetting non base bundle + branch_b_name = 'master-test-something-other-thing' + self.push_commit(self.remote_server_dev, branch_b_name, 'Subject', sha='d0d0abab') + self.repo_server.project_id.process_delay = 10 + self.repo_server._update_batches() + bundle_b = self.Bundle.search([('name', '=', branch_b_name), ('project_id', '=', self.project.id)]) + bundle_b.write({ + 'branch_ids': [(0, 0, { + 'name': '1', + 'is_pr': True, + 'pull_head_remote_id': self.remote_server.id, + 'pull_head_name': f'remote:{branch_b_name}', + 'target_branch_name': bundle.name, + 'remote_id': self.remote_server.id, + })] + }) + self.assertEqual(bundle.all_trigger_custom_ids, bundle_b.all_trigger_custom_ids) + self.repo_server.project_id.process_delay = 0 + bundle_b.last_batch._process() + build_slot = bundle_b.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()