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)
|
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):
|
class Publishers(jenkins_jobs.modules.base.Base):
|
||||||
sequence = 70
|
sequence = 70
|
||||||
|
|
||||||
|
@ -119,6 +119,7 @@ jenkins_jobs.publishers =
|
|||||||
clone-workspace=jenkins_jobs.modules.publishers:clone_workspace
|
clone-workspace=jenkins_jobs.modules.publishers:clone_workspace
|
||||||
cloverphp=jenkins_jobs.modules.publishers:cloverphp
|
cloverphp=jenkins_jobs.modules.publishers:cloverphp
|
||||||
cobertura=jenkins_jobs.modules.publishers:cobertura
|
cobertura=jenkins_jobs.modules.publishers:cobertura
|
||||||
|
conditional-publisher=jenkins_jobs.modules.publishers:conditional_publisher
|
||||||
copy-to-master=jenkins_jobs.modules.publishers:copy_to_master
|
copy-to-master=jenkins_jobs.modules.publishers:copy_to_master
|
||||||
coverage=jenkins_jobs.modules.publishers:coverage
|
coverage=jenkins_jobs.modules.publishers:coverage
|
||||||
cppcheck=jenkins_jobs.modules.publishers:cppcheck
|
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…
x
Reference in New Issue
Block a user