diff options
author | Zuul <zuul@review.openstack.org> | 2019-01-08 16:23:54 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2019-01-08 16:23:54 +0000 |
commit | 51e2a99d5828488aee0ac809c491bf8b1c1321e7 (patch) | |
tree | 36fa9a10e7450fc0bb24368c5a85992b8837efde | |
parent | 5bdefb7d13b2d2118c395ad8f7b892e900db6432 (diff) | |
parent | cf152d67c77a1d1b873a952162f981974b447248 (diff) | |
download | python-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.py | 2 | ||||
-rw-r--r-- | jenkins_jobs/modules/project_multibranch.py | 185 | ||||
-rw-r--r-- | tests/multibranch/fixtures/scm_github_named_branch_props.xml | 94 | ||||
-rw-r--r-- | tests/multibranch/fixtures/scm_github_named_branch_props.yaml | 21 |
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 |