Check branches in supercedent pipelines

Supercedent was designed for a post pipeline and predates common
use of a promote pipeline.  It therefore only consulted the 'ref'
attribute of a change (so that it would work on tags as well as
branches).  However, it should work just fine as a manager for
promote pipelines too, so have it check the branch attribute for
de-duplication first, and only use the ref attribute if it isn't
present.

Change-Id: I1393c828b86a577fba568a183efee98cf5d030e7
This commit is contained in:
James E. Blair 2019-04-05 13:47:15 -07:00
parent 9f7c642ae1
commit bab008ee92
3 changed files with 58 additions and 2 deletions

View File

@ -0,0 +1,20 @@
- pipeline:
name: promote
manager: supercedent
trigger:
gerrit:
- event: change-merged
- job:
name: base
parent: null
run: playbooks/base.yaml
- job:
name: promote-job
- project:
name: org/project
promote:
jobs:
- promote-job

View File

@ -81,3 +81,36 @@ class TestSupercedent(ZuulTestCase):
dict(name='post-job', result='SUCCESS', newrev=arev),
dict(name='post-job', result='SUCCESS', newrev=brev),
], ordered=False)
@simple_layout('layouts/supercedent-promote.yaml')
def test_supercedent_promote(self):
self.executor_server.hold_jobs_in_build = True
A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
A.setMerged()
self.fake_gerrit.addEvent(A.getChangeMergedEvent())
self.waitUntilSettled()
# We should never run jobs for more than one change at a time
self.assertEqual(len(self.builds), 1)
# This change should be superceded by the next
B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
B.setMerged()
self.fake_gerrit.addEvent(B.getChangeMergedEvent())
self.waitUntilSettled()
self.assertEqual(len(self.builds), 1)
C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
C.setMerged()
self.fake_gerrit.addEvent(C.getChangeMergedEvent())
self.waitUntilSettled()
self.assertEqual(len(self.builds), 1)
self.executor_server.hold_jobs_in_build = True
self.orderedRelease()
self.assertHistory([
dict(name='promote-job', result='SUCCESS', changes='1,1'),
dict(name='promote-job', result='SUCCESS', changes='3,1'),
], ordered=False)

View File

@ -26,10 +26,13 @@ class SupercedentPipelineManager(PipelineManager):
return DynamicChangeQueueContextManager(existing)
# Don't use Pipeline.getQueue to find an existing queue
# because we're matching project and ref.
# because we're matching project and (branch or ref).
for queue in self.pipeline.queues:
if (queue.queue[-1].change.project == change.project and
queue.queue[-1].change.ref == change.ref):
((hasattr(change, 'branch') and
hasattr(queue.queue[-1].change, 'branch') and
queue.queue[-1].change.branch == change.branch) or
queue.queue[-1].change.ref == change.ref)):
self.log.debug("Found existing queue %s", queue)
return DynamicChangeQueueContextManager(queue)
change_queue = model.ChangeQueue(