Merge "Adds named branches to property strategy support"

This commit is contained in:
Zuul 2019-01-08 16:23:54 +00:00 committed by Gerrit Code Review
commit 51e2a99d58
4 changed files with 267 additions and 31 deletions

View File

@ -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 coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage', extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage',
'jenkins_jobs.sphinx.yaml', 'sphinxcontrib.programoutput', '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. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']

View File

@ -76,6 +76,7 @@ import six
from jenkins_jobs.modules.scm import git_extensions from jenkins_jobs.modules.scm import git_extensions
from jenkins_jobs.errors import InvalidAttributeError from jenkins_jobs.errors import InvalidAttributeError
from jenkins_jobs.errors import JenkinsJobsException
logger = logging.getLogger(str(__name__)) 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>`. 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 * **all-branches** (list): A list of property strategy definitions
for use with all branches. for use with all branches.
@ -1158,43 +1160,162 @@ def property_strategies(xml_parent, data):
performance-optimized, survivable-nonatomic, or performance-optimized, survivable-nonatomic, or
max-survivability (optional) Requires the :jenkins-wiki: max-survivability (optional) Requires the :jenkins-wiki:
`Pipeline Multibranch Plugin <Pipeline+Multibranch+Plugin>` `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. # Valid options for the pipeline branch durability override.
pbdo_map = collections.OrderedDict([ pbdo_map = collections.OrderedDict([
("max-survivability", "MAX_SURVIVABILITY"), ("max-survivability", "MAX_SURVIVABILITY"),
("performance-optimized", "PERFORMANCE_OPTIMIZED"), ("performance-optimized", "PERFORMANCE_OPTIMIZED"),
("survivable-nonatomic", "SURVIVABLE_NONATOMIC"), ("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: for dbs_list in props_list:
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']))
if dbs_list.get('suppress-scm-triggering', False): pbdo_val = dbs_list.get(
XML.SubElement(props_elem, ''.join([ 'pipeline-branch-durability-override', None)
basic_property_strategies, '.NoTriggerBranchProperty'])) if pbdo_val:
if not pbdo_map.get(pbdo_val):
pbdo_val = dbs_list.get( raise InvalidAttributeError(
'pipeline-branch-durability-override', None) 'pipeline-branch-durability-override',
if pbdo_val: pbdo_val,
if not pbdo_map.get(pbdo_val): pbdo_map.keys())
raise InvalidAttributeError( pbdo_elem = XML.SubElement(props_elem, ''.join([
'pipeline-branch-durability-override', workflow_multibranch,
pbdo_val, '.DurabilityHintBranchProperty']), {
pbdo_map.keys()) 'plugin': 'workflow-multibranch'})
pbdo_elem = XML.SubElement(props_elem, ''.join([ XML.SubElement(pbdo_elem, 'hint').text = pbdo_map.get(
workflow_multibranch, '.DurabilityHintBranchProperty']), { pbdo_val)
'plugin': 'workflow-multibranch'})
XML.SubElement(pbdo_elem, 'hint').text = pbdo_map.get(pbdo_val)

View 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>

View File

@ -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