Added flexible publish support
Added support for the Flexible Publish plugin to the JJB publishers. Updated documentation and unit tests as well. Change-Id: Id72a4b01f451ae2613b24347afb6493bf7641cd1
This commit is contained in:
parent
45644bf8e5
commit
3066e73811
@ -3729,6 +3729,205 @@ def pmd(parser, xml_parent, data):
|
||||
build_trends_publisher('[PMD] ', xml_element, data)
|
||||
|
||||
|
||||
def create_publishers(parser, action):
|
||||
dummy_parent = XML.Element("dummy")
|
||||
parser.registry.dispatch('publisher', parser, dummy_parent, action)
|
||||
return list(dummy_parent)
|
||||
|
||||
|
||||
def conditional_publisher(parser, xml_parent, data):
|
||||
"""yaml: conditional-publisher
|
||||
Conditionally execute some post-build steps. Requires the Jenkins
|
||||
`Flexible Publish Plugin <https://wiki.jenkins-ci.org/display/ \
|
||||
JENKINS/Flexible+Publish+Plugin>`_.
|
||||
|
||||
A Flexible Publish list of Conditional Actions is created in Jenkins.
|
||||
|
||||
:arg str condition-kind: Condition kind that must be verified before the
|
||||
action is executed. Valid values and their additional attributes are
|
||||
described in the conditions_ table.
|
||||
:arg str on-evaluation-failure: What should be the outcome of the build
|
||||
if the evaluation of the condition fails. Possible values are `fail`,
|
||||
`mark-unstable`, `run-and-mark-unstable`, `run` and `dont-run`.
|
||||
Default is `fail`.
|
||||
:arg list action: Action to run if the condition is verified. Item
|
||||
can be any publisher known by Jenkins Job Builder and supported
|
||||
by the Flexible Publish Plugin.
|
||||
|
||||
.. _conditions:
|
||||
|
||||
================== ====================================================
|
||||
Condition kind Description
|
||||
================== ====================================================
|
||||
always Condition is always verified
|
||||
never Condition is never verified
|
||||
boolean-expression Run the action if the expression expands to a
|
||||
representation of true
|
||||
|
||||
:condition-expression: Expression to expand
|
||||
current-status Run the action if the current build status is
|
||||
within the configured range
|
||||
|
||||
:condition-worst: Accepted values are SUCCESS,
|
||||
UNSTABLE, FAILURE, NOT_BUILD, ABORTED
|
||||
:condition-best: Accepted values are SUCCESS,
|
||||
UNSTABLE, FAILURE, NOT_BUILD, ABORTED
|
||||
|
||||
shell Run the action if the shell command succeeds
|
||||
|
||||
:condition-command: Shell command to execute
|
||||
windows-shell Similar to shell, except that commands will be
|
||||
executed by cmd, under Windows
|
||||
|
||||
:condition-command: Command to execute
|
||||
file-exists Run the action if a file exists
|
||||
|
||||
:condition-filename: Check existence of this file
|
||||
:condition-basedir: If condition-filename is
|
||||
relative, it will be considered relative to
|
||||
either `workspace`, `artifact-directory`,
|
||||
or `jenkins-home`. Default is `workspace`.
|
||||
================== ====================================================
|
||||
|
||||
Single Conditional Action Example:
|
||||
|
||||
.. literalinclude:: \
|
||||
/../../tests/publishers/fixtures/conditional-publisher001.yaml
|
||||
:language: yaml
|
||||
|
||||
Multiple Conditional Actions Example:
|
||||
|
||||
.. literalinclude:: \
|
||||
/../../tests/publishers/fixtures/conditional-publisher002.yaml
|
||||
:language: yaml
|
||||
|
||||
"""
|
||||
def publish_condition(cdata):
|
||||
kind = cdata['condition-kind']
|
||||
ctag = XML.SubElement(cond_publisher, condition_tag)
|
||||
class_pkg = 'org.jenkins_ci.plugins.run_condition'
|
||||
|
||||
if kind == "always":
|
||||
ctag.set('class',
|
||||
class_pkg + '.core.AlwaysRun')
|
||||
elif kind == "never":
|
||||
ctag.set('class',
|
||||
class_pkg + '.core.NeverRun')
|
||||
elif kind == "boolean-expression":
|
||||
ctag.set('class',
|
||||
class_pkg + '.core.BooleanCondition')
|
||||
XML.SubElement(ctag, "token").text = cdata['condition-expression']
|
||||
elif kind == "current-status":
|
||||
ctag.set('class',
|
||||
class_pkg + '.core.StatusCondition')
|
||||
wr = XML.SubElement(ctag, 'worstResult')
|
||||
wr_name = cdata['condition-worst']
|
||||
if wr_name not in hudson_model.THRESHOLDS:
|
||||
raise JenkinsJobsException(
|
||||
"threshold must be one of %s" %
|
||||
", ".join(hudson_model.THRESHOLDS.keys()))
|
||||
wr_threshold = hudson_model.THRESHOLDS[wr_name]
|
||||
XML.SubElement(wr, "name").text = wr_threshold['name']
|
||||
XML.SubElement(wr, "ordinal").text = wr_threshold['ordinal']
|
||||
XML.SubElement(wr, "color").text = wr_threshold['color']
|
||||
XML.SubElement(wr, "completeBuild").text = \
|
||||
str(wr_threshold['complete']).lower()
|
||||
|
||||
br = XML.SubElement(ctag, 'bestResult')
|
||||
br_name = cdata['condition-best']
|
||||
if not br_name in hudson_model.THRESHOLDS:
|
||||
raise JenkinsJobsException(
|
||||
"threshold must be one of %s" %
|
||||
", ".join(hudson_model.THRESHOLDS.keys()))
|
||||
br_threshold = hudson_model.THRESHOLDS[br_name]
|
||||
XML.SubElement(br, "name").text = br_threshold['name']
|
||||
XML.SubElement(br, "ordinal").text = br_threshold['ordinal']
|
||||
XML.SubElement(br, "color").text = br_threshold['color']
|
||||
XML.SubElement(br, "completeBuild").text = \
|
||||
str(wr_threshold['complete']).lower()
|
||||
elif kind == "shell":
|
||||
ctag.set('class',
|
||||
class_pkg + '.contributed.ShellCondition')
|
||||
XML.SubElement(ctag, "command").text = cdata['condition-command']
|
||||
elif kind == "windows-shell":
|
||||
ctag.set('class',
|
||||
class_pkg + '.contributed.BatchFileCondition')
|
||||
XML.SubElement(ctag, "command").text = cdata['condition-command']
|
||||
elif kind == "file-exists":
|
||||
ctag.set('class',
|
||||
class_pkg + '.core.FileExistsCondition')
|
||||
XML.SubElement(ctag, "file").text = cdata['condition-filename']
|
||||
basedir = cdata.get('condition-basedir', 'workspace')
|
||||
basedir_tag = XML.SubElement(ctag, "baseDir")
|
||||
if "workspace" == basedir:
|
||||
basedir_tag.set('class',
|
||||
class_pkg + '.common.BaseDirectory$Workspace')
|
||||
elif "artifact-directory" == basedir:
|
||||
basedir_tag.set('class',
|
||||
class_pkg + '.common.'
|
||||
'BaseDirectory$ArtifactsDir')
|
||||
elif "jenkins-home" == basedir:
|
||||
basedir_tag.set('class',
|
||||
class_pkg + '.common.'
|
||||
'BaseDirectory$JenkinsHome')
|
||||
else:
|
||||
raise JenkinsJobsException('%s is not a valid condition-kind '
|
||||
'value.' % kind)
|
||||
|
||||
def publish_action(parent, action):
|
||||
for edited_node in create_publishers(parser, action):
|
||||
edited_node.set('class', edited_node.tag)
|
||||
edited_node.tag = 'publisher'
|
||||
parent.append(edited_node)
|
||||
|
||||
flex_publisher_tag = 'org.jenkins__ci.plugins.flexible__publish.' \
|
||||
'FlexiblePublisher'
|
||||
cond_publisher_tag = 'org.jenkins__ci.plugins.flexible__publish.' \
|
||||
'ConditionalPublisher'
|
||||
|
||||
root_tag = XML.SubElement(xml_parent, flex_publisher_tag)
|
||||
publishers_tag = XML.SubElement(root_tag, "publishers")
|
||||
condition_tag = "condition"
|
||||
|
||||
evaluation_classes_pkg = 'org.jenkins_ci.plugins.run_condition'
|
||||
evaluation_classes = {
|
||||
'fail': evaluation_classes_pkg + '.BuildStepRunner$Fail',
|
||||
'mark-unstable': evaluation_classes_pkg +
|
||||
'.BuildStepRunner$Unstable',
|
||||
'run-and-mark-unstable': evaluation_classes_pkg +
|
||||
'.BuildStepRunner$RunUnstable',
|
||||
'run': evaluation_classes_pkg + '.BuildStepRunner$Run',
|
||||
'dont-run': evaluation_classes_pkg + '.BuildStepRunner$DontRun',
|
||||
}
|
||||
|
||||
for cond_action in data:
|
||||
cond_publisher = XML.SubElement(publishers_tag, cond_publisher_tag)
|
||||
publish_condition(cond_action)
|
||||
evaluation_flag = cond_action.get('on-evaluation-failure', 'fail')
|
||||
if evaluation_flag not in evaluation_classes.keys():
|
||||
raise JenkinsJobsException('on-evaluation-failure value '
|
||||
'specified is not valid. Must be one '
|
||||
'of: %s' % evaluation_classes.keys())
|
||||
|
||||
evaluation_class = evaluation_classes[evaluation_flag]
|
||||
XML.SubElement(cond_publisher, "runner").set('class',
|
||||
evaluation_class)
|
||||
|
||||
if 'action' in cond_action:
|
||||
actions = cond_action['action']
|
||||
|
||||
# Flexible Publish will overwrite action if more than one is
|
||||
# specified. Limit the action list to one element.
|
||||
if len(actions) is not 1:
|
||||
raise JenkinsJobsException("Only one action may be "
|
||||
"specified for each condition.")
|
||||
|
||||
for action in actions:
|
||||
publish_action(cond_publisher, action)
|
||||
else:
|
||||
raise JenkinsJobsException('action must be set for each condition')
|
||||
|
||||
|
||||
class Publishers(jenkins_jobs.modules.base.Base):
|
||||
sequence = 70
|
||||
|
||||
|
@ -119,6 +119,7 @@ jenkins_jobs.publishers =
|
||||
clone-workspace=jenkins_jobs.modules.publishers:clone_workspace
|
||||
cloverphp=jenkins_jobs.modules.publishers:cloverphp
|
||||
cobertura=jenkins_jobs.modules.publishers:cobertura
|
||||
conditional-publisher=jenkins_jobs.modules.publishers:conditional_publisher
|
||||
copy-to-master=jenkins_jobs.modules.publishers:copy_to_master
|
||||
coverage=jenkins_jobs.modules.publishers:coverage
|
||||
cppcheck=jenkins_jobs.modules.publishers:cppcheck
|
||||
|
31
tests/publishers/fixtures/conditional-publisher001.xml
Normal file
31
tests/publishers/fixtures/conditional-publisher001.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project>
|
||||
<publishers>
|
||||
<org.jenkins__ci.plugins.flexible__publish.FlexiblePublisher>
|
||||
<publishers>
|
||||
<org.jenkins__ci.plugins.flexible__publish.ConditionalPublisher>
|
||||
<condition class="org.jenkins_ci.plugins.run_condition.core.StatusCondition">
|
||||
<worstResult>
|
||||
<name>FAILURE</name>
|
||||
<ordinal>2</ordinal>
|
||||
<color>RED</color>
|
||||
<completeBuild>true</completeBuild>
|
||||
</worstResult>
|
||||
<bestResult>
|
||||
<name>SUCCESS</name>
|
||||
<ordinal>0</ordinal>
|
||||
<color>BLUE</color>
|
||||
<completeBuild>true</completeBuild>
|
||||
</bestResult>
|
||||
</condition>
|
||||
<runner class="org.jenkins_ci.plugins.run_condition.BuildStepRunner$Fail"/>
|
||||
<publisher class="hudson.tasks.ArtifactArchiver">
|
||||
<artifacts>**/**</artifacts>
|
||||
<latestOnly>false</latestOnly>
|
||||
<allowEmptyArchive>true</allowEmptyArchive>
|
||||
</publisher>
|
||||
</org.jenkins__ci.plugins.flexible__publish.ConditionalPublisher>
|
||||
</publishers>
|
||||
</org.jenkins__ci.plugins.flexible__publish.FlexiblePublisher>
|
||||
</publishers>
|
||||
</project>
|
9
tests/publishers/fixtures/conditional-publisher001.yaml
Normal file
9
tests/publishers/fixtures/conditional-publisher001.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
publishers:
|
||||
- conditional-publisher:
|
||||
- condition-kind: current-status
|
||||
condition-worst: FAILURE
|
||||
condition-best: SUCCESS
|
||||
action:
|
||||
- archive:
|
||||
artifacts: '**/**'
|
||||
allow-empty: 'true'
|
27
tests/publishers/fixtures/conditional-publisher002.xml
Normal file
27
tests/publishers/fixtures/conditional-publisher002.xml
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project>
|
||||
<publishers>
|
||||
<org.jenkins__ci.plugins.flexible__publish.FlexiblePublisher>
|
||||
<publishers>
|
||||
<org.jenkins__ci.plugins.flexible__publish.ConditionalPublisher>
|
||||
<condition class="org.jenkins_ci.plugins.run_condition.contributed.ShellCondition">
|
||||
<command>ls file*</command>
|
||||
</condition>
|
||||
<runner class="org.jenkins_ci.plugins.run_condition.BuildStepRunner$DontRun"/>
|
||||
<publisher class="com.michelin.cio.hudson.plugins.copytoslave.CopyToMasterNotifier">
|
||||
<includes>file1,file2*.txt</includes>
|
||||
<excludes>file2bad.txt</excludes>
|
||||
<destinationFolder/>
|
||||
</publisher>
|
||||
</org.jenkins__ci.plugins.flexible__publish.ConditionalPublisher>
|
||||
<org.jenkins__ci.plugins.flexible__publish.ConditionalPublisher>
|
||||
<condition class="org.jenkins_ci.plugins.run_condition.core.AlwaysRun"/>
|
||||
<runner class="org.jenkins_ci.plugins.run_condition.BuildStepRunner$RunUnstable"/>
|
||||
<publisher class="hudson.tasks.test.AggregatedTestResultPublisher">
|
||||
<includeFailedBuilds>true</includeFailedBuilds>
|
||||
</publisher>
|
||||
</org.jenkins__ci.plugins.flexible__publish.ConditionalPublisher>
|
||||
</publishers>
|
||||
</org.jenkins__ci.plugins.flexible__publish.FlexiblePublisher>
|
||||
</publishers>
|
||||
</project>
|
18
tests/publishers/fixtures/conditional-publisher002.yaml
Normal file
18
tests/publishers/fixtures/conditional-publisher002.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
publishers:
|
||||
- conditional-publisher:
|
||||
- condition-kind: shell
|
||||
condition-command: ls file*
|
||||
on-evaluation-failure: dont-run
|
||||
action:
|
||||
- copy-to-master:
|
||||
includes:
|
||||
- file1
|
||||
- file2*.txt
|
||||
excludes:
|
||||
- file2bad.txt
|
||||
- condition-kind: always
|
||||
on-evaluation-failure: run-and-mark-unstable
|
||||
action:
|
||||
- aggregate-tests:
|
||||
include-failed-builds: true
|
||||
|
Loading…
Reference in New Issue
Block a user