From fb9861ce26e1622cf465c00df332d5e4f2f9513d Mon Sep 17 00:00:00 2001 From: William Braeckman Date: Wed, 26 Feb 2025 13:47:08 +0100 Subject: [PATCH] [IMP] runbot: match prs with build errors automatically Automatically link the pr with the build error if it contains anything along the lines of `runbot.*error.*{id}`. Among the changes: - Add a path for the build error act_window so that it include runbot-error - Fix the widget for `pr_body` in branch form view to use `text` instead of char as they are most likely multi line string. --- runbot/models/branch.py | 23 ++++++++++++++++++ runbot/tests/test_branch.py | 38 ++++++++++++++++++++++++++++++ runbot/views/branch_views.xml | 2 +- runbot/views/build_error_views.xml | 1 + 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/runbot/models/branch.py b/runbot/models/branch.py index 6aea3c3f..64ef7748 100644 --- a/runbot/models/branch.py +++ b/runbot/models/branch.py @@ -87,6 +87,28 @@ class Branch(models.Model): reference_name = f'{forced_version.name}---{reference_name}' branch.reference_name = reference_name + def _match_errors_from_body(self): + """ + Checks the pr_body for any reference to runbot errors and links the branch + to those errors if they exist. + """ + self.ensure_one() + if not self.pr_body: + return + pr_body_regex = r'^.*runbot.*error[^\d]*(\d+)[ \S]*\r?$' + error_ids = re.findall( + pr_body_regex, + self.pr_body, + re.IGNORECASE | re.MULTILINE + ) + # We need to check if they exist and search does nothing if error_ids is empty + errors = self.env['runbot.build.error'].sudo().search([ + ('id', 'in', error_ids), ('fixing_pr_id', '=', False), + ]) + errors.fixing_pr_id = self + for error in errors: + error.message_post(body='Fixing pr automatically set through PR message') + def _update_branch_infos(self, pull_info=None): """compute branch_url, pull_head_name and target_branch_name based on name""" name_to_remote = {} @@ -131,6 +153,7 @@ class Branch(models.Model): owner, repo_name = pull_head_repo_name.split('/') name_to_remote[pull_head_repo_name] = self.env['runbot.remote'].search([('owner', '=', owner), ('repo_name', '=', repo_name)], limit=1) branch.pull_head_remote_id = name_to_remote[pull_head_repo_name] + branch._match_errors_from_body() except (TypeError, AttributeError): _logger.exception('Error for pr %s using pull_info %s', branch.name, pi) raise diff --git a/runbot/tests/test_branch.py b/runbot/tests/test_branch.py index b4d478c6..66f0ef35 100644 --- a/runbot/tests/test_branch.py +++ b/runbot/tests/test_branch.py @@ -65,6 +65,44 @@ class TestBranch(RunbotCase): self.Branch.search([('dname', '=', branch.dname)]), ) + def test_automatic_match_with_error(self): + self.env['runbot.build.error'].search([]).active = False + errors = self.env['runbot.build.error'].create([{} for _ in range(5)]) + branch = self.Branch.create({ + 'name': '18.0-test', + 'remote_id': self.remote_server.id, + 'is_pr': True, + }) + # Does not crash without pr_body or nothing on pr_body + branch._match_errors_from_body() + branch.pr_body = '' + branch._match_errors_from_body() + # Does not link unknown errors + branch.pr_body = f'This is an error {errors[0].id}' + branch._match_errors_from_body() + self.assertFalse(errors.fixing_pr_id) + # Test multiple formats + branch.pr_body = f""" + Runbot error {errors[0].id} + runbot error {errors[1].id} + runbot-error-{errors[2].id} + https://domain.com/odoo/runbot.build.error/{errors[3].id} + https://domain.com/odoo/runbot-error/{errors[4].id}/ + """ + branch._match_errors_from_body() + self.assertTrue(all(e.fixing_pr_id == branch for e in errors)) + # Test that it does not reassign + errors.fixing_pr_id = False + branch.pr_body = f'Runbot ERror {errors[0].id}' + other_branch = self.Branch.create({ + 'name': 'other-branch', + 'remote_id': self.remote_server.id, + 'is_pr': True, + }) + errors[0].fixing_pr_id = other_branch + branch._match_errors_from_body() + self.assertEqual(errors[0].fixing_pr_id, other_branch) + class TestBranchRelations(RunbotCase): def setUp(self): diff --git a/runbot/views/branch_views.xml b/runbot/views/branch_views.xml index 42654aff..d19445aa 100644 --- a/runbot/views/branch_views.xml +++ b/runbot/views/branch_views.xml @@ -21,7 +21,7 @@ - + diff --git a/runbot/views/build_error_views.xml b/runbot/views/build_error_views.xml index a0e66684..eb199732 100644 --- a/runbot/views/build_error_views.xml +++ b/runbot/views/build_error_views.xml @@ -468,6 +468,7 @@ runbot.build.error list,form {'search_default_not_fixed_errors': True, 'active_test': False} + runbot-error