Handle artifacts on non change types.

It is possible to have artifacts attached to non change types but
previously this resulted in:

  2019-05-15 14:56:57,990 DEBUG zuul.Pipeline.openstack.release: Starting queue processor: release
  2019-05-15 14:56:57,990 DEBUG zuul.Pipeline.openstack.release: Checking for changes needed by <Tag 0x7f315d1816a0 openstack/tripleo-ui creates refs/tags/7.4.10 on 2620fa03c24a0114a144ad01f550f757c59b8d76>:
  2019-05-15 14:56:57,990 DEBUG zuul.Pipeline.openstack.release:   <class 'zuul.model.Tag'> does not support dependencies
  2019-05-15 14:56:57,990 ERROR zuul.Scheduler: Exception in run handler:
  Traceback (most recent call last):
    File "/usr/local/lib/python3.5/dist-packages/zuul/scheduler.py", line 1025, in run
      while (pipeline.manager.processQueue() and
    File "/usr/local/lib/python3.5/dist-packages/zuul/manager/__init__.py", line 787, in processQueue
      item, nnfi)
    File "/usr/local/lib/python3.5/dist-packages/zuul/manager/__init__.py", line 743, in _processOneItem
      if ready and self.executeJobs(item):
    File "/usr/local/lib/python3.5/dist-packages/zuul/manager/__init__.py", line 416, in executeJobs
      item.pipeline.tenant.semaphore_handler)
    File "/usr/local/lib/python3.5/dist-packages/zuul/model.py", line 2439, in findJobsToRun
      job.updateParentData(parent_build)
    File "/usr/local/lib/python3.5/dist-packages/zuul/model.py", line 1432, in updateParentData
      'change': str(change.number),
  AttributeError: 'Tag' object has no attribute 'number'

Improve updateParentData() so that it attached parent data appropriate
for the ref type.

Change-Id: I6f5fc965b2059d04f9880ce69b3ed324f88a4eb0
This commit is contained in:
Clark Boylan 2019-05-15 08:52:43 -07:00
parent 4a0261c9a8
commit d66b504804
5 changed files with 86 additions and 5 deletions

View File

@ -1650,8 +1650,18 @@ class RecordingExecutorServer(zuul.executor.server.ExecutorServer):
:arg dict data: The data to return
"""
# TODO(clarkb) We are incredibly change focused here and in FakeBuild
# above. This makes it very difficult to test non change items with
# return data. We currently rely on the hack that None is used as a
# key for the changes dict, but we should improve that to look up
# refnames or similar.
changes = self.return_data.setdefault(name, {})
cid = ' '.join((str(change.number), str(change.latest_patchset)))
if hasattr(change, 'number'):
cid = ' '.join((str(change.number), str(change.latest_patchset)))
else:
# Not actually a change, but a ref update event for tags/etc
# In this case a key of None is used by writeReturnData
cid = None
changes[cid] = data
def release(self, regex=None):

View File

@ -12,6 +12,14 @@
gerrit:
Verified: -1
- pipeline:
name: tag
manager: independent
trigger:
gerrit:
- event: ref-updated
ref: ^refs/tags/.*$
- job:
name: base
parent: null

View File

@ -13,3 +13,9 @@
- image-user:
dependencies:
- image-builder
tag:
jobs:
- image-builder
- image-user:
dependencies:
- image-builder

View File

@ -5376,6 +5376,51 @@ class TestProvidesRequiresBuildset(ZuulTestCase):
'project': 'org/project1',
'change': '1',
'patchset': '1',
'branch': 'master',
'job': 'image-builder',
'url': 'http://example.com/image',
'name': 'image',
'metadata': {
'type': 'container_image',
}
}])
def test_provides_with_tag_requires_buildset(self):
self.executor_server.hold_jobs_in_build = True
event = self.fake_gerrit.addFakeTag('org/project1', 'master', 'foo')
self.executor_server.returnData(
'image-builder', event,
{'zuul':
{'artifacts': [
{'name': 'image',
'url': 'http://example.com/image',
'metadata': {
'type': 'container_image'
}},
]}}
)
self.fake_gerrit.addEvent(event)
self.waitUntilSettled()
self.assertEqual(len(self.builds), 1)
self.executor_server.hold_jobs_in_build = False
self.executor_server.release()
self.waitUntilSettled()
self.assertHistory([
dict(name='image-builder', result='SUCCESS', ref='refs/tags/foo'),
dict(name='image-user', result='SUCCESS', ref='refs/tags/foo'),
])
build = self.getJobFromHistory('image-user', project='org/project1')
self.assertEqual(
build.parameters['zuul']['artifacts'],
[{
'project': 'org/project1',
'ref': 'refs/tags/foo',
'tag': 'foo',
'oldrev': event['refUpdate']['oldRev'],
'newrev': event['refUpdate']['newRev'],
'job': 'image-builder',
'url': 'http://example.com/image',
'name': 'image',

View File

@ -1427,11 +1427,23 @@ class Job(ConfigObject):
artifact_data = self.artifact_data or []
artifacts = get_artifacts_from_result_data(other_vars)
for a in artifacts:
change = other_build.build_set.item.change
a.update({'project': change.project.name,
'change': str(change.number),
'patchset': change.patchset,
# Change here may be any ref type (tag, change, etc)
ref = other_build.build_set.item.change
a.update({'project': ref.project.name,
'job': other_build.job.name})
# Change is a Branch
if hasattr(ref, 'branch'):
a.update({'branch': ref.branch})
if hasattr(ref, 'number') and hasattr(ref, 'patchset'):
a.update({'change': str(ref.number),
'patchset': ref.patchset})
# Otherwise we are ref type
else:
a.update({'ref': ref.ref,
'oldrev': ref.oldrev,
'newrev': ref.newrev})
if hasattr(ref, 'tag'):
a.update({'tag': ref.tag})
if a not in artifact_data:
artifact_data.append(a)
if artifact_data: