Add implied-branches pragma directive
When two projects have dissimilar stable branch names, for example,
stable/pike and stable/jewel, but should generally be used together
and therefore share job variants, it can be difficult to make that
happen. Currently, one must add explicit multi-branch matchers
to every such job and project-template.
This allows a user to add a pragma directive to indicate all the
jobs in a file should apply to multiple branches.
Change-Id: I57cf159992d8f501cbaf41aef19562951ef6b7ea
diff --git a/tests/fixtures/config/pragma-multibranch/git/common-config/zuul.yaml b/tests/fixtures/config/pragma-multibranch/git/common-config/zuul.yaml
new file mode 100644
index 0000000..dc83f9d
--- /dev/null
+++ b/tests/fixtures/config/pragma-multibranch/git/common-config/zuul.yaml
@@ -0,0 +1,61 @@
+- pipeline:
+ name: check
+ manager: independent
+ trigger:
+ gerrit:
+ - event: patchset-created
+ success:
+ gerrit:
+ Verified: 1
+ failure:
+ gerrit:
+ Verified: -1
+
+- pipeline:
+ name: gate
+ manager: dependent
+ post-review: True
+ trigger:
+ gerrit:
+ - event: comment-added
+ approval:
+ - Approved: 1
+ success:
+ gerrit:
+ Verified: 2
+ submit: true
+ failure:
+ gerrit:
+ Verified: -2
+ start:
+ gerrit:
+ Verified: 0
+ precedence: high
+
+- job:
+ name: base
+ parent: null
+
+- project:
+ name: common-config
+ check:
+ jobs: []
+ gate:
+ jobs:
+ - noop
+
+- project:
+ name: org/project1
+ check:
+ jobs: []
+ gate:
+ jobs:
+ - noop
+
+- project:
+ name: org/project2
+ check:
+ jobs: []
+ gate:
+ jobs:
+ - noop
diff --git a/tests/fixtures/config/pragma-multibranch/git/org_project1/README b/tests/fixtures/config/pragma-multibranch/git/org_project1/README
new file mode 100644
index 0000000..9daeafb
--- /dev/null
+++ b/tests/fixtures/config/pragma-multibranch/git/org_project1/README
@@ -0,0 +1 @@
+test
diff --git a/tests/fixtures/config/pragma-multibranch/git/org_project1/playbooks/test-job1.yaml b/tests/fixtures/config/pragma-multibranch/git/org_project1/playbooks/test-job1.yaml
new file mode 100644
index 0000000..f679dce
--- /dev/null
+++ b/tests/fixtures/config/pragma-multibranch/git/org_project1/playbooks/test-job1.yaml
@@ -0,0 +1,2 @@
+- hosts: all
+ tasks: []
diff --git a/tests/fixtures/config/pragma-multibranch/git/org_project1/playbooks/test-job2.yaml b/tests/fixtures/config/pragma-multibranch/git/org_project1/playbooks/test-job2.yaml
new file mode 100644
index 0000000..f679dce
--- /dev/null
+++ b/tests/fixtures/config/pragma-multibranch/git/org_project1/playbooks/test-job2.yaml
@@ -0,0 +1,2 @@
+- hosts: all
+ tasks: []
diff --git a/tests/fixtures/config/pragma-multibranch/git/org_project1/zuul.yaml b/tests/fixtures/config/pragma-multibranch/git/org_project1/zuul.yaml
new file mode 100644
index 0000000..6c8352a
--- /dev/null
+++ b/tests/fixtures/config/pragma-multibranch/git/org_project1/zuul.yaml
@@ -0,0 +1,13 @@
+- job:
+ name: test-job1
+ run: playbooks/test-job1.yaml
+
+- job:
+ name: test-job2
+ run: playbooks/test-job2.yaml
+
+- project-template:
+ name: test-template
+ check:
+ jobs:
+ - test-job1
diff --git a/tests/fixtures/config/pragma-multibranch/git/org_project2/README b/tests/fixtures/config/pragma-multibranch/git/org_project2/README
new file mode 100644
index 0000000..9daeafb
--- /dev/null
+++ b/tests/fixtures/config/pragma-multibranch/git/org_project2/README
@@ -0,0 +1 @@
+test
diff --git a/tests/fixtures/config/pragma-multibranch/git/org_project2/zuul.yaml b/tests/fixtures/config/pragma-multibranch/git/org_project2/zuul.yaml
new file mode 100644
index 0000000..748cab2
--- /dev/null
+++ b/tests/fixtures/config/pragma-multibranch/git/org_project2/zuul.yaml
@@ -0,0 +1,7 @@
+- project:
+ name: org/project2
+ templates:
+ - test-template
+ check:
+ jobs:
+ - test-job2
diff --git a/tests/fixtures/config/pragma-multibranch/main.yaml b/tests/fixtures/config/pragma-multibranch/main.yaml
new file mode 100644
index 0000000..950b117
--- /dev/null
+++ b/tests/fixtures/config/pragma-multibranch/main.yaml
@@ -0,0 +1,9 @@
+- tenant:
+ name: tenant-one
+ source:
+ gerrit:
+ config-projects:
+ - common-config
+ untrusted-projects:
+ - org/project1
+ - org/project2
diff --git a/tests/unit/test_v3.py b/tests/unit/test_v3.py
index 1f401d0..e4ef619 100755
--- a/tests/unit/test_v3.py
+++ b/tests/unit/test_v3.py
@@ -2232,6 +2232,115 @@
self.assertIsNone(job.branch_matcher)
+class TestPragmaMultibranch(ZuulTestCase):
+ tenant_config_file = 'config/pragma-multibranch/main.yaml'
+
+ def test_no_branch_matchers(self):
+ self.create_branch('org/project1', 'stable/pike')
+ self.create_branch('org/project2', 'stable/jewel')
+ self.fake_gerrit.addEvent(
+ self.fake_gerrit.getFakeBranchCreatedEvent(
+ 'org/project1', 'stable/pike'))
+ self.fake_gerrit.addEvent(
+ self.fake_gerrit.getFakeBranchCreatedEvent(
+ 'org/project2', 'stable/jewel'))
+ self.waitUntilSettled()
+ # We want the jobs defined on the stable/pike branch of
+ # project1 to apply to the stable/jewel branch of project2.
+
+ # First, without the pragma line, the jobs should not run
+ # because in project1 they have branch matchers for pike, so
+ # they will not match a jewel change.
+ B = self.fake_gerrit.addFakeChange('org/project2', 'stable/jewel', 'B')
+ self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
+ self.waitUntilSettled()
+ self.assertHistory([])
+
+ # Add a pragma line to disable implied branch matchers in
+ # project1, so that the jobs and templates apply to both
+ # branches.
+ with open(os.path.join(FIXTURE_DIR,
+ 'config/pragma-multibranch/git/',
+ 'org_project1/zuul.yaml')) as f:
+ config = f.read()
+ extra_conf = textwrap.dedent(
+ """
+ - pragma:
+ implied-branch-matchers: False
+ """)
+ config = extra_conf + config
+ file_dict = {'zuul.yaml': config}
+ A = self.fake_gerrit.addFakeChange('org/project1', 'stable/pike', 'A',
+ files=file_dict)
+ A.addApproval('Code-Review', 2)
+ self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
+ self.waitUntilSettled()
+ self.fake_gerrit.addEvent(A.getChangeMergedEvent())
+ self.waitUntilSettled()
+
+ # Now verify that when we propose a change to jewel, we get
+ # the pike/jewel jobs.
+ self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
+ self.waitUntilSettled()
+ self.assertHistory([
+ dict(name='test-job1', result='SUCCESS', changes='1,1'),
+ dict(name='test-job2', result='SUCCESS', changes='1,1'),
+ ], ordered=False)
+
+ def test_supplied_branch_matchers(self):
+ self.create_branch('org/project1', 'stable/pike')
+ self.create_branch('org/project2', 'stable/jewel')
+ self.fake_gerrit.addEvent(
+ self.fake_gerrit.getFakeBranchCreatedEvent(
+ 'org/project1', 'stable/pike'))
+ self.fake_gerrit.addEvent(
+ self.fake_gerrit.getFakeBranchCreatedEvent(
+ 'org/project2', 'stable/jewel'))
+ self.waitUntilSettled()
+ # We want the jobs defined on the stable/pike branch of
+ # project1 to apply to the stable/jewel branch of project2.
+
+ # First, without the pragma line, the jobs should not run
+ # because in project1 they have branch matchers for pike, so
+ # they will not match a jewel change.
+ B = self.fake_gerrit.addFakeChange('org/project2', 'stable/jewel', 'B')
+ self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
+ self.waitUntilSettled()
+ self.assertHistory([])
+
+ # Add a pragma line to disable implied branch matchers in
+ # project1, so that the jobs and templates apply to both
+ # branches.
+ with open(os.path.join(FIXTURE_DIR,
+ 'config/pragma-multibranch/git/',
+ 'org_project1/zuul.yaml')) as f:
+ config = f.read()
+ extra_conf = textwrap.dedent(
+ """
+ - pragma:
+ implied-branches:
+ - stable/pike
+ - stable/jewel
+ """)
+ config = extra_conf + config
+ file_dict = {'zuul.yaml': config}
+ A = self.fake_gerrit.addFakeChange('org/project1', 'stable/pike', 'A',
+ files=file_dict)
+ A.addApproval('Code-Review', 2)
+ self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
+ self.waitUntilSettled()
+ self.fake_gerrit.addEvent(A.getChangeMergedEvent())
+ self.waitUntilSettled()
+ # Now verify that when we propose a change to jewel, we get
+ # the pike/jewel jobs.
+ self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
+ self.waitUntilSettled()
+ self.assertHistory([
+ dict(name='test-job1', result='SUCCESS', changes='1,1'),
+ dict(name='test-job2', result='SUCCESS', changes='1,1'),
+ ], ordered=False)
+
+
class TestBaseJobs(ZuulTestCase):
tenant_config_file = 'config/base-jobs/main.yaml'