summaryrefslogtreecommitdiff
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)
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 02094e1..08fe56d 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'))
30# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 30# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
31extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage', 31extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage',
32 'jenkins_jobs.sphinx.yaml', 'sphinxcontrib.programoutput', 32 'jenkins_jobs.sphinx.yaml', 'sphinxcontrib.programoutput',
33 'sphinx.ext.extlinks'] 33 'sphinx.ext.extlinks', 'sphinx.ext.doctest']
34 34
35# Add any paths that contain templates here, relative to this directory. 35# Add any paths that contain templates here, relative to this directory.
36templates_path = ['_templates'] 36templates_path = ['_templates']
diff --git a/jenkins_jobs/modules/project_multibranch.py b/jenkins_jobs/modules/project_multibranch.py
index eec0441..207594f 100644
--- a/jenkins_jobs/modules/project_multibranch.py
+++ b/jenkins_jobs/modules/project_multibranch.py
@@ -76,6 +76,7 @@ import six
76 76
77from jenkins_jobs.modules.scm import git_extensions 77from jenkins_jobs.modules.scm import git_extensions
78from jenkins_jobs.errors import InvalidAttributeError 78from jenkins_jobs.errors import InvalidAttributeError
79from jenkins_jobs.errors import JenkinsJobsException
79 80
80logger = logging.getLogger(str(__name__)) 81logger = logging.getLogger(str(__name__))
81 82
@@ -1146,7 +1147,8 @@ def property_strategies(xml_parent, data):
1146 1147
1147 Requires the :jenkins-wiki:`Branch API Plugin <Branch+API+Plugin>`. 1148 Requires the :jenkins-wiki:`Branch API Plugin <Branch+API+Plugin>`.
1148 1149
1149 :arg dict property-strategies: Definition of property strategies. 1150 :arg dict property-strategies: Definition of property strategies. Either
1151 `named-branches` or `all-branches` may be specified, but not both.
1150 1152
1151 * **all-branches** (list): A list of property strategy definitions 1153 * **all-branches** (list): A list of property strategy definitions
1152 for use with all branches. 1154 for use with all branches.
@@ -1158,43 +1160,162 @@ def property_strategies(xml_parent, data):
1158 performance-optimized, survivable-nonatomic, or 1160 performance-optimized, survivable-nonatomic, or
1159 max-survivability (optional) Requires the :jenkins-wiki: 1161 max-survivability (optional) Requires the :jenkins-wiki:
1160 `Pipeline Multibranch Plugin <Pipeline+Multibranch+Plugin>` 1162 `Pipeline Multibranch Plugin <Pipeline+Multibranch+Plugin>`
1163
1164 * **named-branches** (dict): Named branches get different properties.
1165 Comprised of a list of defaults and a list of property strategy
1166 exceptions for use with specific branches.
1167
1168 * **defaults** (list): A list of property strategy definitions
1169 to be applied by default to all branches, unless overridden
1170 by an entry in `exceptions`
1171
1172 * **suppress-scm-triggering** (bool): Suppresses automatic SCM
1173 triggering (optional)
1174 * **pipeline-branch-durability-override** (str): Set a custom
1175 branch speed/durability level. Valid values:
1176 performance-optimized, survivable-nonatomic, or
1177 max-survivability (optional) Requires the :jenkins-wiki:
1178 `Pipeline Multibranch Plugin <Pipeline+Multibranch+Plugin>`
1179
1180 * **exceptions** (list): A list of branch names and the property
1181 strategies to be used on that branch, instead of any listed
1182 in `defaults`.
1183
1184 * **exception** (dict): Defines exception
1185 * **branch-name** (str): Name of the branch to which these
1186 properties will be applied.
1187 * **properties** (list): A list of properties to apply to
1188 this branch.
1189
1190 * **suppress-scm-triggering** (bool): Suppresses
1191 automatic SCM triggering (optional)
1192 * **pipeline-branch-durability-override** (str): Set a
1193 custom branch speed/durability level. Valid values:
1194 performance-optimized, survivable-nonatomic, or
1195 max-survivability (optional) Requires the
1196 :jenkins-wiki:`Pipeline Multibranch Plugin
1197 <Pipeline+Multibranch+Plugin>`
1161 """ 1198 """
1162 1199
1200 valid_prop_strats = [
1201 'all-branches',
1202 'named-branches'
1203 ]
1204
1205 basic_property_strategies = 'jenkins.branch'
1206
1207 prop_strats = data.get('property-strategies', None)
1208
1209 if prop_strats:
1210
1211 for prop_strat in prop_strats:
1212 if prop_strat not in valid_prop_strats:
1213 raise InvalidAttributeError('property-strategies',
1214 prop_strat,
1215 valid_prop_strats)
1216 if len(prop_strats) > 1:
1217 raise JenkinsJobsException(
1218 'Only one property strategy may be specified')
1219
1220 all_branches = prop_strats.get('all-branches', None)
1221 named_branches = prop_strats.get('named-branches', None)
1222
1223 if all_branches:
1224
1225 strat_elem = XML.SubElement(xml_parent, 'strategy', {
1226 'class': ''.join([basic_property_strategies,
1227 '.DefaultBranchPropertyStrategy'])})
1228 props_elem = XML.SubElement(strat_elem, 'properties', {
1229 'class': 'java.util.Arrays$ArrayList'})
1230 props_elem = XML.SubElement(props_elem, 'a', {
1231 'class': ''.join([
1232 basic_property_strategies, '.BranchProperty-array'])})
1233
1234 apply_property_strategies(props_elem, all_branches)
1235
1236 elif named_branches:
1237
1238 strat_elem = XML.SubElement(xml_parent, 'strategy', {
1239 'class': ''.join([basic_property_strategies,
1240 '.NamedExceptionsBranchPropertyStrategy'])})
1241
1242 nbs_defaults = named_branches.get('defaults', None)
1243 if nbs_defaults:
1244
1245 props_elem = XML.SubElement(strat_elem, 'defaultProperties', {
1246 'class': 'java.util.Arrays$ArrayList'})
1247 props_elem = XML.SubElement(props_elem, 'a', {
1248 'class': ''.join([
1249 basic_property_strategies, '.BranchProperty-array'])})
1250
1251 apply_property_strategies(props_elem, nbs_defaults)
1252
1253 nbs_exceptions = named_branches.get('exceptions', None)
1254 if nbs_exceptions:
1255
1256 props_elem = XML.SubElement(strat_elem, 'namedExceptions', {
1257 'class': 'java.util.Arrays$ArrayList'})
1258 props_elem = XML.SubElement(props_elem, 'a', {
1259 'class': ''.join([
1260 basic_property_strategies,
1261 '.NamedExceptionsBranchPropertyStrategy$Named-array'
1262 ])})
1263
1264 for named_exception in nbs_exceptions:
1265 named_exception = named_exception.get('exception', None)
1266 if not named_exception:
1267 continue
1268
1269 exc_elem = XML.SubElement(props_elem, ''.join([
1270 basic_property_strategies,
1271 '.NamedExceptionsBranchPropertyStrategy_-Named']))
1272
1273 ne_branch_name = named_exception.get('branch-name', None)
1274 if ne_branch_name is not None:
1275 XML.SubElement(exc_elem, 'name').text = ne_branch_name
1276
1277 ne_properties = named_exception.get('properties', None)
1278 if ne_properties:
1279 exc_elem = XML.SubElement(exc_elem, 'props', {
1280 'class': 'java.util.Arrays$ArrayList'})
1281 exc_elem = XML.SubElement(exc_elem, 'a', {
1282 'class': ''.join([
1283 basic_property_strategies,
1284 '.BranchProperty-array'])})
1285 apply_property_strategies(exc_elem, ne_properties)
1286
1287
1288def apply_property_strategies(props_elem, props_list):
1289 # there are 3 locations at which property strategies can be defined:
1290 # globally (all-branches), defaults (named-branches), exceptions
1291 # (also named-branches)
1292
1293 basic_property_strategies = 'jenkins.branch'
1294 workflow_multibranch = 'org.jenkinsci.plugins.workflow.multibranch'
1163 # Valid options for the pipeline branch durability override. 1295 # Valid options for the pipeline branch durability override.
1164 pbdo_map = collections.OrderedDict([ 1296 pbdo_map = collections.OrderedDict([
1165 ("max-survivability", "MAX_SURVIVABILITY"), 1297 ("max-survivability", "MAX_SURVIVABILITY"),
1166 ("performance-optimized", "PERFORMANCE_OPTIMIZED"), 1298 ("performance-optimized", "PERFORMANCE_OPTIMIZED"),
1167 ("survivable-nonatomic", "SURVIVABLE_NONATOMIC"), 1299 ("survivable-nonatomic", "SURVIVABLE_NONATOMIC"),
1168 ]) 1300 ])
1169 basic_property_strategies = 'jenkins.branch'
1170 workflow_multibranch = 'org.jenkinsci.plugins.workflow.multibranch'
1171 dbps = XML.SubElement(xml_parent, 'strategy', {
1172 'class': ''.join([basic_property_strategies,
1173 '.DefaultBranchPropertyStrategy'])})
1174 prop_strats = data.get('property-strategies', None)
1175 1301
1176 if prop_strats: 1302 for dbs_list in props_list:
1177 props_elem = XML.SubElement(dbps, 'properties', { 1303
1178 'class': 'java.util.Arrays$ArrayList'}) 1304 if dbs_list.get('suppress-scm-triggering', False):
1179 props_elem = XML.SubElement(props_elem, 'a', { 1305 XML.SubElement(props_elem, ''.join([
1180 'class': ''.join([ 1306 basic_property_strategies, '.NoTriggerBranchProperty']))
1181 basic_property_strategies, '.BranchProperty-array'])}) 1307
1182 1308 pbdo_val = dbs_list.get(
1183 for dbs_list in prop_strats.get('all-branches', None): 1309 'pipeline-branch-durability-override', None)
1184 1310 if pbdo_val:
1185 if dbs_list.get('suppress-scm-triggering', False): 1311 if not pbdo_map.get(pbdo_val):
1186 XML.SubElement(props_elem, ''.join([ 1312 raise InvalidAttributeError(
1187 basic_property_strategies, '.NoTriggerBranchProperty'])) 1313 'pipeline-branch-durability-override',
1188 1314 pbdo_val,
1189 pbdo_val = dbs_list.get( 1315 pbdo_map.keys())
1190 'pipeline-branch-durability-override', None) 1316 pbdo_elem = XML.SubElement(props_elem, ''.join([
1191 if pbdo_val: 1317 workflow_multibranch,
1192 if not pbdo_map.get(pbdo_val): 1318 '.DurabilityHintBranchProperty']), {
1193 raise InvalidAttributeError( 1319 'plugin': 'workflow-multibranch'})
1194 'pipeline-branch-durability-override', 1320 XML.SubElement(pbdo_elem, 'hint').text = pbdo_map.get(
1195 pbdo_val, 1321 pbdo_val)
1196 pbdo_map.keys())
1197 pbdo_elem = XML.SubElement(props_elem, ''.join([
1198 workflow_multibranch, '.DurabilityHintBranchProperty']), {
1199 'plugin': 'workflow-multibranch'})
1200 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 0000000..07818a9
--- /dev/null
+++ b/tests/multibranch/fixtures/scm_github_named_branch_props.xml
@@ -0,0 +1,94 @@
1<?xml version="1.0" encoding="utf-8"?>
2<org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject plugin="workflow-multibranch">
3 <properties/>
4 <views>
5 <hudson.model.AllView>
6 <name>All</name>
7 <filterExecutors>false</filterExecutors>
8 <filterQueue>false</filterQueue>
9 <properties class="hudson.model.View$PropertyList"/>
10 <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../../.."/>
11 </hudson.model.AllView>
12 </views>
13 <viewsTabBar class="hudson.views.DefaultViewsTabBar"/>
14 <folderViews class="jenkins.branch.MultiBranchProjectViewHolder" plugin="branch-api">
15 <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
16 </folderViews>
17 <healthMetrics>
18 <com.cloudbees.hudson.plugins.folder.health.WorstChildHealthMetric plugin="cloudbees-folder">
19 <nonRecursive>false</nonRecursive>
20 </com.cloudbees.hudson.plugins.folder.health.WorstChildHealthMetric>
21 </healthMetrics>
22 <icon class="jenkins.branch.MetadataActionFolderIcon" plugin="branch-api">
23 <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
24 </icon>
25 <orphanedItemStrategy class="com.cloudbees.hudson.plugins.folder.computed.DefaultOrphanedItemStrategy" plugin="cloudbees-folder">
26 <pruneDeadBranches>true</pruneDeadBranches>
27 <daysToKeep>-1</daysToKeep>
28 <numToKeep>-1</numToKeep>
29 </orphanedItemStrategy>
30 <triggers/>
31 <sources class="jenkins.branch.MultiBranchProject$BranchSourceList" plugin="branch-api">
32 <data>
33 <jenkins.branch.BranchSource>
34 <source class="org.jenkinsci.plugins.github_branch_source.GitHubSCMSource" plugin="github-branch-source">
35 <id>gh-johndoe-foo</id>
36 <repoOwner>johndoe</repoOwner>
37 <repository>foo</repository>
38 <traits>
39 <org.jenkinsci.plugins.github__branch__source.BranchDiscoveryTrait>
40 <strategyId>1</strategyId>
41 </org.jenkinsci.plugins.github__branch__source.BranchDiscoveryTrait>
42 <org.jenkinsci.plugins.github__branch__source.ForkPullRequestDiscoveryTrait>
43 <strategyId>1</strategyId>
44 <trust class="org.jenkinsci.plugins.github_branch_source.ForkPullRequestDiscoveryTrait$TrustContributors"/>
45 </org.jenkinsci.plugins.github__branch__source.ForkPullRequestDiscoveryTrait>
46 <org.jenkinsci.plugins.github__branch__source.OriginPullRequestDiscoveryTrait>
47 <strategyId>1</strategyId>
48 </org.jenkinsci.plugins.github__branch__source.OriginPullRequestDiscoveryTrait>
49 <jenkins.plugins.git.traits.WipeWorkspaceTrait>
50 <extension class="hudson.plugins.git.extensions.impl.WipeWorkspace"/>
51 </jenkins.plugins.git.traits.WipeWorkspaceTrait>
52 </traits>
53 </source>
54 <strategy class="jenkins.branch.NamedExceptionsBranchPropertyStrategy">
55 <defaultProperties class="java.util.Arrays$ArrayList">
56 <a class="jenkins.branch.BranchProperty-array">
57 <org.jenkinsci.plugins.workflow.multibranch.DurabilityHintBranchProperty plugin="workflow-multibranch">
58 <hint>MAX_SURVIVABILITY</hint>
59 </org.jenkinsci.plugins.workflow.multibranch.DurabilityHintBranchProperty>
60 </a>
61 </defaultProperties>
62 <namedExceptions class="java.util.Arrays$ArrayList">
63 <a class="jenkins.branch.NamedExceptionsBranchPropertyStrategy$Named-array">
64 <jenkins.branch.NamedExceptionsBranchPropertyStrategy_-Named>
65 <name>master</name>
66 <props class="java.util.Arrays$ArrayList">
67 <a class="jenkins.branch.BranchProperty-array">
68 <jenkins.branch.NoTriggerBranchProperty/>
69 <org.jenkinsci.plugins.workflow.multibranch.DurabilityHintBranchProperty plugin="workflow-multibranch">
70 <hint>SURVIVABLE_NONATOMIC</hint>
71 </org.jenkinsci.plugins.workflow.multibranch.DurabilityHintBranchProperty>
72 </a>
73 </props>
74 </jenkins.branch.NamedExceptionsBranchPropertyStrategy_-Named>
75 <jenkins.branch.NamedExceptionsBranchPropertyStrategy_-Named>
76 <name>staging</name>
77 <props class="java.util.Arrays$ArrayList">
78 <a class="jenkins.branch.BranchProperty-array">
79 <jenkins.branch.NoTriggerBranchProperty/>
80 </a>
81 </props>
82 </jenkins.branch.NamedExceptionsBranchPropertyStrategy_-Named>
83 </a>
84 </namedExceptions>
85 </strategy>
86 </jenkins.branch.BranchSource>
87 </data>
88 <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
89 </sources>
90 <factory class="org.jenkinsci.plugins.workflow.multibranch.WorkflowBranchProjectFactory">
91 <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
92 <scriptPath>Jenkinsfile</scriptPath>
93 </factory>
94</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 0000000..02390c7
--- /dev/null
+++ b/tests/multibranch/fixtures/scm_github_named_branch_props.yaml
@@ -0,0 +1,21 @@
1name: 'demo-multibranch-github-min'
2project-type: multibranch
3scm:
4 - github:
5 repo: 'foo'
6 repo-owner: 'johndoe'
7
8 property-strategies:
9 named-branches:
10 defaults:
11 - pipeline-branch-durability-override: max-survivability
12 exceptions:
13 - exception:
14 branch-name: master
15 properties:
16 - suppress-scm-triggering: true
17 - pipeline-branch-durability-override: survivable-nonatomic
18 - exception:
19 branch-name: staging
20 properties:
21 - suppress-scm-triggering: true