Enable job-specific substitutions in a project's job list.
The motivation for this was to allow for specifying a pipeline of jobs at the project level, thereby re-using the same job templates in different pipelines. Change-Id: I9840d3713669ceca75a831be92c95c3fe9195c01
This commit is contained in:
parent
7dd198eff8
commit
67016c3452
|
@ -90,6 +90,17 @@ template. Any job templates listed under ``jobs:`` will be realized
|
||||||
with those values. The example above would create the job called
|
with those values. The example above would create the job called
|
||||||
'project-name-unit-tests' in Jenkins.
|
'project-name-unit-tests' in Jenkins.
|
||||||
|
|
||||||
|
The ``jobs:`` list can also allow for specifying job-specific
|
||||||
|
substitutions as follows::
|
||||||
|
|
||||||
|
- project:
|
||||||
|
name: project-name
|
||||||
|
jobs:
|
||||||
|
- {name}-unit-tests:
|
||||||
|
mail-to: developer@nowhere.net
|
||||||
|
- {name}-perf-tests:
|
||||||
|
mail-to: projmanager@nowhere.net
|
||||||
|
|
||||||
Job Group
|
Job Group
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,28 @@ import logging
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def deep_format(obj, paramdict):
|
||||||
|
"""Apply the paramdict via str.format() to all string objects found within
|
||||||
|
the supplied obj. Lists and dicts are traversed recursively."""
|
||||||
|
# YAML serialisation was originally used to achieve this, but that places
|
||||||
|
# limitations on the values in paramdict - the post-format result must
|
||||||
|
# still be valid YAML (so substituting-in a string containing quotes, for
|
||||||
|
# example, is problematic).
|
||||||
|
if isinstance(obj, str):
|
||||||
|
ret = obj.format(**paramdict)
|
||||||
|
elif isinstance(obj, list):
|
||||||
|
ret = []
|
||||||
|
for item in obj:
|
||||||
|
ret.append(deep_format(item, paramdict))
|
||||||
|
elif isinstance(obj, dict):
|
||||||
|
ret = {}
|
||||||
|
for item in obj:
|
||||||
|
ret[item] = deep_format(obj[item], paramdict)
|
||||||
|
else:
|
||||||
|
ret = obj
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
class YamlParser(object):
|
class YamlParser(object):
|
||||||
def __init__(self, config=None):
|
def __init__(self, config=None):
|
||||||
self.registry = ModuleRegistry(config)
|
self.registry = ModuleRegistry(config)
|
||||||
|
@ -81,7 +103,13 @@ class YamlParser(object):
|
||||||
self.getXMLForJob(job)
|
self.getXMLForJob(job)
|
||||||
for project in self.data.get('project', {}).values():
|
for project in self.data.get('project', {}).values():
|
||||||
logger.debug("XMLifying project '{0}'".format(project['name']))
|
logger.debug("XMLifying project '{0}'".format(project['name']))
|
||||||
for jobname in project.get('jobs', []):
|
for jobspec in project.get('jobs', []):
|
||||||
|
if isinstance(jobspec, dict):
|
||||||
|
# Singleton dict containing dict of job-specific params
|
||||||
|
jobname, jobparams = jobspec.items()[0]
|
||||||
|
else:
|
||||||
|
jobname = jobspec
|
||||||
|
jobparams = {}
|
||||||
job = self.getJob(jobname)
|
job = self.getJob(jobname)
|
||||||
if job:
|
if job:
|
||||||
# Just naming an existing defined job
|
# Just naming an existing defined job
|
||||||
|
@ -106,13 +134,15 @@ class YamlParser(object):
|
||||||
# see if it's a template
|
# see if it's a template
|
||||||
template = self.getJobTemplate(jobname)
|
template = self.getJobTemplate(jobname)
|
||||||
if template:
|
if template:
|
||||||
self.getXMLForTemplateJob(project, template)
|
params = dict(project)
|
||||||
|
params.update(deep_format(jobparams, project))
|
||||||
|
logger.debug("Generating XML for template job {0}"
|
||||||
|
" (params {1})".format(
|
||||||
|
template['name'], params))
|
||||||
|
self.getXMLForTemplateJob(params, template)
|
||||||
|
|
||||||
def getXMLForTemplateJob(self, project, template):
|
def getXMLForTemplateJob(self, project, template):
|
||||||
s = yaml.dump(template, default_flow_style=False)
|
self.getXMLForJob(deep_format(template, project))
|
||||||
s = s.format(**project)
|
|
||||||
data = yaml.load(s)
|
|
||||||
self.getXMLForJob(data)
|
|
||||||
|
|
||||||
def getXMLForJob(self, data):
|
def getXMLForJob(self, data):
|
||||||
kind = data.get('project-type', 'freestyle')
|
kind = data.get('project-type', 'freestyle')
|
||||||
|
|
Loading…
Reference in New Issue