Merge "Treat always-dynamic-branches projects as multi-branch"

This commit is contained in:
Zuul
2026-07-01 02:11:56 +00:00
committed by Gerrit Code Review
5 changed files with 75 additions and 0 deletions
+9
View File
@@ -307,6 +307,15 @@ configuration. Some examples of tenant definitions are:
change as if it included a change to a ``zuul.yaml`` file,
even if the change does not alter the configuration).
Even though branches specified by
`always-dynamic-branches` are not loaded into Zuul's
configuration, the fact that they may exist causes Zuul to
treat the project as a multi-branch project, and therefore
Zuul will use implied branch matchers even if the project
has only one permanent branch. This behavior may be
overridden with :attr:`pragma` or
:attr:`tenant.untrusted-projects.<project>.implied-branch-matchers`.
With all these caveats in mind, this can be useful for
repos with large numbers of rarely used branches as it
allows Zuul to omit their configuration in most
@@ -0,0 +1,17 @@
---
upgrade:
- |
The behavior of a single-branch project with
:attr:`tenant.untrusted-projects.<project>.always-dynamic-branches`
has changed. Previously, if (after applying includes and
excludes) a project had only one permanent branch it was treated
as a single-branch project even if it also had
`always-dynamic-branches` set. Now if a project has
`always-dynamic-branches` set, it will be treated as a
multi-branch project and therefore implied branch matchers are
enabled.
To retain the previous behavior (or explicitly choose a behavior)
the
:attr:`tenant.untrusted-projects.<project>.implied-branch-matchers`
tenant configuration option may be used.
@@ -1,5 +1,6 @@
- job:
name: project-test
tags: [master]
# Note: this job is not expected to run
- job:
+42
View File
@@ -11774,6 +11774,48 @@ class TestDynamicBranchesProject(IncludeBranchesTestCase):
dict(name='project-dynamic', result='SUCCESS', changes='1,1'),
], ordered=False)
def test_new_dynamic_branch_single_branch(self):
# In this test, the repo has only a single branch ("master"),
# but since it has always-dynamic-branches set, we treat it
# like a normal repo, not a shared-jobs repo, and behave as if
# implied-branch-matchers is set to true.
# Create a new dynamic-only branch. Since it's dynamic only,
# it won't trigger a reconfiguration.
self.create_branch('org/project', 'feature/foo')
self.fake_gerrit.addEvent(
self.fake_gerrit.getFakeBranchCreatedEvent(
'org/project', 'feature/foo'))
self.waitUntilSettled()
# Test that we load configuration from the dynamic branch even
# though the tenant layout doesn't know about it yet (since
# there hasn't been a reconfiguration since it was created).
conf = textwrap.dedent(
"""
- job:
name: project-test
tags: [feature]
- project:
check:
jobs:
- project-test
""")
file_dict = {'zuul.yaml': conf}
A = self.fake_gerrit.addFakeChange('org/project', 'feature/foo', 'A',
files=file_dict)
self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
self.assertHistory([
dict(name='central-test', result='SUCCESS', changes='1,1'),
dict(name='project-test', result='SUCCESS', changes='1,1'),
], ordered=False)
job = self.getJobFromHistory('project-test')
self.assertEqual(set(['feature']),
set(job.parameters['zuul']['jobtags']))
def test_post_jobs(self):
self.create_branch('org/project', 'feature/bar')
self.fake_gerrit.addEvent(
+6
View File
@@ -5230,6 +5230,12 @@ class Job(ConfigObject):
if source_tpc.trusted:
return None
# If we have some always-dynamic-branches, then this is
# probably not a shared jobs repo, so we will use implied
# branches regardless of how many branches it has.
if source_tpc.always_dynamic_branches:
return self.implied_branch_matcher
# If this project only has one branch, don't use implied
# branch matchers. This way central job repos can work.
branches = tenant.getProjectBranches(