From f95c2beafbfeca96737b196af2329dee9e991ba1 Mon Sep 17 00:00:00 2001 From: William Braeckman Date: Thu, 12 Dec 2024 11:00:32 +0100 Subject: [PATCH] [FIX] runbot: fix branch search Allows searching branch through pr url or full branch name. Also fixes a crash when searching invalid values. --- runbot/models/branch.py | 18 +++++++++++++----- runbot/tests/test_branch.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/runbot/models/branch.py b/runbot/models/branch.py index cfcd6561f..d68e6402d 100644 --- a/runbot/models/branch.py +++ b/runbot/models/branch.py @@ -49,11 +49,19 @@ def _compute_dname(self): branch.dname = '%s:%s' % (branch.remote_id.short_name, branch.name) def _search_dname(self, operator, value): - if ':' not in value: - return [('name', operator, value)] - repo_short_name, branch_name = value.split(':') - owner, repo_name = repo_short_name.split('/') - return ['&', ('remote_id', '=', self.env['runbot.remote'].search([('owner', '=', owner), ('repo_name', '=', repo_name)]).id), ('name', operator, branch_name)] + # Match format (owner?, repo, branch) + owner = repo = branch = None + if (m := re.match(r'(?:([\w-]+)/)?([\w-]+):([\w\.-]+)', value)): + owner, repo, branch = m.groups() + # Match PR url format + if (m := re.search(r'/([\w-]+)/([\w-]+)/pull/(\d+)', value)): + owner, repo, branch = m.groups() + if repo and branch: + domain = [('name', operator, branch), ('remote_id.repo_name', '=', repo)] + if owner: + domain.append(('remote_id.owner', '=', owner)) + return domain + return [('name', operator, value)] @api.depends('name', 'is_pr', 'target_branch_name', 'pull_head_name', 'pull_head_remote_id') def _compute_reference_name(self): diff --git a/runbot/tests/test_branch.py b/runbot/tests/test_branch.py index 0824ffbf5..f52384c1b 100644 --- a/runbot/tests/test_branch.py +++ b/runbot/tests/test_branch.py @@ -29,6 +29,38 @@ def test_pull_request(self): self.assertEqual(pr.target_branch_name, 'master') self.assertEqual(pr.pull_head_name, 'foo-dev:bar_branch') + def test_branch_dname_search(self): + # Basic branch + self.assertEqual( + self.branch_server, + self.Branch.search([('dname', '=', self.branch_server.dname)]), + ) + # Basic pr + self.assertEqual( + self.dev_pr, + self.Branch.search([('dname', '=', self.dev_pr.dname)]), + ) + # PR from pull request url + self.assertEqual( + self.dev_pr, + self.Branch.search([('dname', '=', self.dev_pr.branch_url)]), + ) + # With subtree of PR url + self.assertEqual( + self.dev_pr, + self.Branch.search([('dname', '=', self.dev_pr.branch_url + '/files')]), + ) + # Branch with a . inside of it + branch = self.Branch.create({ + 'name': '18.0-test', + 'remote_id': self.remote_server.id, + 'is_pr': False, + }) + self.assertEqual( + branch, + self.Branch.search([('dname', '=', branch.dname)]), + ) + class TestBranchRelations(RunbotCase): def setUp(self):