diff --git a/runbot/models/build.py b/runbot/models/build.py index 02131da5..637196de 100644 --- a/runbot/models/build.py +++ b/runbot/models/build.py @@ -98,6 +98,7 @@ class runbot_build(models.Model): config_id = fields.Many2one('runbot.build.config', 'Run Config', required=True, default=lambda self: self.env.ref('runbot.runbot_build_config_default', raise_if_not_found=False)) real_build = fields.Many2one('runbot.build', 'Real Build', help="duplicate_id or self", compute='_compute_real_build') log_list = fields.Char('Comma separted list of step_ids names with logs', compute="_compute_log_list", store=True) + orphan_result = fields.Boolean('No effect on the parent result', default=False) @api.depends('config_id') def _compute_log_list(self): # storing this field because it will be access trhoug repo viewn and keep track of the list at create @@ -131,20 +132,23 @@ class runbot_build(models.Model): # random note: need to count hidden in pending and testing build displayed in frontend - @api.depends('children_ids.global_result', 'local_result', 'duplicate_id.global_result') + @api.depends('children_ids.global_result', 'local_result', 'duplicate_id.global_result', 'children_ids.orphan_result') def _compute_global_result(self): for record in self: # looks like it's computed twice for children if record.duplicate_id: # would like to avoid to add state as a depends only for this. record.global_result = record.duplicate_id.global_result - elif not record.local_result: + elif record.local_result and record._get_result_score(record.local_result) >= record._get_result_score('ko'): record.global_result = record.local_result - elif record._get_result_score(record.local_result) >= record._get_result_score('ko'): - record.global_result = record.local_result - elif record.children_ids: - children_result = record._get_worst_result([child.global_result for child in record.children_ids], max_res='ko') - record.global_result = record._get_worst_result([record.local_result, children_result]) else: - record.global_result = record.local_result + children_ids = [child for child in record.children_ids if not child.orphan_result] + if children_ids: + children_result = record._get_worst_result([child.global_result for child in children_ids], max_res='ko') + if record.local_result: + record.global_result = record._get_worst_result([record.local_result, children_result]) + else: + record.global_result = children_result + else: + record.global_result = record.local_result def _get_worst_result(self, results, max_res=False): results = [result for result in results if result] # filter Falsy values diff --git a/runbot/models/build_config.py b/runbot/models/build_config.py index abb17455..b8f88a30 100644 --- a/runbot/models/build_config.py +++ b/runbot/models/build_config.py @@ -111,6 +111,7 @@ class ConfigStep(models.Model): hide_build = fields.Boolean('Hide created build in frontend', default=True, tracking=True) force_build = fields.Boolean("As a forced rebuild, don't use duplicate detection", default=False, tracking=True) force_host = fields.Boolean('Use same host as parent for children', default=False, tracking=True) # future + make_orphan = fields.Boolean('No effect on the parent result', help='Created build result will not affect parent build result', default=False, tracking=True) @api.constrains('python_code') def _check_python_code(self): @@ -205,6 +206,7 @@ class ConfigStep(models.Model): 'subject': build.subject, 'modules': build.modules, 'hidden': self.hide_build, + 'orphan_result': self.make_orphan, }) build._log('create_build', 'created with config %s' % create_config.name, log_type='subbuild', path=str(children.id)) diff --git a/runbot/templates/build.xml b/runbot/templates/build.xml index e78d146f..344ef07d 100644 --- a/runbot/templates/build.xml +++ b/runbot/templates/build.xml @@ -215,6 +215,7 @@ Build with config + Running step: @@ -228,7 +229,8 @@ -

Child of

+

Child of +   Orphaned build, the result does not affect parent build result

Duplicate of

diff --git a/runbot/tests/__init__.py b/runbot/tests/__init__.py index 0df5e53e..dd011f06 100644 --- a/runbot/tests/__init__.py +++ b/runbot/tests/__init__.py @@ -4,3 +4,4 @@ from . import test_build from . import test_frontend from . import test_schedule from . import test_cron +from . import test_build_config_step diff --git a/runbot/tests/test_build_config_step.py b/runbot/tests/test_build_config_step.py new file mode 100644 index 00000000..9dbf151f --- /dev/null +++ b/runbot/tests/test_build_config_step.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +from odoo.tests import common + + +class TestBuildConfigStep(common.TransactionCase): + + def setUp(self): + super(TestBuildConfigStep, self).setUp() + self.Repo = self.env['runbot.repo'] + self.repo = self.Repo.create({'name': 'bla@example.com:foo/bar'}) + self.Branch = self.env['runbot.branch'] + self.branch = self.Branch.create({ + 'repo_id': self.repo.id, + 'name': 'refs/heads/master' + }) + self.branch_10 = self.Branch.create({ + 'repo_id': self.repo.id, + 'name': 'refs/heads/10.0' + }) + self.branch_11 = self.Branch.create({ + 'repo_id': self.repo.id, + 'name': 'refs/heads/11.0' + }) + self.Build = self.env['runbot.build'] + self.ConfigStep = self.env['runbot.build.config.step'] + self.Config = self.env['runbot.build.config'] + + self.parent_build = self.Build.create({ + 'branch_id': self.branch.id, + 'name': 'd0d0caca0000ffffffffffffffffffffffffffff', + 'port': '1234', + }) + + def test_config_step_create_results(self): + """ Test child builds are taken into account""" + + config_step = self.ConfigStep.create({ + 'name': 'test_step', + 'job_type': 'create_build', + 'number_builds': 2, + 'make_orphan': False, + 'force_build': True, + }) + + config = self.Config.create({'name': 'test_config'}) + config_step.create_config_ids = [config.id] + + config_step._create_build(self.parent_build, '/tmp/essai') + self.assertEqual(len(self.parent_build.children_ids), 2, 'Two sub-builds should have been generated') + + # check that the result will be ignored by parent build + for child_build in self.parent_build.children_ids: + self.assertFalse(child_build.orphan_result) + child_build.local_result = 'ko' + self.assertEqual(child_build.global_result, 'ko') + + self.assertEqual(self.parent_build.global_result, 'ko') + + def test_config_step_create(self): + """ Test the config step of type create """ + + config_step = self.ConfigStep.create({ + 'name': 'test_step', + 'job_type': 'create_build', + 'number_builds': 2, + 'make_orphan': True, + 'force_build': True, + }) + + config = self.Config.create({'name': 'test_config'}) + config_step.create_config_ids = [config.id] + + config_step._create_build(self.parent_build, '/tmp/essai') + self.assertEqual(len(self.parent_build.children_ids), 2, 'Two sub-builds should have been generated') + + # check that the result will be ignored by parent build + for child_build in self.parent_build.children_ids: + self.assertTrue(child_build.orphan_result, 'An orphan result config step should mark the build as orphan_result') + child_build.local_result = 'ko' + + self.assertFalse(self.parent_build.global_result) diff --git a/runbot/views/build_views.xml b/runbot/views/build_views.xml index 3a3c05e1..39efc9e6 100644 --- a/runbot/views/build_views.xml +++ b/runbot/views/build_views.xml @@ -36,6 +36,7 @@ + diff --git a/runbot/views/config_views.xml b/runbot/views/config_views.xml index 9199a1f6..27741c5c 100644 --- a/runbot/views/config_views.xml +++ b/runbot/views/config_views.xml @@ -61,6 +61,7 @@ +