From b849931c1801e1064337d218690f050fb080da04 Mon Sep 17 00:00:00 2001 From: Ayoub Nasr Date: Wed, 15 Jul 2026 15:34:12 +0200 Subject: [PATCH] fix: honour bypass_author_approval in integration-branch creation gate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `check_integration_branches` decides whether to raise `RequestIntegrationBranches` (asking the user to send `/create_integration_branches`) or let the flow proceed to actually create the branches. When the author has not explicitly approved the PR, the gate relied on `job.settings.approve` alone to detect author consent — meaning `/approve` unblocked integration-branch creation but the equivalent admin escape hatch `/bypass_author_approval` did not. `check_approvals` (in gitwaterflow/__init__.py) already treats `bypass_author_approval` as equivalent to author approval; the two functions had simply drifted apart, leaving admins with a UX where a `/bypass_author_approval` comment first triggers a "please request integration branches" reply instead of moving forward. Reuse the existing `bypass_author_approval` helper from `gitwaterflow.utils` (which also folds in the per-author `pr_author_options` bypass) inside `check_integration_branches`, so both entry points agree on what "author has approved" means. Update the two existing tests that relied on the previous asymmetric behaviour by explicitly leaving `bypass_author_approval` un-bypassed — their intent (verifying the "request integration branches" gate) is preserved. Add a new positive test that exercises the fixed path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- bert_e/tests/test_bert_e.py | 52 ++++++++++++++++++++- bert_e/workflow/gitwaterflow/integration.py | 3 +- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/bert_e/tests/test_bert_e.py b/bert_e/tests/test_bert_e.py index 45d0f291..34d32afe 100644 --- a/bert_e/tests/test_bert_e.py +++ b/bert_e/tests/test_bert_e.py @@ -1346,7 +1346,8 @@ def test_request_integration_branch_creation(self): admins: - {admin} """ # noqa - options = self.bypass_all_but(['bypass_build_status']) + options = self.bypass_all_but(['bypass_build_status', + 'bypass_author_approval']) pr = self.create_pr('feature/TEST-0069', 'development/4.3') with self.assertRaises(exns.RequestIntegrationBranches): self.handle( @@ -1358,6 +1359,9 @@ def test_request_integration_branch_creation(self): '/create_integration_branches', self.get_last_pr_comment(pr)) pr.add_comment('/create_integration_branches') + # Restore bypass_author_approval so subsequent calls can pass + # check_approvals and reach the build-status stage. + options = self.bypass_all_but(['bypass_build_status']) with self.assertRaises(exns.BuildNotStarted): self.handle( pr.id, settings=settings, options=options, backtrace=True) @@ -1398,13 +1402,17 @@ def test_request_integration_branch_by_creating_pull_requests(self): admins: - {admin} """ # noqa - options = self.bypass_all_but(['bypass_build_status']) + options = self.bypass_all_but(['bypass_build_status', + 'bypass_author_approval']) pr = self.create_pr('feature/TEST-0069', 'development/4.3') with self.assertRaises(exns.RequestIntegrationBranches): self.handle( pr.id, settings=settings, options=options, backtrace=True) pr.add_comment('/create_pull_requests') + # Restore bypass_author_approval so subsequent calls can pass + # check_approvals and reach the build-status stage. + options = self.bypass_all_but(['bypass_build_status']) with self.assertRaises(exns.BuildNotStarted): self.handle( pr.id, settings=settings, options=options, backtrace=True) @@ -1420,6 +1428,46 @@ def test_request_integration_branch_by_creating_pull_requests(self): 'I have successfully merged the changeset', self.get_last_pr_comment(pr)) + def test_creation_integration_branch_by_bypass_author_approval(self): + """Test that bypass_author_approval triggers integration branch + creation just like /approve does. + + 1. Create a PR on a repo that would otherwise wait for an explicit + /create_integration_branches command. + 2. Handle the PR with bypass_author_approval enabled and verify that + integration branches are created instead of a + RequestIntegrationBranches reply. + + """ + settings = """ +repository_owner: {owner} +repository_slug: {slug} +repository_host: {host} +robot: {robot} +robot_email: nobody@nowhere.com +pull_request_base_url: https://bitbucket.org/{owner}/{slug}/bar/pull-requests/{{pr_id}} +commit_base_url: https://bitbucket.org/{owner}/{slug}/commits/{{commit_id}} +build_key: pre-merge +required_leader_approvals: 0 +required_peer_approvals: 1 +always_create_integration_branches: false +always_create_integration_pull_requests: false +admins: + - {admin} +""" # noqa + options = self.bypass_all_but(['bypass_build_status']) + pr = self.create_pr('feature/TEST-0069', 'development/4.3') + with self.assertRaises(exns.BuildNotStarted): + self.handle( + pr.id, settings=settings, options=options, backtrace=True) + self.assertIn( + 'Integration data created', self.get_last_pr_comment(pr)) + + options = self.bypass_all + with self.assertRaises(exns.SuccessMessage): + self.handle( + pr.id, settings=settings, options=options, backtrace=True) + def test_creation_integration_branch_by_approve(self): """Test pr.approve() to request integration branches creation. diff --git a/bert_e/workflow/gitwaterflow/integration.py b/bert_e/workflow/gitwaterflow/integration.py index 80783163..7d3ebb4a 100644 --- a/bert_e/workflow/gitwaterflow/integration.py +++ b/bert_e/workflow/gitwaterflow/integration.py @@ -25,6 +25,7 @@ from ..pr_utils import notify_user from .branches import (branch_factory, build_branch_cascade, GhostIntegrationBranch) +from .utils import bypass_author_approval def get_integration_branches(job): @@ -149,7 +150,7 @@ def check_integration_branches(job): """Check if the integration branches can be created.""" approvals = set(job.pull_request.get_approvals()) - if job.settings.approve: + if job.settings.approve or bypass_author_approval(job): approvals.add(job.pull_request.author) approved_by_author = job.pull_request.author in approvals