Browse Source

Merge "Report retried builds in a build set via mqtt."

changes/83/703983/7
Zuul 1 year ago
committed by Gerrit Code Review
parent
commit
03d9ea294a
  1. 11
      tests/unit/test_scheduler.py
  2. 21
      zuul/driver/mqtt/mqttreporter.py
  3. 6
      zuul/executor/client.py
  4. 2
      zuul/manager/__init__.py
  5. 23
      zuul/model.py

11
tests/unit/test_scheduler.py

@ -5737,7 +5737,18 @@ For CI problems and help debugging, contact ci@example.org"""
self.executor_server.release('.*-test*')
self.waitUntilSettled()
tenant = self.scheds.first.sched.abide.tenants.get('tenant-one')
items = tenant.layout.pipelines['check'].getAllItems()
build_set = items[0].current_build_set
for x in range(3):
# We should have x+1 retried builds for project-test1
retry_builds = build_set.getRetryBuildsForJob('project-test1')
self.assertEqual(len(retry_builds), x + 1)
for build in retry_builds:
self.assertEqual(build.retry, True)
self.assertEqual(build.result, 'RETRY')
self.assertEqual(len(self.builds), 1,
'len of builds at x=%d is wrong' % x)
self.builds[0].requeue = True

21
zuul/driver/mqtt/mqttreporter.py

@ -48,7 +48,8 @@ class MQTTReporter(BaseReporter):
'buildset': {
'uuid': item.current_build_set.uuid,
'result': item.current_build_set.result,
'builds': []
'builds': [],
'retry_builds': [],
},
'zuul_event_id': item.event.zuul_event_id,
}
@ -70,6 +71,24 @@ class MQTTReporter(BaseReporter):
'result': result,
'dependencies': [j.name for j in job.dependencies],
})
# Report build data of retried builds if available
retry_builds = item.current_build_set.getRetryBuildsForJob(
job.name)
for build in retry_builds:
(result, url) = item.formatJobResult(job, build)
retry_build_information = {
'job_name': job.name,
'voting': job.voting,
'uuid': build.uuid,
'start_time': build.start_time,
'end_time': build.end_time,
'execute_time': build.execute_time,
'log_url': url,
'result': result,
}
message['buildset']['retry_builds'].append(
retry_build_information)
message['buildset']['builds'].append(job_informations)
topic = None
try:

6
zuul/executor/client.py

@ -457,11 +457,9 @@ class ExecutorClient(object):
warnings = data.get('warnings', [])
log.info("Build complete, result %s, warnings %s",
result, warnings)
# If the build should be retried, don't supply the result
# so that elsewhere we don't have to deal with keeping
# track of which results are non-final.
if build.retry:
result = None
result = 'RETRY'
# If the build was canceled, we did actively cancel the job so
# don't overwrite the result and don't retry.

2
zuul/manager/__init__.py

@ -1035,7 +1035,7 @@ class PipelineManager(metaclass=ABCMeta):
self._resumeBuilds(build.build_set)
if (item.project_pipeline_config.fail_fast and
build.failed and build.job.voting):
build.failed and build.job.voting and not build.retry):
# If fail-fast is set and the build is not successful
# cancel all remaining jobs.
log.debug("Build %s failed and fail-fast enabled, canceling "

23
zuul/model.py

@ -1993,6 +1993,7 @@ class BuildSet(object):
def __init__(self, item):
self.item = item
self.builds = {}
self.retry_builds = {}
self.result = None
self.uuid = None
self.commit = None
@ -2053,6 +2054,9 @@ class BuildSet(object):
self.tries[build.job.name] = 1
build.build_set = self
def addRetryBuild(self, build):
self.retry_builds.setdefault(build.job.name, []).append(build)
def removeBuild(self, build):
if build.job.name not in self.builds:
return
@ -2067,6 +2071,9 @@ class BuildSet(object):
keys.sort()
return [self.builds.get(x) for x in keys]
def getRetryBuildsForJob(self, job_name):
return self.retry_builds.get(job_name, [])
def getJobNodeSet(self, job_name: str) -> NodeSet:
# Return None if not provisioned; empty NodeSet if no nodes
# required
@ -2185,6 +2192,9 @@ class QueueItem(object):
def addBuild(self, build):
self.current_build_set.addBuild(build)
def addRetryBuild(self, build):
self.current_build_set.addRetryBuild(build)
def removeBuild(self, build):
self.current_build_set.removeBuild(build)
@ -2641,6 +2651,7 @@ class QueueItem(object):
def setResult(self, build):
if build.retry:
self.addRetryBuild(build)
self.removeBuild(build)
return
@ -2749,16 +2760,17 @@ class QueueItem(object):
return url
def formatJobResult(self, job):
def formatJobResult(self, job, build=None):
if (self.pipeline.tenant.report_build_page and
self.pipeline.tenant.web_root):
build = self.current_build_set.getBuild(job.name)
if build is None:
build = self.current_build_set.getBuild(job.name)
pattern = urllib.parse.urljoin(self.pipeline.tenant.web_root,
'build/{build.uuid}')
url = self.formatUrlPattern(pattern, job, build)
return (build.result, url)
else:
return self.formatProvisionalJobResult(job)
return self.formatProvisionalJobResult(job, build)
def formatStatusUrl(self):
# If we don't have a web root set, we can't format any url
@ -2784,8 +2796,9 @@ class QueueItem(object):
)
return self.formatUrlPattern(pattern)
def formatProvisionalJobResult(self, job):
build = self.current_build_set.getBuild(job.name)
def formatProvisionalJobResult(self, job, build=None):
if build is None:
build = self.current_build_set.getBuild(job.name)
result = build.result
pattern = None
if result == 'SUCCESS':

Loading…
Cancel
Save