Add best and worst status details for conditional-step plugin.

In order for the conditional step plugin to work properly, a more
detailed status is required otherwise the current build status is not
evaluated properly and is set to SUCCESS in all cases.
A local mapping of the java hudson.model.Result class was created to
unify build statuses names, ordinal and color scheme.

Change-Id: If8a0090b7cd51551ef6756361f6e45af3df1218d
This commit is contained in:
Philippe Godin 2014-01-28 09:07:18 -05:00
parent 704bc0d625
commit 3faf544887
14 changed files with 238 additions and 64 deletions

View File

@ -39,6 +39,7 @@ Example::
import xml.etree.ElementTree as XML
import jenkins_jobs.modules.base
from jenkins_jobs.modules import hudson_model
from jenkins_jobs.errors import JenkinsJobsException
import logging
@ -271,15 +272,9 @@ def trigger_builds(parser, xml_parent, data):
:arg bool block: whether to wait for the triggered jobs
to finish or not (default false)
Example::
builders:
- trigger-builds:
- project: "build_started"
predefined-parameters:
FOO="bar"
block: true
Example:
.. literalinclude:: /../../tests/builders/fixtures/trigger-builds001.yaml
"""
tbuilder = XML.SubElement(xml_parent,
'hudson.plugins.parameterizedtrigger.'
@ -323,17 +318,26 @@ def trigger_builds(parser, xml_parent, data):
if(block):
block = XML.SubElement(tconfig, 'block')
bsft = XML.SubElement(block, 'buildStepFailureThreshold')
XML.SubElement(bsft, 'name').text = 'FAILURE'
XML.SubElement(bsft, 'ordinal').text = '2'
XML.SubElement(bsft, 'color').text = 'RED'
XML.SubElement(bsft, 'name').text = \
hudson_model.FAILURE['name']
XML.SubElement(bsft, 'ordinal').text = \
hudson_model.FAILURE['ordinal']
XML.SubElement(bsft, 'color').text = \
hudson_model.FAILURE['color']
ut = XML.SubElement(block, 'unstableThreshold')
XML.SubElement(ut, 'name').text = 'UNSTABLE'
XML.SubElement(ut, 'ordinal').text = '1'
XML.SubElement(ut, 'color').text = 'Yellow'
XML.SubElement(ut, 'name').text = \
hudson_model.UNSTABLE['name']
XML.SubElement(ut, 'ordinal').text = \
hudson_model.UNSTABLE['ordinal']
XML.SubElement(ut, 'color').text = \
hudson_model.UNSTABLE['color']
ft = XML.SubElement(block, 'failureThreshold')
XML.SubElement(ft, 'name').text = 'FAILURE'
XML.SubElement(ft, 'ordinal').text = '2'
XML.SubElement(ft, 'color').text = 'RED'
XML.SubElement(ft, 'name').text = \
hudson_model.FAILURE['name']
XML.SubElement(ft, 'ordinal').text = \
hudson_model.FAILURE['ordinal']
XML.SubElement(ft, 'color').text = \
hudson_model.FAILURE['color']
# If configs is empty, remove the entire tbuilder tree.
if(len(configs) == 0):
logger.debug("Pruning empty TriggerBuilder tree.")
@ -568,7 +572,8 @@ def create_builders(parser, step):
def conditional_step(parser, xml_parent, data):
"""yaml: conditional-step
Conditionaly execute some build steps. Requires the Jenkins `Conditional
BuildStep Plugin`_.
BuildStep Plugin <https://wiki.jenkins-ci.org/display/ \
JENKINS/Conditional+BuildStep+Plugin>`_.
Depending on the number of declared steps, a `Conditional step (single)`
or a `Conditional steps (multiple)` is created in Jenkins.
@ -597,8 +602,11 @@ def conditional_step(parser, xml_parent, data):
current-status Run the build step if the current build status is
within the configured range
:condition-worst: Worst status
:condition-best: Best status
: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 step if the shell command succeed
:condition-command: Shell command to execute
@ -615,20 +623,11 @@ def conditional_step(parser, xml_parent, data):
or `jenkins-home`. Default is `workspace`.
================== ====================================================
Example::
Example:
builders:
- conditional-step:
condition-kind: boolean-expression
condition-expression: "${ENV,var=IS_STABLE_BRANCH}"
on-evaluation-failure: mark-unstable
steps:
- shell: "echo Making extra checks"
.. _Conditional BuildStep Plugin: https://wiki.jenkins-ci.org/display/
JENKINS/Conditional+BuildStep+Plugin
.. literalinclude:: \
/../../tests/builders/fixtures/conditional-step-success-failure.yaml
"""
def build_condition(cdata):
kind = cdata['condition-kind']
ctag = XML.SubElement(root_tag, condition_tag)
@ -648,9 +647,30 @@ def conditional_step(parser, xml_parent, data):
'org.jenkins_ci.plugins.run_condition.core.'
'StatusCondition')
wr = XML.SubElement(ctag, 'worstResult')
XML.SubElement(wr, "name").text = cdata['condition-worst']
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')
XML.SubElement(br, "name").text = cdata['condition-best']
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',
'org.jenkins_ci.plugins.run_condition.contributed.'

View File

@ -0,0 +1,56 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# Representation of the hudson.model.Result class
SUCCESS = {
'name': 'SUCCESS',
'ordinal': '0',
'color': 'BLUE',
'complete': True
}
UNSTABLE = {
'name': 'UNSTABLE',
'ordinal': '1',
'color': 'YELLOW',
'complete': True
}
FAILURE = {
'name': 'FAILURE',
'ordinal': '2',
'color': 'RED',
'complete': True
}
NOTBUILD = {
'name': 'NOT_BUILD',
'ordinal': '3',
'color': 'NOTBUILD',
'complete': False
}
ABORTED = {
'name': 'ABORTED',
'ordinal': '4',
'color': 'ABORTED',
'complete': False
}
THRESHOLDS = {
'SUCCESS': SUCCESS,
'UNSTABLE': UNSTABLE,
'FAILURE': FAILURE,
'NOT_BUILD': NOTBUILD,
'ABORTED': ABORTED
}

View File

@ -110,7 +110,7 @@ class Matrix(jenkins_jobs.modules.base.Base):
ex_r = XML.SubElement(root, 'executionStrategy',
{'class': 'hudson.matrix.'
'DefaultMatrixExecutionStrategyImpl'})
'DefaultMatrixExecutionStrategyImpl'})
ex_d = data.get('execution-strategy', {})
XML.SubElement(root, 'combinationFilter').text = \
str(ex_d.get('combination-filter', '')).rstrip()

View File

@ -26,6 +26,7 @@ the build is complete.
import xml.etree.ElementTree as XML
import jenkins_jobs.modules.base
from jenkins_jobs.modules import hudson_model
from jenkins_jobs.errors import JenkinsJobsException
import logging
import sys
@ -216,42 +217,26 @@ def trigger(parser, xml_parent, data):
:arg str threshold: when to trigger the other job (default 'SUCCESS'),
alternatives: SUCCESS, UNSTABLE, FAILURE
Example::
Example:
publishers:
- trigger:
project: other_job
.. literalinclude:: /../../tests/publishers/fixtures/trigger_success.yaml
"""
thresholds = {
'SUCCESS': {
'ordinal': '0',
'color': 'BLUE'
},
'UNSTABLE': {
'ordinal': '1',
'color': 'YELLOW'
},
'FAILURE': {
'ordinal': '2',
'color': 'RED'
}
}
tconfig = XML.SubElement(xml_parent, 'hudson.tasks.BuildTrigger')
childProjects = XML.SubElement(tconfig, 'childProjects')
childProjects.text = data['project']
tthreshold = XML.SubElement(tconfig, 'threshold')
threshold = data.get('threshold', 'SUCCESS')
if threshold not in thresholds.keys():
supported_thresholds = ['SUCCESS', 'UNSTABLE', 'FAILURE']
if threshold not in supported_thresholds:
raise JenkinsJobsException("threshold must be one of %s" %
", ".join(threshold.keys()))
", ".join(supported_thresholds))
tname = XML.SubElement(tthreshold, 'name')
tname.text = threshold
tname.text = hudson_model.THRESHOLDS[threshold]['name']
tordinal = XML.SubElement(tthreshold, 'ordinal')
tordinal.text = thresholds[threshold]['ordinal']
tordinal.text = hudson_model.THRESHOLDS[threshold]['ordinal']
tcolor = XML.SubElement(tthreshold, 'color')
tcolor.text = thresholds[threshold]['color']
tcolor.text = hudson_model.THRESHOLDS[threshold]['color']
def cloverphp(parser, xml_parent, data):
@ -3093,7 +3078,7 @@ def description_setter(parser, xml_parent, data):
Example:
.. literalinclude::
/../../tests/publishers/fixtures/description-setter.yaml
/../../tests/publishers/fixtures/description-setter001.yaml
"""

View File

@ -320,7 +320,7 @@ def rbenv(parser, xml_parent, data):
XML.SubElement(o,
'ignore__local__version',
{'ruby-class': ignore_local_class,
'pluginid': 'rbenv'})
'pluginid': 'rbenv'})
def build_name(parser, xml_parent, data):
@ -745,7 +745,7 @@ def sauce_ondemand(parser, xml_parent, data):
XML.SubElement(info, 'isWebDriver').text = 'false'
XML.SubElement(sauce, 'seleniumBrowsers',
{'reference': '../seleniumInformation/'
'seleniumBrowsers'})
'seleniumBrowsers'})
if atype == 'webdriver':
browsers = XML.SubElement(info, 'webDriverBrowsers')
for platform in data['platforms']:
@ -753,7 +753,7 @@ def sauce_ondemand(parser, xml_parent, data):
XML.SubElement(info, 'isWebDriver').text = 'true'
XML.SubElement(sauce, 'webDriverBrowsers',
{'reference': '../seleniumInformation/'
'webDriverBrowsers'})
'webDriverBrowsers'})
XML.SubElement(sauce, 'launchSauceConnectOnSlave').text = str(data.get(
'launch-sauce-connect-on-slave', False)).lower()
protocol = data.get('https-protocol', '')

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<project>
<builders>
<org.jenkinsci.plugins.conditionalbuildstep.singlestep.SingleConditionalBuilder>
<condition class="org.jenkins_ci.plugins.run_condition.core.StatusCondition">
<worstResult>
<name>ABORTED</name>
<ordinal>4</ordinal>
<color>ABORTED</color>
<completeBuild>false</completeBuild>
</worstResult>
<bestResult>
<name>NOT_BUILD</name>
<ordinal>3</ordinal>
<color>NOTBUILD</color>
<completeBuild>false</completeBuild>
</bestResult>
</condition>
<runner class="org.jenkins_ci.plugins.run_condition.BuildStepRunner$Fail"/>
<buildStep class="hudson.tasks.Shell">
<command>sl</command>
</buildStep>
</org.jenkinsci.plugins.conditionalbuildstep.singlestep.SingleConditionalBuilder>
</builders>
</project>

View File

@ -0,0 +1,7 @@
builders:
- conditional-step:
condition-kind: current-status
condition-worst: ABORTED
condition-best: NOT_BUILD
steps:
- shell: "sl"

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<project>
<builders>
<org.jenkinsci.plugins.conditionalbuildstep.singlestep.SingleConditionalBuilder>
<condition class="org.jenkins_ci.plugins.run_condition.core.StatusCondition">
<worstResult>
<name>SUCCESS</name>
<ordinal>0</ordinal>
<color>BLUE</color>
<completeBuild>true</completeBuild>
</worstResult>
<bestResult>
<name>FAILURE</name>
<ordinal>2</ordinal>
<color>RED</color>
<completeBuild>true</completeBuild>
</bestResult>
</condition>
<runner class="org.jenkins_ci.plugins.run_condition.BuildStepRunner$Fail"/>
<buildStep class="hudson.tasks.Shell">
<command>sl</command>
</buildStep>
</org.jenkinsci.plugins.conditionalbuildstep.singlestep.SingleConditionalBuilder>
</builders>
</project>

View File

@ -0,0 +1,7 @@
builders:
- conditional-step:
condition-kind: current-status
condition-worst: SUCCESS
condition-best: FAILURE
steps:
- shell: "sl"

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<project>
<builders>
<org.jenkinsci.plugins.conditionalbuildstep.singlestep.SingleConditionalBuilder>
<condition class="org.jenkins_ci.plugins.run_condition.core.StatusCondition">
<worstResult>
<name>UNSTABLE</name>
<ordinal>1</ordinal>
<color>YELLOW</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"/>
<buildStep class="hudson.tasks.Shell">
<command>sl</command>
</buildStep>
</org.jenkinsci.plugins.conditionalbuildstep.singlestep.SingleConditionalBuilder>
</builders>
</project>

View File

@ -0,0 +1,7 @@
builders:
- conditional-step:
condition-kind: current-status
condition-worst: UNSTABLE
condition-best: SUCCESS
steps:
- shell: "sl"

View File

@ -22,7 +22,7 @@
<unstableThreshold>
<name>UNSTABLE</name>
<ordinal>1</ordinal>
<color>Yellow</color>
<color>YELLOW</color>
</unstableThreshold>
<failureThreshold>
<name>FAILURE</name>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<project>
<publishers>
<hudson.tasks.BuildTrigger>
<childProjects>other_job</childProjects>
<threshold>
<name>SUCCESS</name>
<ordinal>0</ordinal>
<color>BLUE</color>
</threshold>
</hudson.tasks.BuildTrigger>
</publishers>
</project>

View File

@ -0,0 +1,4 @@
publishers:
- trigger:
project: other_job
threshold: SUCCESS