Add option to ignore ref-updated events emitted by branch deletions
When a branch is deleted, gerrit emits a ref-updated event with a newrev value of all zeros. This adds a boolean field to optionally not trigger on these ref-updated events. Change-Id: Iea75d05ddcb49b0bf748b72b9d2d5472d077f0c6
This commit is contained in:
parent
135a9358c1
commit
f95e7232ac
@ -422,6 +422,12 @@ explanation of each of the parameters::
|
||||
provides. This field is treated as a regular expression, and
|
||||
multiple refs may be listed.
|
||||
|
||||
*ignore-deletes*
|
||||
When a branch is deleted, a ref-updated event is emitted with a newrev
|
||||
of all zeros specified. The ``ignore-deletes`` field is a boolean value
|
||||
that describes whether or not these newrevs trigger ref-updated events.
|
||||
The default is True, which will not trigger ref-updated events.
|
||||
|
||||
*approval*
|
||||
This is only used for ``comment-added`` events. It only matches if
|
||||
the event has a matching approval associated with it. Example:
|
||||
|
@ -30,6 +30,7 @@ pipelines:
|
||||
gerrit:
|
||||
- event: ref-updated
|
||||
ref: ^(?!refs/).*$
|
||||
ignore-deletes: False
|
||||
|
||||
- name: gate
|
||||
manager: DependentPipelineManager
|
||||
|
16
tests/fixtures/layout-dont-ignore-deletes.yaml
vendored
Normal file
16
tests/fixtures/layout-dont-ignore-deletes.yaml
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
includes:
|
||||
- python-file: custom_functions.py
|
||||
|
||||
pipelines:
|
||||
- name: post
|
||||
manager: IndependentPipelineManager
|
||||
trigger:
|
||||
gerrit:
|
||||
- event: ref-updated
|
||||
ref: ^(?!refs/).*$
|
||||
ignore-deletes: False
|
||||
|
||||
projects:
|
||||
- name: org/project
|
||||
post:
|
||||
- project-post
|
1
tests/fixtures/layouts/good_layout.yaml
vendored
1
tests/fixtures/layouts/good_layout.yaml
vendored
@ -20,6 +20,7 @@ pipelines:
|
||||
gerrit:
|
||||
- event: ref-updated
|
||||
ref: ^(?!refs/).*$
|
||||
ignore-deletes: True
|
||||
|
||||
- name: gate
|
||||
manager: DependentPipelineManager
|
||||
|
@ -891,6 +891,54 @@ class TestScheduler(ZuulTestCase):
|
||||
self.assertEqual(len(self.history), 1)
|
||||
self.assertIn('project-post', job_names)
|
||||
|
||||
def test_post_ignore_deletes(self):
|
||||
"Test that deleting refs does not trigger post jobs"
|
||||
|
||||
e = {
|
||||
"type": "ref-updated",
|
||||
"submitter": {
|
||||
"name": "User Name",
|
||||
},
|
||||
"refUpdate": {
|
||||
"oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
|
||||
"newRev": "0000000000000000000000000000000000000000",
|
||||
"refName": "master",
|
||||
"project": "org/project",
|
||||
}
|
||||
}
|
||||
self.fake_gerrit.addEvent(e)
|
||||
self.waitUntilSettled()
|
||||
|
||||
job_names = [x.name for x in self.history]
|
||||
self.assertEqual(len(self.history), 0)
|
||||
self.assertNotIn('project-post', job_names)
|
||||
|
||||
def test_post_ignore_deletes_negative(self):
|
||||
"Test that deleting refs does trigger post jobs"
|
||||
|
||||
self.config.set('zuul', 'layout_config',
|
||||
'tests/fixtures/layout-dont-ignore-deletes.yaml')
|
||||
self.sched.reconfigure(self.config)
|
||||
|
||||
e = {
|
||||
"type": "ref-updated",
|
||||
"submitter": {
|
||||
"name": "User Name",
|
||||
},
|
||||
"refUpdate": {
|
||||
"oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
|
||||
"newRev": "0000000000000000000000000000000000000000",
|
||||
"refName": "master",
|
||||
"project": "org/project",
|
||||
}
|
||||
}
|
||||
self.fake_gerrit.addEvent(e)
|
||||
self.waitUntilSettled()
|
||||
|
||||
job_names = [x.name for x in self.history]
|
||||
self.assertEqual(len(self.history), 1)
|
||||
self.assertIn('project-post', job_names)
|
||||
|
||||
def test_build_configuration_branch(self):
|
||||
"Test that the right commits are on alternate branches"
|
||||
|
||||
|
@ -61,6 +61,7 @@ class LayoutSchema(object):
|
||||
'username': toList(str),
|
||||
'branch': toList(str),
|
||||
'ref': toList(str),
|
||||
'ignore-deletes': bool,
|
||||
'approval': toList(variable_dict),
|
||||
'require-approval': toList(require_approval),
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ OrderedDict = extras.try_imports(['collections.OrderedDict',
|
||||
'ordereddict.OrderedDict'])
|
||||
|
||||
|
||||
EMPTY_GIT_REF = '0' * 40 # git sha of all zeros, used during creates/deletes
|
||||
|
||||
MERGER_MERGE = 1 # "git merge"
|
||||
MERGER_MERGE_RESOLVE = 2 # "git merge -s resolve"
|
||||
MERGER_CHERRY_PICK = 3 # "git cherry-pick"
|
||||
@ -1077,7 +1079,8 @@ class BaseFilter(object):
|
||||
class EventFilter(BaseFilter):
|
||||
def __init__(self, trigger, types=[], branches=[], refs=[],
|
||||
event_approvals={}, comments=[], emails=[], usernames=[],
|
||||
timespecs=[], required_approvals=[], pipelines=[]):
|
||||
timespecs=[], required_approvals=[], pipelines=[],
|
||||
ignore_deletes=True):
|
||||
super(EventFilter, self).__init__(
|
||||
required_approvals=required_approvals)
|
||||
self.trigger = trigger
|
||||
@ -1097,6 +1100,7 @@ class EventFilter(BaseFilter):
|
||||
self.pipelines = [re.compile(x) for x in pipelines]
|
||||
self.event_approvals = event_approvals
|
||||
self.timespecs = timespecs
|
||||
self.ignore_deletes = ignore_deletes
|
||||
|
||||
def __repr__(self):
|
||||
ret = '<EventFilter'
|
||||
@ -1109,6 +1113,8 @@ class EventFilter(BaseFilter):
|
||||
ret += ' branches: %s' % ', '.join(self._branches)
|
||||
if self._refs:
|
||||
ret += ' refs: %s' % ', '.join(self._refs)
|
||||
if self.ignore_deletes:
|
||||
ret += ' ignore_deletes: %s' % self.ignore_deletes
|
||||
if self.event_approvals:
|
||||
ret += ' event_approvals: %s' % ', '.join(
|
||||
['%s:%s' % a for a in self.event_approvals.items()])
|
||||
@ -1160,6 +1166,10 @@ class EventFilter(BaseFilter):
|
||||
matches_ref = True
|
||||
if self.refs and not matches_ref:
|
||||
return False
|
||||
if self.ignore_deletes and event.newrev == EMPTY_GIT_REF:
|
||||
# If the updated ref has an empty git sha (all 0s),
|
||||
# then the ref is being deleted
|
||||
return False
|
||||
|
||||
# comments are ORed
|
||||
matches_comment_re = False
|
||||
|
@ -347,6 +347,7 @@ class Scheduler(threading.Thread):
|
||||
usernames = toList(trigger.get('username'))
|
||||
if not usernames:
|
||||
usernames = toList(trigger.get('username_filter'))
|
||||
ignore_deletes = trigger.get('ignore-deletes', True)
|
||||
f = EventFilter(
|
||||
trigger=self.triggers['gerrit'],
|
||||
types=toList(trigger['event']),
|
||||
@ -358,7 +359,8 @@ class Scheduler(threading.Thread):
|
||||
usernames=usernames,
|
||||
required_approvals=toList(
|
||||
trigger.get('require-approval')
|
||||
)
|
||||
),
|
||||
ignore_deletes=ignore_deletes
|
||||
)
|
||||
manager.event_filters.append(f)
|
||||
if 'timer' in conf_pipeline['trigger']:
|
||||
|
Loading…
Reference in New Issue
Block a user