1# Copyright 2012 Hewlett-Packard Development Company, L.P. 2# Copyright 2020 Liberty Global B.V. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13# License for the specific language governing permissions and limitations 14# under the License. 15 16 17""" 18The Properties module supplies a wide range of options that are 19implemented as Jenkins job properties. 20 21**Component**: properties 22 :Macro: property 23 :Entry Point: jenkins_jobs.properties 24 25Example:: 26 27 job: 28 name: test_job 29 30 properties: 31 - github: 32 url: https://github.com/openstack-infra/jenkins-job-builder/ 33""" 34 35import logging 36import pkg_resources 37import xml.etree.ElementTree as XML 38 39from jenkins_jobs.errors import InvalidAttributeError 40from jenkins_jobs.errors import JenkinsJobsException 41from jenkins_jobs.errors import MissingAttributeError 42from jenkins_jobs.errors import AttributeConflictError 43import jenkins_jobs.modules.base 44import jenkins_jobs.modules.helpers as helpers 45 46 47def builds_chain_fingerprinter(registry, xml_parent, data): 48 """yaml: builds-chain-fingerprinter 49 Builds chain fingerprinter. 50 51 Requires the Jenkins :jenkins-github:`Builds chain fingerprinter Plugin 52 <builds-chain-fingerprinter-plugin>`. 53 54 :arg bool per-builds-chain: enable builds hierarchy fingerprinting 55 (default false) 56 :arg bool per-job-chain: enable jobs hierarchy fingerprinting 57 (default false) 58 59 Example: 60 61 .. literalinclude:: /../../tests/properties/fixtures/fingerprinter.yaml 62 :language: yaml 63 """ 64 fingerprinter = XML.SubElement( 65 xml_parent, 66 "org.jenkinsci.plugins." 67 "buildschainfingerprinter." 68 "AutomaticFingerprintJobProperty", 69 ) 70 mapping = [ 71 ("per-builds-chain", "isPerBuildsChainEnabled", False), 72 ("per-job-chain", "isPerJobsChainEnabled", False), 73 ] 74 helpers.convert_mapping_to_xml(fingerprinter, data, mapping, fail_required=True) 75 76 77def ownership(registry, xml_parent, data): 78 """yaml: ownership 79 Plugin provides explicit ownership for jobs and slave nodes. 80 81 Requires the Jenkins :jenkins-plugins:`Ownership Plugin <ownership>`. 82 83 :arg bool enabled: whether ownership enabled (default : true) 84 :arg str owner: the owner of job 85 :arg list co-owners: list of job co-owners 86 87 Example: 88 89 .. literalinclude:: /../../tests/properties/fixtures/ownership.yaml 90 :language: yaml 91 """ 92 ownership_plugin = XML.SubElement( 93 xml_parent, 94 "com.synopsys.arc.jenkins.plugins.ownership.jobs.JobOwnerJobProperty", 95 ) 96 ownership = XML.SubElement(ownership_plugin, "ownership") 97 owner = str(data.get("enabled", True)).lower() 98 XML.SubElement(ownership, "ownershipEnabled").text = owner 99 100 XML.SubElement(ownership, "primaryOwnerId").text = data.get("owner") 101 102 coownersIds = XML.SubElement(ownership, "coownersIds") 103 for coowner in data.get("co-owners", []): 104 XML.SubElement(coownersIds, "string").text = coowner 105 106 107def promoted_build(registry, xml_parent, data): 108 """yaml: promoted-build 109 Marks a build for promotion. A promotion process with an identical 110 name must be created via the web interface in the job in order for the job 111 promotion to persist. Promotion processes themselves cannot be configured 112 by jenkins-jobs due to the separate storage of plugin configuration files. 113 114 Requires the Jenkins :jenkins-plugins:`Promoted Builds Plugin 115 <promoted-builds>`. 116 117 :arg list names: the promoted build names (optional) 118 119 Example: 120 121 .. literalinclude:: /../../tests/properties/fixtures/promoted_build.yaml 122 :language: yaml 123 """ 124 promoted = XML.SubElement( 125 xml_parent, "hudson.plugins.promoted__builds." "JobPropertyImpl" 126 ) 127 names = data.get("names", []) 128 if names: 129 active_processes = XML.SubElement(promoted, "activeProcessNames") 130 for n in names: 131 XML.SubElement(active_processes, "string").text = str(n) 132 133 134def gitbucket(parser, xml_parent, data): 135 """yaml: gitbucket 136 Integrate GitBucket to Jenkins. 137 138 Requires the Jenkins :jenkins-plugins:`GitBucket Plugin <gitbucket>`. 139 140 :arg str url: GitBucket URL to issue (required) 141 :arg bool link-enabled: Enable hyperlink to issue (default false) 142 143 Minimal Example: 144 145 .. literalinclude:: /../../tests/properties/fixtures/gitbucket-minimal.yaml 146 :language: yaml 147 148 Full Example: 149 150 .. literalinclude:: /../../tests/properties/fixtures/gitbucket-full.yaml 151 :language: yaml 152 """ 153 gitbucket = XML.SubElement( 154 xml_parent, "org.jenkinsci.plugins.gitbucket.GitBucketProjectProperty" 155 ) 156 gitbucket.set("plugin", "gitbucket") 157 158 mapping = [("url", "url", None), ("link-enabled", "linkEnabled", False)] 159 helpers.convert_mapping_to_xml(gitbucket, data, mapping, fail_required=True) 160 161 162def github(registry, xml_parent, data): 163 """yaml: github 164 Sets the GitHub URL for the project. 165 166 :arg str url: the GitHub URL (required) 167 :arg str display-name: This value will be used as context name for commit 168 status if status builder or status publisher is defined for this 169 project. (>= 1.14.1) (default '') 170 171 Minimal Example: 172 173 .. literalinclude:: /../../tests/properties/fixtures/github-minimal.yaml 174 :language: yaml 175 176 Full Example: 177 178 .. literalinclude:: /../../tests/properties/fixtures/github-full.yaml 179 :language: yaml 180 """ 181 github = XML.SubElement( 182 xml_parent, "com.coravy.hudson.plugins.github.GithubProjectProperty" 183 ) 184 github.set("plugin", "github") 185 186 mapping = [("url", "projectUrl", None), ("display-name", "displayName", "")] 187 helpers.convert_mapping_to_xml(github, data, mapping, fail_required=True) 188 189 190def gitlab(registry, xml_parent, data): 191 """yaml: gitlab 192 Sets the GitLab connection for the project. Configured via Jenkins Global 193 Configuration. 194 195 Requires the Jenkins :jenkins-plugins:`GitLab Plugin <gitlab-plugin>`. 196 197 :arg str connection: the GitLab connection name (required) 198 199 Example: 200 201 .. literalinclude:: /../../tests/properties/fixtures/gitlab.yaml 202 :language: yaml 203 """ 204 gitlab = XML.SubElement( 205 xml_parent, 206 "com.dabsquared.gitlabjenkins.connection." "GitLabConnectionProperty", 207 ) 208 mapping = [("connection", "gitLabConnection", None)] 209 helpers.convert_mapping_to_xml(gitlab, data, mapping, fail_required=True) 210 211 212def gitlab_logo(registry, xml_parent, data): 213 """yaml: gitlab-logo 214 Configures the GitLab-Logo Plugin. 215 216 Requires the Jenkins :jenkins-plugins:`GitLab Logo Plugin 217 <gitlab-logo>`. 218 219 :arg str repository-name: the GitLab repository name (required) 220 221 Example: 222 223 .. literalinclude:: /../../tests/properties/fixtures/gitlab-logo.yaml 224 :language: yaml 225 """ 226 logo = XML.SubElement( 227 xml_parent, "org.jenkinsci.plugins.gitlablogo." "GitlabLogoProperty" 228 ) 229 mapping = [("repository-name", "repositoryName", None)] 230 helpers.convert_mapping_to_xml(logo, data, mapping, fail_required=True) 231 232 233def gogs(registry, xml_parent, data): 234 """yaml: gogs 235 Sets the Gogs webhook properties for the project. 236 237 Requires the Jenkins :jenkins-plugins:`Gogs Plugin <gogs-webhook>`. 238 239 :arg str secret: webhook secret (default '') 240 :arg str branch-filter: filter which needs to match to trigger a job (default '') 241 242 Minimal Example: 243 244 .. literalinclude:: /../../tests/properties/fixtures/gogs-minimal.yaml 245 :language: yaml 246 247 Full Example: 248 249 .. literalinclude:: /../../tests/properties/fixtures/gogs-full.yaml 250 :language: yaml 251 """ 252 gogs = XML.SubElement(xml_parent, "org.jenkinsci.plugins.gogs.GogsProjectProperty") 253 mapping = [("branch-filter", "gogsBranchFilter", ""), ("secret", "gogsSecret", "")] 254 helpers.convert_mapping_to_xml(gogs, data, mapping) 255 256 257def naginator_opt_out(registry, xml_parent, data): 258 """yaml: naginator-opt-out 259 Lets you opt-out so no rebuild option for Naginator is added. 260 261 Requires the Jenkins :jenkins-plugins:`Naginator Plugin <naginator>`. 262 263 :arg bool opt-out: disables the rebuild option if True (default False). 264 265 Example: 266 267 .. literalinclude:: /../../tests/properties/fixtures/naginator-opt-out002.yaml 268 :language: yaml 269 """ 270 271 opt_out = XML.SubElement( 272 xml_parent, "com.chikli.hudson.plugin.naginator." "NaginatorOptOutProperty" 273 ) 274 mapping = [("opt-out", "optOut", False)] 275 helpers.convert_mapping_to_xml(opt_out, data, mapping, fail_required=True) 276 277 278def disk_usage(registry, xml_parent, data): 279 """yaml: disk-usage 280 Enables the Disk Usage Plugin. 281 282 Requires the Jenkins :jenkins-plugins:`Disk Usage Plugin <disk-usage>`. 283 284 Example: 285 286 .. literalinclude:: /../../tests/properties/fixtures/disk-usage.yaml 287 :language: yaml 288 """ 289 XML.SubElement(xml_parent, "hudson.plugins.disk__usage." "DiskUsageProperty") 290 291 292def least_load(registry, xml_parent, data): 293 """yaml: least-load 294 Enables the Least Load Plugin. 295 296 Requires the Jenkins :jenkins-plugins:`Least Load Plugin <leastload>`. 297 298 :arg bool disabled: whether or not leastload is disabled (default true) 299 300 Example: 301 302 .. literalinclude:: /../../tests/properties/fixtures/least-load002.yaml 303 :language: yaml 304 """ 305 least = XML.SubElement( 306 xml_parent, 307 "org.bstick12.jenkinsci.plugins.leastload." "LeastLoadDisabledProperty", 308 ) 309 mapping = [("disabled", "leastLoadDisabled", True)] 310 helpers.convert_mapping_to_xml(least, data, mapping, fail_required=True) 311 312 313def throttle(registry, xml_parent, data): 314 """yaml: throttle 315 Throttles the number of builds for this job. 316 317 Requires the Jenkins :jenkins-plugins:`Throttle Concurrent Builds Plugin 318 <throttle-concurrents>`. 319 320 :arg str option: throttle `project` (throttle the project alone) 321 or `category` (throttle the project as part of one or more categories) 322 :arg int max-per-node: max concurrent builds per node (default 0) 323 :arg int max-total: max concurrent builds (default 0) 324 :arg bool enabled: whether throttling is enabled (default true) 325 :arg list categories: multiproject throttle categories 326 :arg bool matrix-builds: throttle matrix master builds (default true) 327 :arg bool matrix-configs: throttle matrix config builds (default false) 328 :arg str parameters-limit: prevent jobs with matching parameters from 329 running concurrently (default false) 330 :arg list parameters-check-list: Comma-separated list of parameters 331 to use when comparing jobs (optional) 332 333 Example: 334 335 .. literalinclude:: /../../tests/properties/fixtures/throttle001.yaml 336 :language: yaml 337 """ 338 throttle = XML.SubElement( 339 xml_parent, "hudson.plugins.throttleconcurrents." "ThrottleJobProperty" 340 ) 341 mapping = [ 342 ("max-per-node", "maxConcurrentPerNode", "0"), 343 ("max-total", "maxConcurrentTotal", "0"), 344 ("enabled", "throttleEnabled", True), 345 ] 346 helpers.convert_mapping_to_xml(throttle, data, mapping, fail_required=True) 347 cat = data.get("categories", []) 348 if cat: 349 cn = XML.SubElement(throttle, "categories") 350 for c in cat: 351 XML.SubElement(cn, "string").text = str(c) 352 353 options_list = ("category", "project") 354 option = data.get("option") 355 if option not in options_list: 356 raise InvalidAttributeError("option", option, options_list) 357 mapping = [ 358 ("", "throttleOption", option), 359 ("", "configVersion", "1"), 360 ("parameters-limit", "limitOneJobWithMatchingParams", False), 361 ] 362 helpers.convert_mapping_to_xml(throttle, data, mapping, fail_required=True) 363 364 matrixopt = XML.SubElement(throttle, "matrixOptions") 365 mapping = [ 366 ("matrix-builds", "throttleMatrixBuilds", True), 367 ("matrix-configs", "throttleMatrixConfigurations", False), 368 ] 369 helpers.convert_mapping_to_xml(matrixopt, data, mapping, fail_required=True) 370 371 params_to_use = data.get("parameters-check-list", []) 372 XML.SubElement(throttle, "paramsToUseForLimit").text = ",".join(params_to_use) 373 374 375def branch_api(registry, xml_parent, data): 376 """yaml: branch-api 377 Enforces a minimum time between builds based on the desired maximum rate. 378 379 Requires the Jenkins :jenkins-plugins:`Branch API Plugin <branch-api>`. 380 381 :arg int number-of-builds: The maximum number of builds allowed within 382 the specified time period. (default 1) 383 :arg str time-period: The time period within which the maximum number 384 of builds will be enforced. (default 'Hour') 385 386 :valid values: **Second** **Minute** **Hour**, **Day**, **Week**, **Month**, **Year** 387 :arg bool skip-rate-limit: Permit user triggered builds to 388 skip the rate limit (default false) 389 390 Minimal Example: 391 392 .. literalinclude:: 393 /../../tests/properties/fixtures/branch-api-minimal.yaml 394 :language: yaml 395 396 Full example: 397 398 .. literalinclude:: 399 /../../tests/properties/fixtures/branch-api-full.yaml 400 :language: yaml 401 """ 402 branch = XML.SubElement( 403 xml_parent, "jenkins.branch." "RateLimitBranchProperty_-JobPropertyImpl" 404 ) 405 branch.set("plugin", "branch-api") 406 407 valid_time_periods = ["Second", "Minute", "Hour", "Day", "Week", "Month", "Year"] 408 409 mapping = [ 410 ("time-period", "durationName", "Hour", valid_time_periods), 411 ("number-of-builds", "count", 1), 412 ("skip-rate-limit", "userBoost", False), 413 ] 414 helpers.convert_mapping_to_xml(branch, data, mapping, fail_required=True) 415 416 417def sidebar(registry, xml_parent, data): 418 """yaml: sidebar 419 Allows you to add links in the sidebar. 420 Requires the Jenkins :jenkins-plugins:`Sidebar-Link Plugin <sidebar-link>`. 421 422 :arg str url: url to link to (optional) 423 :arg str text: text for the link (optional) 424 :arg str icon: path to icon (optional) 425 426 Example: 427 428 .. literalinclude:: /../../tests/properties/fixtures/sidebar02.yaml 429 :language: yaml 430 """ 431 sidebar = xml_parent.find("hudson.plugins.sidebar__link.ProjectLinks") 432 if sidebar is None: 433 sidebar = XML.SubElement( 434 xml_parent, "hudson.plugins.sidebar__link.ProjectLinks" 435 ) 436 links = XML.SubElement(sidebar, "links") 437 else: 438 links = sidebar.find("links") 439 action = XML.SubElement(links, "hudson.plugins.sidebar__link.LinkAction") 440 mapping = [("url", "url", ""), ("text", "text", ""), ("icon", "icon", "")] 441 helpers.convert_mapping_to_xml(action, data, mapping, fail_required=True) 442 443 444def inject(registry, xml_parent, data): 445 """yaml: inject 446 Allows you to inject environment variables into the build. 447 448 Requires the Jenkins :jenkins-plugins:`EnvInject Plugin <envinject>`. 449 450 :arg str properties-file: file to read with properties (optional) 451 :arg str properties-content: key=value properties (optional) 452 :arg str script-file: file with script to run (optional) 453 :arg str script-content: script to run (optional) 454 :arg str groovy-content: groovy script to run (optional) 455 :arg bool groovy-sandbox: run groovy script in sandbox (default false) 456 :arg bool load-from-master: load files from master (default false) 457 :arg bool enabled: injection enabled (default true) 458 :arg bool keep-system-variables: keep system variables (default true) 459 :arg bool keep-build-variables: keep build variable (default true) 460 :arg bool override-build-parameters: override build parameters 461 (default false) 462 463 Example: 464 465 .. literalinclude:: /../../tests/properties/fixtures/inject001.yaml 466 :language: yaml 467 468 """ 469 inject = XML.SubElement(xml_parent, "EnvInjectJobProperty") 470 info = XML.SubElement(inject, "info") 471 472 mapping = [ 473 ("properties-file", "propertiesFilePath", None), 474 ("properties-content", "propertiesContent", None), 475 ("script-file", "scriptFilePath", None), 476 ("script-content", "scriptContent", None), 477 ("load-from-master", "loadFilesFromMaster", False), 478 ] 479 helpers.convert_mapping_to_xml(info, data, mapping, fail_required=False) 480 481 # determine version of plugin 482 plugin_info = registry.get_plugin_info("Groovy") 483 version = pkg_resources.parse_version(plugin_info.get("version", "0")) 484 485 if version >= pkg_resources.parse_version("2.0.0"): 486 secure_groovy_script = XML.SubElement(info, "secureGroovyScript") 487 mapping = [ 488 ("groovy-content", "script", None), 489 ("groovy-sandbox", "sandbox", False), 490 ] 491 helpers.convert_mapping_to_xml( 492 secure_groovy_script, data, mapping, fail_required=False 493 ) 494 else: 495 mapping = [("groovy-content", "groovyScriptContent", None)] 496 helpers.convert_mapping_to_xml(info, data, mapping, fail_required=False) 497 498 mapping = [ 499 ("enabled", "on", True), 500 ("keep-system-variables", "keepJenkinsSystemVariables", True), 501 ("keep-build-variables", "keepBuildVariables", True), 502 ("override-build-parameters", "overrideBuildParameters", False), 503 ] 504 helpers.convert_mapping_to_xml(inject, data, mapping, fail_required=True) 505 506 507def authenticated_build(registry, xml_parent, data): 508 """yaml: authenticated-build 509 Specifies an authorization matrix where only authenticated users 510 may trigger a build. 511 512 .. deprecated:: 0.1.0. Please use :ref:`authorization <authorization>`. 513 514 Example: 515 516 .. literalinclude:: 517 /../../tests/properties/fixtures/authenticated_build.yaml 518 :language: yaml 519 520 """ 521 # TODO: generalize this 522 security = XML.SubElement( 523 xml_parent, "hudson.security." "AuthorizationMatrixProperty" 524 ) 525 XML.SubElement( 526 security, "permission" 527 ).text = "hudson.model.Item.Build:authenticated" 528 529 530def authorization(registry, xml_parent, data, job_data): 531 """yaml: authorization 532 Specifies an authorization matrix 533 534 .. _authorization: 535 536 :arg list <name>: `<name>` is the name of the group or user, containing 537 the list of rights to grant. 538 539 :<name> rights: 540 * **credentials-create** 541 * **credentials-delete** 542 * **credentials-manage-domains** 543 * **credentials-update** 544 * **credentials-view** 545 * **job-build** 546 * **job-cancel** 547 * **job-configure** 548 * **job-delete** 549 * **job-discover** 550 * **job-extended-read** 551 * **job-move** 552 * **job-read** 553 * **job-status** 554 * **job-workspace** 555 * **ownership-jobs** 556 * **run-delete** 557 * **run-replay** 558 * **run-update** 559 * **scm-tag** 560 561 Example: 562 563 .. literalinclude:: /../../tests/properties/fixtures/authorization.yaml 564 :language: yaml 565 """ 566 567 is_a_folder = job_data.get("project-type") in ("folder", "multibranch") 568 569 credentials = "com.cloudbees.plugins.credentials.CredentialsProvider." 570 ownership = "com.synopsys.arc.jenkins.plugins.ownership.OwnershipPlugin." 571 572 mapping = { 573 "credentials-create": "".join((credentials, "Create")), 574 "credentials-delete": "".join((credentials, "Delete")), 575 "credentials-manage-domains": "".join((credentials, "ManageDomains")), 576 "credentials-update": "".join((credentials, "Update")), 577 "credentials-view": "".join((credentials, "View")), 578 "job-build": "hudson.model.Item.Build", 579 "job-cancel": "hudson.model.Item.Cancel", 580 "job-configure": "hudson.model.Item.Configure", 581 "job-delete": "hudson.model.Item.Delete", 582 "job-discover": "hudson.model.Item.Discover", 583 "job-extended-read": "hudson.model.Item.ExtendedRead", 584 "job-move": "hudson.model.Item.Move", 585 "job-read": "hudson.model.Item.Read", 586 "job-status": "hudson.model.Item.ViewStatus", 587 "job-workspace": "hudson.model.Item.Workspace", 588 "ownership-jobs": "".join((ownership, "Jobs")), 589 "run-delete": "hudson.model.Run.Delete", 590 "run-replay": "hudson.model.Run.Replay", 591 "run-update": "hudson.model.Run.Update", 592 "scm-tag": "hudson.scm.SCM.Tag", 593 } 594 595 if data: 596 if is_a_folder: 597 element_name = "com.cloudbees.hudson.plugins.folder.properties.AuthorizationMatrixProperty" 598 else: 599 element_name = "hudson.security.AuthorizationMatrixProperty" 600 matrix = XML.SubElement(xml_parent, element_name) 601 XML.SubElement( 602 matrix, 603 "inheritanceStrategy", 604 { 605 "class": "org.jenkinsci.plugins.matrixauth.inheritance.InheritParentStrategy" 606 }, 607 ) 608 609 for (username, perms) in data.items(): 610 for perm in perms: 611 pe = XML.SubElement(matrix, "permission") 612 try: 613 pe.text = "{0}:{1}".format(mapping[perm], username) 614 except KeyError: 615 raise InvalidAttributeError(username, perm, mapping.keys()) 616 617 618def priority_sorter(registry, xml_parent, data): 619 """yaml: priority-sorter 620 Allows simple ordering of builds, using a configurable job priority. 621 622 Requires the Jenkins :jenkins-plugins:`Priority Sorter Plugin 623 <PrioritySorter>`. 624 625 :arg int priority: Priority of the job. Higher value means higher 626 priority, with 3 as the default priority. (required) 627 628 Example: 629 630 .. literalinclude:: 631 /../../tests/properties/fixtures/priority_sorter002.yaml 632 :language: yaml 633 """ 634 plugin_info = registry.get_plugin_info("PrioritySorter") 635 version = pkg_resources.parse_version(plugin_info.get("version", "0")) 636 637 if version >= pkg_resources.parse_version("3.0"): 638 priority_sorter_tag = XML.SubElement( 639 xml_parent, 640 "jenkins.advancedqueue.jobinclusion." "strategy.JobInclusionJobProperty", 641 ) 642 643 mapping = [("use", "useJobGroup", True), ("priority", "jobGroupName", None)] 644 elif version >= pkg_resources.parse_version("2.0"): 645 priority_sorter_tag = XML.SubElement( 646 xml_parent, "jenkins.advancedqueue.priority." "strategy.PriorityJobProperty" 647 ) 648 649 mapping = [("use", "useJobPriority", True), ("priority", "priority", None)] 650 else: 651 priority_sorter_tag = XML.SubElement( 652 xml_parent, "hudson.queueSorter." "PrioritySorterJobProperty" 653 ) 654 655 mapping = [("priority", "priority", None)] 656 657 helpers.convert_mapping_to_xml( 658 priority_sorter_tag, data, mapping, fail_required=True 659 ) 660 661 662def build_blocker(registry, xml_parent, data): 663 """yaml: build-blocker 664 This plugin keeps the actual job in the queue 665 if at least one name of currently running jobs 666 is matching with one of the given regular expressions. 667 668 Requires the Jenkins :jenkins-plugins:`Build Blocker Plugin 669 <build-blocker-plugin>`. 670 671 :arg bool use-build-blocker: Enable or disable build blocker (default true) 672 :arg list blocking-jobs: One regular expression per line to select 673 blocking jobs by their names (required) 674 :arg str block-level: block build globally ('GLOBAL') or per node ('NODE') 675 (default 'GLOBAL') 676 :arg str queue-scanning: scan build queue for all builds ('ALL') or only 677 buildable builds ('BUILDABLE') (default 'DISABLED') 678 679 Example: 680 681 Minimal Example: 682 683 .. literalinclude:: 684 /../../tests/properties/fixtures/build-blocker-minimal.yaml 685 :language: yaml 686 687 Full Example: 688 689 .. literalinclude:: 690 /../../tests/properties/fixtures/build-blocker-full.yaml 691 :language: yaml 692 """ 693 blocker = XML.SubElement( 694 xml_parent, "hudson.plugins." "buildblocker.BuildBlockerProperty" 695 ) 696 if data is None or "blocking-jobs" not in data: 697 raise JenkinsJobsException("blocking-jobs field is missing") 698 elif data.get("blocking-jobs", None) is None: 699 raise JenkinsJobsException("blocking-jobs list must not be empty") 700 701 jobs = "" 702 for setting, value in data.items(): 703 if setting == "blocking-jobs": 704 jobs = "\n".join(value) 705 block_level_types = ["GLOBAL", "NODE"] 706 queue_scan_types = ["DISABLED", "ALL", "BUILDABLE"] 707 mapping = [ 708 ("use-build-blocker", "useBuildBlocker", True), 709 ("", "blockingJobs", jobs), 710 ("block-level", "blockLevel", "GLOBAL", block_level_types), 711 ("queue-scanning", "scanQueueFor", "DISABLED", queue_scan_types), 712 ] 713 helpers.convert_mapping_to_xml(blocker, data, mapping, fail_required=True) 714 715 716def copyartifact(registry, xml_parent, data): 717 """yaml: copyartifact 718 Specify a list of projects that have access to copy the artifacts of 719 this project. 720 721 Requires the Jenkins :jenkins-plugins:`Copy Artifact plugin 722 <copyartifact>`. 723 724 :arg str projects: comma separated list of projects that can copy 725 artifacts of this project. Wild card character '*' is available. 726 727 Example: 728 729 .. literalinclude:: 730 /../../tests/properties/fixtures/copyartifact.yaml 731 :language: yaml 732 733 """ 734 copyartifact = XML.SubElement( 735 xml_parent, 736 "hudson.plugins." "copyartifact." "CopyArtifactPermissionProperty", 737 plugin="copyartifact", 738 ) 739 if not data or not data.get("projects", None): 740 raise JenkinsJobsException("projects string must exist and " "not be empty") 741 projectlist = XML.SubElement(copyartifact, "projectNameList") 742 for project in str(data.get("projects")).split(","): 743 XML.SubElement(projectlist, "string").text = project 744 745 746def batch_tasks(registry, xml_parent, data): 747 """yaml: batch-tasks 748 Batch tasks can be tasks for events like releases, integration, archiving, 749 etc. In this way, anyone in the project team can execute them in a way that 750 leaves a record. 751 752 A batch task consists of a shell script and a name. When you execute 753 a build, the shell script gets run on the workspace, just like a build. 754 Batch tasks and builds "lock" the workspace, so when one of those 755 activities is in progress, all the others will block in the queue. 756 757 Requires the Jenkins :jenkins-plugins:`Batch Task Plugin <batch-task>`. 758 759 :arg list batch-tasks: Batch tasks. 760 761 :Tasks: 762 * **name** (`str`) Task name. 763 * **script** (`str`) Task script. 764 765 Example: 766 767 .. literalinclude:: /../../tests/properties/fixtures/batch-task.yaml 768 :language: yaml 769 770 """ 771 pdef = XML.SubElement(xml_parent, "hudson.plugins.batch__task.BatchTaskProperty") 772 tasks = XML.SubElement(pdef, "tasks") 773 for task in data: 774 batch_task = XML.SubElement(tasks, "hudson.plugins.batch__task.BatchTask") 775 mapping = [("name", "name", None), ("script", "script", None)] 776 helpers.convert_mapping_to_xml(batch_task, task, mapping, fail_required=True) 777 778 779def heavy_job(registry, xml_parent, data): 780 """yaml: heavy-job 781 This plugin allows you to define "weight" on each job, 782 and making each job consume that many executors 783 784 Requires the Jenkins :jenkins-plugins:`Heavy Job Plugin <heavy-job>`. 785 786 :arg int weight: Specify the total number of executors 787 that this job should occupy (default 1) 788 789 Example: 790 791 .. literalinclude:: /../../tests/properties/fixtures/heavy-job.yaml 792 :language: yaml 793 794 """ 795 heavyjob = XML.SubElement( 796 xml_parent, "hudson.plugins." "heavy__job.HeavyJobProperty" 797 ) 798 mapping = [("weight", "weight", 1)] 799 helpers.convert_mapping_to_xml(heavyjob, data, mapping, fail_required=True) 800 801 802def slave_utilization(registry, xml_parent, data): 803 """yaml: slave-utilization 804 This plugin allows you to specify the percentage of a slave's capacity a 805 job wants to use. 806 807 Requires the Jenkins :jenkins-plugins:`Slave Utilization Plugin 808 <slave-utilization-plugin>`. 809 810 :arg int slave-percentage: Specify the percentage of a slave's execution 811 slots that this job should occupy (default 0) 812 :arg bool single-instance-per-slave: Control whether concurrent instances 813 of this job will be permitted to run in parallel on a single slave 814 (default false) 815 816 Example: 817 818 .. literalinclude:: 819 /../../tests/properties/fixtures/slave-utilization1.yaml 820 :language: yaml 821 """ 822 utilization = XML.SubElement( 823 xml_parent, "com.suryagaddipati.jenkins.SlaveUtilizationProperty" 824 ) 825 826 percent = int(data.get("slave-percentage", 0)) 827 exclusive_node_access = True if percent else False 828 829 mapping = [ 830 ("", "needsExclusiveAccessToNode", exclusive_node_access), 831 ("", "slaveUtilizationPercentage", percent), 832 ("single-instance-per-slave", "singleInstancePerSlave", False), 833 ] 834 helpers.convert_mapping_to_xml(utilization, data, mapping, fail_required=True) 835 836 837def delivery_pipeline(registry, xml_parent, data): 838 """yaml: delivery-pipeline 839 Requires the Jenkins :jenkins-plugins:`Delivery Pipeline Plugin 840 <delivery-pipeline-plugin>`. 841 842 :arg str stage: Name of the stage for this job (default '') 843 :arg str task: Name of the task for this job (default '') 844 :arg str description: task description template for this job 845 (default '') 846 847 Minimal Example: 848 849 .. literalinclude:: 850 /../../tests/properties/fixtures/delivery-pipeline-minimal.yaml 851 :language: yaml 852 853 Full Example: 854 855 .. literalinclude:: 856 /../../tests/properties/fixtures/delivery-pipeline-full.yaml 857 :language: yaml 858 """ 859 pipeline = XML.SubElement(xml_parent, "se.diabol.jenkins.pipeline.PipelineProperty") 860 pipeline.set("plugin", "delivery-pipeline-plugin") 861 862 mapping = [ 863 ("stage", "stageName", ""), 864 ("task", "taskName", ""), 865 ("description", "descriptionTemplate", ""), 866 ] 867 helpers.convert_mapping_to_xml(pipeline, data, mapping, fail_required=True) 868 869 870def zeromq_event(registry, xml_parent, data): 871 """yaml: zeromq-event 872 This is a Jenkins plugin that will publish Jenkins Job run events 873 (start, complete, finish) to a ZMQ PUB socket. 874 875 Requires the Jenkins `ZMQ Event Publisher. 876 <https://opendev.org/x/zmq-event-publisher>`_ 877 878 Example: 879 880 .. literalinclude:: 881 /../../tests/properties/fixtures/zeromq-event.yaml 882 :language: yaml 883 884 """ 885 886 zmq_event = XML.SubElement( 887 xml_parent, 888 "org.jenkinsci.plugins." "ZMQEventPublisher.HudsonNotificationProperty", 889 ) 890 mapping = [("", "enabled", True)] 891 helpers.convert_mapping_to_xml(zmq_event, data, mapping, fail_required=True) 892 893 894def slack(registry, xml_parent, data): 895 """yaml: slack 896 Requires the Jenkins :jenkins-plugins:`Slack Plugin <slack>`. 897 898 When using Slack Plugin version < 2.0, Slack Plugin itself requires a 899 publisher aswell as properties please note that you have to add the 900 publisher to your job configuration aswell. When using Slack Plugin 901 version >= 2.0, you should only configure the publisher. 902 903 :arg bool notify-start: Send notification when the job starts 904 (default false) 905 :arg bool notify-success: Send notification on success. (default false) 906 :arg bool notify-aborted: Send notification when job is aborted. ( 907 default false) 908 :arg bool notify-not-built: Send notification when job set to NOT_BUILT 909 status. (default false) 910 :arg bool notify-unstable: Send notification when job becomes unstable. 911 (default false) 912 :arg bool notify-failure: Send notification when job fails. 913 (default false) 914 :arg bool notify-back-to-normal: Send notification when job is 915 succeeding again after being unstable or failed. (default false) 916 :arg bool 'notify-repeated-failure': Send notification when job is 917 still failing after last failure. (default false) 918 :arg bool include-test-summary: Include the test summary. (default 919 False) 920 :arg bool include-custom-message: Include a custom message into the 921 notification. (default false) 922 :arg str custom-message: Custom message to be included. (default '') 923 :arg str room: A comma separated list of rooms / channels to send 924 the notifications to. (default '') 925 926 Example: 927 928 .. literalinclude:: 929 /../../tests/properties/fixtures/slack001.yaml 930 :language: yaml 931 """ 932 logger = logging.getLogger(__name__) 933 934 plugin_info = registry.get_plugin_info("Slack Notification Plugin") 935 plugin_ver = pkg_resources.parse_version(plugin_info.get("version", "0")) 936 937 if plugin_ver >= pkg_resources.parse_version("2.0"): 938 logger.warning("properties section is not used with plugin version >= 2.0") 939 940 mapping = ( 941 ("notify-start", "startNotification", False), 942 ("notify-success", "notifySuccess", False), 943 ("notify-aborted", "notifyAborted", False), 944 ("notify-not-built", "notifyNotBuilt", False), 945 ("notify-unstable", "notifyUnstable", False), 946 ("notify-failure", "notifyFailure", False), 947 ("notify-back-to-normal", "notifyBackToNormal", False), 948 ("notify-repeated-failure", "notifyRepeatedFailure", False), 949 ("include-test-summary", "includeTestSummary", False), 950 ("include-custom-message", "includeCustomMessage", False), 951 ("custom-message", "customMessage", ""), 952 ("room", "room", ""), 953 ) 954 955 slack = XML.SubElement( 956 xml_parent, "jenkins.plugins.slack.SlackNotifier_-SlackJobProperty" 957 ) 958 959 # Ensure that custom-message is set when include-custom-message is set 960 # to true. 961 if data.get("include-custom-message", False): 962 if not data.get("custom-message", ""): 963 raise MissingAttributeError("custom-message") 964 965 helpers.convert_mapping_to_xml(slack, data, mapping, fail_required=True) 966 967 968def rebuild(registry, xml_parent, data): 969 """yaml: rebuild 970 This plug-in allows the user to rebuild a parameterized build without 971 entering the parameters again.It will also allow the user to edit the 972 parameters before rebuilding. 973 974 Requires the Jenkins :jenkins-plugins:`Rebuild Plugin <rebuild>`. 975 976 :arg bool auto-rebuild: Rebuild without asking for parameters 977 (default false) 978 :arg bool rebuild-disabled: Disable rebuilding for this job 979 (default false) 980 981 Minimal Example: 982 983 .. literalinclude:: /../../tests/properties/fixtures/rebuild-minimal.yaml 984 :language: yaml 985 986 Full Example: 987 988 .. literalinclude:: /../../tests/properties/fixtures/rebuild-full.yaml 989 :language: yaml 990 """ 991 sub_element = XML.SubElement(xml_parent, "com.sonyericsson.rebuild.RebuildSettings") 992 sub_element.set("plugin", "rebuild") 993 994 mapping = [ 995 ("auto-rebuild", "autoRebuild", False), 996 ("rebuild-disabled", "rebuildDisabled", False), 997 ] 998 helpers.convert_mapping_to_xml(sub_element, data, mapping, fail_required=True) 999 1000 1001def build_discarder(registry, xml_parent, data): 1002 """yaml: build-discarder 1003 1004 :arg int days-to-keep: Number of days to keep builds for (default -1) 1005 :arg int num-to-keep: Number of builds to keep (default -1) 1006 :arg int artifact-days-to-keep: Number of days to keep builds with 1007 artifacts (default -1) 1008 :arg int artifact-num-to-keep: Number of builds with artifacts to keep 1009 (default -1) 1010 1011 Example: 1012 1013 .. literalinclude:: 1014 /../../tests/properties/fixtures/build-discarder-001.yaml 1015 :language: yaml 1016 1017 .. literalinclude:: 1018 /../../tests/properties/fixtures/build-discarder-002.yaml 1019 :language: yaml 1020 """ 1021 base_sub = XML.SubElement(xml_parent, "jenkins.model.BuildDiscarderProperty") 1022 strategy = XML.SubElement(base_sub, "strategy") 1023 strategy.set("class", "hudson.tasks.LogRotator") 1024 1025 mappings = [ 1026 ("days-to-keep", "daysToKeep", -1), 1027 ("num-to-keep", "numToKeep", -1), 1028 ("artifact-days-to-keep", "artifactDaysToKeep", -1), 1029 ("artifact-num-to-keep", "artifactNumToKeep", -1), 1030 ] 1031 helpers.convert_mapping_to_xml(strategy, data, mappings, fail_required=True) 1032 1033 1034def slave_prerequisites(registry, xml_parent, data): 1035 """yaml: slave-prerequisites 1036 This plugin allows you to check prerequisites on slave before 1037 a job can run a build on it 1038 1039 Requires the Jenkins :jenkins-plugins:`Slave Prerequisites Plugin 1040 <slave-prerequisites>`. 1041 1042 :arg str script: A script to be executed on slave node. 1043 If returning non 0 status, the node will be vetoed from hosting 1044 the build. (required) 1045 :arg str interpreter: Command line interpreter to be used for executing 1046 the prerequisite script - either `shell` for Unix shell or `cmd` for 1047 Windows batch script. (default shell) 1048 1049 Example: 1050 1051 .. literalinclude:: 1052 /../../tests/properties/fixtures/slave-prerequisites-minimal.yaml 1053 :language: yaml 1054 1055 .. literalinclude:: 1056 /../../tests/properties/fixtures/slave-prerequisites-full.yaml 1057 :language: yaml 1058 """ 1059 prereqs = XML.SubElement(xml_parent, "com.cloudbees.plugins.JobPrerequisites") 1060 1061 mappings = [ 1062 ("script", "script", None), 1063 ( 1064 "interpreter", 1065 "interpreter", 1066 "shell", 1067 {"cmd": "windows batch command", "shell": "shell script"}, 1068 ), 1069 ] 1070 helpers.convert_mapping_to_xml(prereqs, data, mappings, fail_required=True) 1071 1072 1073def groovy_label(registry, xml_parent, data): 1074 """yaml: groovy-label 1075 This plugin allows you to use Groovy script to restrict where this project 1076 can be run. 1077 1078 Requires the Jenkins :jenkins-plugins:`Groovy Label Assignment Plugin 1079 <groovy-label-assignment>`. 1080 1081 Return value from Groovy script is treated as Label Expression. 1082 It is treated as followings: 1083 1084 - A non-string value will be converted to a string using toString() 1085 - When null or blank string is returned, node restriction does not take 1086 effect (or is not overwritten). 1087 - When exception occurred or Label Expression is not parsed correctly, 1088 builds are canceled. 1089 1090 :arg str script: Groovy script (default '') 1091 :arg bool sandbox: Use Groovy Sandbox. (default false) 1092 If checked, run this Groovy script in a sandbox with limited abilities. 1093 If unchecked, and you are not a Jenkins administrator, you will need to 1094 wait for an administrator to approve the script 1095 :arg list classpath: Additional classpath entries accessible from 1096 the script, each of which should be an absolute local path or 1097 URL to a JAR file, according to "The file URI Scheme" (optional) 1098 1099 Minimal Example: 1100 1101 .. literalinclude:: 1102 /../../tests/properties/fixtures/groovy-label-minimal.yaml 1103 :language: yaml 1104 1105 Full Example: 1106 1107 .. literalinclude:: 1108 /../../tests/properties/fixtures/groovy-label-full.yaml 1109 :language: yaml 1110 """ 1111 sub_element = XML.SubElement( 1112 xml_parent, 1113 "jp.ikedam.jenkins.plugins." 1114 "groovy__label__assignment." 1115 "GroovyLabelAssignmentProperty", 1116 ) 1117 sub_element.set("plugin", "groovy-label-assignment") 1118 security = XML.SubElement(sub_element, "secureGroovyScript") 1119 security.set("plugin", "script-security") 1120 mapping = [("script", "script", ""), ("sandbox", "sandbox", False)] 1121 1122 helpers.convert_mapping_to_xml(security, data, mapping, fail_required=True) 1123 if data and "classpath" in data: 1124 classpath = XML.SubElement(security, "classpath") 1125 for value in data["classpath"]: 1126 entry = XML.SubElement(classpath, "entry") 1127 XML.SubElement(entry, "url").text = value 1128 1129 1130def lockable_resources(registry, xml_parent, data): 1131 """yaml: lockable-resources 1132 Requires the Jenkins :jenkins-plugins:`Lockable Resources Plugin 1133 <lockable-resources>`. 1134 1135 :arg str resources: List of required resources, space separated. 1136 (required, mutual exclusive with label) 1137 :arg str label: If you have created a pool of resources, i.e. a label, 1138 you can take it into use here. The build will select the resource(s) 1139 from the pool that includes all resources sharing the given label. 1140 (required, mutual exclusive with resources) 1141 :arg str var-name: Name for the Jenkins variable to store the reserved 1142 resources in. Leave empty to disable. (default '') 1143 :arg int number: Number of resources to request, empty value or 0 means 1144 all. This is useful, if you have a pool of similar resources, 1145 from which you want one or more to be reserved. (default 0) 1146 :arg str match-script: Groovy script to reserve resource based on its 1147 properties. Leave empty to disable. (default None) 1148 :arg bool groovy-sandbox: Execute the provided match-script in Groovy 1149 sandbox. Leave empty to disable. (default False) 1150 1151 Example: 1152 1153 .. literalinclude:: 1154 /../../tests/properties/fixtures/lockable_resources_minimal.yaml 1155 :language: yaml 1156 1157 .. literalinclude:: 1158 /../../tests/properties/fixtures/lockable_resources_label.yaml 1159 :language: yaml 1160 1161 .. literalinclude:: 1162 /../../tests/properties/fixtures/lockable_resources_full.yaml 1163 :language: yaml 1164 1165 .. literalinclude:: 1166 /../../tests/properties/fixtures/lockable_resources_groovy.yaml 1167 :language: yaml 1168 """ 1169 lockable_resources = XML.SubElement( 1170 xml_parent, "org.jenkins.plugins.lockableresources.RequiredResourcesProperty" 1171 ) 1172 if data.get("resources") and data.get("label"): 1173 raise AttributeConflictError("resources", ("label",)) 1174 mapping = [ 1175 ("resources", "resourceNames", ""), 1176 ("var-name", "resourceNamesVar", ""), 1177 ("number", "resourceNumber", 0), 1178 ("label", "labelName", ""), 1179 ] 1180 helpers.convert_mapping_to_xml( 1181 lockable_resources, data, mapping, fail_required=True 1182 ) 1183 secure_groovy_script = XML.SubElement(lockable_resources, "resourceMatchScript") 1184 mapping = [("match-script", "script", None), ("groovy-sandbox", "sandbox", False)] 1185 helpers.convert_mapping_to_xml( 1186 secure_groovy_script, data, mapping, fail_required=False 1187 ) 1188 1189 1190def docker_container(registry, xml_parent, data): 1191 """yaml: docker-container 1192 Requires the Jenkins: :jenkins-plugins:`Docker Plugin <docker-plugin>`. 1193 1194 :arg str docker-registry-url: URL of the Docker registry. (default '') 1195 :arg str credentials-id: Credentials Id for the Docker registey. 1196 (default '') 1197 :arg bool commit-on-success: When a job completes, the docker slave 1198 instance is committed with repository based on the job name and build 1199 number as tag. (default false) 1200 :arg str additional-tag: Additional tag to apply to the docker slave 1201 instance when committing it. (default '') 1202 :arg bool push-on-success: Also push the resulting image when committing 1203 the docker slave instance. (default false) 1204 :arg bool clean-local-images: Clean images from the local daemon after 1205 building. (default true) 1206 1207 Minimal Example: 1208 1209 .. literalinclude:: 1210 /../../tests/properties/fixtures/docker-container-minimal.yaml 1211 :language: yaml 1212 1213 Full Example: 1214 1215 .. literalinclude:: 1216 /../../tests/properties/fixtures/docker-container-full.yaml 1217 :language: yaml 1218 """ 1219 xml_docker = XML.SubElement( 1220 xml_parent, "com.nirima.jenkins.plugins.docker.DockerJobProperty" 1221 ) 1222 1223 registry = XML.SubElement(xml_docker, "registry") 1224 registry.set("plugin", "docker-commons") 1225 registry_mapping = [ 1226 ("docker-registry-url", "url", ""), 1227 ("credentials-id", "credentialsId", ""), 1228 ] 1229 helpers.convert_mapping_to_xml( 1230 registry, data, registry_mapping, fail_required=False 1231 ) 1232 mapping = [ 1233 ("commit-on-success", "tagOnCompletion", False), 1234 ("additional-tag", "additionalTag", ""), 1235 ("push-on-success", "pushOnSuccess", False), 1236 ("clean-local-images", "cleanImages", True), 1237 ] 1238 helpers.convert_mapping_to_xml(xml_docker, data, mapping, fail_required=True) 1239 1240 1241def disable_resume(registry, xml_parent, data): 1242 """yaml: disable-resume 1243 Do not allow the pipeline to resume if the master restarts 1244 1245 Requires the Jenkins :jenkins-plugins:`Pipeline Job Plugin 1246 <workflow-aggregator>`. 1247 1248 Example: 1249 1250 .. literalinclude:: 1251 /../../tests/properties/fixtures/disable-resume.yaml 1252 :language: yaml 1253 1254 """ 1255 XML.SubElement( 1256 xml_parent, 1257 "org.jenkinsci.plugins.workflow.job.properties." "DisableResumeJobProperty", 1258 ) 1259 1260 1261def resource_gating(registry, xml_parent, data): 1262 """yaml: resource-gating 1263 Jenkins Gating enables requiring external resources to be available before 1264 build starts. 1265 1266 Requires the Jenkins: :jenkins-plugins:`Jenkins Gating <gating-core>`. 1267 1268 :arg list resources: Resource identifiers to be up before building 1269 1270 Example: 1271 1272 .. literalinclude:: /../../tests/properties/fixtures/gating-core.yaml 1273 :language: yaml 1274 """ 1275 if "resources" not in data.keys(): 1276 raise MissingAttributeError("resources") 1277 1278 gating = XML.SubElement( 1279 xml_parent, "io.jenkins.plugins.gating.ResourceRequirementProperty" 1280 ) 1281 gating.set("plugin", "gating-core") 1282 1283 resources = XML.SubElement(gating, "resources") 1284 resources.set("class", "java.util.Collections$UnmodifiableRandomAccessList") 1285 resources.set("resolves-to", "java.util.Collections$UnmodifiableList") 1286 1287 c = XML.SubElement(resources, "c") 1288 c.set("class", "list") 1289 for resource in data["resources"]: 1290 XML.SubElement(c, "string").text = str(resource) 1291 1292 lst = XML.SubElement(resources, "list") 1293 lst.set("reference", "../c") 1294 1295 1296def cachet_gating(registry, xml_parent, data): 1297 """yaml: cachet-gating 1298 The Cachet Gating Plugin provides a gating mechanism 1299 based on the availability of resources. 1300 1301 Requires the Jenkins: :jenkins-plugins:`Cachet Gate Plugin 1302 <cachet-gating>`. 1303 1304 :arg bool required-resources: Confirm availability of listed 1305 resources before building. Requires the list of resources to 1306 also be defined. (default true) 1307 :arg list resources: which resources to gate 1308 1309 Example: 1310 1311 .. literalinclude:: /../../tests/properties/fixtures/cachet-gating.yaml 1312 :language: yaml 1313 """ 1314 cachet = XML.SubElement( 1315 xml_parent, "com.redhat.jenkins.plugins.cachet.CachetJobProperty" 1316 ) 1317 cachet.set("plugin", "cachet-gating") 1318 1319 mapping = [("required-resources", "requiredResources", True)] 1320 helpers.convert_mapping_to_xml(cachet, data, mapping, fail_required=True) 1321 1322 resources_data = data.get("resources", []) 1323 if resources_data: 1324 resources = XML.SubElement(cachet, "resources") 1325 for resource in resources_data: 1326 XML.SubElement(resources, "string").text = str(resource) 1327 1328 1329def office_365_connector(registry, xml_parent, data): 1330 """yaml: office-365-connector 1331 Used to send actionable messages to MS Outlook or Teams 1332 1333 Requires the Jenkins: :jenkins-plugins:` Office-365-Connector Plugin 1334 <Office-365-Connector>`. 1335 1336 :arg list webhooks: List of webhooks (required) 1337 1338 * **url** (srt): URL generated in the Office 365 Connectors page (required) 1339 * **name** (str): Allows to provide name fo the connection. Name is not 1340 mandatory but helps managing when there are many connection 1341 assigned to the build (optional, default '') 1342 * **start-notification** (bool): If the notification should be sent on 1343 start of build (optional, default False) 1344 * **notify-success** (bool): If the notification should be sent on 1345 succeeded build (optional, default True) 1346 * **notify-aborted** (bool): If the notification should be sent on 1347 aborted build (optional, default False) 1348 * **notify-not-built** (bool): If the notification should be sent on 1349 not built build (optional, default False) 1350 * **notify-unstable** (bool): If the notification should be sent on 1351 unstable build (optional, default True) 1352 * **notify-failure** (bool): If the notification should be sent on 1353 failed build (optional, default True) 1354 * **notify-back-to-normal** (bool): If the notification should be sent on 1355 back to normal build (optional, default True) 1356 * **notify-repeated-failure** (bool): If the notification should be sent on 1357 repeated failures (optional, default False) 1358 * **timeout** (int): connection timeout (in milliseconds) for TCP and HTTP 1359 (optional, default 30000) 1360 * **macros** (list): List of macros 1361 1362 * **template** (str) 1363 **value** (str) 1364 1365 * **fact-definitions** (list): List of fact definitions 1366 1367 * **name** (str) 1368 **template** (str) 1369 1370 Example: 1371 1372 .. literalinclude:: /../../tests/properties/fixtures/office-365-connector-full.yaml 1373 :language: yaml 1374 """ 1375 1376 office_365_connector = XML.SubElement( 1377 xml_parent, "jenkins.plugins.office365connector.WebhookJobProperty" 1378 ) 1379 office_365_connector.set("plugin", "Office-365-Connector") 1380 webhooks = XML.SubElement(office_365_connector, "webhooks") 1381 1382 webhook_mapping = [ 1383 ("url", "url", None), 1384 ("name", "name", ""), 1385 ("start-notification", "startNotification", False), 1386 ("notify-success", "notifySuccess", True), 1387 ("notify-aborted", "notifyAborted", False), 1388 ("notify-not-built", "notifyNotBuilt", False), 1389 ("notify-unstable", "notifyUnstable", True), 1390 ("notify-failure", "notifyFailure", True), 1391 ("notify-back-to-normal", "notifyBackToNormal", True), 1392 ("notify-repeated-failure", "notifyRepeatedFailure", False), 1393 ("timeout", "timeout", 30000), 1394 ] 1395 macro_mapping = [("template", "template", None), ("value", "value", None)] 1396 fact_definition_mapping = [("name", "name", None), ("template", "template", None)] 1397 1398 if "webhooks" not in data.keys(): 1399 raise MissingAttributeError("webhooks") 1400 1401 for webhook_data in data["webhooks"]: 1402 webhook_element = XML.SubElement( 1403 webhooks, "jenkins.plugins.office365connector.Webhook" 1404 ) 1405 helpers.convert_mapping_to_xml( 1406 webhook_element, webhook_data, webhook_mapping, fail_required=True 1407 ) 1408 if "macros" in webhook_data.keys(): 1409 macros = XML.SubElement(webhook_element, "macros") 1410 for macro_data in webhook_data["macros"]: 1411 macro_element = XML.SubElement( 1412 macros, "jenkins.plugins.office365connector.model.Macro" 1413 ) 1414 helpers.convert_mapping_to_xml( 1415 macro_element, macro_data, macro_mapping, fail_required=True 1416 ) 1417 if "fact-definitions" in webhook_data.keys(): 1418 fact_definitions = XML.SubElement(webhook_element, "factDefinitions") 1419 for fact_definition_data in webhook_data["fact-definitions"]: 1420 fact_definition_element = XML.SubElement( 1421 fact_definitions, 1422 "jenkins.plugins.office365connector.model.FactDefinition", 1423 ) 1424 helpers.convert_mapping_to_xml( 1425 fact_definition_element, 1426 fact_definition_data, 1427 fact_definition_mapping, 1428 fail_required=True, 1429 ) 1430 1431 1432def speed_durability(registry, xml_parent, data): 1433 """yaml: speed-durability 1434 This setting allows users to change the default durability mode 1435 for running Pipelines. 1436 1437 :arg str hint: speed durability hint to be used, can be performance-optimized, 1438 survivable-non-atomic, max-survivability 1439 1440 Example: 1441 1442 .. literalinclude:: 1443 /../../tests/properties/fixtures/speed-durability.yaml 1444 :language: yaml 1445 """ 1446 dhp = XML.SubElement( 1447 xml_parent, 1448 "org.jenkinsci.plugins.workflow.job.properties.DurabilityHintJobProperty", 1449 ) 1450 choicedict = { 1451 "performance-optimized": "PERFORMANCE_OPTIMIZED", 1452 "survivable-non-atomic": "SURVIVABLE_NONATOMIC", 1453 "max-survivability": "MAX_SURVIVABILITY", 1454 } 1455 mapping = [("hint", "hint", None, choicedict)] 1456 helpers.convert_mapping_to_xml(dhp, data, mapping, fail_required=True) 1457 1458 1459class Properties(jenkins_jobs.modules.base.Base): 1460 sequence = 20 1461 1462 component_type = "property" 1463 component_list_type = "properties" 1464 1465 def gen_xml(self, xml_parent, data): 1466 properties = xml_parent.find("properties") 1467 if properties is None: 1468 properties = XML.SubElement(xml_parent, "properties") 1469 1470 for prop in data.get("properties", []): 1471 self.registry.dispatch("property", properties, prop, job_data=data) 1472