Take parameter order from yaml in trigger_parameterized_builds

Support taking the order of the parameters to be passed through to a
triggered parameterized build from the user defined yaml via config
option. Use the existing order by default so as not to break current
usage.

The XML ordering of the parameters matters since when the same parameter
is defined through multiple sources, Jenkins uses the ordering to
determine which will be the one that that should win.

ie if FOO=BAR is set as a build parameter of the current job and a
properties file is generated during build that attempts to set FOO=BAZ;
the XML ordering determines which value, BAZ or BAR, that the triggered
job sees for the parameter FOO.

Change-Id: Ia0dafad8ed3976e7b0b11feb6b3af844bbda9d4a
This commit is contained in:
Darragh Bailey 2015-06-19 18:30:47 +01:00 committed by Darragh Bailey
parent 82dd7fd4c4
commit 3e8c31fe94
12 changed files with 465 additions and 33 deletions

View File

@ -114,6 +114,20 @@ stash section
yaml part.
__future__ section
^^^^^^^^^^^^^^^^^^
This section is to control enabling of beta features or behaviour changes that
deviate from previously released behaviour in ways that may require effort to
convert existing JJB configs to adopt. This essentially will act as a method
to share these new behaviours while under active development so they can be
changed ahead of releases.
**param_order_from_yaml**
Used to switch on using the order of the parameters are defined in yaml to
control the order of corresponding XML elements being written out. This is
intended as a global flag and can affect multiple modules.
Running
-------

View File

@ -50,6 +50,9 @@ query_plugins_info=True
[hipchat]
authtoken=dummy
send-as=Jenkins
[__future__]
param_order_from_yaml=False
"""

View File

@ -391,36 +391,67 @@ def trigger_parameterized_builds(parser, xml_parent, data):
/../../tests/publishers/fixtures/trigger_parameterized_builds003.yaml
:language: yaml
"""
logger = logging.getLogger("%s:trigger-parameterized-builds" % __name__)
pt_prefix = 'hudson.plugins.parameterizedtrigger.'
tbuilder = XML.SubElement(xml_parent, pt_prefix + 'BuildTrigger')
configs = XML.SubElement(tbuilder, 'configs')
# original order
orig_order = [
'predefined-parameters',
'git-revision',
'property-file',
'current-parameters',
'node-parameters',
'svn-revision',
'restrict-matrix-project',
'node-label-name',
'node-label',
'boolean-parameters',
]
try:
if parser.config.getboolean('__future__',
'param_order_from_yaml'):
orig_order = None
except six.moves.configparser.NoSectionError:
pass
if orig_order:
logger.warn(
"Using deprecated order for parameter sets in "
"triggered-parameterized-builds. This will be changed in a future "
"release to inherit the order from the user defined yaml. To "
"enable this behaviour immediately, set the config option "
"'__future__.param_order_from_yaml' to 'true' and change the "
"input job configuration to use the desired order")
for project_def in data:
tconfig = XML.SubElement(configs, pt_prefix + 'BuildTriggerConfig')
tconfigs = XML.SubElement(tconfig, 'configs')
if ('predefined-parameters' in project_def
or 'git-revision' in project_def
or 'property-file' in project_def
or 'current-parameters' in project_def
or 'node-parameters' in project_def
or 'svn-revision' in project_def
or 'restrict-matrix-project' in project_def
or 'node-label-name' in project_def
or 'node-label' in project_def
or 'boolean-parameters' in project_def):
if 'predefined-parameters' in project_def:
if orig_order:
parameters = orig_order
else:
parameters = project_def.keys()
for param_type in parameters:
param_value = project_def.get(param_type)
if param_value is None:
continue
if param_type == 'predefined-parameters':
params = XML.SubElement(tconfigs, pt_prefix +
'PredefinedBuildParameters')
properties = XML.SubElement(params, 'properties')
properties.text = project_def['predefined-parameters']
if 'git-revision' in project_def and project_def['git-revision']:
properties.text = param_value
elif param_type == 'git-revision' and param_value:
params = XML.SubElement(tconfigs,
'hudson.plugins.git.'
'GitRevisionBuildParameters')
XML.SubElement(params, 'combineQueuedCommits').text = str(
project_def.get('combine-queued-commits', False)).lower()
if 'property-file' in project_def and project_def['property-file']:
elif param_type == 'property-file':
params = XML.SubElement(tconfigs,
pt_prefix + 'FileBuildParameters')
properties = XML.SubElement(params, 'propertiesFile')
@ -442,50 +473,50 @@ def trigger_parameterized_builds(parser, xml_parent, data):
XML.SubElement(params, "onlyExactRuns").text = (
str(project_def.get('only-exact-matrix-child-runs',
False)).lower())
if ('current-parameters' in project_def
and project_def['current-parameters']):
elif param_type == 'current-parameters' and param_value:
XML.SubElement(tconfigs, pt_prefix + 'CurrentBuildParameters')
if ('node-parameters' in project_def
and project_def['node-parameters']):
elif param_type == 'node-parameters' and param_value:
XML.SubElement(tconfigs, pt_prefix + 'NodeParameters')
if 'svn-revision' in project_def and project_def['svn-revision']:
elif param_type == 'svn-revision' and param_value:
param = XML.SubElement(tconfigs, pt_prefix +
'SubversionRevisionBuildParameters')
XML.SubElement(param, 'includeUpstreamParameters').text = str(
project_def.get('include-upstream', False)).lower()
if ('restrict-matrix-project' in project_def
and project_def['restrict-matrix-project']):
elif param_type == 'restrict-matrix-project' and param_value:
subset = XML.SubElement(tconfigs, pt_prefix +
'matrix.MatrixSubsetBuildParameters')
XML.SubElement(subset, 'filter').text = \
project_def['restrict-matrix-project']
if ('node-label-name' in project_def or
'node-label' in project_def):
params = XML.SubElement(tconfigs,
'org.jvnet.jenkins.plugins.'
'nodelabelparameter.'
'parameterizedtrigger.'
'NodeLabelBuildParameter')
elif (param_type == 'node-label-name' or
param_type == 'node-label'):
tag_name = ('org.jvnet.jenkins.plugins.nodelabelparameter.'
'parameterizedtrigger.NodeLabelBuildParameter')
if tconfigs.find(tag_name) is not None:
# already processed and can only have one
continue
params = XML.SubElement(tconfigs, tag_name)
name = XML.SubElement(params, 'name')
if 'node-label-name' in project_def:
name.text = project_def['node-label-name']
label = XML.SubElement(params, 'nodeLabel')
if 'node-label' in project_def:
label.text = project_def['node-label']
if ('boolean-parameters' in project_def
and project_def['boolean-parameters']):
elif param_type == 'boolean-parameters' and param_value:
params = XML.SubElement(tconfigs,
pt_prefix + 'BooleanParameters')
config_tag = XML.SubElement(params, 'configs')
param_tag_text = pt_prefix + 'BooleanParameterConfig'
params_list = project_def['boolean-parameters']
params_list = param_value
for name, value in params_list.items():
param_tag = XML.SubElement(config_tag, param_tag_text)
XML.SubElement(param_tag, 'name').text = name
XML.SubElement(param_tag, 'value').text = str(
value or False).lower()
else:
if not list(tconfigs):
# not child parameter tags added
tconfigs.set('class', 'java.util.Collections$EmptyList')
projects = XML.SubElement(tconfig, 'projects')
if isinstance(project_def['project'], list):

View File

@ -0,0 +1,2 @@
[__future__]
param_order_from_yaml = True

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<project>
<publishers>
<hudson.plugins.parameterizedtrigger.BuildTrigger>
<configs>
<hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
<configs>
<hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<properties>BUILD_NUM=${BUILD_NUMBER}</properties>
</hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<hudson.plugins.parameterizedtrigger.FileBuildParameters>
<propertiesFile>version.prop</propertiesFile>
<failTriggerOnMissing>false</failTriggerOnMissing>
</hudson.plugins.parameterizedtrigger.FileBuildParameters>
<hudson.plugins.parameterizedtrigger.CurrentBuildParameters/>
</configs>
<projects>another_job</projects>
<condition>ALWAYS</condition>
<triggerWithNoParameters>false</triggerWithNoParameters>
</hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
<hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
<configs>
<hudson.plugins.parameterizedtrigger.CurrentBuildParameters/>
<hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<properties>foo=bar</properties>
</hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<hudson.plugins.parameterizedtrigger.FileBuildParameters>
<propertiesFile>version.prop</propertiesFile>
<failTriggerOnMissing>false</failTriggerOnMissing>
</hudson.plugins.parameterizedtrigger.FileBuildParameters>
</configs>
<projects>yet_another_job</projects>
<condition>ALWAYS</condition>
<triggerWithNoParameters>false</triggerWithNoParameters>
</hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
</configs>
</hudson.plugins.parameterizedtrigger.BuildTrigger>
</publishers>
</project>

View File

@ -0,0 +1,10 @@
publishers:
- trigger-parameterized-builds:
- project: another_job
predefined-parameters: BUILD_NUM=${BUILD_NUMBER}
property-file: version.prop
current-parameters: true
- project: yet_another_job
current-parameters: true
predefined-parameters: foo=bar
property-file: version.prop

View File

@ -0,0 +1,2 @@
[__future__]
param_order_from_yaml = True

View File

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<project>
<actions/>
<description>testing macro trigger-parameterized-builds order v1.0&lt;!-- Managed by Jenkins Job Builder --&gt;</description>
<keepDependencies>false</keepDependencies>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<concurrentBuild>false</concurrentBuild>
<canRoam>true</canRoam>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<builders>
<hudson.tasks.Shell>
<command>#!/usr/bin/env python
#
print(&quot;Doing something cool with python&quot;)
</command>
</hudson.tasks.Shell>
</builders>
<publishers>
<hudson.plugins.parameterizedtrigger.BuildTrigger>
<configs>
<hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
<configs>
<hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<properties>BUILD_NUM=${BUILD_NUMBER}</properties>
</hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<hudson.plugins.parameterizedtrigger.FileBuildParameters>
<propertiesFile>default_version.prop</propertiesFile>
<failTriggerOnMissing>false</failTriggerOnMissing>
</hudson.plugins.parameterizedtrigger.FileBuildParameters>
<hudson.plugins.parameterizedtrigger.CurrentBuildParameters/>
</configs>
<projects>default_job</projects>
<condition>ALWAYS</condition>
<triggerWithNoParameters>false</triggerWithNoParameters>
</hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
</configs>
</hudson.plugins.parameterizedtrigger.BuildTrigger>
<hudson.plugins.parameterizedtrigger.BuildTrigger>
<configs>
<hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
<configs>
<hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<properties>BUILD_NUM=${BUILD_NUMBER}</properties>
</hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<hudson.plugins.parameterizedtrigger.FileBuildParameters>
<propertiesFile>default_version.prop</propertiesFile>
<failTriggerOnMissing>false</failTriggerOnMissing>
</hudson.plugins.parameterizedtrigger.FileBuildParameters>
<hudson.plugins.parameterizedtrigger.CurrentBuildParameters/>
</configs>
<projects>first_job</projects>
<condition>ALWAYS</condition>
<triggerWithNoParameters>false</triggerWithNoParameters>
</hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
<hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
<configs>
<hudson.plugins.parameterizedtrigger.CurrentBuildParameters/>
<hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<properties>foo=bar</properties>
</hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<hudson.plugins.parameterizedtrigger.FileBuildParameters>
<propertiesFile>version.prop</propertiesFile>
<failTriggerOnMissing>false</failTriggerOnMissing>
</hudson.plugins.parameterizedtrigger.FileBuildParameters>
</configs>
<projects>second_job</projects>
<condition>ALWAYS</condition>
<triggerWithNoParameters>false</triggerWithNoParameters>
</hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
</configs>
</hudson.plugins.parameterizedtrigger.BuildTrigger>
</publishers>
<buildWrappers/>
</project>
<?xml version="1.0" encoding="utf-8"?>
<project>
<actions/>
<description>testing macro trigger-parameterized-builds order v1.2&lt;!-- Managed by Jenkins Job Builder --&gt;</description>
<keepDependencies>false</keepDependencies>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<concurrentBuild>false</concurrentBuild>
<canRoam>true</canRoam>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<builders>
<hudson.tasks.Shell>
<command>#!/usr/bin/env python
#
print(&quot;Doing something cool with python&quot;)
</command>
</hudson.tasks.Shell>
</builders>
<publishers>
<hudson.plugins.parameterizedtrigger.BuildTrigger>
<configs>
<hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
<configs>
<hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<properties>BUILD_NUM=${BUILD_NUMBER}</properties>
</hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<hudson.plugins.parameterizedtrigger.FileBuildParameters>
<propertiesFile>default_version.prop</propertiesFile>
<failTriggerOnMissing>false</failTriggerOnMissing>
</hudson.plugins.parameterizedtrigger.FileBuildParameters>
<hudson.plugins.parameterizedtrigger.CurrentBuildParameters/>
</configs>
<projects>default_job</projects>
<condition>ALWAYS</condition>
<triggerWithNoParameters>false</triggerWithNoParameters>
</hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
</configs>
</hudson.plugins.parameterizedtrigger.BuildTrigger>
<hudson.plugins.parameterizedtrigger.BuildTrigger>
<configs>
<hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
<configs>
<hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<properties>BUILD_NUM=${BUILD_NUMBER}</properties>
</hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<hudson.plugins.parameterizedtrigger.CurrentBuildParameters/>
<hudson.plugins.parameterizedtrigger.FileBuildParameters>
<propertiesFile>version.prop</propertiesFile>
<failTriggerOnMissing>false</failTriggerOnMissing>
</hudson.plugins.parameterizedtrigger.FileBuildParameters>
</configs>
<projects>1.2_first_job</projects>
<condition>ALWAYS</condition>
<triggerWithNoParameters>false</triggerWithNoParameters>
</hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
<hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
<configs>
<hudson.plugins.parameterizedtrigger.CurrentBuildParameters/>
<hudson.plugins.parameterizedtrigger.FileBuildParameters>
<propertiesFile>1.2_version.prop</propertiesFile>
<failTriggerOnMissing>false</failTriggerOnMissing>
</hudson.plugins.parameterizedtrigger.FileBuildParameters>
<hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<properties>foo=bar</properties>
</hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
</configs>
<projects>1.2_second_job</projects>
<condition>ALWAYS</condition>
<triggerWithNoParameters>false</triggerWithNoParameters>
</hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
</configs>
</hudson.plugins.parameterizedtrigger.BuildTrigger>
</publishers>
<buildWrappers/>
</project>

View File

@ -0,0 +1,58 @@
- wrapper:
name: timeout-wrapper
wrappers:
- timeout:
fail: true
elastic-percentage: 150
elastic-default-timeout: 90
type: elastic
- publisher:
name: trigger_parameterized_1.0
publishers:
- trigger-parameterized-builds:
- project: first_job
predefined-parameters: BUILD_NUM=${BUILD_NUMBER}
property-file: default_version.prop
current-parameters: true
- project: second_job
current-parameters: true
predefined-parameters: foo=bar
property-file: version.prop
- publisher:
name: trigger_parameterized_1.2
publishers:
- trigger-parameterized-builds:
- project: 1.2_first_job
predefined-parameters: BUILD_NUM=${BUILD_NUMBER}
current-parameters: true
property-file: version.prop
- project: 1.2_second_job
current-parameters: true
property-file: 1.2_version.prop
predefined-parameters: foo=bar
- job-template:
name: 'trigger_parameterized_{version}'
description: testing macro trigger-parameterized-builds order v{version}
builders:
- shell: |
#!/usr/bin/env python
#
print("Doing something cool with python")
publishers:
- trigger-parameterized-builds:
- project: default_job
predefined-parameters: BUILD_NUM=${{BUILD_NUMBER}}
property-file: default_version.prop
current-parameters: true
- trigger_parameterized_{version}
- project:
name: complete_trigger_paramterized
version:
- 1.0
- 1.2
jobs:
- 'trigger_parameterized_{version}'

View File

@ -0,0 +1,2 @@
[__future__]
param_order_from_yaml = True

View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<project>
<actions/>
<description>&lt;!-- Managed by Jenkins Job Builder --&gt;</description>
<keepDependencies>false</keepDependencies>
<displayName>JJB Test1</displayName>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<concurrentBuild>false</concurrentBuild>
<canRoam>true</canRoam>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<builders/>
<publishers>
<hudson.plugins.parameterizedtrigger.BuildTrigger>
<configs>
<hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
<configs>
<hudson.plugins.parameterizedtrigger.CurrentBuildParameters/>
<hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<properties/>
</hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<hudson.plugins.parameterizedtrigger.FileBuildParameters>
<propertiesFile/>
<failTriggerOnMissing>false</failTriggerOnMissing>
</hudson.plugins.parameterizedtrigger.FileBuildParameters>
<hudson.plugins.git.GitRevisionBuildParameters>
<combineQueuedCommits>false</combineQueuedCommits>
</hudson.plugins.git.GitRevisionBuildParameters>
</configs>
<projects/>
<condition>UNSTABLE_OR_BETTER</condition>
<triggerWithNoParameters>false</triggerWithNoParameters>
</hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
</configs>
</hudson.plugins.parameterizedtrigger.BuildTrigger>
</publishers>
<buildWrappers/>
</project>
<BLANKLINE>
<?xml version="1.0" encoding="utf-8"?>
<project>
<actions/>
<description>&lt;!-- Managed by Jenkins Job Builder --&gt;</description>
<keepDependencies>false</keepDependencies>
<displayName>JJB Test2</displayName>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<concurrentBuild>false</concurrentBuild>
<canRoam>true</canRoam>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<builders/>
<publishers>
<hudson.plugins.parameterizedtrigger.BuildTrigger>
<configs>
<hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
<configs>
<hudson.plugins.parameterizedtrigger.FileBuildParameters>
<propertiesFile/>
<failTriggerOnMissing>false</failTriggerOnMissing>
</hudson.plugins.parameterizedtrigger.FileBuildParameters>
<hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<properties/>
</hudson.plugins.parameterizedtrigger.PredefinedBuildParameters>
<hudson.plugins.parameterizedtrigger.CurrentBuildParameters/>
<hudson.plugins.git.GitRevisionBuildParameters>
<combineQueuedCommits>false</combineQueuedCommits>
</hudson.plugins.git.GitRevisionBuildParameters>
</configs>
<projects/>
<condition>UNSTABLE_OR_BETTER</condition>
<triggerWithNoParameters>false</triggerWithNoParameters>
</hudson.plugins.parameterizedtrigger.BuildTriggerConfig>
</configs>
</hudson.plugins.parameterizedtrigger.BuildTrigger>
</publishers>
<buildWrappers/>
</project>

View File

@ -0,0 +1,39 @@
- project:
name: bogus-jankerator
jobs:
- 'hydra_{name}_jjb-test1'
- 'hydra_{name}_jjb-test2'
- job-template:
name: 'hydra_{name}_jjb-test1'
display-name: 'JJB Test1'
publishers:
- trigger-parameterized-builds:
- project: '{obj:tpb_projects}'
current-parameters: '{obj:tpb_current_parameters}'
predefined-parameters: '{obj:tpb_predefined_parameters}'
condition: '{obj:tpb_condition}'
property-file: '{obj:tpb_property_file}'
git-revision: '{obj:tpb_git_revision}'
- job-template:
name: 'hydra_{name}_jjb-test2'
display-name: 'JJB Test2'
publishers:
- trigger-parameterized-builds:
- project: '{obj:tpb_projects}'
property-file: '{obj:tpb_property_file}'
predefined-parameters: '{obj:tpb_predefined_parameters}'
current-parameters: '{obj:tpb_current_parameters}'
condition: '{obj:tpb_condition}'
git-revision: '{obj:tpb_git_revision}'
- defaults:
name: global
tpb_predefined_parameters: ''
tpb_property_file: ''
tpb_current_parameters: True
tpb_condition: 'UNSTABLE_OR_BETTER'
tpb_git_revision: True
tpb_projects: ''