summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2019-01-08 16:23:54 +0000
committerGerrit Code Review <review@openstack.org>2019-01-08 16:23:54 +0000
commit51e2a99d5828488aee0ac809c491bf8b1c1321e7 (patch)
tree36fa9a10e7450fc0bb24368c5a85992b8837efde
parent5bdefb7d13b2d2118c395ad8f7b892e900db6432 (diff)
parentcf152d67c77a1d1b873a952162f981974b447248 (diff)
downloadpython-jenkins-job-builder-51e2a99d5828488aee0ac809c491bf8b1c1321e7.tar.gz
python-jenkins-job-builder-51e2a99d5828488aee0ac809c491bf8b1c1321e7.tar.xz
python-jenkins-job-builder-51e2a99d5828488aee0ac809c491bf8b1c1321e7.zip
Merge "Adds named branches to property strategy support"
-rw-r--r--doc/source/conf.py2
-rw-r--r--jenkins_jobs/modules/project_multibranch.py185
-rw-r--r--tests/multibranch/fixtures/scm_github_named_branch_props.xml94
-rw-r--r--tests/multibranch/fixtures/scm_github_named_branch_props.yaml21
4 files changed, 269 insertions, 33 deletions
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 02094e14..08fe56d9 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -30,7 +30,7 @@ sys.path.insert(0, os.path.abspath('../../jenkins_jobs/modules'))
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage',
'jenkins_jobs.sphinx.yaml', 'sphinxcontrib.programoutput',
- 'sphinx.ext.extlinks']
+ 'sphinx.ext.extlinks', 'sphinx.ext.doctest']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
diff --git a/jenkins_jobs/modules/project_multibranch.py b/jenkins_jobs/modules/project_multibranch.py
index eec04411..207594f0 100644
--- a/jenkins_jobs/modules/project_multibranch.py
+++ b/jenkins_jobs/modules/project_multibranch.py
@@ -76,6 +76,7 @@ import six
from jenkins_jobs.modules.scm import git_extensions
from jenkins_jobs.errors import InvalidAttributeError
+from jenkins_jobs.errors import JenkinsJobsException
logger = logging.getLogger(str(__name__))
@@ -1146,7 +1147,8 @@ def property_strategies(xml_parent, data):
Requires the :jenkins-wiki:`Branch API Plugin <Branch+API+Plugin>`.
- :arg dict property-strategies: Definition of property strategies.
+ :arg dict property-strategies: Definition of property strategies. Either
+ `named-branches` or `all-branches` may be specified, but not both.
* **all-branches** (list): A list of property strategy definitions
for use with all branches.
@@ -1158,43 +1160,162 @@ def property_strategies(xml_parent, data):
performance-optimized, survivable-nonatomic, or
max-survivability (optional) Requires the :jenkins-wiki:
`Pipeline Multibranch Plugin <Pipeline+Multibranch+Plugin>`
+
+ * **named-branches** (dict): Named branches get different properties.
+ Comprised of a list of defaults and a list of property strategy
+ exceptions for use with specific branches.
+
+ * **defaults** (list): A list of property strategy definitions
+ to be applied by default to all branches, unless overridden
+ by an entry in `exceptions`
+
+ * **suppress-scm-triggering** (bool): Suppresses automatic SCM
+ triggering (optional)
+ * **pipeline-branch-durability-override** (str): Set a custom
+ branch speed/durability level. Valid values:
+ performance-optimized, survivable-nonatomic, or
+ max-survivability (optional) Requires the :jenkins-wiki:
+ `Pipeline Multibranch Plugin <Pipeline+Multibranch+Plugin>`
+
+ * **exceptions** (list): A list of branch names and the property
+ strategies to be used on that branch, instead of any listed
+ in `defaults`.
+
+ * **exception** (dict): Defines exception
+ * **branch-name** (str): Name of the branch to which these
+ properties will be applied.
+ * **properties** (list): A list of properties to apply to
+ this branch.
+
+ * **suppress-scm-triggering** (bool): Suppresses
+ automatic SCM triggering (optional)
+ * **pipeline-branch-durability-override** (str): Set a
+ custom branch speed/durability level. Valid values:
+ performance-optimized, survivable-nonatomic, or
+ max-survivability (optional) Requires the
+ :jenkins-wiki:`Pipeline Multibranch Plugin
+ <Pipeline+Multibranch+Plugin>`
"""
+ valid_prop_strats = [
+ 'all-branches',
+ 'named-branches'
+ ]
+
+ basic_property_strategies = 'jenkins.branch'
+
+ prop_strats = data.get('property-strategies', None)
+
+ if prop_strats:
+
+ for prop_strat in prop_strats:
+ if prop_strat not in valid_prop_strats:
+ raise InvalidAttributeError('property-strategies',
+ prop_strat,
+ valid_prop_strats)
+ if len(prop_strats) > 1:
+ raise JenkinsJobsException(
+ 'Only one property strategy may be specified')
+
+ all_branches = prop_strats.get('all-branches', None)
+ named_branches = prop_strats.get('named-branches', None)
+
+ if all_branches:
+
+ strat_elem = XML.SubElement(xml_parent, 'strategy', {
+ 'class': ''.join([basic_property_strategies,
+ '.DefaultBranchPropertyStrategy'])})
+ props_elem = XML.SubElement(strat_elem, 'properties', {
+ 'class': 'java.util.Arrays$ArrayList'})
+ props_elem = XML.SubElement(props_elem, 'a', {
+ 'class': ''.join([
+ basic_property_strategies, '.BranchProperty-array'])})
+
+ apply_property_strategies(props_elem, all_branches)
+
+ elif named_branches:
+
+ strat_elem = XML.SubElement(xml_parent, 'strategy', {
+ 'class': ''.join([basic_property_strategies,
+ '.NamedExceptionsBranchPropertyStrategy'])})
+
+ nbs_defaults = named_branches.get('defaults', None)
+ if nbs_defaults:
+
+ props_elem = XML.SubElement(strat_elem, 'defaultProperties', {
+ 'class': 'java.util.Arrays$ArrayList'})
+ props_elem = XML.SubElement(props_elem, 'a', {
+ 'class': ''.join([
+ basic_property_strategies, '.BranchProperty-array'])})
+
+ apply_property_strategies(props_elem, nbs_defaults)
+
+ nbs_exceptions = named_branches.get('exceptions', None)
+ if nbs_exceptions:
+
+ props_elem = XML.SubElement(strat_elem, 'namedExceptions', {
+ 'class': 'java.util.Arrays$ArrayList'})
+ props_elem = XML.SubElement(props_elem, 'a', {
+ 'class': ''.join([
+ basic_property_strategies,
+ '.NamedExceptionsBranchPropertyStrategy$Named-array'
+ ])})
+
+ for named_exception in nbs_exceptions:
+ named_exception = named_exception.get('exception', None)
+ if not named_exception:
+ continue
+
+ exc_elem = XML.SubElement(props_elem, ''.join([
+ basic_property_strategies,
+ '.NamedExceptionsBranchPropertyStrategy_-Named']))
+
+ ne_branch_name = named_exception.get('branch-name', None)
+ if ne_branch_name is not None:
+ XML.SubElement(exc_elem, 'name').text = ne_branch_name
+
+ ne_properties = named_exception.get('properties', None)
+ if ne_properties:
+ exc_elem = XML.SubElement(exc_elem, 'props', {
+ 'class': 'java.util.Arrays$ArrayList'})
+ exc_elem = XML.SubElement(exc_elem, 'a', {
+ 'class': ''.join([
+ basic_property_strategies,
+ '.BranchProperty-array'])})
+ apply_property_strategies(exc_elem, ne_properties)
+
+
+def apply_property_strategies(props_elem, props_list):
+ # there are 3 locations at which property strategies can be defined:
+ # globally (all-branches), defaults (named-branches), exceptions
+ # (also named-branches)
+
+ basic_property_strategies = 'jenkins.branch'
+ workflow_multibranch = 'org.jenkinsci.plugins.workflow.multibranch'
# Valid options for the pipeline branch durability override.
pbdo_map = collections.OrderedDict([
("max-survivability", "MAX_SURVIVABILITY"),
("performance-optimized", "PERFORMANCE_OPTIMIZED"),
("survivable-nonatomic", "SURVIVABLE_NONATOMIC"),
])
- basic_property_strategies = 'jenkins.branch'
- workflow_multibranch = 'org.jenkinsci.plugins.workflow.multibranch'
- dbps = XML.SubElement(xml_parent, 'strategy', {
- 'class': ''.join([basic_property_strategies,
- '.DefaultBranchPropertyStrategy'])})
- prop_strats = data.get('property-strategies', None)
- if prop_strats:
- props_elem = XML.SubElement(dbps, 'properties', {
- 'class': 'java.util.Arrays$ArrayList'})
- props_elem = XML.SubElement(props_elem, 'a', {
- 'class': ''.join([
- basic_property_strategies, '.BranchProperty-array'])})
-
- for dbs_list in prop_strats.get('all-branches', None):
-
- if dbs_list.get('suppress-scm-triggering', False):
- XML.SubElement(props_elem, ''.join([
- basic_property_strategies, '.NoTriggerBranchProperty']))
-
- pbdo_val = dbs_list.get(
- 'pipeline-branch-durability-override', None)
- if pbdo_val:
- if not pbdo_map.get(pbdo_val):
- raise InvalidAttributeError(
- 'pipeline-branch-durability-override',
- pbdo_val,
- pbdo_map.keys())
- pbdo_elem = XML.SubElement(props_elem, ''.join([
- workflow_multibranch, '.DurabilityHintBranchProperty']), {
- 'plugin': 'workflow-multibranch'})
- XML.SubElement(pbdo_elem, 'hint').text = pbdo_map.get(pbdo_val)
+ for dbs_list in props_list:
+
+ if dbs_list.get('suppress-scm-triggering', False):
+ XML.SubElement(props_elem, ''.join([
+ basic_property_strategies, '.NoTriggerBranchProperty']))
+
+ pbdo_val = dbs_list.get(
+ 'pipeline-branch-durability-override', None)
+ if pbdo_val:
+ if not pbdo_map.get(pbdo_val):
+ raise InvalidAttributeError(
+ 'pipeline-branch-durability-override',
+ pbdo_val,
+ pbdo_map.keys())
+ pbdo_elem = XML.SubElement(props_elem, ''.join([
+ workflow_multibranch,
+ '.DurabilityHintBranchProperty']), {
+ 'plugin': 'workflow-multibranch'})
+ XML.SubElement(pbdo_elem, 'hint').text = pbdo_map.get(
+ pbdo_val)
diff --git a/tests/multibranch/fixtures/scm_github_named_branch_props.xml b/tests/multibranch/fixtures/scm_github_named_branch_props.xml
new file mode 100644
index 00000000..07818a90
--- /dev/null
+++ b/tests/multibranch/fixtures/scm_github_named_branch_props.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+<org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject plugin="workflow-multibranch">
+ <properties/>
+ <views>
+ <hudson.model.AllView>
+ <name>All</name>
+ <filterExecutors>false</filterExecutors>
+ <filterQueue>false</filterQueue>
+ <properties class="hudson.model.View$PropertyList"/>
+ <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../../.."/>
+ </hudson.model.AllView>
+ </views>
+ <viewsTabBar class="hudson.views.DefaultViewsTabBar"/>
+ <folderViews class="jenkins.branch.MultiBranchProjectViewHolder" plugin="branch-api">
+ <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
+ </folderViews>
+ <healthMetrics>
+ <com.cloudbees.hudson.plugins.folder.health.WorstChildHealthMetric plugin="cloudbees-folder">
+ <nonRecursive>false</nonRecursive>
+ </com.cloudbees.hudson.plugins.folder.health.WorstChildHealthMetric>
+ </healthMetrics>
+ <icon class="jenkins.branch.MetadataActionFolderIcon" plugin="branch-api">
+ <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
+ </icon>
+ <orphanedItemStrategy class="com.cloudbees.hudson.plugins.folder.computed.DefaultOrphanedItemStrategy" plugin="cloudbees-folder">
+ <pruneDeadBranches>true</pruneDeadBranches>
+ <daysToKeep>-1</daysToKeep>
+ <numToKeep>-1</numToKeep>
+ </orphanedItemStrategy>
+ <triggers/>
+ <sources class="jenkins.branch.MultiBranchProject$BranchSourceList" plugin="branch-api">
+ <data>
+ <jenkins.branch.BranchSource>
+ <source class="org.jenkinsci.plugins.github_branch_source.GitHubSCMSource" plugin="github-branch-source">
+ <id>gh-johndoe-foo</id>
+ <repoOwner>johndoe</repoOwner>
+ <repository>foo</repository>
+ <traits>
+ <org.jenkinsci.plugins.github__branch__source.BranchDiscoveryTrait>
+ <strategyId>1</strategyId>
+ </org.jenkinsci.plugins.github__branch__source.BranchDiscoveryTrait>
+ <org.jenkinsci.plugins.github__branch__source.ForkPullRequestDiscoveryTrait>
+ <strategyId>1</strategyId>
+ <trust class="org.jenkinsci.plugins.github_branch_source.ForkPullRequestDiscoveryTrait$TrustContributors"/>
+ </org.jenkinsci.plugins.github__branch__source.ForkPullRequestDiscoveryTrait>
+ <org.jenkinsci.plugins.github__branch__source.OriginPullRequestDiscoveryTrait>
+ <strategyId>1</strategyId>
+ </org.jenkinsci.plugins.github__branch__source.OriginPullRequestDiscoveryTrait>
+ <jenkins.plugins.git.traits.WipeWorkspaceTrait>
+ <extension class="hudson.plugins.git.extensions.impl.WipeWorkspace"/>
+ </jenkins.plugins.git.traits.WipeWorkspaceTrait>
+ </traits>
+ </source>
+ <strategy class="jenkins.branch.NamedExceptionsBranchPropertyStrategy">
+ <defaultProperties class="java.util.Arrays$ArrayList">
+ <a class="jenkins.branch.BranchProperty-array">
+ <org.jenkinsci.plugins.workflow.multibranch.DurabilityHintBranchProperty plugin="workflow-multibranch">
+ <hint>MAX_SURVIVABILITY</hint>
+ </org.jenkinsci.plugins.workflow.multibranch.DurabilityHintBranchProperty>
+ </a>
+ </defaultProperties>
+ <namedExceptions class="java.util.Arrays$ArrayList">
+ <a class="jenkins.branch.NamedExceptionsBranchPropertyStrategy$Named-array">
+ <jenkins.branch.NamedExceptionsBranchPropertyStrategy_-Named>
+ <name>master</name>
+ <props class="java.util.Arrays$ArrayList">
+ <a class="jenkins.branch.BranchProperty-array">
+ <jenkins.branch.NoTriggerBranchProperty/>
+ <org.jenkinsci.plugins.workflow.multibranch.DurabilityHintBranchProperty plugin="workflow-multibranch">
+ <hint>SURVIVABLE_NONATOMIC</hint>
+ </org.jenkinsci.plugins.workflow.multibranch.DurabilityHintBranchProperty>
+ </a>
+ </props>
+ </jenkins.branch.NamedExceptionsBranchPropertyStrategy_-Named>
+ <jenkins.branch.NamedExceptionsBranchPropertyStrategy_-Named>
+ <name>staging</name>
+ <props class="java.util.Arrays$ArrayList">
+ <a class="jenkins.branch.BranchProperty-array">
+ <jenkins.branch.NoTriggerBranchProperty/>
+ </a>
+ </props>
+ </jenkins.branch.NamedExceptionsBranchPropertyStrategy_-Named>
+ </a>
+ </namedExceptions>
+ </strategy>
+ </jenkins.branch.BranchSource>
+ </data>
+ <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
+ </sources>
+ <factory class="org.jenkinsci.plugins.workflow.multibranch.WorkflowBranchProjectFactory">
+ <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
+ <scriptPath>Jenkinsfile</scriptPath>
+ </factory>
+</org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject>
diff --git a/tests/multibranch/fixtures/scm_github_named_branch_props.yaml b/tests/multibranch/fixtures/scm_github_named_branch_props.yaml
new file mode 100644
index 00000000..02390c72
--- /dev/null
+++ b/tests/multibranch/fixtures/scm_github_named_branch_props.yaml
@@ -0,0 +1,21 @@
+name: 'demo-multibranch-github-min'
+project-type: multibranch
+scm:
+ - github:
+ repo: 'foo'
+ repo-owner: 'johndoe'
+
+ property-strategies:
+ named-branches:
+ defaults:
+ - pipeline-branch-durability-override: max-survivability
+ exceptions:
+ - exception:
+ branch-name: master
+ properties:
+ - suppress-scm-triggering: true
+ - pipeline-branch-durability-override: survivable-nonatomic
+ - exception:
+ branch-name: staging
+ properties:
+ - suppress-scm-triggering: true