
This is a large refactor and as small as I could feasibly make it while keeping the tests working. I'll do the documentation and touch ups in the next commit to make digesting easier. Change-Id: Iac5083996a183d1d8a9b6cb8f70836f7c39ee910
149 lines
5.4 KiB
Python
149 lines
5.4 KiB
Python
# Copyright 2012-2014 Hewlett-Packard Development Company, L.P.
|
|
# Copyright 2013 OpenStack Foundation
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import logging
|
|
import voluptuous as v
|
|
from zuul.model import EventFilter, TriggerEvent
|
|
from zuul.trigger import BaseTrigger
|
|
|
|
|
|
class ZuulTrigger(BaseTrigger):
|
|
name = 'zuul'
|
|
log = logging.getLogger("zuul.ZuulTrigger")
|
|
|
|
def __init__(self, trigger_config={}, sched=None, connection=None):
|
|
super(ZuulTrigger, self).__init__(trigger_config, sched, connection)
|
|
self._handle_parent_change_enqueued_events = False
|
|
self._handle_project_change_merged_events = False
|
|
|
|
def getEventFilters(self, trigger_conf):
|
|
def toList(item):
|
|
if not item:
|
|
return []
|
|
if isinstance(item, list):
|
|
return item
|
|
return [item]
|
|
|
|
efilters = []
|
|
for trigger in toList(trigger_conf):
|
|
f = EventFilter(
|
|
trigger=self,
|
|
types=toList(trigger['event']),
|
|
pipelines=toList(trigger.get('pipeline')),
|
|
required_approvals=(
|
|
toList(trigger.get('require-approval'))
|
|
),
|
|
reject_approvals=toList(
|
|
trigger.get('reject-approval')
|
|
),
|
|
)
|
|
efilters.append(f)
|
|
|
|
return efilters
|
|
|
|
def onChangeMerged(self, change, source):
|
|
# Called each time zuul merges a change
|
|
if self._handle_project_change_merged_events:
|
|
try:
|
|
self._createProjectChangeMergedEvents(change, source)
|
|
except Exception:
|
|
self.log.exception(
|
|
"Unable to create project-change-merged events for "
|
|
"%s" % (change,))
|
|
|
|
def onChangeEnqueued(self, change, pipeline):
|
|
# Called each time a change is enqueued in a pipeline
|
|
if self._handle_parent_change_enqueued_events:
|
|
try:
|
|
self._createParentChangeEnqueuedEvents(change, pipeline)
|
|
except Exception:
|
|
self.log.exception(
|
|
"Unable to create parent-change-enqueued events for "
|
|
"%s in %s" % (change, pipeline))
|
|
|
|
def _createProjectChangeMergedEvents(self, change, source):
|
|
changes = source.getProjectOpenChanges(
|
|
change.project)
|
|
for open_change in changes:
|
|
self._createProjectChangeMergedEvent(open_change)
|
|
|
|
def _createProjectChangeMergedEvent(self, change):
|
|
event = TriggerEvent()
|
|
event.type = 'project-change-merged'
|
|
event.trigger_name = self.name
|
|
event.project_name = change.project.name
|
|
event.change_number = change.number
|
|
event.branch = change.branch
|
|
event.change_url = change.url
|
|
event.patch_number = change.patchset
|
|
event.refspec = change.refspec
|
|
self.sched.addEvent(event)
|
|
|
|
def _createParentChangeEnqueuedEvents(self, change, pipeline):
|
|
self.log.debug("Checking for changes needing %s:" % change)
|
|
if not hasattr(change, 'needed_by_changes'):
|
|
self.log.debug(" Changeish does not support dependencies")
|
|
return
|
|
for needs in change.needed_by_changes:
|
|
self._createParentChangeEnqueuedEvent(needs, pipeline)
|
|
|
|
def _createParentChangeEnqueuedEvent(self, change, pipeline):
|
|
event = TriggerEvent()
|
|
event.type = 'parent-change-enqueued'
|
|
event.trigger_name = self.name
|
|
event.pipeline_name = pipeline.name
|
|
event.project_name = change.project.name
|
|
event.change_number = change.number
|
|
event.branch = change.branch
|
|
event.change_url = change.url
|
|
event.patch_number = change.patchset
|
|
event.refspec = change.refspec
|
|
self.sched.addEvent(event)
|
|
|
|
def postConfig(self):
|
|
self._handle_parent_change_enqueued_events = False
|
|
self._handle_project_change_merged_events = False
|
|
for pipeline in self.sched.layout.pipelines.values():
|
|
for ef in pipeline.manager.event_filters:
|
|
if ef.trigger != self:
|
|
continue
|
|
if 'parent-change-enqueued' in ef._types:
|
|
self._handle_parent_change_enqueued_events = True
|
|
elif 'project-change-merged' in ef._types:
|
|
self._handle_project_change_merged_events = True
|
|
|
|
|
|
def getSchema():
|
|
def toList(x):
|
|
return v.Any([x], x)
|
|
|
|
approval = v.Schema({'username': str,
|
|
'email-filter': str,
|
|
'email': str,
|
|
'older-than': str,
|
|
'newer-than': str,
|
|
}, extra=True)
|
|
|
|
zuul_trigger = {
|
|
v.Required('event'):
|
|
toList(v.Any('parent-change-enqueued',
|
|
'project-change-merged')),
|
|
'pipeline': toList(str),
|
|
'require-approval': toList(approval),
|
|
'reject-approval': toList(approval),
|
|
}
|
|
|
|
return zuul_trigger
|