Adds named branches to property strategy support
My previous submission added support for property strategy: all branches get the same properties. This patch adds support for the second of 2 options, "named branches get different properties", which allows for a default definition of properties + exceptions for individual refspecs based on their literal branch name. Also includes some re-org of the existing prop. strat. support in order to DRY up the code for both. Also adds sphinx.ext.doctest to docs/src/conf.py extensions to allow for running `make doctest` locally. Change-Id: Icd143fe25b1e2d5c8d1e7e8b0650d91f40838043 Signed-off-by: sbussetti <steve.bussetti@gmail.com>
This commit is contained in:
parent
02e85408f0
commit
cf152d67c7
@ -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']
|
||||
|
@ -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__))
|
||||
|
||||
@ -1141,7 +1142,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.
|
||||
@ -1153,43 +1155,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 props_list:
|
||||
|
||||
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']))
|
||||
|
||||
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)
|
||||
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)
|
||||
|
94
tests/multibranch/fixtures/scm_github_named_branch_props.xml
Normal file
94
tests/multibranch/fixtures/scm_github_named_branch_props.xml
Normal file
@ -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>
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user