1# Copyright 2012 Hewlett-Packard Development Company, L.P. 2# Copyright 2012 Varnish Software AS 3# Copyright 2013-2014 Antoine "hashar" Musso 4# Copyright 2013-2014 Wikimedia Foundation Inc. 5# 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15# License for the specific language governing permissions and limitations 16# under the License. 17 18 19""" 20Publishers define actions that the Jenkins job should perform after 21the build is complete. 22 23**Component**: publishers 24 :Macro: publisher 25 :Entry Point: jenkins_jobs.publishers 26""" 27 28import logging 29import pkg_resources 30import sys 31import xml.etree.ElementTree as XML 32 33import six 34 35from jenkins_jobs.errors import InvalidAttributeError 36from jenkins_jobs.errors import JenkinsJobsException 37from jenkins_jobs.errors import MissingAttributeError 38import jenkins_jobs.modules.base 39from jenkins_jobs.modules import hudson_model 40import jenkins_jobs.modules.helpers as helpers 41 42logger = logging.getLogger(__name__) 43 44 45def influx_db(registry, xml_parent, data): 46 """yaml: influx-db 47 Requires the Jenkins :jenkins-plugins: `Influx DB 48 <influxdb>`. 49 """ 50 51 influx_db = XML.SubElement( 52 xml_parent, 53 "jenkinsci.plugins.influxdb.InfluxDbPublisher", 54 {"plugin": "influx-db"}, 55 ) 56 57 mapping = [ 58 ("selected-target", "selectedTarget", ""), 59 ("custom-project-name", "customProjectName", ""), 60 ("custom-prefix", "customPrefix", ""), 61 ("jenkins-env-parameter-field", "jenkinsEnvParameterField", ""), 62 ("jenkins-env-parameter-tag", "jenkinsEnvParameterTag", ""), 63 ] 64 65 helpers.convert_mapping_to_xml(influx_db, data, mapping, fail_required=True) 66 67 68def allure(registry, xml_parent, data): 69 """yaml: allure 70 71 Publish Allure report for the build. Requires the Jenkins 72 :jenkins-plugins:`Allure Plugin <allure-jenkins-plugin>`. 73 74 :arg str jdk: String identifier for a JDK installation in Jenkins 75 :arg str commandline: String identifier for a Allure-commandline tool 76 installation 77 :arg str report-build-policy: String identifier for a report build 78 policy enum. Possible values: 'ALWAYS', 'UNSTABLE', 'UNSUCCESSFUL'. 79 (By default is 'ALWAYS') 80 :arg bool include-properties: Flag to include specified properties 81 :arg list results-paths: List of results directories 82 :arg list properties: List of key:value property pairs 83 84 Minimal Example: 85 86 .. literalinclude:: 87 /../../tests/publishers/fixtures/allure-minimal.yaml 88 :language: yaml 89 90 Full Example: 91 92 .. literalinclude:: /../../tests/publishers/fixtures/allure-full.yaml 93 :language: yaml 94 95 """ 96 publisher_class = "ru.yandex.qatools.allure.jenkins.AllureReportPublisher" 97 property_class = "ru.yandex.qatools.allure.jenkins.config.PropertyConfig" 98 results_class = "ru.yandex.qatools.allure.jenkins.config.ResultsConfig" 99 100 allure_publisher = XML.SubElement(xml_parent, publisher_class) 101 allure_publisher.set("plugin", "allure-jenkins-plugin") 102 config = XML.SubElement(allure_publisher, "config") 103 104 results = XML.SubElement(config, "results") 105 if "results-paths" in data: 106 for results_path in data["results-paths"]: 107 entry = XML.SubElement(results, results_class) 108 path = XML.SubElement(entry, "path") 109 path.text = results_path["path"] 110 111 properties = XML.SubElement(config, "properties") 112 if "properties" in data: 113 property_mapping = [("key", "key", None), ("value", "value", None)] 114 for prop in data["properties"]: 115 entry = XML.SubElement(properties, property_class) 116 helpers.convert_mapping_to_xml( 117 entry, prop, property_mapping, fail_required=True 118 ) 119 else: 120 properties.set("class", "empty-list") 121 122 mapping = [ 123 ("jdk", "jdk", ""), 124 ("commandline", "commandline", ""), 125 ( 126 "report-build-policy", 127 "reportBuildPolicy", 128 "ALWAYS", 129 ["ALWAYS", "UNSTABLE", "UNSUCCESSFUL"], 130 ), 131 ("include-properties", "includeProperties", False), 132 ] 133 134 helpers.convert_mapping_to_xml(config, data, mapping, fail_required=True) 135 136 137def archive(registry, xml_parent, data): 138 """yaml: archive 139 Archive build artifacts 140 141 :arg str artifacts: path specifier for artifacts to archive 142 :arg str excludes: path specifier for artifacts to exclude (optional) 143 :arg bool latest-only: only keep the artifacts from the latest 144 successful build 145 :arg bool allow-empty: pass the build if no artifacts are 146 found (default false) 147 :arg bool only-if-success: archive artifacts only if build is successful 148 (default false) 149 :arg bool fingerprint: fingerprint all archived artifacts (default false) 150 :arg bool default-excludes: This option allows you to enable or disable the 151 default Ant exclusions. (default true) 152 :arg bool case-sensitive: Treat include and exclude patterns as case 153 sensitive. (default true) 154 155 Example: 156 157 .. literalinclude:: /../../tests/publishers/fixtures/archive001.yaml 158 :language: yaml 159 """ 160 archiver = XML.SubElement(xml_parent, "hudson.tasks.ArtifactArchiver") 161 mapping = [ 162 ("artifacts", "artifacts", None), 163 ("allow-empty", "allowEmptyArchive", False), 164 ("only-if-success", "onlyIfSuccessful", False), 165 ("fingerprint", "fingerprint", False), 166 ("default-excludes", "defaultExcludes", True), 167 ("case-sensitive", "caseSensitive", True), 168 ("latest-only", "latestOnly", False), 169 ] 170 171 if "excludes" in data: 172 mapping.append(("excludes", "excludes", None)) 173 helpers.convert_mapping_to_xml(archiver, data, mapping, fail_required=True) 174 175 176def blame_upstream(registry, xml_parent, data): 177 """yaml: blame-upstream 178 Notify upstream committers when build fails 179 180 Requires the Jenkins :jenkins-github:`Blame Upstream Committers Plugin 181 <blame-upstream-commiters-plugin>`. 182 183 Example: 184 185 .. literalinclude:: /../../tests/publishers/fixtures/blame001.yaml 186 :language: yaml 187 """ 188 189 XML.SubElement( 190 xml_parent, 191 "hudson.plugins.blame__upstream__commiters." "BlameUpstreamCommitersPublisher", 192 ) 193 194 195def jclouds(registry, xml_parent, data): 196 """yaml: jclouds 197 JClouds Cloud Storage Settings provides a way to store artifacts on 198 JClouds supported storage providers. Requires the Jenkins 199 :jenkins-plugins:`JClouds Plugin <jclouds-jenkins>`. 200 201 JClouds Cloud Storage Settings must be configured for the Jenkins instance. 202 203 :arg str profile: preconfigured storage profile (required) 204 :arg str files: files to upload (regex) (required) 205 :arg str basedir: the source file path (relative to workspace, Optional) 206 :arg str container: the destination container name (required) 207 :arg bool hierarchy: keep hierarchy (default false) 208 209 Example: 210 211 .. literalinclude:: /../../tests/publishers/fixtures/jclouds001.yaml 212 213 """ 214 215 deployer = XML.SubElement( 216 xml_parent, "jenkins.plugins.jclouds.blobstore." "BlobStorePublisher" 217 ) 218 entries = XML.SubElement(deployer, "entries") 219 deployer_entry = XML.SubElement( 220 entries, "jenkins.plugins.jclouds.blobstore." "BlobStoreEntry" 221 ) 222 deployer_mapping = [("profile", "profileName", None)] 223 helpers.convert_mapping_to_xml(deployer, data, deployer_mapping, fail_required=True) 224 try: 225 XML.SubElement(deployer_entry, "container").text = data["container"] 226 XML.SubElement(deployer_entry, "sourceFile").text = data["files"] 227 except KeyError as e: 228 raise JenkinsJobsException("blobstore requires '%s' to be set" % e.args[0]) 229 deployer_entry_mapping = [ 230 ("hierarchy", "keepHierarchy", False), 231 ("basedir", "path", ""), 232 ] 233 helpers.convert_mapping_to_xml( 234 deployer_entry, data, deployer_entry_mapping, fail_required=True 235 ) 236 237 238def javadoc(registry, xml_parent, data): 239 """yaml: javadoc 240 Publish Javadoc 241 Requires the Jenkins :jenkins-plugins:`Javadoc Plugin <javadoc>`. 242 243 :arg str directory: Directory relative to the root of the workspace, 244 such as 'myproject/build/javadoc' (optional) 245 :arg bool keep-all-successful: When true, it will retain Javadoc for each 246 successful build. This allows you to browse Javadoc for older builds, 247 at the expense of additional disk space requirement. If false, it will 248 only keep the latest Javadoc, so older Javadoc will be overwritten as 249 new builds succeed. (default false) 250 251 Example: 252 253 .. literalinclude:: /../../tests/publishers/fixtures/javadoc001.yaml 254 :language: yaml 255 """ 256 257 root = XML.SubElement(xml_parent, "hudson.tasks.JavadocArchiver") 258 259 mapping = [ 260 ("directory", "javadocDir", None), 261 ("keep-all-successful", "keepAll", False), 262 ] 263 helpers.convert_mapping_to_xml(root, data, mapping, fail_required=False) 264 265 266def jdepend(registry, xml_parent, data): 267 """yaml: jdepend 268 Publish jdepend report 269 Requires the :jenkins-plugins:`JDepend Plugin <jdepend>`. 270 271 :arg str file: path to jdepend file (required) 272 273 Example: 274 275 .. literalinclude:: /../../tests/publishers/fixtures/jdepend001.yaml 276 :language: yaml 277 """ 278 jdepend = XML.SubElement(xml_parent, "hudson.plugins.jdepend.JDependRecorder") 279 mapping = [("file", "configuredJDependFile", None)] 280 helpers.convert_mapping_to_xml(jdepend, data, mapping, fail_required=True) 281 282 283def hue_light(registry, xml_parent, data): 284 """yaml: hue-light 285 This plugin shows the state of your builds using the awesome Philips hue 286 lights. 287 288 Requires the Jenkins :jenkins-plugins:`hue-light Plugin 289 <hue-light>`. 290 291 :arg int light-id: ID of light. Define multiple lights by a comma as a 292 separator (required) 293 :arg str pre-build: Colour of building state (default 'blue') 294 :arg str good-build: Colour of successful state (default 'green') 295 :arg str unstable-build: Colour of unstable state (default 'yellow') 296 :arg str bad-build: Colour of unsuccessful state (default 'red') 297 298 Full Example: 299 300 .. literalinclude:: 301 /../../tests/publishers/fixtures/hue-light-full.yaml 302 :language: yaml 303 304 Minimal Example: 305 306 .. literalinclude:: 307 /../../tests/publishers/fixtures/hue-light-minimal.yaml 308 :language: yaml 309 """ 310 311 hue_light = XML.SubElement( 312 xml_parent, "org.jenkinsci.plugins.hue__light.LightNotifier" 313 ) 314 hue_light.set("plugin", "hue-light") 315 lightId = XML.SubElement(hue_light, "lightId") 316 317 id_mapping = [("light-id", "string", None)] 318 helpers.convert_mapping_to_xml(lightId, data, id_mapping, fail_required=True) 319 320 build_mapping = [ 321 ("pre-build", "preBuild", "blue"), 322 ("good-build", "goodBuild", "green"), 323 ("unstable-build", "unstableBuild", "yellow"), 324 ("bad-build", "badBuild", "red"), 325 ] 326 helpers.convert_mapping_to_xml(hue_light, data, build_mapping, fail_required=True) 327 328 329def campfire(registry, xml_parent, data): 330 """yaml: campfire 331 Send build notifications to Campfire rooms. 332 Requires the Jenkins :jenkins-plugins:`Campfire Plugin <campfire>`. 333 334 Campfire notifications global default values must be configured for 335 the Jenkins instance. Default values will be used if no specific 336 values are specified for each job, so all config params are optional. 337 338 :arg str subdomain: override the default campfire subdomain 339 :arg str token: override the default API token 340 :arg bool ssl: override the default 'use SSL' 341 :arg str room: override the default room name 342 343 Example: 344 345 .. literalinclude:: /../../tests/publishers/fixtures/campfire001.yaml 346 :language: yaml 347 """ 348 349 root = XML.SubElement(xml_parent, "hudson.plugins.campfire." "CampfireNotifier") 350 campfire = XML.SubElement(root, "campfire") 351 352 mapping = [ 353 ("subdomain", "subdomain", None), 354 ("token", "token", None), 355 ("ssl", "ssl", None), 356 ] 357 helpers.convert_mapping_to_xml(campfire, data, mapping, fail_required=False) 358 359 if "room" in data: 360 room = XML.SubElement(root, "room") 361 mapping = [("room", "name", None)] 362 helpers.convert_mapping_to_xml(room, data, mapping, fail_required=True) 363 364 XML.SubElement(room, 'campfire reference="../../campfire"') 365 366 367def mqtt(registry, xml_parent, data): 368 """yaml: mqtt 369 This plugin lets you send build notifications to a MQTT message queue. 370 Requires the :jenkins-plugins:`MQTT Notification Plugin 371 <mqtt-notification-plugin>`. 372 373 :arg str broker-url: the broker URL, as protocol://address:port (required) 374 :arg str credentials-id: credentials to use to connect to the broker 375 (optional) 376 :arg str topic: the message topic (default "jenkins/$PROJECT_URL") 377 :arg str message: the message itself (default "$BUILD_RESULT") 378 :arg str qos: one of AT_MOST_ONCE, AT_LEAST_ONCE, or EXACTLY_ONCE 379 (default AT_MOST_ONCE) 380 :arg bool retain-message: whether to resend message or not when a new 381 client connects (default false) 382 383 Minimal Example: 384 385 .. literalinclude:: /../../tests/publishers/fixtures/mqtt-minimal.yaml 386 :language: yaml 387 388 Full Example: 389 390 .. literalinclude:: /../../tests/publishers/fixtures/mqtt-full.yaml 391 :language: yaml 392 """ 393 394 mqtt = XML.SubElement(xml_parent, "jenkins.plugins.mqttnotification.MqttNotifier") 395 mqtt.set("plugin", "mqtt-notification-plugin") 396 mqtt_mapping = [("broker-url", "brokerUrl", None)] 397 helpers.convert_mapping_to_xml(mqtt, data, mqtt_mapping, fail_required=True) 398 mqtt_mapping = [ 399 ("credentials-id", "credentialsId", None), 400 ("topic", "topic", "jenkins/$PROJECT_URL"), 401 ("message", "message", "$BUILD_RESULT"), 402 ( 403 "qos", 404 "qos", 405 "AT_MOST_ONCE", 406 {"AT_MOST_ONCE": "0", "AT_LEAST_ONCE": "1", "EXACTLY_ONCE": "2"}, 407 ), 408 ("retain-message", "retainMessage", False), 409 ] 410 helpers.convert_mapping_to_xml(mqtt, data, mqtt_mapping, fail_required=False) 411 412 413def codecover(registry, xml_parent, data): 414 """yaml: codecover 415 This plugin allows you to capture code coverage report from CodeCover. 416 Jenkins will generate the trend report of coverage. 417 Requires the Jenkins :jenkins-plugins:`CodeCover Plugin <codecover>`. 418 419 :arg str include: Specify the path to the CodeCover HTML report file, 420 relative to the workspace root (default '') 421 :arg int min-statement: Minimum statement threshold (default 0) 422 :arg int max-statement: Maximum statement threshold (default 90) 423 :arg int min-branch: Minimum branch threshold (default 0) 424 :arg int max-branch: Maximum branch threshold (default 80) 425 :arg int min-loop: Minimum loop threshold (default 0) 426 :arg int max-loop: Maximum loop threshold (default 50) 427 :arg int min-condition: Minimum condition threshold (default 0) 428 :arg int max-condition: Maximum conditon threshold (default 50) 429 430 Minimal Example: 431 432 .. literalinclude:: 433 /../../tests/publishers/fixtures/codecover-minimal.yaml 434 :language: yaml 435 436 Full Example: 437 438 .. literalinclude:: 439 /../../tests/publishers/fixtures/codecover-full.yaml 440 :language: yaml 441 """ 442 443 codecover = XML.SubElement( 444 xml_parent, "hudson.plugins.codecover.CodeCoverPublisher" 445 ) 446 codecover.set("plugin", "codecover") 447 448 XML.SubElement(codecover, "includes").text = str(data.get("include", "")) 449 450 health_report = XML.SubElement(codecover, "healthReports") 451 mapping = [ 452 ("min-statement", "minStatement", 0), 453 ("max-statement", "maxStatement", 90), 454 ("min-branch", "minBranch", 0), 455 ("max-branch", "maxBranch", 80), 456 ("min-loop", "minLoop", 0), 457 ("max-loop", "maxLoop", 50), 458 ("min-condition", "minCondition", 0), 459 ("max-condition", "maxCondition", 50), 460 ] 461 helpers.convert_mapping_to_xml(health_report, data, mapping, fail_required=True) 462 463 464def emotional_jenkins(registry, xml_parent, data): 465 """yaml: emotional-jenkins 466 Emotional Jenkins. This funny plugin changes the expression of Mr. Jenkins 467 in the background when your builds fail. 468 469 Requires the Jenkins :jenkins-plugins:`Emotional Jenkins Plugin 470 <emotional-jenkins-plugin>`. 471 472 Example: 473 474 .. literalinclude:: 475 /../../tests/publishers/fixtures/emotional-jenkins.yaml 476 :language: yaml 477 """ 478 XML.SubElement( 479 xml_parent, 480 "org.jenkinsci.plugins.emotional__jenkins." "EmotionalJenkinsPublisher", 481 ) 482 483 484def trigger_parameterized_builds(registry, xml_parent, data): 485 """yaml: trigger-parameterized-builds 486 Trigger parameterized builds of other jobs. 487 Requires the Jenkins :jenkins-plugins:`Parameterized Trigger Plugin 488 <parameterized-trigger>`. 489 490 Use of the `node-label-name` or `node-label` parameters 491 requires the Jenkins :jenkins-plugins:`NodeLabel Parameter Plugin 492 <nodelabelparameter>`. 493 Note: 'node-parameters' overrides the Node that the triggered 494 project is tied to. 495 496 :arg list project: list the jobs to trigger, will generate comma-separated 497 string containing the named jobs. 498 :arg str predefined-parameters: parameters to pass to the other 499 job (optional) 500 :arg bool current-parameters: Whether to include the parameters passed 501 to the current build to the triggered job (optional) 502 :arg bool node-parameters: Use the same Node for the triggered builds 503 that was used for this build. (optional) 504 :arg bool svn-revision: Pass svn revision to the triggered job (optional) 505 :arg bool include-upstream: Include/pass through Upstream SVN Revisons. 506 Only valid when 'svn-revision' is true. (default false) 507 :arg dict git-revision: Passes git revision to the triggered job 508 (optional). 509 510 * **combine-queued-commits** (bool): Whether to combine queued git 511 hashes or not (default false) 512 513 :arg bool combine-queued-commits: Combine Queued git hashes. Only valid 514 when 'git-revision' is true. (default false) 515 516 .. deprecated:: 1.5.0 Please use `combine-queued-commits` under the 517 `git-revision` argument instead. 518 519 :arg dict boolean-parameters: Pass boolean parameters to the downstream 520 jobs. Specify the name and boolean value mapping of the parameters. 521 (optional) 522 :arg str condition: when to trigger the other job. Can be: 'SUCCESS', 523 'UNSTABLE', 'FAILED_OR_BETTER', 'UNSTABLE_OR_BETTER', 524 'UNSTABLE_OR_WORSE', 'FAILED', 'ALWAYS'. (default 'ALWAYS') 525 :arg str property-file: Use properties from file (optional) 526 :arg bool fail-on-missing: Blocks the triggering of the downstream jobs 527 if any of the property files are not found in the workspace. 528 Only valid when 'property-file' is specified. 529 (default 'False') 530 :arg bool property-multiline: When enabled properties containing 531 newline character(s) are propagated as TextParameterValue which is 532 a specialized StringParameterValue commonly used for handling 533 multi-line strings in Jenkins. When disabled (default) 534 all properties are propagated as StringParameterValue. (default 535 'False') (>=2.35.2) 536 :arg bool trigger-from-child-projects: Trigger build from child projects. 537 Used for matrix projects. (default 'False') 538 :arg bool use-matrix-child-files: Use files in workspaces of child 539 builds (default 'False') 540 :arg str matrix-child-combination-filter: A Groovy expression to filter 541 the child builds to look in for files 542 :arg bool only-exact-matrix-child-runs: Use only child builds triggered 543 exactly by the parent. 544 :arg str file-encoding: Encoding of contents of the files. If not 545 specified, default encoding of the platform is used. Only valid when 546 'property-file' is specified. (optional) 547 :arg bool trigger-with-no-params: Trigger a build even when there are 548 currently no parameters defined (default 'False') 549 :arg str restrict-matrix-project: Filter that restricts the subset 550 of the combinations that the downstream project will run (optional) 551 :arg str node-label-name: Specify the Name for the NodeLabel parameter. 552 (optional) 553 :arg str node-label: Specify the Node for the NodeLabel parameter. 554 (optional) 555 556 Example: 557 558 .. literalinclude:: 559 /../../tests/publishers/fixtures/trigger_parameterized_builds001.yaml 560 :language: yaml 561 .. literalinclude:: 562 /../../tests/publishers/fixtures/trigger_parameterized_builds003.yaml 563 :language: yaml 564 """ 565 pt_prefix = "hudson.plugins.parameterizedtrigger." 566 tbuilder = XML.SubElement(xml_parent, pt_prefix + "BuildTrigger") 567 configs = XML.SubElement(tbuilder, "configs") 568 569 param_order = helpers.trigger_get_parameter_order( 570 registry, "trigger-parameterized-builds" 571 ) 572 573 for project_def in data: 574 tconfig = XML.SubElement(configs, pt_prefix + "BuildTriggerConfig") 575 tconfigs = XML.SubElement(tconfig, "configs") 576 577 helpers.trigger_project(tconfigs, project_def, registry, param_order) 578 579 if not list(tconfigs): 580 # no child parameter tags added 581 tconfigs.set("class", "java.util.Collections$EmptyList") 582 583 projects = XML.SubElement(tconfig, "projects") 584 585 if isinstance(project_def["project"], list): 586 projects.text = ",".join(project_def["project"]) 587 else: 588 projects.text = project_def["project"] 589 590 condition = XML.SubElement(tconfig, "condition") 591 condition.text = project_def.get("condition", "ALWAYS") 592 mapping = [ 593 ("trigger-from-child-projects", "triggerFromChildProjects", False), 594 ("trigger-with-no-params", "triggerWithNoParameters", False), 595 ] 596 helpers.convert_mapping_to_xml( 597 tconfig, project_def, mapping, fail_required=False 598 ) 599 600 601def trigger(registry, xml_parent, data): 602 """yaml: trigger 603 Trigger non-parametrised builds of other jobs. 604 605 :arg str project: name of the job to trigger 606 :arg str threshold: when to trigger the other job (default 'SUCCESS'), 607 alternatives: SUCCESS, UNSTABLE, FAILURE 608 609 Example: 610 611 .. literalinclude:: /../../tests/publishers/fixtures/trigger_success.yaml 612 :language: yaml 613 """ 614 tconfig = XML.SubElement(xml_parent, "hudson.tasks.BuildTrigger") 615 childProjects = XML.SubElement(tconfig, "childProjects") 616 childProjects.text = data["project"] 617 618 threshold = data.get("threshold", "SUCCESS") 619 supported_thresholds = ["SUCCESS", "UNSTABLE", "FAILURE"] 620 helpers.trigger_threshold( 621 tconfig, "threshold", threshold, supported_thresholds=supported_thresholds 622 ) 623 624 625def clone_workspace(registry, xml_parent, data): 626 """yaml: clone-workspace 627 Archive the workspace from builds of one project and reuse them as the SCM 628 source for another project. 629 Requires the Jenkins :jenkins-plugins:`Clone Workspace SCM Plugin 630 <clone-workspace-scm>`. 631 632 :arg str workspace-glob: Files to include in cloned workspace (default '') 633 :arg str workspace-exclude-glob: Files to exclude from cloned workspace 634 :arg str criteria: Criteria for build to be archived. Can be 'any', 635 'not failed', or 'successful'. (default 'any') 636 :arg str archive-method: Choose the method to use for archiving the 637 workspace. Can be 'tar' or 'zip'. (default 'tar') 638 :arg bool override-default-excludes: Override default ant excludes. 639 (default false) 640 641 Minimal example: 642 643 .. literalinclude:: 644 /../../tests/publishers/fixtures/clone-workspace001.yaml 645 :language: yaml 646 647 Full example: 648 649 .. literalinclude:: 650 /../../tests/publishers/fixtures/clone-workspace002.yaml 651 :language: yaml 652 """ 653 654 cloneworkspace = XML.SubElement( 655 xml_parent, "hudson.plugins.cloneworkspace.CloneWorkspacePublisher" 656 ) 657 cloneworkspace.set("plugin", "clone-workspace-scm") 658 659 criteria_valid_types = ["Any", "Not Failed", "Successful"] 660 archive_valid_types = ["TAR", "ZIP"] 661 662 mappings = [ 663 ("workspace-glob", "workspaceGlob", ""), 664 ("override-default-excludes", "overrideDefaultExcludes", False), 665 ("criteria", "criteria", "Any", criteria_valid_types), 666 ("archive-method", "archiveMethod", "TAR", archive_valid_types), 667 ] 668 helpers.convert_mapping_to_xml(cloneworkspace, data, mappings, fail_required=True) 669 670 mappings = [("workspace-exclude-glob", "workspaceExcludeGlob", "")] 671 helpers.convert_mapping_to_xml(cloneworkspace, data, mappings, fail_required=False) 672 673 674def cloud_foundry(parser, xml_parent, data): 675 """yaml: cloudfoundry 676 Pushes a project to Cloud Foundry or a CF-based platform (e.g. Stackato) at 677 the end of a build. Requires the Jenkins :jenkins-plugins:`Cloud Foundry 678 Plugin <cloudfoundry>`. 679 680 :arg str target: The API endpoint of the platform you want to push to. 681 This is the URL you use to access the platform, possibly with ".api" 682 added. (required) 683 :arg str organization: An org is a development account that an individual 684 or multiple collaborators can own and use (required) 685 :arg str space: Provide users with access to a shared location for 686 application development, deployment, and maintenance (required) 687 :arg str credentials-id: credentials-id of the user (required) 688 :arg bool self-signed: Allow self-signed SSL certificates from the target 689 (default false) 690 :arg bool reset-app: Delete app before pushing app's configurations 691 (default false) 692 :arg int plugin-timeout: The time in seconds before the Cloud Foundry 693 plugin stops fetching logs and marks the build a failure (default 120) 694 :arg list create-services: Create services automatically (default '') 695 696 :create-services: 697 * **name** ('str') -- Service name (default '') 698 * **type** ('str') -- Service type (default '') 699 * **plan** ('str') -- Service plan (default '') 700 * **reset-service** ('bool') -- Delete the service before creating 701 the new one (default false) 702 :arg str value: Select to read configuration from manifest file or to enter 703 configuration in Jenkins (default 'manifestFile') 704 :arg str manifest-file: Path to manifest file (default 'manifest.yml') 705 :arg str app-name: The application's name. Default to Jenkins build name. 706 (default '') 707 :arg int memory: The application's memory usage in MB (default 512) 708 :arg str host-name: The hostname of the URI to access your application. 709 Default to app-name (default '') 710 :arg int instances: Number of instances of your application on creation 711 (default 1) 712 :arg int manifest-timeout: The time in seconds before the health-manager 713 gives up on starting the application (default 60) 714 :arg bool no-route: No URI path will be created to access the application 715 (default false) 716 :arg str app-path: Path to application (default '') 717 :arg build-pack: If your application requires a custom buildpack, you can 718 use this to specify its URL or name (default '') 719 :arg str stack: If your application requires a custom stack, you can use 720 this to specify its name. (default '') 721 :arg str command: Set a custom start command for your application 722 (default '') 723 :arg str domain: The domain of the URI to access your application 724 (default '') 725 :arg list environment-variables: Inject environment variables 726 727 :environment-variables: 728 * **key** ('str') -- Environment variable key (default '') 729 * **value** ('str') -- Environment variable value (default '') 730 :arg list services-names: Name of service instances 731 732 :services-names: 733 * **name** ('str') -- Name of the service instance (default '') 734 735 Minimal example: 736 737 .. literalinclude:: 738 /../../tests/publishers/fixtures/cloudfoundry-minimal.yaml 739 :language: yaml 740 741 Full example: 742 743 .. literalinclude:: /../../tests/publishers/fixtures/cloudfoundry-full.yaml 744 :language: yaml 745 """ 746 cloud_foundry = XML.SubElement( 747 xml_parent, "com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher" 748 ) 749 cloud_foundry.set("plugin", "cloudfoundry") 750 751 mapping = [ 752 ("target", "target", None), 753 ("organization", "organization", None), 754 ("space", "cloudSpace", None), 755 ("credentials-id", "credentialsId", None), 756 ("self-signed", "selfSigned", False), 757 ("reset-app", "resetIfExists", False), 758 ("timeout", "pluginTimeout", 120), 759 ] 760 helpers.convert_mapping_to_xml(cloud_foundry, data, mapping, fail_required=True) 761 XML.SubElement(cloud_foundry, "appURIs").text = "" 762 763 create_services = XML.SubElement(cloud_foundry, "servicesToCreate") 764 create_services_mapping = [ 765 ("name", "name", ""), 766 ("type", "type", ""), 767 ("plan", "plan", ""), 768 ("reset-service", "resetService", ""), 769 ] 770 for service in data.get("create-services", ""): 771 create_services_sub = XML.SubElement( 772 create_services, 773 "com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher_-Service", 774 ) 775 helpers.convert_mapping_to_xml( 776 create_services_sub, service, create_services_mapping, fail_required=True 777 ) 778 779 manifest = XML.SubElement(cloud_foundry, "manifestChoice") 780 valid_values = ["manifestFile", "jenkinsConfig"] 781 manifest_mapping = [ 782 ("value", "value", "manifestFile", valid_values), 783 ("manifest-file", "manifestFile", "manifest.yml"), 784 ("app-name", "appName", ""), 785 ("memory", "memory", 512), 786 ("host-name", "hostname", ""), 787 ("instances", "instances", 1), 788 ("manifest-timeout", "timeout", 60), 789 ("no-route", "noRoute", False), 790 ("app-path", "appPath", ""), 791 ("build-pack", "buildpack", ""), 792 ("stack", "stack", ""), 793 ("command", "command", ""), 794 ("domain", "domain", ""), 795 ] 796 helpers.convert_mapping_to_xml(manifest, data, manifest_mapping, fail_required=True) 797 798 if "environment-variables" in data: 799 env_vars = XML.SubElement(manifest, "envVars") 800 env_vars_mapping = [("key", "key", ""), ("value", "value", "")] 801 for var in data["environment-variables"]: 802 env_vars_sub = XML.SubElement( 803 env_vars, 804 "com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher_-" 805 "EnvironmentVariable", 806 ) 807 helpers.convert_mapping_to_xml( 808 env_vars_sub, var, env_vars_mapping, fail_required=True 809 ) 810 811 if "services-names" in data: 812 services_names = XML.SubElement(manifest, "servicesNames") 813 service_name_mapping = [("name", "name", "")] 814 for name in data["services-names"]: 815 services_names_sub = XML.SubElement( 816 services_names, 817 "com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher_-" "ServiceName", 818 ) 819 helpers.convert_mapping_to_xml( 820 services_names_sub, name, service_name_mapping, fail_required=True 821 ) 822 823 824def cloverphp(registry, xml_parent, data): 825 """yaml: cloverphp 826 Capture code coverage reports from PHPUnit 827 Requires the Jenkins :jenkins-plugins:`Clover PHP Plugin <cloverphp>`. 828 829 Your job definition should pass to PHPUnit the --coverage-clover option 830 pointing to a file in the workspace (ex: clover-coverage.xml). The filename 831 has to be filled in the `xml-location` field. 832 833 :arg str xml-location: Path to the coverage XML file generated by PHPUnit 834 using --coverage-clover. Relative to workspace. (required) 835 :arg dict html: When existent, whether the plugin should generate a HTML 836 report. Note that PHPUnit already provide a HTML report via its 837 --cover-html option which can be set in your builder (optional): 838 839 * **dir** (str): Directory where HTML report will be generated relative 840 to workspace. (required in `html` dict). 841 * **archive** (bool): Whether to archive HTML reports (default true). 842 843 :arg list metric-targets: List of metric targets to reach, must be one of 844 **healthy**, **unhealthy** and **failing**. Each metric target can 845 takes two parameters: 846 847 * **method** Target for method coverage 848 * **statement** Target for statements coverage 849 850 Whenever a metric target is not filled in, the Jenkins plugin can fill 851 in defaults for you (as of v0.3.3 of the plugin the healthy target will 852 have method: 70 and statement: 80 if both are left empty). Jenkins Job 853 Builder will mimic that feature to ensure clean configuration diff. 854 855 Minimal example: 856 857 .. literalinclude:: /../../tests/publishers/fixtures/cloverphp001.yaml 858 :language: yaml 859 860 Full example: 861 862 .. literalinclude:: /../../tests/publishers/fixtures/cloverphp002.yaml 863 :language: yaml 864 """ 865 cloverphp = XML.SubElement( 866 xml_parent, "org.jenkinsci.plugins.cloverphp.CloverPHPPublisher" 867 ) 868 cloverphp.set("plugin", "cloverphp") 869 870 # The plugin requires clover XML file to parse 871 if "xml-location" not in data: 872 raise JenkinsJobsException("xml-location must be set") 873 874 # Whether HTML publishing has been checked 875 html_publish = False 876 # By default, disableArchiving = false. Note that we use 877 # reversed logic. 878 html_archive = True 879 880 if "html" in data: 881 html_publish = True 882 html_dir = data["html"].get("dir", None) 883 html_archive = data["html"].get("archive", html_archive) 884 if html_dir is None: 885 # No point in going further, the plugin would not work 886 raise JenkinsJobsException("htmldir is required in a html block") 887 888 XML.SubElement(cloverphp, "publishHtmlReport").text = str(html_publish).lower() 889 if html_publish: 890 XML.SubElement(cloverphp, "reportDir").text = html_dir 891 XML.SubElement(cloverphp, "xmlLocation").text = data.get("xml-location") 892 XML.SubElement(cloverphp, "disableArchiving").text = str(not html_archive).lower() 893 894 # Handle targets 895 896 # Plugin v0.3.3 will fill defaults for us whenever healthy targets are both 897 # blanks. 898 default_metrics = {"healthy": {"method": 70, "statement": 80}} 899 allowed_metrics = ["healthy", "unhealthy", "failing"] 900 901 metrics = data.get("metric-targets", []) 902 # list of dicts to dict 903 metrics = dict(kv for m in metrics for kv in m.items()) 904 905 # Populate defaults whenever nothing has been filled by user. 906 for default in default_metrics.keys(): 907 if metrics.get(default, None) is None: 908 metrics[default] = default_metrics[default] 909 910 # The plugin would at least define empty targets so make sure 911 # we output them all in the XML regardless of what the user 912 # has or has not entered. 913 for target in allowed_metrics: 914 cur_target = XML.SubElement(cloverphp, target + "Target") 915 916 for t_type in ["method", "statement"]: 917 val = metrics.get(target, {}).get(t_type) 918 if val is None or type(val) != int: 919 continue 920 if val < 0 or val > 100: 921 raise JenkinsJobsException( 922 "Publisher cloverphp metric target %s:%s = %s " 923 "is not in valid range 0-100." % (target, t_type, val) 924 ) 925 XML.SubElement(cur_target, t_type + "Coverage").text = str(val) 926 927 928def coverage(registry, xml_parent, data): 929 """yaml: coverage 930 WARNING: The coverage function is deprecated. Instead, use the 931 cobertura function to generate a cobertura coverage report. 932 Requires the Jenkins :jenkins-plugins:`Cobertura Coverage Plugin 933 <cobertura>`. 934 935 Example: 936 937 .. literalinclude:: /../../tests/publishers/fixtures/coverage001.yaml 938 :language: yaml 939 """ 940 logger = logging.getLogger(__name__) 941 logger.warning("Coverage function is deprecated. Switch to cobertura.") 942 943 cobertura = XML.SubElement( 944 xml_parent, "hudson.plugins.cobertura.CoberturaPublisher" 945 ) 946 XML.SubElement(cobertura, "coberturaReportFile").text = "**/coverage.xml" 947 XML.SubElement(cobertura, "onlyStable").text = "false" 948 healthy = XML.SubElement(cobertura, "healthyTarget") 949 targets = XML.SubElement( 950 healthy, 951 "targets", 952 { 953 "class": "enum-map", 954 "enum-type": "hudson.plugins.cobertura.targets.CoverageMetric", 955 }, 956 ) 957 entry = XML.SubElement(targets, "entry") 958 XML.SubElement( 959 entry, "hudson.plugins.cobertura.targets.CoverageMetric" 960 ).text = "CONDITIONAL" 961 XML.SubElement(entry, "int").text = "70" 962 entry = XML.SubElement(targets, "entry") 963 XML.SubElement( 964 entry, "hudson.plugins.cobertura.targets.CoverageMetric" 965 ).text = "LINE" 966 XML.SubElement(entry, "int").text = "80" 967 entry = XML.SubElement(targets, "entry") 968 XML.SubElement( 969 entry, "hudson.plugins.cobertura.targets.CoverageMetric" 970 ).text = "METHOD" 971 XML.SubElement(entry, "int").text = "80" 972 unhealthy = XML.SubElement(cobertura, "unhealthyTarget") 973 targets = XML.SubElement( 974 unhealthy, 975 "targets", 976 { 977 "class": "enum-map", 978 "enum-type": "hudson.plugins.cobertura.targets.CoverageMetric", 979 }, 980 ) 981 entry = XML.SubElement(targets, "entry") 982 XML.SubElement( 983 entry, "hudson.plugins.cobertura.targets.CoverageMetric" 984 ).text = "CONDITIONAL" 985 XML.SubElement(entry, "int").text = "0" 986 entry = XML.SubElement(targets, "entry") 987 XML.SubElement( 988 entry, "hudson.plugins.cobertura.targets.CoverageMetric" 989 ).text = "LINE" 990 XML.SubElement(entry, "int").text = "0" 991 entry = XML.SubElement(targets, "entry") 992 XML.SubElement( 993 entry, "hudson.plugins.cobertura.targets.CoverageMetric" 994 ).text = "METHOD" 995 XML.SubElement(entry, "int").text = "0" 996 failing = XML.SubElement(cobertura, "failingTarget") 997 targets = XML.SubElement( 998 failing, 999 "targets", 1000 { 1001 "class": "enum-map", 1002 "enum-type": "hudson.plugins.cobertura.targets.CoverageMetric", 1003 }, 1004 ) 1005 entry = XML.SubElement(targets, "entry") 1006 XML.SubElement( 1007 entry, "hudson.plugins.cobertura.targets.CoverageMetric" 1008 ).text = "CONDITIONAL" 1009 XML.SubElement(entry, "int").text = "0" 1010 entry = XML.SubElement(targets, "entry") 1011 XML.SubElement( 1012 entry, "hudson.plugins.cobertura.targets.CoverageMetric" 1013 ).text = "LINE" 1014 XML.SubElement(entry, "int").text = "0" 1015 entry = XML.SubElement(targets, "entry") 1016 XML.SubElement( 1017 entry, "hudson.plugins.cobertura.targets.CoverageMetric" 1018 ).text = "METHOD" 1019 XML.SubElement(entry, "int").text = "0" 1020 XML.SubElement(cobertura, "sourceEncoding").text = "ASCII" 1021 1022 1023def cobertura(registry, xml_parent, data): 1024 """yaml: cobertura 1025 Generate a cobertura coverage report. 1026 Requires the Jenkins :jenkins-plugins:`Cobertura Coverage Plugin 1027 <cobertura>`. 1028 1029 :arg str report-file: This is a file name pattern that can be used 1030 to locate the cobertura xml report files (optional) 1031 :arg bool only-stable: Include only stable builds (default false) 1032 :arg bool fail-no-reports: fail builds if no coverage reports are found 1033 (default false) 1034 :arg bool fail-unhealthy: Unhealthy projects will be failed (default false) 1035 :arg bool fail-unstable: Unstable projects will be failed (default false) 1036 :arg bool health-auto-update: Auto update threshold for health on 1037 successful build (default false) 1038 :arg bool stability-auto-update: Auto update threshold for stability on 1039 successful build (default false) 1040 :arg bool zoom-coverage-chart: Zoom the coverage chart and crop area below 1041 the minimum and above the maximum coverage of the past reports 1042 (default false) 1043 :arg str source-encoding: Override the source encoding (default ASCII) 1044 :arg dict targets: 1045 1046 :targets: (packages, files, classes, method, line, conditional) 1047 1048 * **healthy** (`int`): Healthy threshold (default 0) 1049 * **unhealthy** (`int`): Unhealthy threshold (default 0) 1050 * **failing** (`int`): Failing threshold (default 0) 1051 1052 Example: 1053 1054 .. literalinclude:: /../../tests/publishers/fixtures/cobertura001.yaml 1055 :language: yaml 1056 """ 1057 cobertura = XML.SubElement( 1058 xml_parent, "hudson.plugins.cobertura.CoberturaPublisher" 1059 ) 1060 mapping = [ 1061 ("report-file", "coberturaReportFile", "**/coverage.xml"), 1062 ("only-stable", "onlyStable", False), 1063 ("fail-unhealthy", "failUnhealthy", False), 1064 ("fail-unstable", "failUnstable", False), 1065 ("health-auto-update", "autoUpdateHealth", False), 1066 ("stability-auto-update", "autoUpdateStability", False), 1067 ("zoom-coverage-chart", "zoomCoverageChart", False), 1068 ("fail-no-reports", "failNoReports", False), 1069 ] 1070 helpers.convert_mapping_to_xml(cobertura, data, mapping, fail_required=True) 1071 1072 healthy = XML.SubElement(cobertura, "healthyTarget") 1073 targets = XML.SubElement( 1074 healthy, 1075 "targets", 1076 { 1077 "class": "enum-map", 1078 "enum-type": "hudson.plugins.cobertura.targets.CoverageMetric", 1079 }, 1080 ) 1081 for item in data["targets"]: 1082 item_name = next(iter(item.keys())) 1083 item_values = item.get(item_name, 0) 1084 entry = XML.SubElement(targets, "entry") 1085 XML.SubElement( 1086 entry, "hudson.plugins.cobertura.targets." "CoverageMetric" 1087 ).text = str(item_name).upper() 1088 XML.SubElement(entry, "int").text = str(item_values.get("healthy", 0)) 1089 unhealthy = XML.SubElement(cobertura, "unhealthyTarget") 1090 targets = XML.SubElement( 1091 unhealthy, 1092 "targets", 1093 { 1094 "class": "enum-map", 1095 "enum-type": "hudson.plugins.cobertura.targets.CoverageMetric", 1096 }, 1097 ) 1098 for item in data["targets"]: 1099 item_name = next(iter(item.keys())) 1100 item_values = item.get(item_name, 0) 1101 entry = XML.SubElement(targets, "entry") 1102 XML.SubElement( 1103 entry, "hudson.plugins.cobertura.targets." "CoverageMetric" 1104 ).text = str(item_name).upper() 1105 XML.SubElement(entry, "int").text = str(item_values.get("unhealthy", 0)) 1106 failing = XML.SubElement(cobertura, "failingTarget") 1107 targets = XML.SubElement( 1108 failing, 1109 "targets", 1110 { 1111 "class": "enum-map", 1112 "enum-type": "hudson.plugins.cobertura.targets.CoverageMetric", 1113 }, 1114 ) 1115 for item in data["targets"]: 1116 item_name = next(iter(item.keys())) 1117 item_values = item.get(item_name, 0) 1118 entry = XML.SubElement(targets, "entry") 1119 XML.SubElement( 1120 entry, "hudson.plugins.cobertura.targets." "CoverageMetric" 1121 ).text = str(item_name).upper() 1122 XML.SubElement(entry, "int").text = str(item_values.get("failing", 0)) 1123 XML.SubElement(cobertura, "sourceEncoding").text = data.get( 1124 "source-encoding", "ASCII" 1125 ) 1126 1127 1128def jacoco(registry, xml_parent, data): 1129 """yaml: jacoco 1130 Generate a JaCoCo coverage report. 1131 Requires the Jenkins :jenkins-plugins:`JaCoCo Plugin <jacoco>`. 1132 1133 :arg str exec-pattern: This is a file name pattern that can be used to 1134 locate the jacoco report files (default ``**/**.exec``) 1135 :arg str class-pattern: This is a file name pattern that can be used 1136 to locate class files (default ``**/classes``) 1137 :arg str source-pattern: This is a file name pattern that can be used 1138 to locate source files (default ``**/src/main/java``) 1139 :arg str source-inclusion-pattern: This is a file name pattern that can 1140 be used to include certain source files (default ``**/*.java``) 1141 :arg bool update-build-status: Update the build according to the results 1142 (default false) 1143 :arg str inclusion-pattern: This is a file name pattern that can be used 1144 to include certain class files (default '') 1145 :arg str exclusion-pattern: This is a file name pattern that can be used 1146 to exclude certain class files (default '') 1147 :arg dict targets: 1148 1149 :targets: (instruction, branch, complexity, line, method, class) 1150 1151 * **healthy** (`int`): Healthy threshold (default 0) 1152 * **unhealthy** (`int`): Unhealthy threshold (default 0) 1153 1154 Minimal Example: 1155 1156 .. literalinclude:: /../../tests/publishers/fixtures/jacoco-minimal.yaml 1157 :language: yaml 1158 1159 Full Example: 1160 1161 .. literalinclude:: /../../tests/publishers/fixtures/jacoco-full.yaml 1162 :language: yaml 1163 """ 1164 1165 jacoco = XML.SubElement(xml_parent, "hudson.plugins.jacoco.JacocoPublisher") 1166 jacoco.set("plugin", "jacoco") 1167 1168 mappings = [ 1169 ("exec-pattern", "execPattern", "**/**.exec"), 1170 ("class-pattern", "classPattern", "**/classes"), 1171 ("source-pattern", "sourcePattern", "**/src/main/java"), 1172 ("source-inclusion-pattern", "sourceInclusionPattern", "**/*.java"), 1173 ("update-build-status", "changeBuildStatus", False), 1174 ("inclusion-pattern", "inclusionPattern", ""), 1175 ("exclusion-pattern", "exclusionPattern", ""), 1176 ] 1177 helpers.convert_mapping_to_xml(jacoco, data, mappings, fail_required=True) 1178 1179 itemsList = ["instruction", "branch", "complexity", "line", "method", "class"] 1180 1181 if "targets" in data: 1182 for item in data["targets"]: 1183 item_name = next(iter(item.keys())) 1184 if item_name not in itemsList: 1185 raise InvalidAttributeError("targets", item_name, itemsList) 1186 1187 item_values = item[item_name] 1188 if item_values: 1189 XML.SubElement( 1190 jacoco, "maximum" + item_name.capitalize() + "Coverage" 1191 ).text = str(item_values.get("healthy", 0)) 1192 XML.SubElement( 1193 jacoco, "minimum" + item_name.capitalize() + "Coverage" 1194 ).text = str(item_values.get("unhealthy", 0)) 1195 else: 1196 raise MissingAttributeError( 1197 ["healthy", "unhealthy"], "publishers.jacoco.targets." + item_name 1198 ) 1199 1200 1201def ftp(registry, xml_parent, data): 1202 """yaml: ftp 1203 Upload files via FTP. 1204 Requires the Jenkins :jenkins-plugins:`Publish over FTP Plugin 1205 <publish-over-ftp>`. 1206 1207 :arg str site: name of the ftp site (required) 1208 :arg str target: destination directory (required) 1209 :arg bool target-is-date-format: whether target is a date format. If true, 1210 raw text should be quoted (default false) 1211 :arg bool clean-remote: should the remote directory be deleted before 1212 transferring files (default false) 1213 :arg str source: source path specifier (required) 1214 :arg str excludes: excluded file pattern (optional) 1215 :arg str remove-prefix: prefix to remove from uploaded file paths 1216 (optional) 1217 :arg bool fail-on-error: fail the build if an error occurs (default false). 1218 :arg bool flatten: only create files on the server, don't create 1219 directories (default false). 1220 :arg bool verbose: adds lots of detail useful for debug to the console 1221 but generally should be left off (default false) 1222 :arg int retries: the number of times to retry this server in the event of 1223 failure (optional) 1224 :arg int retry-delay: the time to wait, in milliseconds, before attempting 1225 another transfer (default 10000) 1226 1227 Minimal Example: 1228 1229 .. literalinclude:: /../../tests/publishers/fixtures/ftp-minimal.yaml 1230 :language: yaml 1231 1232 Full Example: 1233 1234 .. literalinclude:: /../../tests/publishers/fixtures/ftp-full.yaml 1235 :language: yaml 1236 1237 """ 1238 console_prefix = "FTP: " 1239 plugin_tag = "jenkins.plugins.publish__over__ftp.BapFtpPublisherPlugin" 1240 publisher_tag = "jenkins.plugins.publish__over__ftp.BapFtpPublisher" 1241 transfer_tag = "jenkins.plugins.publish__over__ftp.BapFtpTransfer" 1242 retry_tag = "jenkins.plugins.publish_over_ftp.BapFtpRetry" 1243 plugin_reference_tag = "jenkins.plugins.publish_over_ftp." "BapFtpPublisherPlugin" 1244 (_, transfer_node) = base_publish_over( 1245 xml_parent, 1246 data, 1247 console_prefix, 1248 plugin_tag, 1249 publisher_tag, 1250 transfer_tag, 1251 retry_tag, 1252 plugin_reference_tag, 1253 ) 1254 mapping = [("", "asciiMode", "false")] 1255 helpers.convert_mapping_to_xml(transfer_node, data, mapping, fail_required=True) 1256 1257 1258def ftp_publisher(registry, xml_parent, data): 1259 """yaml: ftp-publisher 1260 This plugin can be used to upload project artifacts and whole directories 1261 to an ftp server. 1262 Requires the Jenkins :jenkins-plugins:`FTP-Publisher Plugin 1263 <ftppublisher>`. 1264 1265 :arg list uploads: List of files to upload 1266 1267 :uploads: 1268 * **file-path** ('str') -- Destination folder. It will be created 1269 if doesn't exists. Created relative to ftp root directory. 1270 (default '') 1271 * **source-file** ('str') -- Source files which will be uploaded 1272 (default '') 1273 :arg str site-name: Name of FTP server to upload to (required) 1274 :arg bool use-timestamps: Use timestamps in the FTP directory path (default 1275 false) 1276 :arg bool flatten-files: Flatten files on the FTP host (default false) 1277 :arg bool skip-publishing: Skip publishing (default false) 1278 1279 Minimal Example: 1280 1281 .. literalinclude:: 1282 /../../tests/publishers/fixtures/ftp-publisher-minimal.yaml 1283 :language: yaml 1284 1285 Full Example: 1286 1287 .. literalinclude:: 1288 /../../tests/publishers/fixtures/ftp-publisher-full.yaml 1289 :language: yaml 1290 """ 1291 ftp = XML.SubElement(xml_parent, "com.zanox.hudson.plugins.FTPPublisher") 1292 ftp.set("plugin", "ftppublisher") 1293 1294 entries = XML.SubElement(ftp, "entries") 1295 if "uploads" in data: 1296 upload_mapping = [ 1297 ("file-path", "filePath", ""), 1298 ("source-file", "sourceFile", ""), 1299 ] 1300 for upload in data["uploads"]: 1301 entry = XML.SubElement(entries, "com.zanox.hudson.plugins.Entry") 1302 helpers.convert_mapping_to_xml( 1303 entry, upload, upload_mapping, fail_required=True 1304 ) 1305 1306 mapping = [ 1307 ("site-name", "siteName", None), 1308 ("use-timestamps", "useTimestamps", False), 1309 ("flatten-files", "flatten", False), 1310 ("skip-publishing", "skip", False), 1311 ] 1312 helpers.convert_mapping_to_xml(ftp, data, mapping, fail_required=True) 1313 1314 1315def opsgenie(registry, xml_parent, data): 1316 """yaml: opsgenie 1317 OpsGenie notification on build completion, 1318 Requires the :jenkins-plugins:`OpsGenie Notifier Plugin <opsgenie>`. 1319 1320 :arg bool enable-sending-alerts: Send alerts to opsgenie. (default false) 1321 :arg bool notify-build-start: Send a notification when the build starts. (default false) 1322 :arg str api-key: This token is used to verify requests between OpsGenie and Jenkins. You can copy this key from your OpsGenie-Jenkins Integration page. (default '') 1323 :arg str tags: Comma-separated list of tags you want to add on alert. (default '') 1324 :arg str teams: Comma-separated list of teams that get notified from alert. (default '') 1325 :arg str priority: Set the priority of the alert that's going to be created at OpsGenie, if job's build fails. (default 'P3') 1326 :arg str build-starts-alerts-priority: Set the priority of the build started alert that's going to be created at OpsGenie. (default 'P3') 1327 :arg str api-url: Api url that collects the webhook. (default '') 1328 1329 Minimal example: 1330 1331 .. literalinclude:: 1332 /../../tests/publishers/fixtures/opsgenie-minimal.yaml 1333 :language: yaml 1334 1335 Full Example: 1336 1337 .. literalinclude:: 1338 /../../tests/publishers/fixtures/opsgenie-full.yaml 1339 :language: yaml 1340 """ 1341 1342 mapping = [ 1343 ("priority", "alertPriority", "P3"), 1344 ("build-starts-alerts-priority", "notifyBuildStartPriority", "P3"), 1345 ("enable-sending-alerts", "enable", "false"), 1346 ("notify-build-start", "notifyBuildStart", "false"), 1347 ("api-key", "apiKey", ""), 1348 ("api-url", "apiUrl", ""), 1349 ("tags", "tags", ""), 1350 ("teams", "teams", ""), 1351 ] 1352 1353 opsgenie_notifier = XML.SubElement( 1354 xml_parent, 1355 "com.opsgenie.integration.jenkins.OpsGenieNotifier", 1356 {"plugin": "opsgenie"}, 1357 ) 1358 1359 helpers.convert_mapping_to_xml(opsgenie_notifier, data, mapping, fail_required=True) 1360 1361 1362def rocket(registry, xml_parent, data): 1363 """yaml: rocket 1364 RocketChat notification on build completion, 1365 Requires the :jenkins-plugins:`RocketChat Notifier Plugin 1366 <rocketchatnotifier>`. 1367 1368 :arg str channel: Comma separated list of rooms (e.g. #project) 1369 or persons (e.g. @john) 1370 :arg bool abort: Notify abort (default false) 1371 :arg bool start: Notify start (default false) 1372 :arg bool success: Notify success (default false) 1373 :arg bool failure: Notify failure (default false) 1374 :arg bool repeated-failure: Notify repeated failure (default false) 1375 :arg bool back-to-normal: Notify back to normal (default false) 1376 :arg bool not-built: Notify if not built (default false) 1377 :arg bool unstable: Notify if unstable (default false) 1378 :arg str webhook-token: Webhook token for posting messages. 1379 Overrides global authentication data and channel 1380 :arg str commit-info: What commit information to include into 1381 notification message. 1382 1383 :commit-info values: 1384 * **none** 1385 * **authors** 1386 * **authors-and-titles** 1387 1388 :arg str custom-message: Custom text message (default '') 1389 :arg bool trust-ssl: Trust RocketChat server certificate, if checked, 1390 the SSL certificate will not be checked (default false) 1391 :arg str build-server: Build Server URL 1392 :arg list attachments: Optional list of attachments 1393 1394 :attachments: 1395 * **title** (`str`) Attachment title (required) 1396 * **title-link** (`str`) 1397 * **title-link-download** (`bool`) 1398 * **color** (`str`) 1399 * **text** (`str`) 1400 * **collapsed** (`bool`) 1401 * **message-link** (`str`) 1402 * **author-name** (`str`) 1403 * **author-link** (`str`) 1404 * **author-icon** (`str`) 1405 * **thumb** (`str`) Thumb URL 1406 * **image** (`str`) Image URL 1407 * **audio** (`str`) Audio URL 1408 * **video** (`str`) Video URL 1409 1410 Minimal example using defaults: 1411 1412 .. literalinclude:: /../../tests/publishers/fixtures/rocket001.yaml 1413 :language: yaml 1414 1415 Full example: 1416 1417 .. literalinclude:: /../../tests/publishers/fixtures/rocket002.yaml 1418 :language: yaml 1419 """ 1420 rocketchat = XML.SubElement( 1421 xml_parent, "jenkins.plugins.rocketchatnotifier.RocketChatNotifier" 1422 ) 1423 rocketchat.set("plugin", "rocketchatnotifier") 1424 required_mapping = [ 1425 ("channel", "channel", ""), 1426 ("start", "startNotification", False), 1427 ("success", "notifySuccess", False), 1428 ("abort", "notifyAborted", False), 1429 ("not-built", "notifyNotBuilt", False), 1430 ("unstable", "notifyUnstable", False), 1431 ("failure", "notifyFailure", False), 1432 ("back-to-normal", "notifyBackToNormal", False), 1433 ("repeated-failure", "notifyRepeatedFailure", False), 1434 ("include-test-summary", "includeTestSummary", False), 1435 ("include-test-log", "includeTestLog", False), 1436 ("include-custom-message", "includeCustomMessage", False), 1437 ( 1438 "commit-info", 1439 "commitInfoChoice", 1440 "none", 1441 { 1442 "none": "NONE", 1443 "authors": "AUTHORS", 1444 "authors-and-titles": "AUTHORS_AND_TITLES", 1445 }, 1446 ), 1447 ("raw-message", "rawMessage", False), 1448 ("webhook-token", "webhookToken", ""), 1449 ("webhook-token-credential-id", "webhookTokenCredentialId", ""), 1450 ] 1451 optional_mapping = [ 1452 ("trust-ssl", "trustSSL", None), 1453 ("build-server", "buildServerUrl", None), 1454 ] 1455 1456 helpers.convert_mapping_to_xml( 1457 rocketchat, data, optional_mapping, fail_required=False 1458 ) 1459 helpers.convert_mapping_to_xml( 1460 rocketchat, data, required_mapping, fail_required=True 1461 ) 1462 1463 attach_required_mapping = [("title", "title", None)] 1464 attach_optional_mapping = [ 1465 ("title-link", "titleLink", None), 1466 ("title-link-download", "titleLinkDownload", None), 1467 ("color", "color", None), 1468 ("text", "text", None), 1469 ("collapsed", "collapsed", None), # false | true 1470 ("message-link", "messageLink", None), 1471 ("author-name", "authorName", None), 1472 ("author-link", "authorLink", None), 1473 ("author-icon", "authorIcon", None), 1474 ("thumb", "thumbUrl", None), 1475 ("image", "imageUrl", None), 1476 ("audio", "audioUrl", None), 1477 ("video", "videoUrl", None), 1478 ] 1479 attach_list = data.get("attachments", None) 1480 1481 attachments = XML.SubElement(rocketchat, "attachments") 1482 if attach_list is not None: 1483 for attach_data in attach_list: 1484 item = XML.SubElement( 1485 attachments, 1486 "jenkins.plugins.rocketchatnotifier.model.MessageAttachment", 1487 ) 1488 helpers.convert_mapping_to_xml( 1489 item, attach_data, attach_required_mapping, fail_required=True 1490 ) 1491 helpers.convert_mapping_to_xml( 1492 item, attach_data, attach_optional_mapping, fail_required=False 1493 ) 1494 1495 XML.SubElement(rocketchat, "customMessage").text = data.get("custom-message", "") 1496 1497 1498def hp_alm(registry, xml_parent, data): 1499 """yaml: hp-alm 1500 Publish test results to HP-ALM. 1501 1502 Requires the Jenkins :jenkins-plugins:`Micro Focus Application Automation 1503 Tools <hp-application-automation-tools-plugin>`. 1504 1505 :arg str server-name: The name of the ALM Server. (required) 1506 :arg str credentials-id: credentials-id of the user (default '') 1507 :arg str domaine: The Domain of the project to be used. (required) 1508 :arg str client-type: Client type is required for some ALM above 12.60 1509 in authentication.(default '') 1510 :arg str project: The project to be used. (required) 1511 :arg str testing-framework: The testing framework that is used when 1512 generate the testing result file. (default Junit) 1513 :arg str testing-tool: The testing tool that is used when generate 1514 the testing result file. (default '') 1515 :arg str folder: The path of the test folder that will contain 1516 the uploaded test. 1517 The path doesn't include the Root test folder (Subject). 1518 For example, sampletestfolder/subfolder means, the tests will be 1519 uploaded to test folder named 'subfolder', which is under 1520 the test folder named 'sampletestfolder', and 'sampletestfolder' 1521 is under the root test folder 'Subject'. (required) 1522 :arg str set-folder: The path of the testset folder that will contain 1523 the uploaded testset. The path doesn't include the Root testset folder. 1524 For example, sampletestsetfolder/subfolder means, the testsets will be 1525 uploaded to testset folder named 'subfolder', which is under 1526 the testset folder named 'sampletestsetfolder', 1527 and 'sampletestsetfolder' is under the root testset folder 'Root'. 1528 (required) 1529 :arg str testing-result-file: The condition to find the testing 1530 result file, start from the root path of the job. 1531 For example, ``**/junitResult.xml`` to find testing result file 1532 for Junit Plugin, ``**/testng-results.xml`` to find 1533 testing result file for TestNG plugin. (required) 1534 :arg str jenkins-server-url: The HTTP URL of the Jenkins Server, 1535 form example, http://jenkins.example.org:8080 . (optional) 1536 1537 Minimal example using defaults: 1538 1539 .. literalinclude:: /../../tests/publishers/fixtures/hp-alm001.yaml 1540 :language: yaml 1541 1542 Full example: 1543 1544 .. literalinclude:: /../../tests/publishers/fixtures/hp-alm002.yaml 1545 :language: yaml 1546 """ 1547 alm_uploader = XML.SubElement( 1548 xml_parent, 1549 "com.microfocus.application.automation." 1550 "tools.results.TestResultToALMUploader", 1551 ) 1552 alm_uploader.set("plugin", "hp-application-automation-tools-plugin") 1553 mapping = [ 1554 ("server-name", "almServerName", None), 1555 ("credentials-id", "credentialsId", ""), 1556 ("domain", "almDomain", None), 1557 ("project", "almProject", None), 1558 ("client-type", "clientType", ""), 1559 ("testing-framework", "testingFramework", "JUnit"), 1560 ("testing-tool", "testingTool", ""), 1561 ("folder", "almTestFolder", None), 1562 ("set-folder", "almTestSetFolder", None), 1563 ("testing-result-file", "testingResultFile", None), 1564 ("jenkins-server-url", "jenkinsServerUrl", ""), 1565 ] 1566 helpers.convert_mapping_to_xml(alm_uploader, data, mapping, fail_required=True) 1567 1568 1569def junit(registry, xml_parent, data): 1570 """yaml: junit 1571 Publish JUnit test results. Requires the Jenkins :jenkins-plugins:`JUnit 1572 Plugin <junit>`. 1573 1574 :arg str results: results filename (required) 1575 :arg bool keep-long-stdio: Retain long standard output/error in test 1576 results (default true). 1577 :arg float health-scale-factor: Amplification factor to apply to test 1578 failures when computing the test result contribution to the build 1579 health score. (default 1.0) 1580 :arg bool allow-empty-results: Do not fail the build on empty test results 1581 (default false) 1582 :arg bool skip-publishing-checks: Do not publish issues to SCM provider 1583 platforms (default false) 1584 :arg bool skip-marking-build-unstable: Do not mark build as unstable on 1585 test failure (default false) 1586 :arg bool test-stability: Add historical information about test 1587 results stability (default false). 1588 Requires the Jenkins :jenkins-plugins:`Test stability Plugin 1589 <test-stability>`. 1590 :arg bool claim-build: Allow claiming of failed tests (default false) 1591 Requires the Jenkins :jenkins-plugins:`Claim Plugin <claim>`. 1592 :arg bool measurement-plots: Create measurement plots (default false) 1593 Requires the Jenkins :jenkins-github:`Measurement Plots Plugin 1594 <measurement-plots-plugin>`. 1595 :arg bool flaky-test-reports: Publish flaky test reports (default false). 1596 Requires the Jenkins :jenkins-plugins:`Flaky Test Handler Plugin 1597 <flaky-test-handler>`. 1598 :arg bool junit-attachments: Publish test attachments (default false). 1599 Requires the Jenkins :jenkins-plugins:`JUnit Attachments Plugin 1600 <junit-attachments>`. 1601 1602 1603 Minimal example using defaults: 1604 1605 .. literalinclude:: /../../tests/publishers/fixtures/junit001.yaml 1606 :language: yaml 1607 1608 Full example: 1609 1610 .. literalinclude:: /../../tests/publishers/fixtures/junit002.yaml 1611 :language: yaml 1612 """ 1613 junitresult = XML.SubElement(xml_parent, "hudson.tasks.junit.JUnitResultArchiver") 1614 junitresult.set("plugin", "junit") 1615 mapping = [ 1616 ("results", "testResults", None), 1617 ("keep-long-stdio", "keepLongStdio", True), 1618 ("health-scale-factor", "healthScaleFactor", "1.0"), 1619 ("allow-empty-results", "allowEmptyResults", False), 1620 ("skip-publishing-checks", "skipPublishingChecks", False), 1621 ("skip-marking-build-unstable", "skipMarkingBuildUnstable", False), 1622 ] 1623 helpers.convert_mapping_to_xml(junitresult, data, mapping, fail_required=True) 1624 1625 datapublisher = XML.SubElement(junitresult, "testDataPublishers") 1626 if str(data.get("test-stability", False)).lower() == "true": 1627 XML.SubElement( 1628 datapublisher, 1629 "de.esailors.jenkins.teststability" ".StabilityTestDataPublisher", 1630 ) 1631 if str(data.get("claim-build", False)).lower() == "true": 1632 XML.SubElement(datapublisher, "hudson.plugins.claim.ClaimTestDataPublisher") 1633 if str(data.get("measurement-plots", False)).lower() == "true": 1634 XML.SubElement( 1635 datapublisher, "hudson.plugins.measurement__plots.TestDataPublisher" 1636 ) 1637 if str(data.get("flaky-test-reports", False)).lower() == "true": 1638 XML.SubElement( 1639 datapublisher, 1640 "com.google.jenkins.flakyTestHandler.plugin" ".JUnitFlakyTestDataPublisher", 1641 ) 1642 if str(data.get("junit-attachments", False)).lower() == "true": 1643 XML.SubElement( 1644 datapublisher, "hudson.plugins.junitattachments.AttachmentPublisher" 1645 ) 1646 1647 1648def cucumber_reports(registry, xml_parent, data): 1649 """yaml: cucumber-reports 1650 This plugin creates pretty cucumber-jvm html reports on jenkins. 1651 1652 Requires the Jenkins :jenkins-plugins:`cucumber reports 1653 <cucumber-reports>`. 1654 1655 :arg str json-reports-path: The path relative to the workspace of 1656 the json reports generated by cucumber-jvm e.g. target - leave 1657 empty to scan the whole workspace (default '') 1658 :arg str file-include-pattern: Include pattern (default '') 1659 :arg str file-exclude-pattern: Exclude pattern (default '') 1660 :arg str plugin-url-path: The path to the jenkins user content url 1661 e.g. :samp:`http://host:port[/jenkins/]plugin` - leave empty if jenkins 1662 url root is host:port (default '') 1663 :arg bool skipped-fails: Skipped steps to cause the build to fail 1664 (default false) 1665 :arg bool pending-fails: Pending steps to cause the build to fail 1666 (default false) 1667 :arg bool undefined-fails: Undefined steps to cause the build to fail 1668 (default false) 1669 :arg bool missing-fails: Missing steps to cause the build to fail 1670 (default false) 1671 :arg bool no-flash-charts: Use javascript charts instead of flash charts 1672 (default false) 1673 :arg bool ignore-failed-tests: Entire build to fail when these tests fail 1674 (default false) 1675 :arg bool parallel-testing: Run same test in parallel for multiple devices 1676 (default false) 1677 :arg int failed-steps-number: Maximum number of failed steps above which 1678 build result is changed (default 0) 1679 :arg int skipped-steps-number: Maximum number of skipped steps above which 1680 build result is changed (default 0) 1681 :arg int pending-steps-number: Maximum number of pending steps above which 1682 build result is changed (default 0) 1683 :arg int undefined-steps-number: Maximum number of undefined steps above 1684 which build result is changed (default 0) 1685 :arg int failed-scenarios-number: Maximum number of failed scenarios above 1686 which build result is changed (default 0) 1687 :arg int failed-features-number: Maximum number of failed features above 1688 which build result is changed (default 0) 1689 :arg list build-status: Build result to which the build should be set 1690 when the report becomes failed or unstable (default '') 1691 :arg int trends-limit: Number of past reports that should be presented. 1692 Zero means unlimited number of builds (default 0) 1693 :arg list sorting-method: Result sorting order (default 'NATURAL') 1694 1695 Full example: 1696 1697 .. literalinclude:: 1698 /../../tests/publishers/fixtures/cucumber-reports-full.yaml 1699 :language: yaml 1700 1701 Minimal Example: 1702 1703 .. literalinclude:: 1704 /../../tests/publishers/fixtures/cucumber-reports-minimal.yaml 1705 :language: yaml 1706 """ 1707 cucumber_reports = XML.SubElement( 1708 xml_parent, "net.masterthought.jenkins." "CucumberReportPublisher" 1709 ) 1710 cucumber_reports.set("plugin", "cucumber-reports") 1711 1712 valid_build_status = ["", "UNSTABLE", "FAILURE"] 1713 valid_sorting_method = ["NATURAL", "ALPHABETICAL"] 1714 mappings = [ 1715 ("json-reports-path", "jsonReportDirectory", ""), 1716 ("plugin-url-path", "pluginUrlPath", ""), 1717 ("file-include-pattern", "fileIncludePattern", ""), 1718 ("file-exclude-pattern", "fileExcludePattern", ""), 1719 ("skipped-fails", "skippedFails", False), 1720 ("pending-fails", "pendingFails", False), 1721 ("undefined-fails", "undefinedFails", False), 1722 ("missing-fails", "missingFails", False), 1723 ("no-flash-charts", "noFlashCharts", False), 1724 ("ignore-failed-tests", "ignoreFailedTests", False), 1725 ("parallel-testing", "parallelTesting", False), 1726 ("failed-steps-number", "failedStepsNumber", 0), 1727 ("skipped-steps-number", "skippedStepsNumber", 0), 1728 ("pending-steps-number", "pendingStepsNumber", 0), 1729 ("undefined-steps-number", "undefinedStepsNumber", 0), 1730 ("failed-scenarios-number", "failedScenariosNumber", 0), 1731 ("failed-features-number", "failedFeaturesNumber", 0), 1732 ("build-status", "buildStatus", "", valid_build_status), 1733 ("trends-limit", "trendsLimit", 0), 1734 ("sorting-method", "sortingMethod", "NATURAL", valid_sorting_method), 1735 ] 1736 helpers.convert_mapping_to_xml(cucumber_reports, data, mappings, fail_required=True) 1737 1738 if "sorting-values" in data: 1739 format_dict = { 1740 "classifications": "net.masterthought.jenkins" 1741 ".CucumberReportPublisher_-Classification" 1742 } 1743 classifications_tag = XML.SubElement(cucumber_reports, "classifications") 1744 for values in data["sorting-values"]: 1745 for value, params in values.items(): 1746 cucumber_report_publisher = XML.SubElement( 1747 classifications_tag, format_dict.get("classifications") 1748 ) 1749 XML.SubElement(cucumber_report_publisher, "key").text = params.get( 1750 "key" 1751 ) 1752 XML.SubElement(cucumber_report_publisher, "value").text = params.get( 1753 "value" 1754 ) 1755 1756 1757def cucumber_testresult(registry, xml_parent, data): 1758 """yaml: cucumber-testresult 1759 Publish cucumber test results. 1760 Requires the Jenkins :jenkins-plugins:`Cucumber testresult 1761 <cucumber-testresult-plugin>`. 1762 1763 :arg str results: Results filename (required) 1764 :arg bool ignore-bad-steps: Ignore not existed step results (default false) 1765 1766 Minimal example: 1767 1768 .. literalinclude:: 1769 /../../tests/publishers/fixtures/cucumber-testresult-minimal.yaml 1770 :language: yaml 1771 1772 Full Example: 1773 1774 .. literalinclude:: 1775 /../../tests/publishers/fixtures/cucumber-testresult-full.yaml 1776 :language: yaml 1777 """ 1778 cucumber_result = XML.SubElement( 1779 xml_parent, 1780 "org.jenkinsci.plugins.cucumber." 1781 "jsontestsupport." 1782 "CucumberTestResultArchiver", 1783 ) 1784 cucumber_result.set("plugin", "cucumber-testresult-plugin") 1785 1786 mappings = [ 1787 ("results", "testResults", None), 1788 ("ignore-bad-steps", "ignoreBadSteps", False), 1789 ] 1790 helpers.convert_mapping_to_xml(cucumber_result, data, mappings, fail_required=True) 1791 1792 1793def xunit(registry, xml_parent, data): 1794 """yaml: xunit 1795 Publish tests results. Requires the Jenkins :jenkins-plugins:`xUnit Plugin 1796 <xunit>`. 1797 1798 :arg str thresholdmode: Whether thresholds represents an absolute number 1799 of tests or a percentage. Either 'number' or 'percent'. (default 1800 'number') 1801 :arg list thresholds: Thresholds for both 'failed' and 'skipped' tests. 1802 1803 :threshold (`dict`): Threshold values to set, where missing, xUnit 1804 should default to an internal value of 0. Each test threshold 1805 should contain the following: 1806 1807 * **unstable** (`int`) 1808 * **unstablenew** (`int`) 1809 * **failure** (`int`) 1810 * **failurenew** (`int`) 1811 1812 :arg int test-time-margin: Give the report time margin value in ms, before 1813 to fail if not new unless the option **requireupdate** is set for the 1814 configured framework. (default 3000) 1815 :arg list types: Frameworks to configure, and options. Supports the 1816 following: ``aunit``, ``boosttest``, ``checktype``, ``cpptest``, 1817 ``cppunit``, ``ctest``, ``dotnettest``, ``embunit``, ``fpcunit``, 1818 ``gtest``, ``junit``, ``mstest``, ``nunit``, ``phpunit``, ``tusar``, 1819 ``unittest``, and ``valgrind``. 1820 1821 The 'custom' type is not supported. 1822 1823 :type (`dict`): each type can be configured using the following: 1824 1825 * **pattern** (`str`): An Ant pattern to look for Junit result 1826 files, relative to the workspace root (default '') 1827 * **requireupdate** (`bool`): fail the build whenever fresh tests 1828 results have not been found (default true). 1829 * **deleteoutput** (`bool`): delete temporary JUnit files 1830 (default true). 1831 * **skip-if-no-test-files** (`bool`): Skip parsing this xUnit type 1832 report if there are no test reports files (default false). 1833 * **stoponerror** (`bool`): Fail the build whenever an error occur 1834 during a result file processing (default true). 1835 1836 Example: 1837 1838 .. literalinclude:: /../../tests/publishers/fixtures/xunit001.yaml 1839 :language: yaml 1840 1841 """ 1842 info = registry.get_plugin_info("xunit") 1843 plugin_version = pkg_resources.parse_version(info.get("version", str(sys.maxsize))) 1844 1845 logger = logging.getLogger(__name__) 1846 xunit = XML.SubElement(xml_parent, "xunit") 1847 xunit.set("plugin", "xunit") 1848 1849 # Map our internal types to the XML element names used by Jenkins plugin 1850 types_to_plugin_types = { 1851 "aunit": "AUnitJunitHudsonTestType", 1852 "boosttest": "BoostTestJunitHudsonTestType", 1853 "checktype": "CheckType", 1854 "cpptest": "CppTestJunitHudsonTestType", 1855 "cppunit": "CppUnitJunitHudsonTestType", 1856 "ctest": "CTestType", 1857 "dotnettest": "XUnitDotNetTestType", # since plugin v1.93 1858 "embunit": "EmbUnitType", # since plugin v1.84 1859 "fpcunit": "FPCUnitJunitHudsonTestType", 1860 "gtest": "GoogleTestType", 1861 "junit": "JUnitType", 1862 "mstest": "MSTestJunitHudsonTestType", 1863 "nunit": "NUnitJunitHudsonTestType", 1864 "phpunit": "PHPUnitJunitHudsonTestType", 1865 "tusar": "TUSARJunitHudsonTestType", 1866 "unittest": "UnitTestJunitHudsonTestType", 1867 "valgrind": "ValgrindJunitHudsonTestType", 1868 # FIXME should implement the 'custom' type 1869 } 1870 implemented_types = types_to_plugin_types.keys() # shortcut 1871 1872 # Unit framework we are going to generate xml for 1873 supported_types = [] 1874 1875 for configured_type in data["types"]: 1876 type_name = next(iter(configured_type.keys())) 1877 if type_name not in implemented_types: 1878 logger.warning("Requested xUnit type '%s' is not yet supported", type_name) 1879 else: 1880 # Append for generation 1881 supported_types.append(configured_type) 1882 1883 # Generate XML for each of the supported framework types 1884 # Note: versions 3+ are now using the 'tools' sub-element instead of 'types' 1885 if plugin_version < pkg_resources.parse_version("3.0.0"): 1886 types_name = "types" 1887 else: 1888 types_name = "tools" 1889 1890 xmltypes = XML.SubElement(xunit, types_name) 1891 for supported_type in supported_types: 1892 framework_name = next(iter(supported_type.keys())) 1893 xmlframework = XML.SubElement(xmltypes, types_to_plugin_types[framework_name]) 1894 1895 mappings = [ 1896 ("pattern", "pattern", ""), 1897 ("requireupdate", "failIfNotNew", True), 1898 ("deleteoutput", "deleteOutputFiles", True), 1899 ("skip-if-no-test-files", "skipNoTestFiles", False), 1900 ("stoponerror", "stopProcessingIfError", True), 1901 ] 1902 helpers.convert_mapping_to_xml( 1903 xmlframework, supported_type[framework_name], mappings, fail_required=True 1904 ) 1905 1906 xmlthresholds = XML.SubElement(xunit, "thresholds") 1907 for t in data.get("thresholds", []): 1908 if not ("failed" in t or "skipped" in t): 1909 logger.warning("Unrecognized threshold, should be 'failed' or 'skipped'") 1910 continue 1911 elname = ( 1912 "org.jenkinsci.plugins.xunit.threshold.%sThreshold" 1913 % next(iter(t.keys())).title() 1914 ) 1915 el = XML.SubElement(xmlthresholds, elname) 1916 for threshold_name, threshold_value in next(iter(t.values())).items(): 1917 # Normalize and craft the element name for this threshold 1918 elname = "%sThreshold" % threshold_name.lower().replace("new", "New") 1919 XML.SubElement(el, elname).text = str(threshold_value) 1920 1921 # Whether to use percent of exact number of tests. 1922 # Thresholdmode is either: 1923 # - 1 : absolute (number of tests), default. 1924 # - 2 : relative (percentage of tests) 1925 thresholdmode = "1" 1926 if "percent" == data.get("thresholdmode", "number"): 1927 thresholdmode = "2" 1928 XML.SubElement(xunit, "thresholdMode").text = thresholdmode 1929 1930 extra_config = XML.SubElement(xunit, "extraConfiguration") 1931 XML.SubElement(extra_config, "testTimeMargin").text = str( 1932 data.get("test-time-margin", "3000") 1933 ) 1934 1935 1936def _violations_add_entry(xml_parent, name, data): 1937 vmin = data.get("min", 10) 1938 vmax = data.get("max", 999) 1939 vunstable = data.get("unstable", 999) 1940 pattern = data.get("pattern", None) 1941 1942 entry = XML.SubElement(xml_parent, "entry") 1943 mapping = [("", "string", name)] 1944 helpers.convert_mapping_to_xml(entry, data, mapping, fail_required=True) 1945 1946 tconfig = XML.SubElement(entry, "hudson.plugins.violations.TypeConfig") 1947 mapping = [ 1948 ("", "type", name), 1949 ("", "min", str(vmin)), 1950 ("", "max", str(vmax)), 1951 ("", "unstable", str(vunstable)), 1952 ("", "usePattern", "false"), 1953 ] 1954 helpers.convert_mapping_to_xml(tconfig, data, mapping, fail_required=True) 1955 1956 if pattern: 1957 XML.SubElement(tconfig, "pattern").text = pattern 1958 else: 1959 XML.SubElement(tconfig, "pattern") 1960 1961 1962def violations(registry, xml_parent, data): 1963 """yaml: violations 1964 Publish code style violations. 1965 Requires the Jenkins :jenkins-plugins:`Violations Plugin <violations>`. 1966 1967 The violations component accepts any number of dictionaries keyed 1968 by the name of the violations system. The dictionary has the 1969 following values: 1970 1971 :arg int min: sunny threshold 1972 :arg int max: stormy threshold 1973 :arg int unstable: unstable threshold 1974 :arg str pattern: report filename pattern 1975 1976 Any system without a dictionary provided will use default values. 1977 1978 Valid systems are: 1979 1980 checkstyle, codenarc, cpd, cpplint, csslint, findbugs, fxcop, 1981 gendarme, jcreport, jslint, pep8, perlcritic, pmd, pylint, 1982 simian, stylecop 1983 1984 Example: 1985 1986 .. literalinclude:: /../../tests/publishers/fixtures/violations001.yaml 1987 :language: yaml 1988 """ 1989 violations = XML.SubElement( 1990 xml_parent, "hudson.plugins.violations." "ViolationsPublisher" 1991 ) 1992 config = XML.SubElement(violations, "config") 1993 suppressions = XML.SubElement(config, "suppressions", {"class": "tree-set"}) 1994 XML.SubElement(suppressions, "no-comparator") 1995 configs = XML.SubElement(config, "typeConfigs") 1996 XML.SubElement(configs, "no-comparator") 1997 1998 for name in [ 1999 "checkstyle", 2000 "codenarc", 2001 "cpd", 2002 "cpplint", 2003 "csslint", 2004 "findbugs", 2005 "fxcop", 2006 "gendarme", 2007 "jcreport", 2008 "jslint", 2009 "pep8", 2010 "perlcritic", 2011 "pmd", 2012 "pylint", 2013 "simian", 2014 "stylecop", 2015 ]: 2016 _violations_add_entry(configs, name, data.get(name, {})) 2017 mapping = [ 2018 ("", "limit", "100"), 2019 ("", "sourcePathPattern", ""), 2020 ("", "fauxProjectPath", ""), 2021 ("", "encoding", "default"), 2022 ] 2023 helpers.convert_mapping_to_xml(config, data, mapping, fail_required=True) 2024 2025 2026def findbugs(registry, xml_parent, data): 2027 r"""yaml: findbugs 2028 FindBugs reporting for builds 2029 2030 Requires the Jenkins FindBugs Plugin 2031 (https://github.com/jenkinsci/findbugs-plugin). 2032 2033 :arg str pattern: specifies the generated raw FindBugs XML report files, 2034 such as \*\*/findbugs.xml or \*\*/findbugsXml.xml. (default '') 2035 :arg bool rank-priority: Use rank as priority (default false) 2036 :arg str include-files: Comma separated list of files to include. 2037 (default '') 2038 :arg str exclude-files: Comma separated list of files to exclude. 2039 (default '') 2040 :arg bool can-run-on-failed: Weather or not to run plug-in on failed builds 2041 (default false) 2042 :arg bool should-detect-modules: Determines if Ant or Maven modules should 2043 be detected for all files that contain warnings. (default false) 2044 :arg int healthy: Sunny threshold (default '') 2045 :arg int unhealthy: Stormy threshold (default '') 2046 :arg str health-threshold: Threshold priority for health status 2047 ('low', 'normal' or 'high', defaulted to 'low') 2048 :arg bool dont-compute-new: If set to false, computes new warnings based on 2049 the reference build (default true) 2050 :arg bool use-delta-values: Use delta for new warnings. (default false) 2051 :arg bool use-previous-build-as-reference: If set then the number of new 2052 warnings will always be calculated based on the previous build. 2053 Otherwise the reference build. (default false) 2054 :arg bool use-stable-build-as-reference: The number of new warnings will be 2055 calculated based on the last stable build, allowing reverts of unstable 2056 builds where the number of warnings was decreased. (default false) 2057 :arg dict thresholds: 2058 :thresholds: 2059 * **unstable** (`dict`) 2060 :unstable: * **total-all** (`int`) 2061 * **total-high** (`int`) 2062 * **total-normal** (`int`) 2063 * **total-low** (`int`) 2064 * **new-all** (`int`) 2065 * **new-high** (`int`) 2066 * **new-normal** (`int`) 2067 * **new-low** (`int`) 2068 2069 * **failed** (`dict`) 2070 :failed: * **total-all** (`int`) 2071 * **total-high** (`int`) 2072 * **total-normal** (`int`) 2073 * **total-low** (`int`) 2074 * **new-all** (`int`) 2075 * **new-high** (`int`) 2076 * **new-normal** (`int`) 2077 * **new-low** (`int`) 2078 2079 Minimal Example: 2080 2081 .. literalinclude:: /../../tests/publishers/fixtures/findbugs-minimal.yaml 2082 2083 Full Example: 2084 2085 .. literalinclude:: /../../tests/publishers/fixtures/findbugs-full.yaml 2086 """ 2087 findbugs = XML.SubElement(xml_parent, "hudson.plugins.findbugs.FindBugsPublisher") 2088 findbugs.set("plugin", "findbugs") 2089 2090 helpers.findbugs_settings(findbugs, data) 2091 helpers.build_trends_publisher("[FINDBUGS] ", findbugs, data) 2092 2093 2094def checkstyle(registry, xml_parent, data): 2095 """yaml: checkstyle 2096 Publish trend reports with Checkstyle. 2097 2098 Requires the Jenkins Checkstyle Plugin 2099 (https://github.com/jenkinsci/checkstyle-plugin). 2100 2101 The checkstyle component accepts a dictionary with the 2102 following values: 2103 2104 :arg str pattern: Report filename pattern (default '') 2105 :arg bool can-run-on-failed: Also runs for failed builds, instead of just 2106 stable or unstable builds (default false) 2107 :arg bool should-detect-modules: Determines if Ant or Maven modules should 2108 be detected for all files that contain warnings (default false) 2109 :arg int healthy: Sunny threshold (default '') 2110 :arg int unhealthy: Stormy threshold (default '') 2111 :arg str health-threshold: Threshold priority for health status 2112 ('low', 'normal' or 'high') (default 'low') 2113 :arg dict thresholds: Mark build as failed or unstable if the number of 2114 errors exceeds a threshold. (optional) 2115 2116 :thresholds: 2117 * **unstable** (`dict`) 2118 :unstable: * **total-all** (`int`) 2119 * **total-high** (`int`) 2120 * **total-normal** (`int`) 2121 * **total-low** (`int`) 2122 * **new-all** (`int`) 2123 * **new-high** (`int`) 2124 * **new-normal** (`int`) 2125 * **new-low** (`int`) 2126 2127 * **failed** (`dict`) 2128 :failed: * **total-all** (`int`) 2129 * **total-high** (`int`) 2130 * **total-normal** (`int`) 2131 * **total-low** (`int`) 2132 * **new-all** (`int`) 2133 * **new-high** (`int`) 2134 * **new-normal** (`int`) 2135 * **new-low** (`int`) 2136 :arg str default-encoding: Encoding for parsing or showing files 2137 (default '') 2138 :arg bool do-not-resolve-relative-paths: (default false) 2139 :arg bool dont-compute-new: If set to false, computes new warnings based on 2140 the reference build (default true) 2141 :arg bool use-previous-build-as-reference: determines whether to always 2142 use the previous build as the reference build (default false) 2143 :arg bool use-stable-build-as-reference: The number of new warnings will be 2144 calculated based on the last stable build, allowing reverts of unstable 2145 builds where the number of warnings was decreased. (default false) 2146 :arg bool use-delta-values: If set then the number of new warnings is 2147 calculated by subtracting the total number of warnings of the current 2148 build from the reference build. (default false) 2149 2150 Example: 2151 2152 .. literalinclude:: /../../tests/publishers/fixtures/checkstyle004.yaml 2153 :language: yaml 2154 2155 Full example: 2156 2157 .. literalinclude:: /../../tests/publishers/fixtures/checkstyle006.yaml 2158 :language: yaml 2159 """ 2160 2161 def convert_settings(lookup, data): 2162 """Helper to convert settings from one key to another.""" 2163 2164 for old_key in list(data.keys()): 2165 if old_key in lookup: 2166 data.setdefault(lookup[old_key], data[old_key]) 2167 del data[old_key] 2168 2169 checkstyle = XML.SubElement( 2170 xml_parent, "hudson.plugins.checkstyle." "CheckStylePublisher" 2171 ) 2172 checkstyle.set("plugin", "checkstyle") 2173 2174 # Convert old style yaml to new style 2175 convert_settings( 2176 { 2177 "unHealthy": "unhealthy", 2178 "healthThreshold": "health-threshold", 2179 "defaultEncoding": "default-encoding", 2180 "canRunOnFailed": "can-run-on-failed", 2181 "shouldDetectModules": "should-detect-modules", 2182 }, 2183 data, 2184 ) 2185 2186 threshold_data = data.get("thresholds", {}) 2187 for threshold in ["unstable", "failed"]: 2188 convert_settings( 2189 { 2190 "totalAll": "total-all", 2191 "totalHigh": "total-high", 2192 "totalNormal": "total-normal", 2193 "totalLow": "total-low", 2194 }, 2195 threshold_data.get(threshold, {}), 2196 ) 2197 2198 helpers.build_trends_publisher("[CHECKSTYLE] ", checkstyle, data) 2199 2200 2201def scp(registry, xml_parent, data): 2202 """yaml: scp 2203 Upload files via SCP 2204 Requires the Jenkins :jenkins-plugins:`SCP Plugin <scp>`. 2205 2206 When writing a publisher macro, it is important to keep in mind that 2207 Jenkins uses Ant's `SCP Task 2208 <https://ant.apache.org/manual/Tasks/scp.html>`_ via the Jenkins 2209 :jenkins-plugins:`SCP Plugin <scp>` which relies on `FileSet 2210 <https://ant.apache.org/manual/Types/fileset.html>`_ 2211 and `DirSet <https://ant.apache.org/manual/Types/dirset.html>`_ patterns. 2212 The relevant piece of documentation is excerpted below: 2213 2214 Source points to files which will be uploaded. You can use ant 2215 includes syntax, eg. ``folder/dist/*.jar``. Path is constructed from 2216 workspace root. Note that you cannot point files outside the workspace 2217 directory. For example providing: ``../myfile.txt`` won't work... 2218 Destination points to destination folder on remote site. It will be 2219 created if doesn't exists and relative to root repository path. You 2220 can define multiple blocks of source/destination pairs. 2221 2222 This means that absolute paths, e.g., ``/var/log/**`` will not work and 2223 will fail to compile. All paths need to be relative to the directory that 2224 the publisher runs and the paths have to be contained inside of that 2225 directory. The relative working directory is usually:: 2226 2227 /home/jenkins/workspace/${JOB_NAME} 2228 2229 :arg str site: name of the scp site (required) 2230 :arg str target: destination directory (required) 2231 :arg str source: source path specifier (default '') 2232 :arg bool keep-hierarchy: keep the file hierarchy when uploading 2233 (default false) 2234 :arg bool copy-after-failure: copy files even if the job fails 2235 (default false) 2236 :arg bool copy-console: copy the console log (default false); if 2237 specified, omit 'source' 2238 2239 Example: 2240 2241 .. literalinclude:: /../../tests/publishers/fixtures/scp001.yaml 2242 :language: yaml 2243 """ 2244 scp = XML.SubElement( 2245 xml_parent, "be.certipost.hudson.plugin.SCPRepositoryPublisher" 2246 ) 2247 scp.set("plugin", "scp") 2248 2249 mappings = [("site", "siteName", None)] 2250 helpers.convert_mapping_to_xml(scp, data, mappings, fail_required=True) 2251 2252 entries = XML.SubElement(scp, "entries") 2253 for entry in data["files"]: 2254 entry_e = XML.SubElement(entries, "be.certipost.hudson.plugin.Entry") 2255 mappings = [ 2256 ("target", "filePath", None), 2257 ("source", "sourceFile", ""), 2258 ("keep-hierarchy", "keepHierarchy", False), 2259 ("copy-console", "copyConsoleLog", False), 2260 ("copy-after-failure", "copyAfterFailure", False), 2261 ] 2262 helpers.convert_mapping_to_xml(entry_e, entry, mappings, fail_required=True) 2263 2264 2265def ssh(registry, xml_parent, data): 2266 """yaml: ssh 2267 Upload files via SCP. 2268 Requires the Jenkins :jenkins-plugins:`Publish over SSH Plugin 2269 <publish-over-ssh>`. 2270 2271 :arg str site: name of the ssh site 2272 :arg str target: destination directory 2273 :arg bool target-is-date-format: whether target is a date format. If true, 2274 raw text should be quoted (default false) 2275 :arg bool clean-remote: should the remote directory be deleted before 2276 transferring files (default false) 2277 :arg str source: source path specifier 2278 :arg str command: a command to execute on the remote server (optional) 2279 :arg int timeout: timeout in milliseconds for the Exec command (optional) 2280 :arg bool use-pty: run the exec command in pseudo TTY (default false) 2281 :arg str excludes: excluded file pattern (optional) 2282 :arg str remove-prefix: prefix to remove from uploaded file paths 2283 (optional) 2284 :arg bool fail-on-error: fail the build if an error occurs (default false). 2285 :arg bool always-publish-from-master: transfer the files through the master 2286 before being sent to the remote server (defaults false) 2287 :arg bool flatten: only create files on the server, don't create 2288 directories (default false). 2289 :arg bool verbose: adds lots of detail useful for debug to the console 2290 but generally should be left off (default false) 2291 :arg int retries: the number of times to retry this server in the event of 2292 failure (optional) 2293 :arg int retry-delay: the time to wait, in milliseconds, before attempting 2294 another transfer (default 10000) 2295 2296 Minimal Example: 2297 2298 .. literalinclude:: /../../tests/publishers/fixtures/ssh-minimal.yaml 2299 :language: yaml 2300 2301 Full Example: 2302 2303 .. literalinclude:: /../../tests/publishers/fixtures/ssh-full.yaml 2304 :language: yaml 2305 """ 2306 console_prefix = "SSH: " 2307 tag_prefix = "jenkins.plugins.publish" 2308 publisher_tag = "%s__over__ssh.BapSshPublisher" % tag_prefix 2309 transfer_tag = "%s__over__ssh.BapSshTransfer" % tag_prefix 2310 retry_tag = "%s_over_ssh.BapSshRetry" % tag_prefix 2311 reference_tag = "%s_over_ssh.BapSshPublisherPlugin" % tag_prefix 2312 2313 if xml_parent.tag == "publishers": 2314 plugin_tag = "%s__over__ssh.BapSshPublisherPlugin" % tag_prefix 2315 is_builder = False 2316 else: 2317 plugin_tag = "%s__over__ssh.BapSshBuilderPlugin" % tag_prefix 2318 is_builder = True 2319 2320 base_publish_over( 2321 xml_parent, 2322 data, 2323 console_prefix, 2324 plugin_tag, 2325 publisher_tag, 2326 transfer_tag, 2327 retry_tag, 2328 reference_tag, 2329 is_builder, 2330 ) 2331 2332 2333def pipeline(registry, xml_parent, data): 2334 """yaml: pipeline 2335 Specify a downstream project in a pipeline. 2336 Requires the Jenkins :jenkins-plugins:`Build Pipeline Plugin 2337 <build-pipeline-plugin>`. 2338 2339 Use of the `node-label-name` or `node-label` parameters 2340 requires the Jenkins :jenkins-plugins:`NodeLabel Parameter Plugin 2341 <nodelabelparameter>`. 2342 Note: 'node-parameters' overrides the Node that the triggered 2343 project is tied to. 2344 2345 :arg list projects: list the jobs to trigger, will generate comma-separated 2346 string containing the named jobs. 2347 :arg str predefined-parameters: parameters to pass to the other 2348 job (optional) 2349 :arg bool current-parameters: Whether to include the parameters passed 2350 to the current build to the triggered job (optional) 2351 :arg bool node-parameters: Use the same Node for the triggered builds 2352 that was used for this build. (optional) 2353 :arg bool svn-revision: Pass svn revision to the triggered job (optional) 2354 :arg bool include-upstream: Include/pass through Upstream SVN Revisons. 2355 Only valid when 'svn-revision' is true. (default false) 2356 :arg dict git-revision: Passes git revision to the triggered job 2357 (optional). 2358 2359 * **combine-queued-commits** (bool): Whether to combine queued git 2360 hashes or not (default false) 2361 2362 :arg dict boolean-parameters: Pass boolean parameters to the downstream 2363 jobs. Specify the name and boolean value mapping of the parameters. 2364 (optional) 2365 :arg str property-file: Use properties from file (optional) 2366 :arg bool fail-on-missing: Blocks the triggering of the downstream jobs 2367 if any of the property files are not found in the workspace. 2368 Only valid when 'property-file' is specified. 2369 (default false) 2370 :arg str file-encoding: Encoding of contents of the files. If not 2371 specified, default encoding of the platform is used. Only valid when 2372 'property-file' is specified. (optional) 2373 :arg str restrict-matrix-project: Filter that restricts the subset 2374 of the combinations that the downstream project will run (optional) 2375 2376 Example: 2377 2378 .. literalinclude:: /../../tests/publishers/fixtures/pipeline002.yaml 2379 :language: yaml 2380 2381 .. literalinclude:: /../../tests/publishers/fixtures/pipeline003.yaml 2382 :language: yaml 2383 2384 2385 You can build pipeline jobs that are re-usable in different pipelines by 2386 using a :ref:`job-template` to define the pipeline jobs, 2387 and variable substitution to specify the name of 2388 the downstream job in the pipeline. 2389 Job-specific substitutions are useful here (see :ref:`project`). 2390 2391 See 'samples/pipeline.yaml' for an example pipeline implementation. 2392 """ 2393 logger = logging.getLogger("%s:pipeline" % __name__) 2394 param_order = helpers.trigger_get_parameter_order(registry, "pipeline") 2395 2396 if "project" in data: 2397 logger.warning( 2398 "Using 'project' for pipeline definition is deprecated. Please " 2399 "update your job definition to use 'projects' with a list format." 2400 ) 2401 2402 projects = ",".join(data.get("projects", [data.get("project", "")])) 2403 if projects != "": 2404 2405 pippub = XML.SubElement( 2406 xml_parent, 2407 "au.com.centrumsystems.hudson.plugin." 2408 "buildpipeline.trigger.BuildPipelineTrigger", 2409 ) 2410 2411 configs = XML.SubElement(pippub, "configs") 2412 2413 helpers.trigger_project(configs, data, registry, param_order) 2414 2415 XML.SubElement(pippub, "downstreamProjectNames").text = projects 2416 2417 2418def email(registry, xml_parent, data): 2419 """yaml: email 2420 Email notifications on build failure. 2421 Requires the Jenkins :jenkins-plugins:`Mailer Plugin <mailer>`. 2422 2423 :arg str recipients: Space separated list of recipient email addresses 2424 (required) 2425 :arg bool notify-every-unstable-build: Send an email for every 2426 unstable build (default true) 2427 :arg bool send-to-individuals: Send an email to the individual 2428 who broke the build (default false) 2429 2430 Example: 2431 2432 .. literalinclude:: 2433 /../../tests/publishers/fixtures/email-minimal.yaml 2434 :language: yaml 2435 2436 .. literalinclude:: /../../tests/publishers/fixtures/email-full.yaml 2437 :language: yaml 2438 """ 2439 2440 # TODO: raise exception if this is applied to a maven job 2441 mailer = XML.SubElement(xml_parent, "hudson.tasks.Mailer") 2442 mailer.set("plugin", "mailer") 2443 mapping = [("recipients", "recipients", None)] 2444 helpers.convert_mapping_to_xml(mailer, data, mapping, fail_required=True) 2445 2446 # Note the logic reversal (included here to match the GUI 2447 if data.get("notify-every-unstable-build", True): 2448 XML.SubElement(mailer, "dontNotifyEveryUnstableBuild").text = "false" 2449 else: 2450 XML.SubElement(mailer, "dontNotifyEveryUnstableBuild").text = "true" 2451 XML.SubElement(mailer, "sendToIndividuals").text = str( 2452 data.get("send-to-individuals", False) 2453 ).lower() 2454 2455 2456def claim_build(registry, xml_parent, data): 2457 """yaml: claim-build 2458 Claim build failures 2459 Requires the Jenkins :jenkins-plugins:`Claim Plugin <claim>`. 2460 2461 Example: 2462 2463 .. literalinclude:: /../../tests/publishers/fixtures/claim-build001.yaml 2464 :language: yaml 2465 """ 2466 2467 XML.SubElement(xml_parent, "hudson.plugins.claim.ClaimPublisher") 2468 2469 2470def base_email_ext(registry, xml_parent, data, ttype): 2471 trigger = XML.SubElement( 2472 xml_parent, "hudson.plugins.emailext.plugins.trigger." + ttype 2473 ) 2474 2475 info = registry.get_plugin_info("email-ext") 2476 plugin_version = pkg_resources.parse_version(info.get("version", str(sys.maxsize))) 2477 2478 email = XML.SubElement(trigger, "email") 2479 2480 if plugin_version < pkg_resources.parse_version("2.39"): 2481 XML.SubElement(email, "recipientList").text = "" 2482 XML.SubElement(email, "subject").text = "$PROJECT_DEFAULT_SUBJECT" 2483 XML.SubElement(email, "body").text = "$PROJECT_DEFAULT_CONTENT" 2484 if plugin_version >= pkg_resources.parse_version("2.39"): 2485 XML.SubElement(email, "replyTo").text = "$PROJECT_DEFAULT_REPLYTO" 2486 XML.SubElement(email, "contentType").text = "project" 2487 if "send-to" in data: 2488 recipient_providers = None 2489 if plugin_version < pkg_resources.parse_version("2.39"): 2490 XML.SubElement(email, "sendToDevelopers").text = str( 2491 "developers" in data["send-to"] 2492 ).lower() 2493 XML.SubElement(email, "sendToRequester").text = str( 2494 "requester" in data["send-to"] 2495 ).lower() 2496 XML.SubElement(email, "includeCulprits").text = str( 2497 "culprits" in data["send-to"] 2498 ).lower() 2499 XML.SubElement(email, "sendToRecipientList").text = str( 2500 "recipients" in data["send-to"] 2501 ).lower() 2502 else: 2503 for recipient in data["send-to"]: 2504 if "developers" == recipient: 2505 if recipient_providers is None: 2506 recipient_providers = XML.SubElement( 2507 email, "recipientProviders" 2508 ) 2509 XML.SubElement( 2510 recipient_providers, 2511 "hudson.plugins.emailext.plugins.recipients.DevelopersRecipientProvider", 2512 ).text = "" 2513 elif "requester" == recipient: 2514 if recipient_providers is None: 2515 recipient_providers = XML.SubElement( 2516 email, "recipientProviders" 2517 ) 2518 XML.SubElement( 2519 recipient_providers, 2520 "hudson.plugins.emailext.plugins.recipients.RequesterRecipientProvider", 2521 ).text = "" 2522 elif "culprits" == recipient: 2523 if recipient_providers is None: 2524 recipient_providers = XML.SubElement( 2525 email, "recipientProviders" 2526 ) 2527 XML.SubElement( 2528 recipient_providers, 2529 "hudson.plugins.emailext.plugins.recipients.CulpritsRecipientProvider", 2530 ).text = "" 2531 elif "recipients" == recipient: 2532 if recipient_providers is None: 2533 recipient_providers = XML.SubElement( 2534 email, "recipientProviders" 2535 ) 2536 XML.SubElement( 2537 recipient_providers, 2538 "hudson.plugins.emailext.plugins.recipients.ListRecipientProvider", 2539 ).text = "" 2540 elif "failing-test-suspects-recipients" == recipient: 2541 if recipient_providers is None: 2542 recipient_providers = XML.SubElement( 2543 email, "recipientProviders" 2544 ) 2545 XML.SubElement( 2546 recipient_providers, 2547 "hudson.plugins.emailext.plugins.recipients.FailingTestSuspectsRecipientProvider", 2548 ).text = "" 2549 elif "first-failing-build-suspects-recipients" == recipient: 2550 if recipient_providers is None: 2551 recipient_providers = XML.SubElement( 2552 email, "recipientProviders" 2553 ) 2554 XML.SubElement( 2555 recipient_providers, 2556 "hudson.plugins.emailext.plugins.recipients.FirstFailingBuildSuspectsRecipientProvider", 2557 ).text = "" 2558 # `failureCount` is deprecated and has no effect 2559 # on email, but the element has been created 2560 # in order to match the XML generated via UI. 2561 failure_count_supporters = ["FirstFailureTrigger", "SecondFailureTrigger"] 2562 if ttype in failure_count_supporters: 2563 XML.SubElement(trigger, "failureCount").text = "0" 2564 if "upstream-committers" in data["send-to"]: 2565 if recipient_providers is None: 2566 recipient_providers = XML.SubElement(email, "recipientProviders") 2567 XML.SubElement( 2568 recipient_providers, 2569 "hudson.plugins.emailext.plugins.recipients.UpstreamComitterRecipientProvider", 2570 ).text = "" 2571 else: 2572 if plugin_version < pkg_resources.parse_version("2.39"): 2573 XML.SubElement(email, "sendToRequester").text = "false" 2574 XML.SubElement(email, "sendToDevelopers").text = "false" 2575 XML.SubElement(email, "includeCulprits").text = "false" 2576 XML.SubElement(email, "sendToRecipientList").text = "true" 2577 else: 2578 recipient_providers = XML.SubElement(email, "recipientProviders") 2579 XML.SubElement( 2580 recipient_providers, 2581 "hudson.plugins.emailext.plugins.recipients.ListRecipientProvider", 2582 ).text = "" 2583 2584 if ttype == "ScriptTrigger": 2585 XML.SubElement(trigger, "triggerScript").text = data["trigger-script"] 2586 2587 if plugin_version >= pkg_resources.parse_version("2.39"): 2588 mappings = [ 2589 ("attachments", "attachmentsPattern", ""), 2590 ("attach-build-log", "attachBuildLog", False), 2591 ("compress-log", "compressBuildLog", False), 2592 ] 2593 2594 helpers.convert_mapping_to_xml(email, data, mappings, fail_required=True) 2595 2596 2597def email_ext(registry, xml_parent, data): 2598 """yaml: email-ext 2599 Extend Jenkin's built in email notification 2600 Requires the Jenkins :jenkins-plugins:`Email-ext Plugin 2601 <email-ext>`. 2602 2603 :arg bool disable-publisher: Disable the publisher, while maintaining the 2604 settings. The usage model for this is when you want to test things out 2605 in the build, not send out e-mails during the testing. A message will 2606 be printed to the build log saying that the publisher is disabled. 2607 (default false) 2608 :arg str recipients: Comma separated list of recipient email addresses 2609 (default '$DEFAULT_RECIPIENTS') 2610 :arg str reply-to: Comma separated list of email addresses that should be 2611 in the Reply-To header for this project (default '$DEFAULT_REPLYTO') 2612 :arg str from: Email address that should be 2613 in the From header for this project (default '') 2614 :arg str content-type: The content type of the emails sent. If not set, the 2615 Jenkins plugin uses the value set on the main configuration page. 2616 Possible values: 'html', 'text', 'both-html-text' or 'default' 2617 (default 'default') 2618 :arg str subject: Subject for the email, can include variables like 2619 ${BUILD_NUMBER} or even groovy or javascript code 2620 (default '$DEFAULT_SUBJECT') 2621 :arg str body: Content for the body of the email, can include variables 2622 like ${BUILD_NUMBER}, but the real magic is using groovy or 2623 javascript to hook into the Jenkins API itself 2624 (default '$DEFAULT_CONTENT') 2625 :arg bool attach-build-log: Include build log in the email (default false) 2626 :arg bool compress-log: Compress build log in the email (default false) 2627 :arg str attachments: pattern of files to include as attachment 2628 (default '') 2629 :arg bool always: Send an email for every result (default false) 2630 :arg bool unstable: Send an email for an unstable result (default false) 2631 :arg bool first-failure: Send an email for just the first failure 2632 (default false) 2633 :arg bool first-unstable: Send an email for just the first unstable build 2634 (default false) 2635 :arg bool not-built: Send an email if not built (default false) 2636 :arg bool aborted: Send an email if the build is aborted (default false) 2637 :arg bool regression: Send an email if there is a regression 2638 (default false) 2639 :arg bool failure: Send an email if the build fails (default true) 2640 :arg bool second-failure: Send an email for the second failure 2641 (default false) 2642 :arg bool improvement: Send an email if the build improves (default false) 2643 :arg bool still-failing: Send an email if the build is still failing 2644 (default false) 2645 :arg bool success: Send an email for a successful build (default false) 2646 :arg bool fixed: Send an email if the build is fixed (default false) 2647 :arg bool fixed-unhealthy: Send an email if the build status 2648 changes from "Failure" or "Unstable" to "Success". Intermediate 2649 "Aborted" builds are ignored. (default false) 2650 :arg bool still-unstable: Send an email if the build is still unstable 2651 (default false) 2652 :arg bool pre-build: Send an email before the build (default false) 2653 :arg str trigger-script: A Groovy script used to determine if an email 2654 should be sent. 2655 :arg str presend-script: A Groovy script executed prior sending the mail. 2656 (default '') 2657 :arg str postsend-script: A Goovy script executed after sending the email. 2658 (default '') 2659 :arg bool save-output: Save email content to workspace (default false) 2660 :arg str matrix-trigger: If using matrix projects, when to trigger 2661 2662 :matrix-trigger values: 2663 * **both** 2664 * **only-parent** 2665 * **only-configurations** 2666 :arg list send-to: list of recipients from the predefined groups 2667 2668 :send-to values: 2669 * **developers** (disabled by default) 2670 * **requester** (disabled by default) 2671 * **culprits** (disabled by default) 2672 * **recipients** (enabled by default) 2673 * **upstream-committers** (>=2.39) (disabled by default) 2674 * **failing-test-suspects-recipients** (>=2.39) (disabled by default) 2675 * **first-failing-build-suspects-recipients** (>=2.39) (disabled by default) 2676 2677 Example: 2678 2679 .. literalinclude:: /../../tests/publishers/fixtures/email-ext001.yaml 2680 :language: yaml 2681 """ 2682 2683 emailext = XML.SubElement( 2684 xml_parent, "hudson.plugins.emailext.ExtendedEmailPublisher" 2685 ) 2686 2687 info = registry.get_plugin_info("email-ext") 2688 plugin_version = pkg_resources.parse_version(info.get("version", str(sys.maxsize))) 2689 2690 if "recipients" in data: 2691 XML.SubElement(emailext, "recipientList").text = data["recipients"] 2692 else: 2693 XML.SubElement(emailext, "recipientList").text = "$DEFAULT_RECIPIENTS" 2694 ctrigger = XML.SubElement(emailext, "configuredTriggers") 2695 if data.get("always", False): 2696 base_email_ext(registry, ctrigger, data, "AlwaysTrigger") 2697 if data.get("unstable", False): 2698 base_email_ext(registry, ctrigger, data, "UnstableTrigger") 2699 if data.get("first-failure", False): 2700 base_email_ext(registry, ctrigger, data, "FirstFailureTrigger") 2701 if data.get("first-unstable", False): 2702 base_email_ext(registry, ctrigger, data, "FirstUnstableTrigger") 2703 if data.get("not-built", False): 2704 base_email_ext(registry, ctrigger, data, "NotBuiltTrigger") 2705 if data.get("aborted", False): 2706 base_email_ext(registry, ctrigger, data, "AbortedTrigger") 2707 if data.get("regression", False): 2708 base_email_ext(registry, ctrigger, data, "RegressionTrigger") 2709 if data.get("failure", True): 2710 base_email_ext(registry, ctrigger, data, "FailureTrigger") 2711 if data.get("second-failure", False): 2712 base_email_ext(registry, ctrigger, data, "SecondFailureTrigger") 2713 if data.get("improvement", False): 2714 base_email_ext(registry, ctrigger, data, "ImprovementTrigger") 2715 if data.get("still-failing", False): 2716 base_email_ext(registry, ctrigger, data, "StillFailingTrigger") 2717 if data.get("success", False): 2718 base_email_ext(registry, ctrigger, data, "SuccessTrigger") 2719 if data.get("fixed", False): 2720 base_email_ext(registry, ctrigger, data, "FixedTrigger") 2721 if data.get("fixed-unhealthy", False): 2722 base_email_ext(registry, ctrigger, data, "FixedUnhealthyTrigger") 2723 if data.get("still-unstable", False): 2724 base_email_ext(registry, ctrigger, data, "StillUnstableTrigger") 2725 if data.get("pre-build", False): 2726 base_email_ext(registry, ctrigger, data, "PreBuildTrigger") 2727 if data.get("trigger-script", False): 2728 base_email_ext(registry, ctrigger, data, "ScriptTrigger") 2729 2730 content_type_mime = { 2731 "text": "text/plain", 2732 "html": "text/html", 2733 "default": "default", 2734 "both-html-text": "both", 2735 } 2736 ctype = data.get("content-type", "default") 2737 if ctype not in content_type_mime: 2738 raise InvalidAttributeError(ctype, ctype, content_type_mime.keys()) 2739 XML.SubElement(emailext, "contentType").text = content_type_mime[ctype] 2740 2741 mappings = [ 2742 ("subject", "defaultSubject", "$DEFAULT_SUBJECT"), 2743 ("body", "defaultContent", "$DEFAULT_CONTENT"), 2744 ("attachments", "attachmentsPattern", ""), 2745 ("presend-script", "presendScript", ""), 2746 ("postsend-script", "postsendScript", ""), 2747 ("attach-build-log", "attachBuildLog", False), 2748 ("compress-log", "compressBuildLog", False), 2749 ("save-output", "saveOutput", False), 2750 ("disable-publisher", "disabled", False), 2751 ("reply-to", "replyTo", "$DEFAULT_REPLYTO"), 2752 ] 2753 2754 if plugin_version >= pkg_resources.parse_version("2.39"): 2755 mappings.append(("from", "from", "")) 2756 2757 helpers.convert_mapping_to_xml(emailext, data, mappings, fail_required=True) 2758 2759 matrix_dict = { 2760 "both": "BOTH", 2761 "only-configurations": "ONLY_CONFIGURATIONS", 2762 "only-parent": "ONLY_PARENT", 2763 } 2764 matrix_trigger = data.get("matrix-trigger", None) 2765 # If none defined, then do not create entry 2766 if matrix_trigger is not None: 2767 if matrix_trigger not in matrix_dict: 2768 raise InvalidAttributeError( 2769 matrix_trigger, matrix_trigger, matrix_dict.keys() 2770 ) 2771 XML.SubElement(emailext, "matrixTriggerMode").text = matrix_dict.get( 2772 matrix_trigger 2773 ) 2774 2775 2776def fingerprint(registry, xml_parent, data): 2777 """yaml: fingerprint 2778 Fingerprint files to track them across builds. Requires the 2779 Jenkins :jenkins-plugins:`Fingerprint Plugin <create-fingerprint>`. 2780 2781 :arg str files: files to fingerprint, follows the @includes of Ant fileset 2782 (default '') 2783 :arg bool record-artifacts: fingerprint all archived artifacts 2784 (default false) 2785 2786 Example: 2787 2788 .. literalinclude:: /../../tests/publishers/fixtures/fingerprint001.yaml 2789 :language: yaml 2790 """ 2791 finger = XML.SubElement(xml_parent, "hudson.tasks.Fingerprinter") 2792 mappings = [ 2793 ("files", "targets", ""), 2794 ("record-artifacts", "recordBuildArtifacts", False), 2795 ] 2796 helpers.convert_mapping_to_xml(finger, data, mappings, fail_required=True) 2797 2798 2799def aggregate_tests(registry, xml_parent, data): 2800 """yaml: aggregate-tests 2801 Aggregate downstream test results 2802 2803 :arg bool include-failed-builds: whether to include failed builds 2804 (default false) 2805 2806 Example: 2807 2808 .. literalinclude:: 2809 /../../tests/publishers/fixtures/aggregate-tests001.yaml 2810 :language: yaml 2811 """ 2812 agg = XML.SubElement(xml_parent, "hudson.tasks.test.AggregatedTestResultPublisher") 2813 mapping = [("include-failed-builds", "includeFailedBuilds", False)] 2814 helpers.convert_mapping_to_xml(agg, data, mapping, fail_required=True) 2815 2816 2817def aggregate_flow_tests(registry, xml_parent, data): 2818 """yaml: aggregate-flow-tests 2819 Aggregate downstream test results in a Build Flow job. 2820 2821 Requires the Jenkins `Build Flow Test Aggregator Plugin 2822 <https://github.com/zeroturnaround/build-flow-test-aggregator>`_. 2823 2824 :arg bool show-test-results-trend: whether to show test results 2825 trend graph (default true) 2826 2827 Example: 2828 2829 .. literalinclude:: 2830 /../../tests/publishers/fixtures/aggregate-flow-tests002.yaml 2831 :language: yaml 2832 2833 """ 2834 agg_flow = XML.SubElement( 2835 xml_parent, 2836 "org.zeroturnaround.jenkins." "flowbuildtestaggregator.FlowTestAggregator", 2837 ) 2838 mapping = [("show-test-results-trend", "showTestResultTrend", True)] 2839 helpers.convert_mapping_to_xml(agg_flow, data, mapping, fail_required=True) 2840 2841 2842def cppcheck(registry, xml_parent, data): 2843 """yaml: cppcheck 2844 Cppcheck result publisher 2845 Requires the Jenkins :jenkins-plugins:`Cppcheck Plugin <cppcheck>`. 2846 2847 :arg str pattern: File pattern for cppcheck xml report (required) 2848 :arg bool ignoreblankfiles: Ignore blank files (default false) 2849 :arg bool allow-no-report: Do not fail the build if the Cppcheck report 2850 is not found (default false) 2851 :arg dict thresholds: 2852 :thresholds: Configure the build status and health. A build is 2853 considered as unstable or failure if the new or total number 2854 of issues exceeds the specified thresholds. The build health 2855 is also determined by thresholds. If the actual number of issues 2856 is between the provided thresholds, then the build health is 2857 interpolated. 2858 2859 * **unstable** (`str`): Total number unstable threshold (default '') 2860 * **new-unstable** (`str`): New number unstable threshold (default '') 2861 * **failure** (`str`): Total number failure threshold (default '') 2862 * **new-failure** (`str`): New number failure threshold (default '') 2863 * **healthy** (`str`): Healthy threshold (default '') 2864 * **unhealthy** (`str`): Unhealthy threshold (default '') 2865 2866 :arg dict severity: 2867 :severity: Determines which severity of issues should be considered 2868 when evaluating the build status and health, default all true 2869 2870 * **error** (`bool`): Severity error (default true) 2871 * **warning** (`bool`): Severity warning (default true) 2872 * **style** (`bool`): Severity style (default true) 2873 * **performance** (`bool`): Severity performance (default true) 2874 * **information** (`bool`): Severity information (default true) 2875 * **nocategory** (`bool`): Severity nocategory (default true) 2876 * **portability** (`bool`): Severity portability (default true) 2877 2878 :arg dict graph: 2879 :graph: Graph configuration 2880 2881 * **xysize** (`array`): Chart width and height (default [500, 200]) 2882 * **num-builds-in-graph** (`int`): Builds number in graph (default 0) 2883 2884 :arg dict display 2885 :display: which errors to display, default only sum 2886 2887 * **sum** (`bool`): Display sum of all issues (default true) 2888 * **error** (`bool`): Display errors (default false) 2889 * **warning** (`bool`): Display warnings (default false) 2890 * **style** (`bool`): Display style (default false) 2891 * **performance** (`bool`): Display performance (default false) 2892 * **information** (`bool`): Display information (default false) 2893 * **nocategory** (`bool`): Display no category (default false) 2894 * **portability** (`bool`): Display portability (default false) 2895 2896 Minimal Example: 2897 2898 .. literalinclude:: 2899 /../../tests/publishers/fixtures/cppcheck-minimal.yaml 2900 :language: yaml 2901 2902 Full Example: 2903 2904 .. literalinclude:: 2905 /../../tests/publishers/fixtures/cppcheck-full.yaml 2906 :language: yaml 2907 """ 2908 2909 cppextbase = XML.SubElement( 2910 xml_parent, "org.jenkinsci.plugins.cppcheck." "CppcheckPublisher" 2911 ) 2912 cppextbase.set("plugin", "cppcheck") 2913 cppext = XML.SubElement(cppextbase, "cppcheckConfig") 2914 mappings = [ 2915 ("pattern", "pattern", None), 2916 ("ignoreblankfiles", "ignoreBlankFiles", False), 2917 ("allow-no-report", "allowNoReport", False), 2918 ] 2919 helpers.convert_mapping_to_xml(cppext, data, mappings, fail_required=True) 2920 2921 csev = XML.SubElement(cppext, "configSeverityEvaluation") 2922 thrsh = data.get("thresholds", {}) 2923 thrsh_mappings = [ 2924 ("unstable", "threshold", ""), 2925 ("new-unstable", "newThreshold", ""), 2926 ("failure", "failureThreshold", ""), 2927 ("new-failure", "newFailureThreshold", ""), 2928 ("healthy", "healthy", ""), 2929 ("unhealthy", "unHealthy", ""), 2930 ] 2931 helpers.convert_mapping_to_xml(csev, thrsh, thrsh_mappings, fail_required=True) 2932 2933 sev = thrsh.get("severity", {}) 2934 sev_mappings = [ 2935 ("error", "severityError", True), 2936 ("warning", "severityWarning", True), 2937 ("style", "severityStyle", True), 2938 ("performance", "severityPerformance", True), 2939 ("information", "severityInformation", True), 2940 ("nocategory", "severityNoCategory", True), 2941 ("portability", "severityPortability", True), 2942 ] 2943 helpers.convert_mapping_to_xml(csev, sev, sev_mappings, fail_required=True) 2944 2945 graph = data.get("graph", {}) 2946 cgraph = XML.SubElement(cppext, "configGraph") 2947 x, y = graph.get("xysize", [500, 200]) 2948 XML.SubElement(cgraph, "xSize").text = str(x) 2949 XML.SubElement(cgraph, "ySize").text = str(y) 2950 graph_mapping = [("num-builds-in-graph", "numBuildsInGraph", 0)] 2951 helpers.convert_mapping_to_xml(cgraph, graph, graph_mapping, fail_required=True) 2952 2953 gdisplay = graph.get("display", {}) 2954 gdisplay_mappings = [ 2955 ("sum", "displayAllErrors", True), 2956 ("error", "displayErrorSeverity", False), 2957 ("warning", "displayWarningSeverity", False), 2958 ("style", "displayStyleSeverity", False), 2959 ("performance", "displayPerformanceSeverity", False), 2960 ("information", "displayInformationSeverity", False), 2961 ("nocategory", "displayNoCategorySeverity", False), 2962 ("portability", "displayPortabilitySeverity", False), 2963 ] 2964 helpers.convert_mapping_to_xml( 2965 cgraph, gdisplay, gdisplay_mappings, fail_required=True 2966 ) 2967 2968 2969def logparser(registry, xml_parent, data): 2970 """yaml: logparser 2971 Requires the Jenkins :jenkins-plugins:`Log Parser Plugin <log-parser>`. 2972 2973 :arg str parse-rules: full path to parse rules (default '') 2974 :arg bool use-project-rules: use project rules instead of global 2975 (default true) 2976 :arg bool unstable-on-warning: mark build unstable on warning 2977 (default false) 2978 :arg bool fail-on-error: mark build failed on error (default false) 2979 :arg bool show-graphs: show parser trend graphs (default true) 2980 2981 Minimal Example: 2982 2983 .. literalinclude:: 2984 /../../tests/publishers/fixtures/logparser-minimal.yaml 2985 :language: yaml 2986 2987 Full Example: 2988 2989 .. literalinclude:: 2990 /../../tests/publishers/fixtures/logparser-full.yaml 2991 :language: yaml 2992 """ 2993 2994 clog = XML.SubElement(xml_parent, "hudson.plugins.logparser.LogParserPublisher") 2995 clog.set("plugin", "log-parser") 2996 rules_path_element = ( 2997 "projectRulePath" if data.get("use-project-rules", True) else "parsingRulesPath" 2998 ) 2999 mappings = [ 3000 ("unstable-on-warning", "unstableOnWarning", False), 3001 ("fail-on-error", "failBuildOnError", False), 3002 ("show-graphs", "showGraphs", True), 3003 ("use-project-rules", "useProjectRule", True), 3004 ("parse-rules", rules_path_element, ""), 3005 ] 3006 helpers.convert_mapping_to_xml(clog, data, mappings, fail_required=True) 3007 3008 3009def copy_to_master(registry, xml_parent, data): 3010 """yaml: copy-to-master 3011 Copy files to master from slave. 3012 3013 Requires the Jenkins :jenkins-plugins:`Copy To Slave Plugin <copy-to-slave>`. 3014 3015 :arg list includes: list of file patterns to copy 3016 :arg list excludes: list of file patterns to exclude 3017 :arg str destination: absolute path into which the files will be copied. 3018 If left blank they will be copied into the workspace of the current job 3019 (default '') 3020 :arg bool run-after-result: If this is checked then copying files back to 3021 master will not run until the build result is finalized.(default true) 3022 3023 Example: 3024 3025 .. literalinclude:: 3026 /../../tests/publishers/fixtures/copy-to-master001.yaml 3027 :language: yaml 3028 """ 3029 cm = XML.SubElement( 3030 xml_parent, 3031 "com.michelin." "cio.hudson.plugins.copytoslave.CopyToMasterNotifier", 3032 ) 3033 cm.set("plugin", "copy-to-slave") 3034 3035 XML.SubElement(cm, "includes").text = ",".join(data.get("includes", [""])) 3036 XML.SubElement(cm, "excludes").text = ",".join(data.get("excludes", [""])) 3037 mappings = [ 3038 ("run-after-result", "runAfterResultFinalised", True), 3039 ("destination", "destinationFolder", ""), 3040 ] 3041 helpers.convert_mapping_to_xml(cm, data, mappings, fail_required=True) 3042 3043 if data.get("destination", ""): 3044 XML.SubElement(cm, "overrideDestinationFolder").text = "true" 3045 3046 3047def jira(registry, xml_parent, data): 3048 """yaml: jira 3049 Update relevant JIRA issues 3050 Requires the Jenkins :jenkins-plugins:`JIRA Plugin <jira>`. 3051 3052 Example: 3053 3054 .. literalinclude:: /../../tests/publishers/fixtures/jira001.yaml 3055 :language: yaml 3056 """ 3057 XML.SubElement(xml_parent, "hudson.plugins.jira.JiraIssueUpdater") 3058 3059 3060def growl(registry, xml_parent, data): 3061 """yaml: growl 3062 Push notifications to growl client. 3063 Requires the Jenkins :jenkins-plugins:`Growl Plugin <growl>`. 3064 3065 :arg str ip: IP address to send growl notifications to (required) 3066 :arg bool notify-only-on-fail-or-recovery: send a growl only when build 3067 fails or recovers from a failure (default false) 3068 3069 Minimal Example: 3070 3071 .. literalinclude:: /../../tests/publishers/fixtures/growl-minimal.yaml 3072 :language: yaml 3073 3074 Full Example: 3075 3076 .. literalinclude:: /../../tests/publishers/fixtures/growl-full.yaml 3077 :language: yaml 3078 """ 3079 growl = XML.SubElement(xml_parent, "hudson.plugins.growl.GrowlPublisher") 3080 growl.set("plugin", "growl") 3081 3082 mapping = [ 3083 ("ip", "IP", None), 3084 ("notify-only-on-fail-or-recovery", "onlyOnFailureOrRecovery", False), 3085 ] 3086 helpers.convert_mapping_to_xml(growl, data, mapping, fail_required=True) 3087 3088 3089def groovy_postbuild(registry, xml_parent, data): 3090 """yaml: groovy-postbuild 3091 Execute a groovy script. 3092 Requires the Jenkins :jenkins-plugins:`Groovy Postbuild Plugin 3093 <groovy-postbuild>`. 3094 3095 Please pay attention on version of plugin you have installed. 3096 There were incompatible changes between 1.x and 2.x. Please see 3097 :jenkins-plugins:`home page <groovy-postbuild>` of this plugin 3098 for full information including migration process. 3099 3100 :arg str script: The groovy script to execute 3101 :arg list classpath: List of additional classpaths (>=1.6) 3102 :arg str on-failure: In case of script failure leave build as it is 3103 for "nothing" option, mark build as unstable 3104 for "unstable" and mark job as failure for "failed" 3105 (default 'nothing') 3106 :arg bool matrix-parent: Run script for matrix parent only (>=1.9) 3107 (default false) 3108 :arg bool sandbox: Execute script inside of groovy sandbox (>=2.0) 3109 (default false) 3110 3111 Example: 3112 3113 .. literalinclude:: 3114 /../../tests/publishers/fixtures/groovy-postbuild001.yaml 3115 :language: yaml 3116 """ 3117 logger = logging.getLogger("%s:groovy-postbuild" % __name__) 3118 # Backward compatibility with old format 3119 if isinstance(data, six.string_types): 3120 logger.warning( 3121 "You use deprecated configuration, please follow documentation " 3122 "to change configuration. It is not going to be supported in " 3123 "future releases!" 3124 ) 3125 data = {"script": data} 3126 # There are incompatible changes, we need to know version 3127 info = registry.get_plugin_info("groovy-postbuild") 3128 # Note: Assume latest version of plugin is preferred config format 3129 version = pkg_resources.parse_version(info.get("version", str(sys.maxsize))) 3130 # Version specific predicates 3131 matrix_parent_support = version >= pkg_resources.parse_version("1.9") 3132 security_plugin_support = version >= pkg_resources.parse_version("2.0") 3133 extra_classpath_support = version >= pkg_resources.parse_version("1.6") 3134 3135 root_tag = "org.jvnet.hudson.plugins.groovypostbuild.GroovyPostbuildRecorder" 3136 groovy = XML.SubElement(xml_parent, root_tag) 3137 3138 behavior = data.get("on-failure") 3139 XML.SubElement(groovy, "behavior").text = {"unstable": "1", "failed": "2"}.get( 3140 behavior, "0" 3141 ) 3142 3143 if matrix_parent_support: 3144 XML.SubElement(groovy, "runForMatrixParent").text = str( 3145 data.get("matrix-parent", False) 3146 ).lower() 3147 3148 classpaths = data.get("classpath", list()) 3149 if security_plugin_support: 3150 script = XML.SubElement(groovy, "script") 3151 XML.SubElement(script, "script").text = data.get("script") 3152 XML.SubElement(script, "sandbox").text = str(data.get("sandbox", False)).lower() 3153 if classpaths: 3154 classpath = XML.SubElement(script, "classpath") 3155 for path in classpaths: 3156 script_path = XML.SubElement(classpath, "entry") 3157 XML.SubElement(script_path, "url").text = path 3158 else: 3159 XML.SubElement(groovy, "groovyScript").text = data.get("script") 3160 if extra_classpath_support and classpaths: 3161 classpath = XML.SubElement(groovy, "classpath") 3162 for path in classpaths: 3163 script_path = XML.SubElement( 3164 classpath, 3165 "org.jvnet.hudson.plugins.groovypostbuild." "GroovyScriptPath", 3166 ) 3167 XML.SubElement(script_path, "path").text = path 3168 3169 3170def base_publish_over( 3171 xml_parent, 3172 data, 3173 console_prefix, 3174 plugin_tag, 3175 publisher_tag, 3176 transferset_tag, 3177 retry_tag, 3178 reference_plugin_tag, 3179 is_builder=False, 3180): 3181 outer = XML.SubElement(xml_parent, plugin_tag) 3182 # 'Publish over SSH' builder has an extra top delegate element 3183 if xml_parent.tag == "builders" or is_builder: 3184 outer = XML.SubElement(outer, "delegate") 3185 3186 XML.SubElement(outer, "consolePrefix").text = console_prefix 3187 delegate = XML.SubElement(outer, "delegate") 3188 publishers = XML.SubElement(delegate, "publishers") 3189 3190 inner = XML.SubElement(publishers, publisher_tag) 3191 XML.SubElement(inner, "configName").text = data["site"] 3192 XML.SubElement(inner, "verbose").text = str(data.get("verbose", False)).lower() 3193 3194 transfers = XML.SubElement(inner, "transfers") 3195 transfersset = XML.SubElement(transfers, transferset_tag) 3196 3197 XML.SubElement(transfersset, "remoteDirectory").text = data["target"] 3198 XML.SubElement(transfersset, "sourceFiles").text = data["source"] 3199 XML.SubElement(transfersset, "excludes").text = data.get("excludes", "") 3200 XML.SubElement(transfersset, "removePrefix").text = data.get("remove-prefix", "") 3201 XML.SubElement(transfersset, "remoteDirectorySDF").text = str( 3202 data.get("target-is-date-format", False) 3203 ).lower() 3204 XML.SubElement(transfersset, "flatten").text = str( 3205 data.get("flatten", False) 3206 ).lower() 3207 XML.SubElement(transfersset, "cleanRemote").text = str( 3208 data.get("clean-remote", False) 3209 ).lower() 3210 3211 if "command" in data: 3212 XML.SubElement(transfersset, "execCommand").text = data["command"] 3213 if "timeout" in data: 3214 XML.SubElement(transfersset, "execTimeout").text = str(data["timeout"]) 3215 if "use-pty" in data: 3216 XML.SubElement(transfersset, "usePty").text = str( 3217 data.get("use-pty", False) 3218 ).lower() 3219 3220 XML.SubElement(inner, "useWorkspaceInPromotion").text = "false" 3221 XML.SubElement(inner, "usePromotionTimestamp").text = "false" 3222 3223 if "retries" in data: 3224 retry = XML.SubElement(inner, "retry", {"class": retry_tag}) 3225 XML.SubElement(retry, "retries").text = str(data.get("retries", 0)) 3226 XML.SubElement(retry, "retryDelay").text = str(data.get("retry-delay", 10000)) 3227 3228 XML.SubElement(delegate, "continueOnError").text = "false" 3229 XML.SubElement(delegate, "failOnError").text = str( 3230 data.get("fail-on-error", False) 3231 ).lower() 3232 XML.SubElement(delegate, "alwaysPublishFromMaster").text = str( 3233 data.get("always-publish-from-master", False) 3234 ).lower() 3235 XML.SubElement( 3236 delegate, 3237 "hostConfigurationAccess", 3238 {"class": reference_plugin_tag, "reference": "../.."}, 3239 ) 3240 3241 return (outer, transfersset) 3242 3243 3244def cifs(registry, xml_parent, data): 3245 """yaml: cifs 3246 Upload files via CIFS. 3247 Requires the Jenkins :jenkins-plugins:`Publish over CIFS Plugin 3248 <publish-over-cifs>`. 3249 3250 :arg str site: name of the cifs site/share (required) 3251 :arg str target: destination directory (required) 3252 :arg bool target-is-date-format: whether target is a date format. If true, 3253 raw text should be quoted (default false) 3254 :arg bool clean-remote: should the remote directory be deleted before 3255 transferring files (default false) 3256 :arg str source: source path specifier (required) 3257 :arg str excludes: excluded file pattern (default '') 3258 :arg str remove-prefix: prefix to remove from uploaded file paths 3259 (default '') 3260 :arg bool fail-on-error: fail the build if an error occurs (default false). 3261 :arg bool flatten: only create files on the server, don't create 3262 directories (default false). 3263 :arg bool verbose: adds lots of detail useful for debug to the console 3264 but generally should be left off (default false) 3265 :arg int retries: the number of times to retry this server in the event of 3266 failure (optional) 3267 :arg int retry-delay: the time to wait, in milliseconds, before attempting 3268 another transfer (default 10000) 3269 3270 Minimal Example: 3271 3272 .. literalinclude:: /../../tests/publishers/fixtures/cifs-minimal.yaml 3273 :language: yaml 3274 3275 Full Example: 3276 3277 .. literalinclude:: /../../tests/publishers/fixtures/cifs-full.yaml 3278 :language: yaml 3279 3280 """ 3281 console_prefix = "CIFS: " 3282 if xml_parent.tag == "publishers": 3283 plugin_tag = "jenkins.plugins.publish__over__cifs.CifsPublisherPlugin" 3284 is_builder = False 3285 else: 3286 plugin_tag = "jenkins.plugins.publish__over__cifs.CifsBuilderPlugin" 3287 is_builder = True 3288 publisher_tag = "jenkins.plugins.publish__over__cifs.CifsPublisher" 3289 transfer_tag = "jenkins.plugins.publish__over__cifs.CifsTransfer" 3290 retry_tag = "jenkins.plugins.publish_over_cifs.CifsRetry" 3291 plugin_reference_tag = "jenkins.plugins.publish_over_cifs." "CifsPublisherPlugin" 3292 base_publish_over( 3293 xml_parent, 3294 data, 3295 console_prefix, 3296 plugin_tag, 3297 publisher_tag, 3298 transfer_tag, 3299 retry_tag, 3300 plugin_reference_tag, 3301 is_builder, 3302 ) 3303 3304 3305def cigame(registry, xml_parent, data): 3306 """yaml: cigame 3307 This plugin introduces a game where users get points 3308 for improving the builds. 3309 Requires the Jenkins Continuous Integration Game 3310 plugin (https://github.com/jenkinsci/ci-game-plugin). 3311 3312 Example: 3313 3314 .. literalinclude:: /../../tests/publishers/fixtures/cigame.yaml 3315 :language: yaml 3316 """ 3317 XML.SubElement(xml_parent, "hudson.plugins.cigame.GamePublisher") 3318 3319 3320def sonar(registry, xml_parent, data): 3321 """yaml: sonar 3322 Sonar plugin support. 3323 Requires the Jenkins `Sonar Plugin. 3324 <https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-jenkins>`_ 3325 3326 :arg str installation-name: name of the Sonar instance to use (optional) 3327 :arg str jdk: JDK to use (inherited from the job if omitted). (optional) 3328 :arg str branch: branch onto which the analysis will be posted (default '') 3329 :arg str language: source code language (default '') 3330 :arg str root-pom: Root POM (default 'pom.xml') 3331 :arg bool private-maven-repo: If true, use private Maven repository. 3332 (default false) 3333 :arg str maven-opts: options given to maven (default '') 3334 :arg str additional-properties: sonar analysis parameters (default '') 3335 :arg str maven-installation-name: the name of the Maven installation 3336 to use (optional) 3337 :arg dict skip-global-triggers: 3338 :Triggers: * **skip-when-scm-change** (`bool`): skip analysis when 3339 build triggered by scm (default false) 3340 * **skip-when-upstream-build** (`bool`): skip analysis when 3341 build triggered by an upstream build (default false) 3342 * **skip-when-envvar-defined** (`str`): skip analysis when 3343 the specified environment variable is set to true 3344 (default '') 3345 :arg str settings: Path to use as user settings.xml. It is possible to 3346 provide a ConfigFileProvider settings file, see Example below. 3347 (optional) 3348 :arg str global-settings: Path to use as global settings.xml. It is 3349 possible to provide a ConfigFileProvider settings file, see Example 3350 below. (optional) 3351 3352 Requires the Jenkins :jenkins-plugins:`Config File Provider Plugin 3353 <config-file-provider>` 3354 for the Config File Provider "settings" and "global-settings" config. 3355 3356 This publisher supports the post-build action exposed by the Jenkins 3357 Sonar Plugin, which is triggering a Sonar Analysis with Maven. 3358 3359 Minimal Example: 3360 3361 .. literalinclude:: /../../tests/publishers/fixtures/sonar-minimal.yaml 3362 :language: yaml 3363 3364 Full Example: 3365 3366 .. literalinclude:: /../../tests/publishers/fixtures/sonar-full.yaml 3367 :language: yaml 3368 """ 3369 3370 sonar = XML.SubElement(xml_parent, "hudson.plugins.sonar.SonarPublisher") 3371 sonar.set("plugin", "sonar") 3372 if "installation-name" in data: 3373 XML.SubElement(sonar, "installationName").text = data["installation-name"] 3374 if "jdk" in data: 3375 XML.SubElement(sonar, "jdk").text = data["jdk"] 3376 if "maven-installation-name" in data: 3377 XML.SubElement(sonar, "mavenInstallationName").text = data[ 3378 "maven-installation-name" 3379 ] 3380 3381 mappings = [ 3382 ("branch", "branch", ""), 3383 ("language", "language", ""), 3384 ("root-pom", "rootPom", "pom.xml"), 3385 ("private-maven-repo", "usePrivateRepository", False), 3386 ("maven-opts", "mavenOpts", ""), 3387 ("additional-properties", "jobAdditionalProperties", ""), 3388 ] 3389 helpers.convert_mapping_to_xml(sonar, data, mappings, fail_required=True) 3390 3391 if "skip-global-triggers" in data: 3392 data_triggers = data["skip-global-triggers"] 3393 triggers = XML.SubElement(sonar, "triggers") 3394 triggers_mappings = [ 3395 ("skip-when-scm-change", "skipScmCause", False), 3396 ("skip-when-upstream-build", "skipUpstreamCause", False), 3397 ("skip-when-envvar-defined", "envVar", ""), 3398 ] 3399 helpers.convert_mapping_to_xml( 3400 triggers, data_triggers, triggers_mappings, fail_required=True 3401 ) 3402 3403 helpers.config_file_provider_settings(sonar, data) 3404 3405 3406def sounds(parser, xml_parent, data): 3407 """yaml: sounds 3408 Play audio clips locally through sound hardware, 3409 remotely by piping them through an operating system command, 3410 or simultaneously through all browsers on a Jenkins page. 3411 3412 Requires the Jenkins :jenkins-plugins:`Jenkins Sounds plugin 3413 <sounds>` 3414 3415 :arg dict success: Play on success 3416 3417 :success: 3418 .. _sound_and_cond: 3419 3420 * **sound** (`str`) - Sound name 3421 * **from** (`list`) - Previous build result (default is all) 3422 :from values: 3423 * **success** 3424 * **unstable** 3425 * **failure** 3426 * **not_build** 3427 * **aborted** 3428 3429 :arg dict unstable: Play on unstable. 3430 Specifying sound and conditions see :ref:`above <sound_and_cond>`. 3431 :arg dict failure: Play on failure. 3432 Specifying sound and conditions see :ref:`above <sound_and_cond>`. 3433 :arg dict not_build: Play on not build. 3434 Specifying sound and conditions see :ref:`above <sound_and_cond>`. 3435 :arg dict aborted: Play on aborted. 3436 Specifying sound and conditions see :ref:`above <sound_and_cond>`. 3437 3438 Minimal example using defaults: 3439 3440 .. literalinclude:: /../../tests/publishers/fixtures/sounds001.yaml 3441 :language: yaml 3442 3443 Full example: 3444 3445 .. literalinclude:: /../../tests/publishers/fixtures/sounds003.yaml 3446 :language: yaml 3447 """ 3448 3449 mapping_dict = { 3450 "success": hudson_model.SUCCESS, 3451 "unstable": hudson_model.UNSTABLE, 3452 "failure": hudson_model.FAILURE, 3453 "not_build": hudson_model.NOTBUILD, 3454 "aborted": hudson_model.ABORTED, 3455 } 3456 sounds = XML.SubElement( 3457 xml_parent, "net.hurstfrost.hudson." "sounds.HudsonSoundsNotifier" 3458 ) 3459 events = XML.SubElement(sounds, "soundEvents") 3460 for status, v in data.items(): 3461 try: 3462 model = mapping_dict[status] 3463 except KeyError: 3464 raise InvalidAttributeError("build status", status, mapping_dict) 3465 3466 event = XML.SubElement( 3467 events, "net.hurstfrost.hudson.sounds." "HudsonSoundsNotifier_-SoundEvent" 3468 ) 3469 XML.SubElement(event, "soundId").text = v["sound"] 3470 to_result = XML.SubElement(event, "toResult") 3471 XML.SubElement(to_result, "name").text = model["name"] 3472 XML.SubElement(to_result, "ordinal").text = model["ordinal"] 3473 XML.SubElement(to_result, "color").text = model["color"] 3474 XML.SubElement(to_result, "completeBuild").text = str(model["complete"]).lower() 3475 3476 from_results = XML.SubElement(event, "fromResults") 3477 results = ["not_build", "success", "aborted", "failure", "unstable"] 3478 if "from" in v: 3479 results = v["from"] 3480 for result in results: 3481 model = mapping_dict[result] 3482 from_result = XML.SubElement(from_results, "hudson.model.Result") 3483 XML.SubElement(from_result, "name").text = model["name"] 3484 XML.SubElement(from_result, "ordinal").text = model["ordinal"] 3485 XML.SubElement(from_result, "color").text = model["color"] 3486 XML.SubElement(from_result, "completeBuild").text = str( 3487 model["complete"] 3488 ).lower() 3489 3490 3491def performance(registry, xml_parent, data): 3492 r"""yaml: performance 3493 Publish performance test results from jmeter and junit. 3494 Requires the Jenkins :jenkins-plugins:`Performance Plugin 3495 <performance>`. 3496 3497 :arg int failed-threshold: Specify the error percentage threshold that 3498 set the build failed. A negative value means don't use this threshold 3499 (default 0) 3500 :arg int unstable-threshold: Specify the error percentage threshold that 3501 set the build unstable. A negative value means don't use this threshold 3502 (default 0) 3503 :arg str unstable-response-time-threshold: Average response time threshold 3504 (default '') 3505 :arg float failed-threshold-positive: Maximum failed percentage for build 3506 comparison (default 0.0) 3507 :arg float failed-threshold-negative: Minimum failed percentage for build 3508 comparison (default 0.0) 3509 :arg float unstable-threshold-positive: Maximum unstable percentage for 3510 build comparison (default 0.0) 3511 :arg float unstable-threshold-negative: Minimum unstable percentage for 3512 build comparison (default 0.0) 3513 :arg int nth-build-number: Build number for build comparison (default 0) 3514 :arg bool mode-relative-thresholds: Relative threshold mode (default false) 3515 :arg str config-type: Compare based on (default 'ART') 3516 3517 :config-type values: 3518 * **ART** -- Average Response Time 3519 * **MRT** -- Median Response Time 3520 * **PRT** -- Percentile Response Time 3521 3522 :arg bool mode-of-threshold: Mode of threshold, true for relative threshold 3523 and false for error threshold (default false) 3524 :arg bool fail-build: Fail build when result files are not present 3525 (default false) 3526 :arg bool compare-build-previous: Compare with previous build 3527 (default false) 3528 :arg bool mode-performance-per-test-case: Performance Per Test Case Mode 3529 (default true) 3530 :arg bool mode-thoughput: Show Throughput Chart (default false) 3531 3532 :arg dict report: 3533 3534 :(jmeter or junit): (`dict` or `str`): Specify a custom report file 3535 (optional; jmeter default \**/*.jtl, junit default **/TEST-\*.xml) 3536 3537 Minimal Example: 3538 3539 .. literalinclude:: 3540 /../../tests/publishers/fixtures/performance-minimal.yaml 3541 :language: yaml 3542 3543 Full Example: 3544 3545 .. literalinclude:: 3546 /../../tests/publishers/fixtures/performance-full.yaml 3547 :language: yaml 3548 """ 3549 perf = XML.SubElement( 3550 xml_parent, "hudson.plugins.performance." "PerformancePublisher" 3551 ) 3552 perf.set("plugin", "performance") 3553 types = ["ART", "MRT", "PRT"] 3554 mappings = [ 3555 ("failed-threshold", "errorFailedThreshold", 0), 3556 ("unstable-threshold", "errorUnstableThreshold", 0), 3557 ("unstable-response-time-threshold", "errorUnstableResponseTimeThreshold", ""), 3558 ("failed-threshold-positive", "relativeFailedThresholdPositive", "0.0"), 3559 ("failed-threshold-negative", "relativeFailedThresholdNegative", "0.0"), 3560 ("unstable-threshold-positive", "relativeUnstableThresholdPositive", "0.0"), 3561 ("unstable-threshold-negative", "relativeUnstableThresholdNegative", "0.0"), 3562 ("nth-build-number", "nthBuildNumber", 0), 3563 ("mode-relative-thresholds", "modeRelativeThresholds", False), 3564 ("config-type", "configType", "ART", types), 3565 ("mode-of-threshold", "modeOfThreshold", False), 3566 ("fail-build", "failBuildIfNoResultFile", False), 3567 ("compare-build-previous", "compareBuildPrevious", False), 3568 ("mode-performance-per-test-case", "modePerformancePerTestCase", True), 3569 ("mode-thoughput", "modeThroughput", False), 3570 ] 3571 helpers.convert_mapping_to_xml(perf, data, mappings, fail_required=True) 3572 3573 parsers = XML.SubElement(perf, "parsers") 3574 if "report" in data: 3575 for item in data["report"]: 3576 if isinstance(item, dict): 3577 item_name = next(iter(item.keys())) 3578 item_values = item.get(item_name, None) 3579 if item_name == "jmeter": 3580 jmhold = XML.SubElement( 3581 parsers, "hudson.plugins." "performance." "JMeterParser" 3582 ) 3583 XML.SubElement(jmhold, "glob").text = str(item_values) 3584 elif item_name == "junit": 3585 juhold = XML.SubElement( 3586 parsers, "hudson.plugins." "performance." "JUnitParser" 3587 ) 3588 XML.SubElement(juhold, "glob").text = str(item_values) 3589 else: 3590 raise JenkinsJobsException( 3591 "You have not specified jmeter " 3592 "or junit, or you have " 3593 "incorrectly assigned the key " 3594 "value." 3595 ) 3596 elif isinstance(item, str): 3597 if item == "jmeter": 3598 jmhold = XML.SubElement( 3599 parsers, "hudson.plugins." "performance." "JMeterParser" 3600 ) 3601 XML.SubElement(jmhold, "glob").text = "**/*.jtl" 3602 elif item == "junit": 3603 juhold = XML.SubElement( 3604 parsers, "hudson.plugins." "performance." "JUnitParser" 3605 ) 3606 XML.SubElement(juhold, "glob").text = "**/TEST-*.xml" 3607 else: 3608 raise JenkinsJobsException( 3609 "You have not specified jmeter " 3610 "or junit, or you have " 3611 "incorrectly assigned the key " 3612 "value." 3613 ) 3614 3615 3616def join_trigger(registry, xml_parent, data): 3617 """yaml: join-trigger 3618 Trigger a job after all the immediate downstream jobs have completed. 3619 Requires the Jenkins :jenkins-plugins:`Join Plugin <join>`. 3620 3621 :arg list projects: list of projects to trigger 3622 :arg list publishers: list of triggers from publishers module that 3623 defines projects that need to be triggered 3624 :arg str threshold: result threshold to trigger jobs (optional). 3625 Valid values are "success", "unstable", "failure", and "aborted". 3626 :arg bool even-if-unstable: if true jobs will trigger even if some 3627 downstream jobs are marked as unstable (default false) (DEPRECATED) 3628 3629 Example: 3630 3631 .. literalinclude:: 3632 /../../tests/publishers/fixtures/join-trigger001.yaml 3633 :language: yaml 3634 """ 3635 jointrigger = XML.SubElement(xml_parent, "join.JoinTrigger") 3636 3637 joinProjectsText = ",".join(data.get("projects", [""])) 3638 XML.SubElement(jointrigger, "joinProjects").text = joinProjectsText 3639 3640 publishers = XML.SubElement(jointrigger, "joinPublishers") 3641 for pub in data.get("publishers", []): 3642 for edited_node in create_publishers(registry, pub): 3643 publishers.append(edited_node) 3644 3645 unstable = str(data.get("even-if-unstable", "")).lower() 3646 if unstable: 3647 XML.SubElement(jointrigger, "evenIfDownstreamUnstable").text = unstable 3648 3649 threshold = data.get("threshold", "") 3650 if threshold: 3651 helpers.trigger_threshold(jointrigger, "resultThreshold", threshold) 3652 3653 3654def jabber(registry, xml_parent, data): 3655 """yaml: jabber 3656 Integrates Jenkins with the Jabber/XMPP instant messaging protocol 3657 Requires the Jenkins :jenkins-plugins:`Jabber Plugin <jabber>`. 3658 3659 :arg bool notify-on-build-start: Whether to send notifications 3660 to channels when a build starts (default false) 3661 :arg bool notify-scm-committers: Whether to send notifications 3662 to the users that are suspected of having broken this build 3663 (default false) 3664 :arg bool notify-scm-culprits: Also send notifications to 'culprits' 3665 from previous unstable/failed builds (default false) 3666 :arg bool notify-upstream-committers: Whether to send notifications to 3667 upstream committers if no committers were found for a broken build 3668 (default false) 3669 :arg bool notify-scm-fixers: Whether to send notifications to the users 3670 that have fixed a broken build (default false) 3671 :arg list group-targets: List of group targets to notify 3672 :arg list individual-targets: List of individual targets to notify 3673 :arg dict strategy: When to send notifications (default all) 3674 3675 :strategy values: 3676 * **all** -- Always 3677 * **failure** -- On any failure 3678 * **failure-fixed** -- On failure and fixes 3679 * **new-failure-fixed** -- On new failure and fixes 3680 * **change** -- Only on state change 3681 :arg dict message: Channel notification message (default summary-scm) 3682 3683 :message values: 3684 * **summary-scm** -- Summary + SCM changes 3685 * **summary** -- Just summary 3686 * **summary-build** -- Summary and build parameters 3687 * **summary-scm-fail** -- Summary, SCM changes, and failed tests 3688 3689 Minimal Example: 3690 3691 .. literalinclude:: 3692 /../../tests/publishers/fixtures/jabber-minimal.yaml 3693 :language: yaml 3694 3695 Full Example: 3696 3697 .. literalinclude:: /../../tests/publishers/fixtures/jabber-full.yaml 3698 :language: yaml 3699 """ 3700 j = XML.SubElement( 3701 xml_parent, "hudson.plugins.jabber.im.transport." "JabberPublisher" 3702 ) 3703 j.set("plugin", "jabber") 3704 3705 t = XML.SubElement(j, "targets") 3706 if "group-targets" in data: 3707 for group in data["group-targets"]: 3708 gcimt = XML.SubElement(t, "hudson.plugins.im." "GroupChatIMMessageTarget") 3709 gcimt.set("plugin", "instant-messaging") 3710 XML.SubElement(gcimt, "name").text = group 3711 XML.SubElement(gcimt, "notificationOnly").text = "false" 3712 if "individual-targets" in data: 3713 for individual in data["individual-targets"]: 3714 dimt = XML.SubElement(t, "hudson.plugins.im." "DefaultIMMessageTarget") 3715 dimt.set("plugin", "instant-messaging") 3716 XML.SubElement(dimt, "value").text = individual 3717 strategy = data.get("strategy", "all") 3718 strategydict = { 3719 "all": "ALL", 3720 "failure": "ANY_FAILURE", 3721 "failure-fixed": "FAILURE_AND_FIXED", 3722 "new-failure-fixed": "NEW_FAILURE_AND_FIXED", 3723 "change": "STATECHANGE_ONLY", 3724 } 3725 if strategy not in strategydict: 3726 raise JenkinsJobsException( 3727 "Strategy entered is not valid, must be " 3728 + "one of: all, failure, failure-fixed, or " 3729 "change" 3730 ) 3731 XML.SubElement(j, "strategy").text = strategydict[strategy] 3732 3733 mappings = [ 3734 ("notify-on-build-start", "notifyOnBuildStart", False), 3735 ("notify-scm-committers", "notifySuspects", False), 3736 ("notify-scm-culprits", "notifyCulprits", False), 3737 ("notify-scm-fixers", "notifyFixers", False), 3738 ("notify-upstream-committers", "notifyUpstreamCommitters", False), 3739 ] 3740 helpers.convert_mapping_to_xml(j, data, mappings, fail_required=True) 3741 3742 message = data.get("message", "summary-scm") 3743 messagedict = { 3744 "summary-scm": "DefaultBuildToChatNotifier", 3745 "summary": "SummaryOnlyBuildToChatNotifier", 3746 "summary-build": "BuildParametersBuildToChatNotifier", 3747 "summary-scm-fail": "PrintFailingTestsBuildToChatNotifier", 3748 } 3749 if message not in messagedict: 3750 raise JenkinsJobsException( 3751 "Message entered is not valid, must be one " 3752 "of: summary-scm, summary, summary-build " 3753 "or summary-scm-fail" 3754 ) 3755 XML.SubElement( 3756 j, 3757 "buildToChatNotifier", 3758 {"class": "hudson.plugins.im.build_notify." + messagedict[message]}, 3759 ) 3760 XML.SubElement(j, "matrixMultiplier").text = "ONLY_CONFIGURATIONS" 3761 3762 3763def workspace_cleanup(registry, xml_parent, data): 3764 """yaml: workspace-cleanup (post-build) 3765 3766 Requires the Jenkins :jenkins-plugins:`Workspace Cleanup Plugin 3767 <ws-cleanup>`. 3768 3769 The pre-build workspace-cleanup is available as a wrapper. 3770 3771 :arg list include: list of files to be included 3772 :arg list exclude: list of files to be excluded 3773 :arg bool dirmatch: Apply pattern to directories too (default false) 3774 :arg list clean-if: clean depending on build status 3775 3776 :clean-if values: 3777 * **success** (`bool`) (default true) 3778 * **unstable** (`bool`) (default true) 3779 * **failure** (`bool`) (default true) 3780 * **aborted** (`bool`) (default true) 3781 * **not-built** (`bool`) (default true) 3782 :arg bool fail-build: Fail the build if the cleanup fails (default true) 3783 :arg bool clean-parent: Cleanup matrix parent workspace (default false) 3784 :arg str external-deletion-command: external deletion command to run 3785 against files and directories 3786 :arg bool disable-deferred-wipeout: Disable improved deferred wipeout 3787 method (default false) 3788 3789 Minimal Example: 3790 3791 .. literalinclude:: 3792 /../../tests/publishers/fixtures/workspace-cleanup-minimal.yaml 3793 :language: yaml 3794 3795 Full Example: 3796 3797 .. literalinclude:: 3798 /../../tests/publishers/fixtures/workspace-cleanup-full.yaml 3799 :language: yaml 3800 """ 3801 3802 p = XML.SubElement(xml_parent, "hudson.plugins.ws__cleanup.WsCleanup") 3803 p.set("plugin", "ws-cleanup") 3804 if "include" in data or "exclude" in data: 3805 patterns = XML.SubElement(p, "patterns") 3806 3807 for inc in data.get("include", []): 3808 ptrn = XML.SubElement(patterns, "hudson.plugins.ws__cleanup.Pattern") 3809 XML.SubElement(ptrn, "pattern").text = inc 3810 XML.SubElement(ptrn, "type").text = "INCLUDE" 3811 3812 for exc in data.get("exclude", []): 3813 ptrn = XML.SubElement(patterns, "hudson.plugins.ws__cleanup.Pattern") 3814 XML.SubElement(ptrn, "pattern").text = exc 3815 XML.SubElement(ptrn, "type").text = "EXCLUDE" 3816 3817 mappings = [ 3818 ("dirmatch", "deleteDirs", False), 3819 ("clean-parent", "cleanupMatrixParent", False), 3820 ("external-deletion-command", "externalDelete", ""), 3821 ("disable-deferred-wipeout", "disableDeferredWipeout", False), 3822 ] 3823 helpers.convert_mapping_to_xml(p, data, mappings, fail_required=True) 3824 3825 mask = [ 3826 ("success", "cleanWhenSuccess"), 3827 ("unstable", "cleanWhenUnstable"), 3828 ("failure", "cleanWhenFailure"), 3829 ("not-built", "cleanWhenNotBuilt"), 3830 ("aborted", "cleanWhenAborted"), 3831 ] 3832 clean = data.get("clean-if", []) 3833 cdict = dict() 3834 for d in clean: 3835 cdict.update(d) 3836 for k, v in mask: 3837 XML.SubElement(p, v).text = str(cdict.pop(k, True)).lower() 3838 3839 if len(cdict) > 0: 3840 raise ValueError("clean-if must be one of: %r" % list(mask.keys())) 3841 3842 if str(data.get("fail-build", False)).lower() == "false": 3843 XML.SubElement(p, "notFailBuild").text = "true" 3844 else: 3845 XML.SubElement(p, "notFailBuild").text = "false" 3846 3847 3848def maven_deploy(registry, xml_parent, data): 3849 """yaml: maven-deploy 3850 Deploy artifacts to Maven repository. 3851 3852 :arg str id: Repository ID 3853 :arg str url: Repository URL (optional) 3854 :arg bool unique-version: Assign unique versions to snapshots 3855 (default true) 3856 :arg bool deploy-unstable: Deploy even if the build is unstable 3857 (default false) 3858 :arg str release-env-var: If the given variable name is set to "true", 3859 the deploy steps are skipped. (optional) 3860 3861 3862 Example: 3863 3864 .. literalinclude:: /../../tests/publishers/fixtures/maven-deploy001.yaml 3865 :language: yaml 3866 """ 3867 3868 p = XML.SubElement(xml_parent, "hudson.maven.RedeployPublisher") 3869 if "id" in data: 3870 XML.SubElement(p, "id").text = data["id"] 3871 if "url" in data: 3872 XML.SubElement(p, "url").text = data["url"] 3873 XML.SubElement(p, "uniqueVersion").text = str( 3874 data.get("unique-version", True) 3875 ).lower() 3876 XML.SubElement(p, "evenIfUnstable").text = str( 3877 data.get("deploy-unstable", False) 3878 ).lower() 3879 if "release-env-var" in data: 3880 XML.SubElement(p, "releaseEnvVar").text = data["release-env-var"] 3881 3882 3883def artifactory(registry, xml_parent, data): 3884 """yaml: artifactory 3885 Uses/requires the Artifactory plugin to deploy artifacts to 3886 Artifactory Server. 3887 3888 Requires the Jenkins :jenkins-plugins:`Artifactory Plugin 3889 <artifactory>`. 3890 3891 :arg str url: Artifactory server url (default '') 3892 :arg str name: Artifactory user with permissions use for 3893 connected to the selected Artifactory Server (default '') 3894 :arg str release-repo-key: Release repository name (default '') 3895 :arg str snapshot-repo-key: Snapshots repository name (default '') 3896 :arg bool publish-build-info: Push build metadata with artifacts 3897 (default false) 3898 :arg bool discard-old-builds: 3899 Remove older build info from Artifactory (default false) 3900 :arg bool discard-build-artifacts: 3901 Remove older build artifacts from Artifactory (default false) 3902 :arg bool even-if-unstable: Deploy artifacts even when the build 3903 is unstable (default false) 3904 :arg bool run-checks: Run automatic license scanning check after the 3905 build is complete (default false) 3906 :arg bool include-publish-artifacts: Include the build's published 3907 module artifacts in the license violation checks if they are 3908 also used as dependencies for other modules in this build 3909 (default false) 3910 :arg bool pass-identified-downstream: When true, a build parameter 3911 named ARTIFACTORY_BUILD_ROOT with a value of 3912 ${JOB_NAME}-${BUILD_NUMBER} will be sent to downstream builds 3913 (default false) 3914 :arg bool license-auto-discovery: Tells Artifactory not to try 3915 and automatically analyze and tag the build's dependencies 3916 with license information upon deployment (default true) 3917 :arg bool enable-issue-tracker-integration: When the Jenkins 3918 JIRA plugin is enabled, synchronize information about JIRA 3919 issues to Artifactory and attach issue information to build 3920 artifacts (default false) 3921 :arg bool aggregate-build-issues: When the Jenkins JIRA plugin 3922 is enabled, include all issues from previous builds up to the 3923 latest build status defined in "Aggregation Build Status" 3924 (default false) 3925 :arg bool allow-promotion-of-non-staged-builds: The build 3926 promotion operation will be available to all successful builds 3927 instead of only staged ones (default false) 3928 :arg bool filter-excluded-artifacts-from-build: Add the excluded 3929 files to the excludedArtifacts list and remove them from the 3930 artifacts list in the build info (default false) 3931 :arg str scopes: A list of dependency scopes/configurations to run 3932 license violation checks on. If left empty all dependencies from 3933 all scopes will be checked (default '') 3934 :arg str violation-recipients: Recipients that need to be notified 3935 of license violations in the build info (default '') 3936 :arg list matrix-params: Semicolon-separated list of properties to 3937 attach to all deployed artifacts in addition to the default ones: 3938 build.name, build.number, and vcs.revision (default []) 3939 :arg str black-duck-app-name: The existing Black Duck Code Center 3940 application name (default '') 3941 :arg str black-duck-app-version: The existing Black Duck Code Center 3942 application version (default '') 3943 :arg str black-duck-report-recipients: Recipients that will be emailed 3944 a report after the automatic Black Duck Code Center compliance checks 3945 finished (default '') 3946 :arg str black-duck-scopes: A list of dependency scopes/configurations 3947 to run Black Duck Code Center compliance checks on. If left empty 3948 all dependencies from all scopes will be checked (default '') 3949 :arg bool black-duck-run-checks: Automatic Black Duck Code Center 3950 compliance checks will occur after the build completes 3951 (default false) 3952 :arg bool black-duck-include-published-artifacts: Include the build's 3953 published module artifacts in the license violation checks if they 3954 are also used as dependencies for other modules in this build 3955 (default false) 3956 :arg bool auto-create-missing-component-requests: Auto create 3957 missing components in Black Duck Code Center application after 3958 the build is completed and deployed in Artifactory 3959 (default true) 3960 :arg bool auto-discard-stale-component-requests: Auto discard 3961 stale components in Black Duck Code Center application after 3962 the build is completed and deployed in Artifactory 3963 (default true) 3964 :arg bool deploy-artifacts: Push artifacts to the Artifactory 3965 Server. Use deployment-include-patterns and 3966 deployment-exclude-patterns to filter deploy artifacts. (default true) 3967 :arg list deployment-include-patterns: New line or comma separated mappings 3968 of build artifacts to published artifacts. Supports Ant-style wildcards 3969 mapping to target directories. E.g.: */*.zip=>dir (default []) 3970 :arg list deployment-exclude-patterns: New line or comma separated patterns 3971 for excluding artifacts from deployment to Artifactory (default []) 3972 :arg bool env-vars-include: Include all environment variables 3973 accessible by the build process. Jenkins-specific env variables 3974 are always included. Use env-vars-include-patterns and 3975 env-vars-exclude-patterns to filter variables to publish, 3976 (default false) 3977 :arg list env-vars-include-patterns: Comma or space-separated list of 3978 environment variables that will be included as part of the published 3979 build info. Environment variables may contain the * and the ? wildcards 3980 (default []) 3981 :arg list env-vars-exclude-patterns: Comma or space-separated list of 3982 environment variables that will be excluded from the published 3983 build info (default []) 3984 3985 Example: 3986 3987 .. literalinclude:: /../../tests/publishers/fixtures/artifactory01.yaml 3988 3989 .. literalinclude:: /../../tests/publishers/fixtures/artifactory02.yaml 3990 3991 """ 3992 3993 artifactory = XML.SubElement( 3994 xml_parent, "org.jfrog.hudson.ArtifactoryRedeployPublisher" 3995 ) 3996 3997 # optional_props 3998 helpers.artifactory_optional_props(artifactory, data, "publishers") 3999 4000 XML.SubElement(artifactory, "matrixParams").text = ",".join( 4001 data.get("matrix-params", []) 4002 ) 4003 4004 # details 4005 details = XML.SubElement(artifactory, "details") 4006 helpers.artifactory_common_details(details, data) 4007 4008 mapping = [ 4009 ("release-repo-key", "repositoryKey", ""), 4010 ("snapshot-repo-key", "snapshotsRepositoryKey", ""), 4011 ] 4012 helpers.convert_mapping_to_xml(details, data, mapping, fail_required=True) 4013 4014 plugin = XML.SubElement(details, "stagingPlugin") 4015 XML.SubElement(plugin, "pluginName").text = "None" 4016 4017 # artifactDeploymentPatterns 4018 helpers.artifactory_deployment_patterns(artifactory, data) 4019 4020 # envVarsPatterns 4021 helpers.artifactory_env_vars_patterns(artifactory, data) 4022 4023 4024def test_fairy(registry, xml_parent, data): 4025 """yaml: test-fairy 4026 This plugin helps you to upload Android APKs or iOS IPA files to 4027 www.testfairy.com. 4028 4029 Requires the Jenkins :jenkins-plugins:`Test Fairy Plugin 4030 <TestFairy>`. 4031 4032 :arg str platform: Select platform to upload to, **android** or **ios** 4033 (required) 4034 4035 Android Only: 4036 4037 :arg str proguard-file: Path to Proguard file. Path of mapping.txt from 4038 your proguard output directory. (default '') 4039 :arg str storepass: Password for the keystore (default android) 4040 :arg str alias: alias for key (default androiddebugkey) 4041 :arg str keypass: password for the key (default '') 4042 :arg str keystorepath: Path to Keystore file (required) 4043 4044 IOS Only: 4045 4046 :arg str dSYM-file: Path to .dSYM.zip file (default '') 4047 4048 All: 4049 4050 :arg str apikey: TestFairy API_KEY. Find it in your TestFairy account 4051 settings (required) 4052 :arg str appfile: Path to App file (.apk) or (.ipa). For example: 4053 $WORKSPACE/[YOUR_FILE_NAME].apk or full path to the apk file. 4054 (required) 4055 :arg str tester-groups: Tester groups to notify (default '') 4056 :arg bool notify-testers: Send email with changelogs to testers 4057 (default false) 4058 :arg bool autoupdate: Automatic update (default false) 4059 :arg str max-duration: Duration of the session (default 10m) 4060 4061 :max-duration values: 4062 * **10m** 4063 * **60m** 4064 * **300m** 4065 * **1440m** 4066 :arg bool record-on-background: Record on background (default false) 4067 :arg bool data-only-wifi: Record data only in wifi (default false) 4068 :arg bool video-enabled: Record video (default true) 4069 :arg int screenshot-interval: Time interval between screenshots 4070 (default 1) 4071 4072 :screenshot-interval values: 4073 * **1** 4074 * **2** 4075 * **5** 4076 :arg str video-quality: Video quality (default high) 4077 4078 :video-quality values: 4079 * **high** 4080 * **medium** 4081 * **low** 4082 :arg bool cpu: Enable CPU metrics (default true) 4083 :arg bool memory: Enable memory metrics (default true) 4084 :arg bool logs: Enable logs metrics (default true) 4085 :arg bool network: Enable network metrics (default false) 4086 :arg bool phone-signal: Enable phone signal metrics (default false) 4087 :arg bool wifi: Enable wifi metrics (default false) 4088 :arg bool gps: Enable gps metrics (default false) 4089 :arg bool battery: Enable battery metrics (default false) 4090 :arg bool opengl: Enable opengl metrics (default false) 4091 4092 Example: 4093 4094 .. literalinclude:: 4095 /../../tests/publishers/fixtures/test-fairy-android-minimal.yaml 4096 :language: yaml 4097 4098 .. literalinclude:: 4099 /../../tests/publishers/fixtures/test-fairy-android001.yaml 4100 :language: yaml 4101 4102 .. literalinclude:: 4103 /../../tests/publishers/fixtures/test-fairy-ios-minimal.yaml 4104 :language: yaml 4105 4106 .. literalinclude:: 4107 /../../tests/publishers/fixtures/test-fairy-ios001.yaml 4108 :language: yaml 4109 """ 4110 platform = data.get("platform") 4111 valid_platforms = ["android", "ios"] 4112 4113 if "platform" not in data: 4114 raise MissingAttributeError("platform") 4115 if platform == "android": 4116 root = XML.SubElement( 4117 xml_parent, "org.jenkinsci.plugins.testfairy.TestFairyAndroidRecorder" 4118 ) 4119 helpers.test_fairy_common(root, data) 4120 4121 mappings = [ 4122 ("proguard-file", "mappingFile", ""), 4123 ("keystorepath", "keystorePath", None), 4124 ("storepass", "storepass", "android"), 4125 ("alias", "alias", "androiddebugkey"), 4126 ("keypass", "keypass", ""), 4127 ] 4128 helpers.convert_mapping_to_xml(root, data, mappings, fail_required=True) 4129 elif platform == "ios": 4130 root = XML.SubElement( 4131 xml_parent, "org.jenkinsci.plugins.testfairy.TestFairyIosRecorder" 4132 ) 4133 helpers.test_fairy_common(root, data) 4134 4135 mappings = [("dSYM-file", "mappingFile", "")] 4136 helpers.convert_mapping_to_xml(root, data, mappings, fail_required=True) 4137 else: 4138 raise InvalidAttributeError("platform", platform, valid_platforms) 4139 4140 4141def text_finder(registry, xml_parent, data): 4142 """yaml: text-finder 4143 This plugin lets you search keywords in the files you specified and 4144 additionally check build status 4145 4146 Requires the Jenkins :jenkins-plugins:`Text-finder Plugin 4147 <text-finder>`. 4148 4149 :arg str regexp: Specify a regular expression (required) 4150 :arg str fileset: Specify the path to search (optional) 4151 :arg bool also-check-console-output: 4152 Search the console output (default false) 4153 :arg bool succeed-if-found: 4154 Force a build to succeed if a string was found (default false) 4155 :arg bool unstable-if-found: 4156 Set build unstable instead of failing the build (default false) 4157 :arg bool not-built-if-found: 4158 Set build to "Not Built" instead of failing the build (default false) 4159 4160 Example: 4161 4162 .. literalinclude:: /../../tests/publishers/fixtures/text-finder001.yaml 4163 :language: yaml 4164 """ 4165 4166 finder = XML.SubElement(xml_parent, "hudson.plugins.textfinder.TextFinderPublisher") 4167 finder.set("plugin", "text-finder") 4168 if "fileset" in data: 4169 XML.SubElement(finder, "fileSet").text = data["fileset"] 4170 mappings = [ 4171 ("regexp", "regexp", None), 4172 ("also-check-console-output", "alsoCheckConsoleOutput", False), 4173 ("succeed-if-found", "succeedIfFound", False), 4174 ("unstable-if-found", "unstableIfFound", False), 4175 ("not-built-if-found", "notBuiltIfFound", False), 4176 ] 4177 helpers.convert_mapping_to_xml(finder, data, mappings, fail_required=True) 4178 4179 4180def html_publisher(registry, xml_parent, data): 4181 """yaml: html-publisher 4182 This plugin publishes HTML reports. 4183 4184 Requires the Jenkins :jenkins-plugins:`HTML Publisher Plugin 4185 <htmlpublisher>`. 4186 4187 :arg str name: Report name (required) 4188 :arg str dir: HTML directory to archive (required) 4189 :arg str files: Specify the pages to display (required) 4190 :arg bool keep-all: keep HTML reports for each past build (default false) 4191 :arg bool allow-missing: Allow missing HTML reports (default false) 4192 :arg bool link-to-last-build: If this and 'keep-all' both are true, it 4193 publishes the link on project level even if build failed. 4194 (default false) 4195 4196 4197 Example: 4198 4199 .. literalinclude:: /../../tests/publishers/fixtures/html-publisher001.yaml 4200 :language: yaml 4201 """ 4202 4203 reporter = XML.SubElement(xml_parent, "htmlpublisher.HtmlPublisher") 4204 targets = XML.SubElement(reporter, "reportTargets") 4205 ptarget = XML.SubElement(targets, "htmlpublisher.HtmlPublisherTarget") 4206 4207 mapping = [ 4208 ("name", "reportName", None), 4209 ("dir", "reportDir", None), 4210 ("files", "reportFiles", None), 4211 ("link-to-last-build", "alwaysLinkToLastBuild", False), 4212 ("keep-all", "keepAll", False), 4213 ("allow-missing", "allowMissing", False), 4214 ] 4215 helpers.convert_mapping_to_xml(ptarget, data, mapping, fail_required=True) 4216 XML.SubElement(ptarget, "wrapperName").text = "htmlpublisher-wrapper.html" 4217 4218 4219def rich_text_publisher(registry, xml_parent, data): 4220 """yaml: rich-text-publisher 4221 This plugin puts custom rich text message to the Build pages and Job main 4222 page. 4223 4224 Requires the Jenkins :jenkins-plugins:`Rich Text Publisher Plugin 4225 <rich-text-publisher-plugin>`. 4226 4227 :arg str stable-text: The stable text (required) 4228 :arg str unstable-text: The unstable text if different from stable 4229 (default '') 4230 :arg bool unstable-as-stable: The same text block is used for stable and 4231 unstable builds (default true) 4232 :arg str failed-text: The failed text if different from stable (default '') 4233 :arg bool failed-as-stable: The same text block is used for stable and 4234 failed builds (default true) 4235 :arg str parser-name: HTML, Confluence or WikiText (default 'WikiText') 4236 4237 4238 Minimal Example: 4239 4240 .. literalinclude:: /../../tests/publishers/fixtures/richtext-minimal.yaml 4241 :language: yaml 4242 4243 Full Example: 4244 4245 .. literalinclude:: 4246 /../../tests/publishers/fixtures/richtext-full.yaml 4247 :language: yaml 4248 """ 4249 4250 parsers = ["HTML", "Confluence", "WikiText"] 4251 reporter = XML.SubElement( 4252 xml_parent, "org.korosoft.jenkins.plugin.rtp.RichTextPublisher" 4253 ) 4254 reporter.set("plugin", "rich-text-publisher-plugin") 4255 4256 mappings = [ 4257 ("stable-text", "stableText", None), 4258 ("unstable-text", "unstableText", ""), 4259 ("failed-text", "failedText", ""), 4260 ("unstable-as-stable", "unstableAsStable", True), 4261 ("failed-as-stable", "failedAsStable", True), 4262 ("parser-name", "parserName", "WikiText", parsers), 4263 ] 4264 helpers.convert_mapping_to_xml(reporter, data, mappings, fail_required=True) 4265 4266 4267def tap(registry, xml_parent, data): 4268 """yaml: tap 4269 Adds support to TAP test result files 4270 4271 Requires the Jenkins :jenkins-plugins:`TAP Plugin <tap>`. 4272 4273 :arg str results: TAP test result files (required) 4274 :arg bool fail-if-no-results: Fail if no result (default false) 4275 :arg bool failed-tests-mark-build-as-failure: 4276 Mark build as failure if test fails (default false) 4277 :arg bool output-tap-to-console: Output tap to console (default true) 4278 :arg bool enable-subtests: Enable subtests (default true) 4279 :arg bool discard-old-reports: Discard old reports (default false) 4280 :arg bool todo-is-failure: Handle TODO's as failures (default true) 4281 :arg bool include-comment-diagnostics: Include comment diagnostics (#) in 4282 the results table (>=1.12) (default false) 4283 :arg bool validate-tests: Validate number of tests (>=1.13) (default false) 4284 :arg bool plan-required: TAP plan required? (>=1.17) (default true) 4285 :arg bool verbose: Print a message for each TAP stream file (>=1.17) 4286 (default true) 4287 :arg bool show-only-failures: show only test failures (>=1.17) 4288 (default false) 4289 4290 Full Example: 4291 4292 .. literalinclude:: /../../tests/publishers/fixtures/tap-full.yaml 4293 :language: yaml 4294 4295 Minimal Example: 4296 4297 .. literalinclude:: /../../tests/publishers/fixtures/tap-minimal.yaml 4298 :language: yaml 4299 """ 4300 4301 tap = XML.SubElement(xml_parent, "org.tap4j.plugin.TapPublisher") 4302 tap.set("plugin", "tap") 4303 4304 mappings = [ 4305 ("results", "testResults", None), 4306 ("fail-if-no-results", "failIfNoResults", False), 4307 ("failed-tests-mark-build-as-failure", "failedTestsMarkBuildAsFailure", False), 4308 ("output-tap-to-console", "outputTapToConsole", True), 4309 ("enable-subtests", "enableSubtests", True), 4310 ("discard-old-reports", "discardOldReports", False), 4311 ("todo-is-failure", "todoIsFailure", True), 4312 ("include-comment-diagnostics", "includeCommentDiagnostics", False), 4313 ("validate-tests", "validateNumberOfTests", False), 4314 ("plan-required", "planRequired", True), 4315 ("verbose", "verbose", True), 4316 ("show-only-failures", "showOnlyFailures", False), 4317 ] 4318 helpers.convert_mapping_to_xml(tap, data, mappings, fail_required=True) 4319 4320 4321def post_tasks(registry, xml_parent, data): 4322 """yaml: post-tasks 4323 Adds support to post build task plugin 4324 4325 Requires the Jenkins :jenkins-plugins:`Post Build Task plugin 4326 <postbuild-task>`. 4327 4328 :arg dict task: Post build task definition 4329 :arg list task[matches]: list of matches when to run the task 4330 :arg dict task[matches][*]: match definition 4331 :arg str task[matches][*][log-text]: text to match against the log 4332 :arg str task[matches][*][operator]: operator to apply with the next match 4333 4334 :task[matches][*][operator] values (default 'AND'): 4335 * **AND** 4336 * **OR** 4337 4338 :arg bool task[escalate-status]: Escalate the task status to the job 4339 (default 'false') 4340 :arg bool task[run-if-job-successful]: Run only if the job was successful 4341 (default 'false') 4342 :arg str task[script]: Shell script to run (default '') 4343 4344 Example: 4345 4346 .. literalinclude:: /../../tests/publishers/fixtures/post-tasks001.yaml 4347 :language: yaml 4348 """ 4349 4350 pb_xml = XML.SubElement(xml_parent, "hudson.plugins.postbuildtask.PostbuildTask") 4351 tasks_xml = XML.SubElement(pb_xml, "tasks") 4352 for task in data: 4353 task_xml = XML.SubElement( 4354 tasks_xml, "hudson.plugins.postbuildtask.TaskProperties" 4355 ) 4356 matches_xml = XML.SubElement(task_xml, "logTexts") 4357 for match in task.get("matches", []): 4358 lt_xml = XML.SubElement( 4359 matches_xml, "hudson.plugins.postbuildtask.LogProperties" 4360 ) 4361 XML.SubElement(lt_xml, "logText").text = str( 4362 match.get("log-text", False) or "" 4363 ) 4364 XML.SubElement(lt_xml, "operator").text = str( 4365 match.get("operator", "AND") 4366 ).upper() 4367 mapping = [ 4368 ("escalate-status", "EscalateStatus", False), 4369 ("run-if-job-successful", "RunIfJobSuccessful", False), 4370 ("script", "script", ""), 4371 ] 4372 helpers.convert_mapping_to_xml(task_xml, task, mapping, fail_required=True) 4373 4374 4375def postbuildscript(registry, xml_parent, data): 4376 """yaml: postbuildscript 4377 Executes additional builders, script or Groovy after the build is 4378 complete. 4379 4380 Requires the Jenkins :jenkins-plugins:`Post Build Script plugin 4381 <postbuildscript>`. 4382 4383 :arg list generic-script: Series of Batch/Shell scripts to to run 4384 4385 :generic-script: * **file-path** (`str`) - Path to Batch/Shell scripts 4386 * **role** (`str`) - Execute scripts on. One of 4387 MASTER / SLAVE / BOTH. (default 'BOTH') 4388 * **build-on** (`list`) - Build statuses which trigger 4389 the scripts. Valid options: 4390 SUCCESS / UNSTABLE / FAILURE / NOT_BUILT / ABORTED 4391 (default 'SUCCESS') 4392 * ** execute-on (`str`) - For matrix projects, scripts 4393 can be run after each axis is built (`axes`), after 4394 all axis of the matrix are built (`matrix`) or after 4395 each axis AND the matrix are built (`both`). (default `both`) 4396 4397 :arg list groovy-script: Paths to Groovy scripts 4398 4399 :groovy-script: * **file-path** (`str`) - Path to Groovy scripts 4400 * **role** (`str`) - Execute scripts on. One of 4401 MASTER / SLAVE / BOTH. (default 'BOTH') 4402 * **build-on** (`list`) - Build statuses which trigger 4403 the scripts. Valid options: 4404 SUCCESS / UNSTABLE / FAILURE / NOT_BUILT / ABORTED 4405 (default 'SUCCESS') 4406 * ** execute-on (`str`) - For matrix projects, scripts 4407 can be run after each axis is built (`axes`), after 4408 all axis of the matrix are built (`matrix`) or after 4409 each axis AND the matrix are built (`both`). (default `both`) 4410 4411 :arg list groovy: Inline Groovy 4412 4413 :groovy: * **content** (`str`) - Inline Groovy script. 4414 * **role** (`str`) - Execute scripts on. One of 4415 MASTER / SLAVE / BOTH. (default 'BOTH') 4416 * **build-on** (`list`) - Build statuses which trigger 4417 the scripts. Valid options: 4418 SUCCESS / UNSTABLE / FAILURE / NOT_BUILT / ABORTED 4419 (default 'SUCCESS') 4420 * ** execute-on (`str`) - For matrix projects, scripts 4421 can be run after each axis is built (`axes`), after 4422 all axis of the matrix are built (`matrix`) or after 4423 each axis AND the matrix are built (`both`). (default `both`) 4424 4425 :arg list builders: Execute any number of supported Jenkins builders. 4426 4427 :builders: * **build-steps** (`str`) - Any supported builders, 4428 see :doc:`builders`. 4429 * **role** (`str`) - Execute scripts on. One of 4430 MASTER / SLAVE / BOTH. (default 'BOTH') 4431 * **build-on** (`list`) - Build statuses which trigger 4432 the scripts. Valid options: 4433 SUCCESS / UNSTABLE / FAILURE / NOT_BUILT / ABORTED 4434 (default 'SUCCESS') 4435 * ** execute-on (`str`) - For matrix projects, scripts 4436 can be run after each axis is built (`axes`), after 4437 all axis of the matrix are built (`matrix`) or after 4438 each axis AND the matrix are built (`both`). (default `both`) 4439 4440 :arg bool mark-unstable-if-failed: Build will be marked unstable 4441 if job will be successfully completed but publishing script will return 4442 non zero exit code (default false) 4443 4444 Deprecated Options for versions < 2.0 of plugin: 4445 4446 :arg bool onsuccess: Deprecated, replaced with script-only-if-succeeded 4447 :arg bool script-only-if-succeeded: Scripts and builders are run only if 4448 the build succeeded (default true) 4449 :arg bool onfailure: Deprecated, replaced with script-only-if-failed 4450 :arg bool script-only-if-failed: Scripts and builders are run only if the 4451 build failed (default false) 4452 :arg str execute-on: For matrix projects, scripts can be run after each 4453 axis is built (`axes`), after all axis of the matrix are built 4454 (`matrix`) or after each axis AND the matrix are built (`both`). 4455 4456 The `script-only-if-succeeded` and `bool script-only-if-failed` options are 4457 confusing. If you want the post build to always run regardless of the build 4458 status, you should set them both to `false`. 4459 4460 Minimal Example: 4461 4462 .. literalinclude:: 4463 /../../tests/publishers/fixtures/postbuildscript-minimal.yaml 4464 :language: yaml 4465 4466 Full Example: 4467 4468 .. literalinclude:: 4469 /../../tests/publishers/fixtures/postbuildscript-full.yaml 4470 :language: yaml 4471 4472 Example(s) versions < 2.0: 4473 4474 .. literalinclude:: 4475 /../../tests/publishers/fixtures/postbuildscript001.yaml 4476 :language: yaml 4477 4478 You can also execute :doc:`builders </builders>`: 4479 4480 .. literalinclude:: 4481 /../../tests/publishers/fixtures/postbuildscript002.yaml 4482 :language: yaml 4483 4484 Run once after the whole matrix (all axes) is built: 4485 4486 .. literalinclude:: 4487 /../../tests/publishers/fixtures/postbuildscript003.yaml 4488 :language: yaml 4489 """ 4490 4491 pbs_xml = XML.SubElement( 4492 xml_parent, "org.jenkinsci.plugins.postbuildscript.PostBuildScript" 4493 ) 4494 4495 info = registry.get_plugin_info("postbuildscript") 4496 # Note: Assume latest version of plugin is preferred config format 4497 version = pkg_resources.parse_version(info.get("version", str(sys.maxsize))) 4498 if version >= pkg_resources.parse_version("2.0"): 4499 pbs_xml = XML.SubElement(pbs_xml, "config") 4500 4501 mapping = [("mark-unstable-if-failed", "markBuildUnstable", False)] 4502 helpers.convert_mapping_to_xml(pbs_xml, data, mapping, fail_required=True) 4503 4504 if version >= pkg_resources.parse_version("2.0"): 4505 4506 def add_execute_on(bs_data, result_xml): 4507 valid_values = ("matrix", "axes", "both") 4508 execute_on = bs_data.get("execute-on") 4509 if not execute_on: 4510 return 4511 if execute_on not in valid_values: 4512 raise JenkinsJobsException( 4513 "execute-on must be one of %s, got %s" % valid_values, execute_on 4514 ) 4515 execute_on_xml = XML.SubElement(result_xml, "executeOn") 4516 execute_on_xml.text = execute_on.upper() 4517 4518 ################ 4519 # Script Files # 4520 ################ 4521 4522 script_mapping = [("role", "role", "BOTH"), ("file-path", "filePath", False)] 4523 sf_path = "org.jenkinsci.plugins.postbuildscript.model.ScriptFile" 4524 sf_xml = XML.SubElement(pbs_xml, "scriptFiles") 4525 4526 for gs_data in data.get("generic-script", []): 4527 x = XML.SubElement(sf_xml, sf_path) 4528 results_xml = XML.SubElement(x, "results") 4529 4530 for result in gs_data.get("build-on", ["SUCCESS"]): 4531 XML.SubElement(results_xml, "string").text = result 4532 4533 add_execute_on(gs_data, x) 4534 4535 helpers.convert_mapping_to_xml( 4536 x, gs_data, script_mapping, fail_required=True 4537 ) 4538 XML.SubElement(x, "scriptType").text = "GENERIC" 4539 4540 for gs_data in data.get("groovy-script", []): 4541 x = XML.SubElement(sf_xml, sf_path) 4542 results_xml = XML.SubElement(x, "results") 4543 4544 for result in gs_data.get("build-on", ["SUCCESS"]): 4545 XML.SubElement(results_xml, "string").text = result 4546 4547 add_execute_on(gs_data, x) 4548 4549 helpers.convert_mapping_to_xml( 4550 x, gs_data, script_mapping, fail_required=True 4551 ) 4552 XML.SubElement(x, "scriptType").text = "GROOVY" 4553 4554 ################# 4555 # Inline Groovy # 4556 ################# 4557 4558 groovy_mapping = [("role", "role", "BOTH"), ("content", "content", False)] 4559 gs_path = "org.jenkinsci.plugins.postbuildscript.model.Script" 4560 gs_xml = XML.SubElement(pbs_xml, "groovyScripts") 4561 for gs_data in data.get("groovy", []): 4562 x = XML.SubElement(gs_xml, gs_path) 4563 results_xml = XML.SubElement(x, "results") 4564 4565 for result in gs_data.get("build-on", ["SUCCESS"]): 4566 XML.SubElement(results_xml, "string").text = result 4567 4568 add_execute_on(gs_data, x) 4569 4570 helpers.convert_mapping_to_xml( 4571 x, gs_data, groovy_mapping, fail_required=True 4572 ) 4573 4574 ############ 4575 # Builders # 4576 ############ 4577 4578 builder_mapping = [("role", "role", "BOTH")] 4579 bs_path = "org.jenkinsci.plugins.postbuildscript.model.PostBuildStep" 4580 bs_xml = XML.SubElement(pbs_xml, "buildSteps") 4581 for bs_data in data.get("builders", []): 4582 x = XML.SubElement(bs_xml, bs_path) 4583 results_xml = XML.SubElement(x, "results") 4584 4585 for result in bs_data.get("build-on", ["SUCCESS"]): 4586 XML.SubElement(results_xml, "string").text = result 4587 4588 add_execute_on(bs_data, x) 4589 4590 helpers.convert_mapping_to_xml( 4591 x, bs_data, builder_mapping, fail_required=True 4592 ) 4593 4594 build_steps_xml = XML.SubElement(x, "buildSteps") 4595 for builder in bs_data.get("build-steps"): 4596 registry.dispatch("builder", build_steps_xml, builder) 4597 4598 else: # Options below are all deprecated in version < 2.0 of plugin 4599 4600 # Shell/Groovy in a file 4601 script_types = { 4602 "generic-script": "GenericScript", 4603 "groovy-script": "GroovyScriptFile", 4604 } 4605 4606 # Assuming yaml preserves order of input data make sure 4607 # corresponding XML steps are generated in the same order 4608 build_scripts = [ 4609 (k, v) 4610 for k, v in data.items() 4611 if k in script_types or k in ["groovy", "builders"] 4612 ] 4613 4614 for step, script_data in build_scripts: 4615 if step in script_types: 4616 scripts_xml = XML.SubElement( 4617 pbs_xml, step[: -len("-script")] + "ScriptFileList" 4618 ) 4619 for shell_script in script_data: 4620 script_xml = XML.SubElement( 4621 scripts_xml, 4622 "org.jenkinsci.plugins.postbuildscript." + script_types[step], 4623 ) 4624 file_path_xml = XML.SubElement(script_xml, "filePath") 4625 file_path_xml.text = shell_script 4626 4627 # Inlined Groovy 4628 if step == "groovy": 4629 groovy_inline_xml = XML.SubElement(pbs_xml, "groovyScriptContentList") 4630 for groovy in script_data: 4631 groovy_xml = XML.SubElement( 4632 groovy_inline_xml, 4633 "org.jenkinsci.plugins.postbuildscript." "GroovyScriptContent", 4634 ) 4635 groovy_content = XML.SubElement(groovy_xml, "content") 4636 groovy_content.text = groovy 4637 4638 # Inject builders 4639 if step == "builders": 4640 build_steps_xml = XML.SubElement(pbs_xml, "buildSteps") 4641 for builder in script_data: 4642 registry.dispatch("builder", build_steps_xml, builder) 4643 4644 # When to run the build? Note the plugin let one specify both options 4645 # although they are antinomic 4646 # onsuccess and onfailure parameters are deprecated, this is to keep 4647 # backwards compatability 4648 success_xml = XML.SubElement(pbs_xml, "scriptOnlyIfSuccess") 4649 if "script-only-if-succeeded" in data: 4650 success_xml.text = str(data.get("script-only-if-succeeded", True)).lower() 4651 else: 4652 success_xml.text = str(data.get("onsuccess", True)).lower() 4653 4654 failure_xml = XML.SubElement(pbs_xml, "scriptOnlyIfFailure") 4655 if "script-only-if-failed" in data: 4656 failure_xml.text = str(data.get("script-only-if-failed", False)).lower() 4657 else: 4658 failure_xml.text = str(data.get("onfailure", False)).lower() 4659 4660 # TODO: we may want to avoid setting "execute-on" on non-matrix jobs, 4661 # either by skipping this part or by raising an error to let the user 4662 # know an attempt was made to set execute-on on a non-matrix job. 4663 # There are currently no easy ways to check for this though. 4664 if "execute-on" in data: 4665 valid_values = ("matrix", "axes", "both") 4666 execute_on = data["execute-on"].lower() 4667 if execute_on not in valid_values: 4668 raise JenkinsJobsException( 4669 "execute-on must be one of %s, got %s" % valid_values, execute_on 4670 ) 4671 execute_on_xml = XML.SubElement(pbs_xml, "executeOn") 4672 execute_on_xml.text = execute_on.upper() 4673 4674 4675def xml_summary(registry, xml_parent, data): 4676 """yaml: xml-summary 4677 Adds support for the Summary Display Plugin 4678 4679 Requires the Jenkins :jenkins-plugins:`Summary Display Plugin 4680 <summary_report>`. 4681 4682 :arg str files: Files to parse (required) 4683 :arg bool shown-on-project-page: Display summary on project page 4684 (default false) 4685 4686 Minimal Example: 4687 4688 .. literalinclude:: 4689 /../../tests/publishers/fixtures/xml-summary-minimal.yaml 4690 :language: yaml 4691 4692 Full Example: 4693 4694 .. literalinclude:: /../../tests/publishers/fixtures/xml-summary-full.yaml 4695 :language: yaml 4696 """ 4697 4698 summary = XML.SubElement( 4699 xml_parent, "hudson.plugins.summary__report.ACIPluginPublisher" 4700 ) 4701 summary.set("plugin", "summary_report") 4702 4703 mapping = [ 4704 ("files", "name", None), 4705 ("shown-on-project-page", "shownOnProjectPage", False), 4706 ] 4707 helpers.convert_mapping_to_xml(summary, data, mapping, fail_required=True) 4708 4709 4710def robot(registry, xml_parent, data): 4711 """yaml: robot 4712 Adds support for the Robot Framework Plugin 4713 4714 Requires the Jenkins :jenkins-plugins:`Robot Framework Plugin <robot>`. 4715 4716 :arg str output-path: Path to directory containing robot xml and html files 4717 relative to build workspace. (required) 4718 :arg str log-file-link: Name of log or report file to be linked on jobs 4719 front page (default '') 4720 :arg str report-html: Name of the html file containing robot test report 4721 (default 'report.html') 4722 :arg str log-html: Name of the html file containing detailed robot test log 4723 (default 'log.html') 4724 :arg str output-xml: Name of the xml file containing robot output 4725 (default 'output.xml') 4726 :arg str pass-threshold: Minimum percentage of passed tests to consider 4727 the build successful (default 0.0) 4728 :arg str unstable-threshold: Minimum percentage of passed test to 4729 consider the build as not failed (default 0.0) 4730 :arg bool only-critical: Take only critical tests into account when 4731 checking the thresholds (default true) 4732 :arg list other-files: list other files to archive (default '') 4733 :arg bool archive-output-xml: Archive output xml file to server 4734 (default true) 4735 :arg bool enable-cache: Enable cache for test results (default true) 4736 4737 Minimal Example: 4738 4739 .. literalinclude:: /../../tests/publishers/fixtures/robot-minimal.yaml 4740 :language: yaml 4741 4742 Full Example: 4743 4744 .. literalinclude:: /../../tests/publishers/fixtures/robot-full.yaml 4745 :language: yaml 4746 """ 4747 parent = XML.SubElement(xml_parent, "hudson.plugins.robot.RobotPublisher") 4748 parent.set("plugin", "robot") 4749 mappings = [ 4750 ("output-path", "outputPath", None), 4751 ("log-file-link", "logFileLink", ""), 4752 ("report-html", "reportFileName", "report.html"), 4753 ("log-html", "logFileName", "log.html"), 4754 ("output-xml", "outputFileName", "output.xml"), 4755 ("pass-threshold", "passThreshold", "0.0"), 4756 ("unstable-threshold", "unstableThreshold", "0.0"), 4757 ("only-critical", "onlyCritical", True), 4758 ("enable-cache", "enableCache", True), 4759 ] 4760 helpers.convert_mapping_to_xml(parent, data, mappings, fail_required=True) 4761 4762 other_files = XML.SubElement(parent, "otherFiles") 4763 for other_file in data.get("other-files", []): 4764 XML.SubElement(other_files, "string").text = str(other_file) 4765 XML.SubElement(parent, "disableArchiveOutput").text = str( 4766 not data.get("archive-output-xml", True) 4767 ).lower() 4768 4769 4770def warnings(registry, xml_parent, data): 4771 """yaml: warnings 4772 Generate trend report for compiler warnings in the console log or 4773 in log files. 4774 4775 Requires the Jenkins Warnings Plugin 4776 (https://github.com/jenkinsci/warnings-plugin). 4777 4778 :arg list console-log-parsers: The parser to use to scan the console 4779 log (default '') 4780 :arg dict workspace-file-scanners: 4781 4782 :workspace-file-scanners: 4783 * **file-pattern** (`str`) -- Fileset 'includes' setting that 4784 specifies the files to scan for warnings (required) 4785 * **scanner** (`str`) -- The parser to use to scan the files 4786 provided in workspace-file-pattern (default '') 4787 :arg str files-to-include: Comma separated list of regular 4788 expressions that specifies the files to include in the report 4789 (based on their absolute filename). By default all files are 4790 included 4791 :arg str files-to-ignore: Comma separated list of regular expressions 4792 that specifies the files to exclude from the report (based on their 4793 absolute filename). (default '') 4794 :arg str messages-to-ignore: Newline separated list of regular 4795 expressions that specifies the warning messages to exclude form the 4796 report (based on the warning messages). By default all warning 4797 messages are included 4798 :arg str categories-to-ignore: Newline separated list of regular 4799 expressions that specifies the warning messages to exclude form the 4800 report (based on the warning categories). By default all warning 4801 categories are included 4802 :arg bool run-always: By default, this plug-in runs only for stable or 4803 unstable builds, but not for failed builds. Set to true if the 4804 plug-in should run even for failed builds. (default false) 4805 :arg bool detect-modules: Determines if Ant or Maven modules should be 4806 detected for all files that contain warnings. Activating this 4807 option may increase your build time since the detector scans 4808 the whole workspace for 'build.xml' or 'pom.xml' files in order 4809 to assign the correct module names. (default false) 4810 :arg bool resolve-relative-paths: Determines if relative paths in 4811 warnings should be resolved using a time expensive operation that 4812 scans the whole workspace for matching files. Deactivate this 4813 option if you encounter performance problems. (default false) 4814 :arg int health-threshold-high: The upper threshold for the build 4815 health. If left empty then no health report is created. If 4816 the actual number of warnings is between the provided 4817 thresholds then the build health is interpolated (default '') 4818 :arg int health-threshold-low: The lower threshold for the build 4819 health. See health-threshold-high. (default '') 4820 :arg dict health-priorities: Determines which warning priorities 4821 should be considered when evaluating the build health (default 4822 all-priorities) 4823 4824 :health-priorities values: 4825 * **priority-high** -- Only priority high 4826 * **high-and-normal** -- Priorities high and normal 4827 * **all-priorities** -- All priorities 4828 :arg dict total-thresholds: If the number of total warnings is greater 4829 than one of these thresholds then a build is considered as unstable 4830 or failed, respectively. (default '') 4831 4832 :total-thresholds: 4833 * **unstable** (`dict`) 4834 :unstable: * **total-all** (`int`) 4835 * **total-high** (`int`) 4836 * **total-normal** (`int`) 4837 * **total-low** (`int`) 4838 * **failed** (`dict`) 4839 :failed: * **total-all** (`int`) 4840 * **total-high** (`int`) 4841 * **total-normal** (`int`) 4842 * **total-low** (`int`) 4843 :arg dict new-thresholds: If the specified number of new warnings exceeds 4844 one of these thresholds then a build is considered as unstable or 4845 failed, respectively. (default '') 4846 4847 :new-thresholds: 4848 * **unstable** (`dict`) 4849 :unstable: * **new-all** (`int`) 4850 * **new-high** (`int`) 4851 * **new-normal** (`int`) 4852 * **new-low** (`int`) 4853 * **failed** (`dict`) 4854 :failed: * **new-all** (`int`) 4855 * **new-high** (`int`) 4856 * **new-normal** (`int`) 4857 * **new-high** (`int`) 4858 :arg bool use-delta-for-new-warnings: If set then the number of new 4859 warnings is calculated by subtracting the total number of warnings 4860 of the current build from the reference build. This may lead to wrong 4861 results if you have both fixed and new warnings in a build. If not set, 4862 then the number of new warnings is calculated by an asymmetric set 4863 difference of the warnings in the current and reference build. This 4864 will find all new warnings even if the number of total warnings is 4865 decreasing. However, sometimes false positives will be reported due 4866 to minor changes in a warning (refactoring of variable of method 4867 names, etc.) (default false) 4868 :arg bool use-previous-build-as-reference: If set the number of new 4869 warnings will always be computed based on the previous build, even if 4870 that build is unstable (due to a violated warning threshold). 4871 Otherwise the last build that did not violate any given threshold will 4872 be used as 4873 reference. It is recommended to uncheck this option if the plug-in 4874 should ensure that all new warnings will be finally fixed in subsequent 4875 builds. (default false) 4876 :arg bool only-use-stable-builds-as-reference: The number of new warnings 4877 will be calculated based on the last stable build, allowing reverts 4878 of unstable builds where the number of warnings was decreased. 4879 (default false) 4880 :arg str default-encoding: Default encoding when parsing or showing files 4881 Leave empty to use default encoding of platform (default '') 4882 4883 Minimal Example: 4884 4885 .. literalinclude:: /../../tests/publishers/fixtures/warnings-minimal.yaml 4886 :language: yaml 4887 4888 Full Example: 4889 4890 .. literalinclude:: /../../tests/publishers/fixtures/warnings-full.yaml 4891 :language: yaml 4892 """ 4893 4894 warnings = XML.SubElement( 4895 xml_parent, "hudson.plugins.warnings." "WarningsPublisher" 4896 ) 4897 warnings.set("plugin", "warnings") 4898 console = XML.SubElement(warnings, "consoleParsers") 4899 for parser in data.get("console-log-parsers", []): 4900 console_parser = XML.SubElement( 4901 console, "hudson.plugins.warnings." "ConsoleParser" 4902 ) 4903 XML.SubElement(console_parser, "parserName").text = parser 4904 workspace = XML.SubElement(warnings, "parserConfigurations") 4905 for wfs in data.get("workspace-file-scanners", []): 4906 workspace_pattern = XML.SubElement( 4907 workspace, "hudson.plugins.warnings." "ParserConfiguration" 4908 ) 4909 workspace_pattern_mappings = [ 4910 ("file-pattern", "pattern", None), 4911 ("scanner", "parserName", ""), 4912 ] 4913 helpers.convert_mapping_to_xml( 4914 workspace_pattern, wfs, workspace_pattern_mappings, fail_required=True 4915 ) 4916 prioritiesDict = { 4917 "priority-high": "high", 4918 "high-and-normal": "normal", 4919 "all-priorities": "low", 4920 } 4921 warnings_mappings = [ 4922 ("files-to-include", "includePattern", ""), 4923 ("files-to-ignore", "excludePattern", ""), 4924 ("messages-to-ignore", "messagesPattern", ""), 4925 ("categories-to-ignore", "categoriesPattern", ""), 4926 ("plugin-name", "pluginName", "[WARNINGS]"), 4927 ("run-always", "canRunOnFailed", False), 4928 ("detect-modules", "shouldDetectModules", False), 4929 ("health-threshold-high", "healthy", ""), 4930 ("health-threshold-low", "unHealthy", ""), 4931 ("health-priorities", "thresholdLimit", "all-priorities", prioritiesDict), 4932 ("default-encoding", "defaultEncoding", ""), 4933 ] 4934 helpers.convert_mapping_to_xml( 4935 warnings, data, warnings_mappings, fail_required=True 4936 ) 4937 # Note the logic reversal (included here to match the GUI) 4938 XML.SubElement(warnings, "doNotResolveRelativePaths").text = str( 4939 not data.get("resolve-relative-paths", False) 4940 ).lower() 4941 td = XML.SubElement(warnings, "thresholds") 4942 for base in ["total", "new"]: 4943 thresholds = data.get("%s-thresholds" % base, {}) 4944 for status in ["unstable", "failed"]: 4945 bystatus = thresholds.get(status, {}) 4946 for level in ["all", "high", "normal", "low"]: 4947 val = str(bystatus.get("%s-%s" % (base, level), "")) 4948 XML.SubElement( 4949 td, "%s%s%s" % (status, base.capitalize(), level.capitalize()) 4950 ).text = val 4951 if data.get("new-thresholds"): 4952 XML.SubElement(warnings, "dontComputeNew").text = "false" 4953 delta = data.get("use-delta-for-new-warnings", False) 4954 XML.SubElement(warnings, "useDeltaValues").text = str(delta).lower() 4955 use_previous_build = data.get("use-previous-build-as-reference", False) 4956 XML.SubElement(warnings, "usePreviousBuildAsReference").text = str( 4957 use_previous_build 4958 ).lower() 4959 use_stable_builds = data.get("only-use-stable-builds-as-reference", False) 4960 XML.SubElement(warnings, "useStableBuildAsReference").text = str( 4961 use_stable_builds 4962 ).lower() 4963 else: 4964 XML.SubElement(warnings, "dontComputeNew").text = "true" 4965 XML.SubElement(warnings, "useDeltaValues").text = "false" 4966 XML.SubElement(warnings, "usePreviousBuildAsReference").text = "false" 4967 XML.SubElement(warnings, "useStableBuildAsReference").text = "false" 4968 4969 4970def sloccount(registry, xml_parent, data): 4971 r"""yaml: sloccount 4972 Generates the trend report for SLOCCount 4973 4974 Requires the Jenkins :jenkins-plugins:`SLOCCount Plugin <sloccount>`. 4975 4976 :arg str report-files: Setting that specifies the generated raw 4977 SLOCCount report files. Be sure not to include any non-report files 4978 into this pattern. The report files must have been generated by 4979 sloccount using the "--wide --details" options. 4980 (default '\*\*/sloccount.sc') 4981 :arg str charset: The character encoding to be used to read the SLOCCount 4982 result files. (default 'UTF-8') 4983 :arg int builds-in-graph: Maximal number of last successful builds, that 4984 are displayed in the trend graphs. (default 0) 4985 :arg bool comment-is-code: This option is considered only in the cloc 4986 report parser and is ignored in the SLOCCount one. (default false) 4987 :arg bool ignore-build-failure: Try to process the report files even if 4988 the build is not successful. (default false) 4989 4990 Minimal Example: 4991 4992 .. literalinclude:: /../../tests/publishers/fixtures/sloccount-minimal.yaml 4993 :language: yaml 4994 4995 Full Example: 4996 4997 .. literalinclude:: 4998 /../../tests/publishers/fixtures/sloccount-full.yaml 4999 :language: yaml 5000 """ 5001 top = XML.SubElement(xml_parent, "hudson.plugins.sloccount.SloccountPublisher") 5002 top.set("plugin", "sloccount") 5003 mappings = [ 5004 ("report-files", "pattern", "**/sloccount.sc"), 5005 ("charset", "encoding", "UTF-8"), 5006 ("builds-in-graph", "numBuildsInGraph", 0), 5007 ("comment-is-code", "commentIsCode", False), 5008 ("ignore-build-failure", "ignoreBuildFailure", False), 5009 ] 5010 helpers.convert_mapping_to_xml(top, data, mappings, fail_required=True) 5011 5012 5013def ircbot(registry, xml_parent, data): 5014 """yaml: ircbot 5015 ircbot enables Jenkins to send build notifications via IRC and lets you 5016 interact with Jenkins via an IRC bot. 5017 5018 Requires the Jenkins :jenkins-plugins:`IRC Plugin <ircbot>`. 5019 5020 :arg str strategy: When to send notifications 5021 5022 :strategy values: 5023 * **all** always (default) 5024 * **any-failure** on any failure 5025 * **failure-and-fixed** on failure and fixes 5026 * **new-failure-and-fixed** on new failure and fixes 5027 * **statechange-only** only on state change 5028 :arg bool notify-start: Whether to send notifications to channels when a 5029 build starts (default false) 5030 :arg bool notify-committers: Whether to send notifications to the users 5031 that are suspected of having broken this build (default false) 5032 :arg bool notify-culprits: Also send notifications to 'culprits' from 5033 previous unstable/failed builds (default false) 5034 :arg bool notify-upstream: Whether to send notifications to upstream 5035 committers if no committers were found for a broken build 5036 (default false) 5037 :arg bool notify-fixers: Whether to send notifications to the users that 5038 have fixed a broken build (default false) 5039 :arg str message-type: Channel Notification Message. 5040 5041 :message-type values: 5042 * **summary-scm** for summary and SCM changes (default) 5043 * **summary** for summary only 5044 * **summary-params** for summary and build parameters 5045 * **summary-scm-fail** for summary, SCM changes, failures) 5046 :arg list channels: list channels definitions 5047 If empty, it takes channel from Jenkins configuration. 5048 (default empty) 5049 WARNING: the IRC plugin requires the channel to be configured in the 5050 system wide configuration or the jobs will fail to emit notifications 5051 to the channel 5052 5053 :Channel: * **name** (`str`) Channel name 5054 * **password** (`str`) Channel password (optional) 5055 * **notify-only** (`bool`) Set to true if you want to 5056 disallow bot commands (default false) 5057 :arg str matrix-notifier: notify for matrix projects 5058 instant-messaging-plugin injects an additional 5059 field in the configuration form whenever the 5060 project is a multi-configuration project 5061 5062 :matrix-notifier values: 5063 * **all** 5064 * **only-configurations** (default) 5065 * **only-parent** 5066 5067 Minimal Example: 5068 5069 .. literalinclude:: /../../tests/publishers/fixtures/ircbot-minimal.yaml 5070 :language: yaml 5071 5072 Full Example: 5073 5074 .. literalinclude:: /../../tests/publishers/fixtures/ircbot-full.yaml 5075 :language: yaml 5076 """ 5077 top = XML.SubElement(xml_parent, "hudson.plugins.ircbot.IrcPublisher") 5078 top.set("plugin", "ircbot") 5079 message_dict = { 5080 "summary-scm": "DefaultBuildToChatNotifier", 5081 "summary": "SummaryOnlyBuildToChatNotifier", 5082 "summary-params": "BuildParametersBuildToChatNotifier", 5083 "summary-scm-fail": "PrintFailingTestsBuildToChatNotifier", 5084 } 5085 message = data.get("message-type", "summary-scm") 5086 if message not in message_dict: 5087 raise JenkinsJobsException( 5088 "message-type entered is not valid, must " 5089 "be one of: %s" % ", ".join(message_dict.keys()) 5090 ) 5091 message = "hudson.plugins.im.build_notify." + message_dict.get(message) 5092 XML.SubElement(top, "buildToChatNotifier", attrib={"class": message}) 5093 targets = XML.SubElement(top, "targets") 5094 channels = data.get("channels", []) 5095 for channel in channels: 5096 sub = XML.SubElement(targets, "hudson.plugins.im.GroupChatIMMessageTarget") 5097 sub_mappings = [ 5098 ("name", "name", ""), 5099 ("password", "password", ""), 5100 ("notify-only", "notificationOnly", False), 5101 ] 5102 helpers.convert_mapping_to_xml(sub, channel, sub_mappings, fail_required=True) 5103 strategy_dict = { 5104 "all": "ALL", 5105 "any-failure": "ANY_FAILURE", 5106 "failure-and-fixed": "FAILURE_AND_FIXED", 5107 "new-failure-and-fixed": "NEW_FAILURE_AND_FIXED", 5108 "statechange-only": "STATECHANGE_ONLY", 5109 } 5110 matrix_dict = { 5111 "all": "ALL", 5112 "only-configurations": "ONLY_CONFIGURATIONS", 5113 "only-parent": "ONLY_PARENT", 5114 } 5115 mappings = [ 5116 ("strategy", "strategy", "all", strategy_dict), 5117 ("notify-start", "notifyOnBuildStart", False), 5118 ("notify-committers", "notifySuspects", False), 5119 ("notify-culprits", "notifyCulprits", False), 5120 ("notify-fixers", "notifyFixers", False), 5121 ("notify-upstream", "notifyUpstreamCommitters", False), 5122 ("matrix-notifier", "matrixMultiplier", "only-configurations", matrix_dict), 5123 ] 5124 helpers.convert_mapping_to_xml(top, data, mappings, fail_required=True) 5125 5126 5127def plot(registry, xml_parent, data): 5128 """yaml: plot 5129 Plot provides generic plotting (or graphing). 5130 5131 Requires the Jenkins :jenkins-plugins:`Plot Plugin <plot>`. 5132 5133 :arg str title: title for the graph (default '') 5134 :arg str yaxis: title of Y axis (default '') 5135 :arg int width: the width of the plot in pixels (default 750) 5136 :arg int height: the height of the plot in pixels (default 450) 5137 :arg str group: name of the group to which the plot belongs (required) 5138 :arg int num-builds: number of builds to plot across 5139 (default plot all builds) 5140 :arg str style: Specifies the graph style of the plot 5141 Can be: area, bar, bar3d, line, line3d, stackedArea, stackedbar, 5142 stackedbar3d, waterfall (default 'line') 5143 :arg bool use-description: When false, the X-axis labels are formed using 5144 build numbers and dates, and the corresponding tooltips contain the 5145 build descriptions. When enabled, the contents of the labels and 5146 tooltips are swapped, with the descriptions used as X-axis labels and 5147 the build number and date used for tooltips. (default false) 5148 :arg bool exclude-zero-yaxis: When false, Y-axis contains the value zero 5149 even if it is not included in the data series. When true, the value 5150 zero is not automatically included. (default false) 5151 :arg bool logarithmic-yaxis: When true, the Y-axis will use a logarithmic 5152 scale. By default, the Y-axis uses a linear scale. (default false) 5153 :arg bool keep-records: When true, show all builds up to 'Number of 5154 builds to include'. (default false) 5155 :arg str csv-file-name: Use for choosing the file name in which the data 5156 will be persisted. If none specified and random name is generated as 5157 done in the Jenkins Plot plugin. (default random generated .csv 5158 filename, same behaviour as the Jenkins Plot plugin) 5159 :arg list series: list data series definitions 5160 5161 :Series: * **file** (`str`) : files to include 5162 * **inclusion-flag** filtering mode for CSV files. Possible 5163 values are: 5164 5165 * **off** (default) 5166 * **include-by-string** 5167 * **exclude-by-string** 5168 * **include-by-column** 5169 * **exclude-by-column** 5170 5171 * **exclude** (`str`) : exclude pattern for CSV file. 5172 * **url** (`str`) : for 'csv' and 'xml' file types 5173 used when you click on a point (default empty) 5174 * **display-table** (`bool`) : for 'csv' file type 5175 if true, original CSV will be shown above plot (default false) 5176 * **label** (`str`) : used by 'properties' file type 5177 Specifies the legend label for this data series. 5178 (default empty) 5179 * **format** (`str`) : Type of file where we get datas. 5180 Can be: properties, csv, xml 5181 * **xpath-type** (`str`) : The result type of the expression must 5182 be supplied due to limitations in the java.xml.xpath parsing. 5183 The result can be: node, nodeset, boolean, string, or number. 5184 Strings and numbers will be converted to double. Boolean will 5185 be converted to 1 for true, and 0 for false. (default 'node') 5186 * **xpath** (`str`) : used by 'xml' file type 5187 Xpath which selects the values that should be plotted. 5188 5189 5190 Minimal Example: 5191 5192 .. literalinclude:: /../../tests/publishers/fixtures/plot-minimal.yaml 5193 :language: yaml 5194 5195 Full Example: 5196 5197 .. literalinclude:: /../../tests/publishers/fixtures/plot-full.yaml 5198 :language: yaml 5199 """ 5200 top = XML.SubElement(xml_parent, "hudson.plugins.plot.PlotPublisher") 5201 plots = XML.SubElement(top, "plots") 5202 format_dict = { 5203 "properties": "hudson.plugins.plot.PropertiesSeries", 5204 "csv": "hudson.plugins.plot.CSVSeries", 5205 "xml": "hudson.plugins.plot.XMLSeries", 5206 } 5207 xpath_dict = { 5208 "nodeset": "NODESET", 5209 "node": "NODE", 5210 "string": "STRING", 5211 "boolean": "BOOLEAN", 5212 "number": "NUMBER", 5213 } 5214 inclusion_dict = { 5215 "off": "OFF", 5216 "include-by-string": "INCLUDE_BY_STRING", 5217 "exclude-by-string": "EXCLUDE_BY_STRING", 5218 "include-by-column": "INCLUDE_BY_COLUMN", 5219 "exclude-by-column": "EXCLUDE_BY_COLUMN", 5220 } 5221 5222 style_list = [ 5223 "area", 5224 "bar", 5225 "bar3d", 5226 "line", 5227 "line3d", 5228 "stackedArea", 5229 "stackedbar", 5230 "stackedbar3d", 5231 "waterfall", 5232 ] 5233 5234 plot_mappings = [ 5235 ("title", "title", ""), 5236 ("yaxis", "yaxis", ""), 5237 ("width", "width", "750"), 5238 ("height", "height", "450"), 5239 ("csv-file-name", "csvFileName", ""), 5240 ("group", "group", None), 5241 ("use-description", "useDescr", False), 5242 ("exclude-zero-yaxis", "exclZero", False), 5243 ("logarithmic-yaxis", "logarithmic", False), 5244 ("keep-records", "keepRecords", False), 5245 ("num-builds", "numBuilds", ""), 5246 ("style", "style", "line", style_list), 5247 ] 5248 5249 plot_csv_mappings = [ 5250 ("inclusion-flag", "inclusionFlag", "off", inclusion_dict), 5251 ("exclude", "exclusionValues", ""), 5252 ("url", "url", ""), 5253 ("display-table", "displayTableFlag", False), 5254 ] 5255 5256 plot_xml_mappings = [ 5257 ("url", "url", ""), 5258 ("xpath", "xpathString", ""), 5259 ("xpath-type", "nodeTypeString", "node", xpath_dict), 5260 ] 5261 5262 for plot in data: 5263 plugin = XML.SubElement(plots, "hudson.plugins.plot.Plot") 5264 helpers.convert_mapping_to_xml(plugin, plot, plot_mappings, fail_required=True) 5265 5266 topseries = XML.SubElement(plugin, "series") 5267 series = plot["series"] 5268 for serie in series: 5269 format_data = serie.get("format") 5270 if format_data not in format_dict: 5271 raise JenkinsJobsException( 5272 "format entered is not valid, must " 5273 "be one of: %s" % " , ".join(format_dict.keys()) 5274 ) 5275 subserie = XML.SubElement(topseries, format_dict.get(format_data)) 5276 XML.SubElement(subserie, "file").text = serie.get("file") 5277 if format_data == "properties": 5278 XML.SubElement(subserie, "label").text = serie.get("label", "") 5279 if format_data == "csv": 5280 helpers.convert_mapping_to_xml( 5281 subserie, serie, plot_csv_mappings, fail_required=True 5282 ) 5283 if serie.get("exclude", ""): 5284 exclude_strings = serie.get("exclude", "").split(",") 5285 exclusionset = XML.SubElement(subserie, "strExclusionSet") 5286 for exclude_string in exclude_strings: 5287 XML.SubElement(exclusionset, "string").text = exclude_string 5288 if format_data == "xml": 5289 helpers.convert_mapping_to_xml( 5290 subserie, serie, plot_xml_mappings, fail_required=True 5291 ) 5292 XML.SubElement(subserie, "fileType").text = serie.get("format") 5293 5294 5295def git(registry, xml_parent, data): 5296 """yaml: git 5297 This plugin will configure the Jenkins Git plugin to 5298 push merge results, tags, and/or branches to 5299 remote repositories after the job completes. 5300 5301 Requires the Jenkins :jenkins-plugins:`Git Plugin <git>`. 5302 5303 :arg bool push-merge: push merges back to the origin specified in the 5304 pre-build merge options (default false) 5305 :arg bool push-only-if-success: Only push to remotes if the build succeeds 5306 - otherwise, nothing will be pushed. 5307 (default true) 5308 :arg bool force-push: Add force option to git push (default false) 5309 :arg list tags: tags to push at the completion of the build 5310 5311 :tag: * **remote** (`str`) remote repo name to push to 5312 (default 'origin') 5313 * **name** (`str`) name of tag to push 5314 * **message** (`str`) message content of the tag 5315 * **create-tag** (`bool`) whether or not to create the tag 5316 after the build, if this is False then the tag needs to 5317 exist locally (default false) 5318 * **update-tag** (`bool`) whether to overwrite a remote tag 5319 or not (default false) 5320 5321 :arg list branches: branches to push at the completion of the build 5322 5323 :branch: * **remote** (`str`) remote repo name to push to 5324 (default 'origin') 5325 * **name** (`str`) name of remote branch to push to 5326 5327 :arg list notes: notes to push at the completion of the build 5328 5329 :note: * **remote** (`str`) remote repo name to push to 5330 (default 'origin') 5331 * **message** (`str`) content of the note 5332 * **namespace** (`str`) namespace of the note 5333 (default master) 5334 * **replace-note** (`bool`) whether to overwrite a note or not 5335 (default false) 5336 5337 5338 Minimal Example: 5339 5340 .. literalinclude:: /../../tests/publishers/fixtures/git-minimal.yaml 5341 :language: yaml 5342 5343 Full Example: 5344 5345 .. literalinclude:: /../../tests/publishers/fixtures/git-full.yaml 5346 :language: yaml 5347 """ 5348 mappings = [ 5349 ("push-merge", "pushMerge", False), 5350 ("push-only-if-success", "pushOnlyIfSuccess", True), 5351 ("force-push", "forcePush", False), 5352 ] 5353 5354 tag_mappings = [ 5355 ("remote", "targetRepoName", "origin"), 5356 ("name", "tagName", None), 5357 ("message", "tagMessage", ""), 5358 ("create-tag", "createTag", False), 5359 ("update-tag", "updateTag", False), 5360 ] 5361 5362 branch_mappings = [ 5363 ("remote", "targetRepoName", "origin"), 5364 ("name", "branchName", None), 5365 ] 5366 5367 note_mappings = [ 5368 ("remote", "targetRepoName", "origin"), 5369 ("message", "noteMsg", None), 5370 ("namespace", "noteNamespace", "master"), 5371 ("replace-note", "noteReplace", False), 5372 ] 5373 5374 top = XML.SubElement(xml_parent, "hudson.plugins.git.GitPublisher") 5375 XML.SubElement(top, "configVersion").text = "2" 5376 helpers.convert_mapping_to_xml(top, data, mappings, fail_required=True) 5377 5378 tags = data.get("tags", []) 5379 if tags: 5380 xml_tags = XML.SubElement(top, "tagsToPush") 5381 for tag in tags: 5382 xml_tag = XML.SubElement( 5383 xml_tags, "hudson.plugins.git.GitPublisher_-TagToPush" 5384 ) 5385 helpers.convert_mapping_to_xml( 5386 xml_tag, tag["tag"], tag_mappings, fail_required=True 5387 ) 5388 5389 branches = data.get("branches", []) 5390 if branches: 5391 xml_branches = XML.SubElement(top, "branchesToPush") 5392 for branch in branches: 5393 xml_branch = XML.SubElement( 5394 xml_branches, "hudson.plugins.git.GitPublisher_-BranchToPush" 5395 ) 5396 helpers.convert_mapping_to_xml( 5397 xml_branch, branch["branch"], branch_mappings, fail_required=True 5398 ) 5399 5400 notes = data.get("notes", []) 5401 if notes: 5402 xml_notes = XML.SubElement(top, "notesToPush") 5403 for note in notes: 5404 xml_note = XML.SubElement( 5405 xml_notes, "hudson.plugins.git.GitPublisher_-NoteToPush" 5406 ) 5407 helpers.convert_mapping_to_xml( 5408 xml_note, note["note"], note_mappings, fail_required=True 5409 ) 5410 5411 5412def github_notifier(registry, xml_parent, data): 5413 """yaml: github-notifier 5414 Set build status on Github commit. 5415 Requires the Jenkins :jenkins-plugins:`Github Plugin <github>`. 5416 5417 Example: 5418 5419 .. literalinclude:: /../../tests/publishers/fixtures/github-notifier.yaml 5420 :language: yaml 5421 """ 5422 XML.SubElement(xml_parent, "com.cloudbees.jenkins.GitHubCommitNotifier") 5423 5424 5425def gitlab_notifier(registry, xml_parent, data): 5426 """yaml: gitlab-notifier 5427 Set build status on GitLab commit. 5428 Requires the Jenkins :jenkins-plugins:`GitLab Plugin <gitlab-plugin>`. 5429 5430 :arg str name: The name of the build in GitLab. With this you can 5431 distinguish different Jenkins jobs for the same commit in GitLab. 5432 (default 'jenkins') 5433 :arg bool mark-unstable-as-success: (default false) 5434 5435 Minimal Example: 5436 5437 .. literalinclude:: 5438 /../../tests/publishers/fixtures/gitlab-notifier-minimal.yaml 5439 :language: yaml 5440 5441 Full Example: 5442 5443 .. literalinclude:: 5444 /../../tests/publishers/fixtures/gitlab-notifier-full.yaml 5445 :language: yaml 5446 """ 5447 top = XML.SubElement( 5448 xml_parent, "com.dabsquared.gitlabjenkins.publisher.GitLabCommitStatusPublisher" 5449 ) 5450 top.set("plugin", "gitlab-plugin") 5451 5452 mappings = [ 5453 ("name", "name", "jenkins"), 5454 ("mark-unstable-as-success", "markUnstableAsSuccess", False), 5455 ] 5456 helpers.convert_mapping_to_xml(top, data, mappings, fail_required=True) 5457 5458 5459def gitlab_vote(registry, xml_parent, data): 5460 """yaml: gitlab-vote 5461 Set vote for build status on GitLab merge request. 5462 Requires the Jenkins :jenkins-plugins:`GitLab Plugin <gitlab-plugin>`. 5463 5464 Example: 5465 5466 .. literalinclude:: 5467 ../../tests/publishers/fixtures/gitlab-vote.yaml 5468 :language: yaml 5469 """ 5470 XML.SubElement( 5471 xml_parent, "com.dabsquared.gitlabjenkins.publisher.GitLabVotePublisher" 5472 ) 5473 5474 5475def gitlab_message(registry, xml_parent, data): 5476 """yaml: gitlab-message 5477 Add note with build status on GitLab merge request. 5478 Requires the Jenkins :jenkins-plugins:`GitLab Plugin <gitlab-plugin>`. 5479 5480 :arg bool failure-only: make a comment only on failure (default false) 5481 :arg bool success-note: make a comment on GitLab Merge Request 5482 if build succeeds (default false) 5483 :arg bool failure-note: make a comment on GitLab Merge Request 5484 if build failed (default false) 5485 :arg bool abort-note: make a comment on GitLab Merge Request 5486 if build aborted (default false) 5487 :arg bool unstable-note: make a comment on GitLab Merge Request 5488 if build unstable (default false) 5489 5490 :arg str success-note-text: text of comment on success build (default '') 5491 :arg str failure-note-text: text of comment on failed build (default '') 5492 :arg str abort-note-text: text of comment on aborted build (default '') 5493 :arg str unstable-note-text: text of comment on unstable build (default '') 5494 5495 Minimal Example: 5496 5497 .. literalinclude:: 5498 /../../tests/publishers/fixtures/gitlab-message-minimal.yaml 5499 :language: yaml 5500 5501 Full Example: 5502 5503 .. literalinclude:: 5504 /../../tests/publishers/fixtures/gitlab-message-full.yaml 5505 :language: yaml 5506 """ 5507 gitlab = XML.SubElement( 5508 xml_parent, "com.dabsquared.gitlabjenkins.publisher.GitLabMessagePublisher" 5509 ) 5510 gitlab.set("plugin", "gitlab-plugin") 5511 5512 mapping = [ 5513 ("failure-only", "onlyForFailure", False), 5514 ("success-note", "replaceSuccessNote", False), 5515 ("failure-note", "replaceFailureNote", False), 5516 ("abort-note", "replaceAbortNote", False), 5517 ("unstable-note", "replaceUnstableNote", False), 5518 ("success-note-text", "successNoteText", ""), 5519 ("failure-note-text", "failureNoteText", ""), 5520 ("abort-note-text", "abortNoteText", ""), 5521 ("unstable-note-text", "unstableNoteText", ""), 5522 ] 5523 5524 helpers.convert_mapping_to_xml(gitlab, data, mapping, fail_required=True) 5525 5526 5527def zulip(registry, xml_parent, data): 5528 """yaml: zulip 5529 Set build status on zulip. 5530 Requires the Jenkins :jenkins-plugins:`Humbug Plugin <humbug>`. 5531 5532 Example: 5533 5534 .. literalinclude:: /../../tests/publishers/fixtures/zulip.yaml 5535 :language: yaml 5536 """ 5537 XML.SubElement(xml_parent, "hudson.plugins.humbug.HumbugNotifier") 5538 5539 5540def build_publisher(registry, xml_parent, data): 5541 """yaml: build-publisher 5542 This plugin allows records from one Jenkins to be published 5543 on another Jenkins. 5544 5545 Requires the Jenkins :jenkins-plugins:`Build Publisher Plugin 5546 <build-publisher>`. 5547 5548 :arg bool publish-unstable-builds: publish unstable builds (default true) 5549 :arg bool publish-failed-builds: publish failed builds (default true) 5550 :arg int days-to-keep: days to keep when publishing results (optional) 5551 :arg int num-to-keep: number of jobs to keep in the published results 5552 (optional) 5553 5554 Minimal Example: 5555 5556 .. literalinclude:: 5557 /../../tests/publishers/fixtures/build-publisher-minimal.yaml 5558 :language: yaml 5559 5560 Full Example: 5561 5562 .. literalinclude:: 5563 /../../tests/publishers/fixtures/build-publisher-full.yaml 5564 :language: yaml 5565 """ 5566 5567 reporter = XML.SubElement( 5568 xml_parent, "hudson.plugins.build__publisher.BuildPublisher" 5569 ) 5570 5571 mappings = [ 5572 ("publish-unstable-builds", "publishUnstableBuilds", True), 5573 ("publish-failed-builds", "publishFailedBuilds", True), 5574 ] 5575 helpers.convert_mapping_to_xml(reporter, data, mappings, fail_required=True) 5576 if "days-to-keep" in data or "num-to-keep" in data: 5577 logrotator = XML.SubElement(reporter, "logRotator") 5578 mappings = [ 5579 ("days-to-keep", "daysToKeep", -1), 5580 ("num-to-keep", "numToKeep", -1), 5581 # hardcoded to -1 to emulate what the build publisher 5582 # plugin seem to do. 5583 ("", "artifactDaysToKeep", -1), 5584 ("", "artifactNumToKeep", -1), 5585 ] 5586 helpers.convert_mapping_to_xml(logrotator, data, mappings, fail_required=True) 5587 5588 5589def stash(registry, xml_parent, data): 5590 """yaml: stash 5591 This plugin will configure the Jenkins BitBucket Server Notifier plugin to 5592 notify Atlassian BitBucket after job completes. 5593 5594 Requires the Jenkins :jenkins-plugins:`Bitbucket Server Notifier Plugin 5595 <stashNotifier>`. 5596 5597 :arg str url: Base url of Stash Server (default "") 5598 :arg str username: Username of Stash Server (default "") 5599 :arg str password: Password of Stash Server (default "") 5600 :arg str credentials-id: Credentials of Stash Server (optional) 5601 :arg bool ignore-ssl: Ignore unverified SSL certificate (default false) 5602 :arg str commit-sha1: Commit SHA1 to notify (default "") 5603 :arg bool include-build-number: Include build number in key 5604 (default false) 5605 5606 Minimal Example: 5607 5608 .. literalinclude:: /../../tests/publishers/fixtures/stash-minimal.yaml 5609 :language: yaml 5610 5611 Full Example: 5612 5613 .. literalinclude:: /../../tests/publishers/fixtures/stash-full.yaml 5614 :language: yaml 5615 """ 5616 top = XML.SubElement( 5617 xml_parent, "org.jenkinsci.plugins.stashNotifier.StashNotifier" 5618 ) 5619 5620 XML.SubElement(top, "stashServerBaseUrl").text = data.get("url", "") 5621 if data.get("credentials-id") is not None: 5622 XML.SubElement(top, "credentialsId").text = str(data.get("credentials-id")) 5623 else: 5624 XML.SubElement( 5625 top, "stashUserName" 5626 ).text = helpers.get_value_from_yaml_or_config_file( 5627 "username", "stash", data, registry.jjb_config 5628 ) 5629 XML.SubElement( 5630 top, "stashUserPassword" 5631 ).text = helpers.get_value_from_yaml_or_config_file( 5632 "password", "stash", data, registry.jjb_config 5633 ) 5634 mappings = [ 5635 ("ignore-ssl", "ignoreUnverifiedSSLPeer", False), 5636 ("commit-sha1", "commitSha1", ""), 5637 ("include-build-number", "includeBuildNumberInKey", False), 5638 ] 5639 helpers.convert_mapping_to_xml(top, data, mappings, fail_required=True) 5640 5641 5642def dependency_check(registry, xml_parent, data): 5643 """yaml: dependency-check 5644 Dependency-Check is an open source utility that identifies project 5645 dependencies and checks if there are any known, publicly disclosed, 5646 vulnerabilities. 5647 5648 Requires the Jenkins :jenkins-plugins:`OWASP Dependency-Check Plugin 5649 <dependency-check-jenkins-plugin>`. 5650 5651 :arg str pattern: Report filename pattern (optional) 5652 :arg bool can-run-on-failed: Also runs for failed builds, instead of just 5653 stable or unstable builds (default false) 5654 :arg bool should-detect-modules: Determines if Ant or Maven modules should 5655 be detected for all files that contain warnings (default false) 5656 :arg int healthy: Sunny threshold (optional) 5657 :arg int unhealthy: Stormy threshold (optional) 5658 :arg str health-threshold: Threshold priority for health status 5659 ('low', 'normal' or 'high', defaulted to 'low') 5660 :arg dict thresholds: Mark build as failed or unstable if the number of 5661 errors exceeds a threshold. (optional) 5662 5663 :thresholds: 5664 * **unstable** (`dict`) 5665 :unstable: * **total-all** (`int`) 5666 * **total-high** (`int`) 5667 * **total-normal** (`int`) 5668 * **total-low** (`int`) 5669 * **new-all** (`int`) 5670 * **new-high** (`int`) 5671 * **new-normal** (`int`) 5672 * **new-low** (`int`) 5673 5674 * **failed** (`dict`) 5675 :failed: * **total-all** (`int`) 5676 * **total-high** (`int`) 5677 * **total-normal** (`int`) 5678 * **total-low** (`int`) 5679 * **new-all** (`int`) 5680 * **new-high** (`int`) 5681 * **new-normal** (`int`) 5682 * **new-low** (`int`) 5683 :arg str default-encoding: Encoding for parsing or showing files (optional) 5684 :arg bool do-not-resolve-relative-paths: (default false) 5685 :arg bool dont-compute-new: If set to false, computes new warnings based on 5686 the reference build (default true) 5687 :arg bool use-previous-build-as-reference: determines whether to always 5688 use the previous build as the reference build (default false) 5689 :arg bool use-stable-build-as-reference: The number of new warnings will be 5690 calculated based on the last stable build, allowing reverts of unstable 5691 builds where the number of warnings was decreased. (default false) 5692 :arg bool use-delta-values: If set then the number of new warnings is 5693 calculated by subtracting the total number of warnings of the current 5694 build from the reference build. 5695 (default false) 5696 5697 Minimal Example: 5698 5699 .. literalinclude:: 5700 /../../tests/publishers/fixtures/dependency-check-minimal.yaml 5701 :language: yaml 5702 5703 Full Example: 5704 5705 .. literalinclude:: 5706 /../../tests/publishers/fixtures/dependency-check-full.yaml 5707 :language: yaml 5708 """ 5709 5710 dependency_check = XML.SubElement( 5711 xml_parent, "org.jenkinsci.plugins.DependencyCheck.DependencyCheckPublisher" 5712 ) 5713 5714 # trends 5715 helpers.build_trends_publisher("[DEPENDENCYCHECK] ", dependency_check, data) 5716 5717 5718def description_setter(registry, xml_parent, data): 5719 """yaml: description-setter 5720 This plugin sets the description for each build, 5721 based upon a RegEx test of the build log file. 5722 5723 Requires the Jenkins :jenkins-plugins:`Description Setter Plugin 5724 <description-setter>`. 5725 5726 :arg str regexp: A RegEx which is used to scan the build log file 5727 (default '') 5728 :arg str regexp-for-failed: A RegEx which is used for failed builds 5729 (default '') 5730 :arg str description: The description to set on the build (optional) 5731 :arg str description-for-failed: The description to set on 5732 the failed builds (optional) 5733 :arg bool set-for-matrix: Also set the description on 5734 a multi-configuration build (default false) 5735 5736 Minimal Example: 5737 5738 .. literalinclude:: 5739 /../../tests/publishers/fixtures/description-setter-minimal.yaml 5740 :language: yaml 5741 5742 Full Example: 5743 5744 .. literalinclude:: 5745 /../../tests/publishers/fixtures/description-setter-full.yaml 5746 :language: yaml 5747 """ 5748 5749 descriptionsetter = XML.SubElement( 5750 xml_parent, "hudson.plugins.descriptionsetter.DescriptionSetterPublisher" 5751 ) 5752 mappings = [ 5753 ("regexp", "regexp", ""), 5754 ("regexp-for-failed", "regexpForFailed", ""), 5755 ("description", "description", None), 5756 ("description-for-failed", "descriptionForFailed", None), 5757 ("set-for-matrix", "setForMatrix", False), 5758 ] 5759 helpers.convert_mapping_to_xml( 5760 descriptionsetter, data, mappings, fail_required=False 5761 ) 5762 5763 5764def doxygen(registry, xml_parent, data): 5765 """yaml: doxygen 5766 This plugin parses the Doxygen descriptor (Doxyfile) and provides a link to 5767 the generated Doxygen documentation. 5768 5769 Requires the Jenkins :jenkins-plugins:`Doxygen Plugin <doxygen>`. 5770 5771 :arg str doxyfile: The doxyfile path (required) 5772 :arg str slave: The node or label to pull the doxygen HTML files from 5773 (default '') 5774 :arg bool keep-all: Retain doxygen generation for each successful build 5775 (default false) 5776 :arg str folder: Folder where you run doxygen (default '') 5777 5778 Minimal Example: 5779 5780 .. literalinclude:: /../../tests/publishers/fixtures/doxygen-minimal.yaml 5781 :language: yaml 5782 5783 Full Example: 5784 5785 .. literalinclude:: /../../tests/publishers/fixtures/doxygen-full.yaml 5786 :language: yaml 5787 """ 5788 5789 logger = logging.getLogger(__name__) 5790 p = XML.SubElement(xml_parent, "hudson.plugins.doxygen.DoxygenArchiver") 5791 mappings = [ 5792 ("doxyfile", "doxyfilePath", None), 5793 ("slave", "runOnChild", ""), 5794 ("folder", "folderWhereYouRunDoxygen", ""), 5795 ] 5796 helpers.convert_mapping_to_xml(p, data, mappings, fail_required=True) 5797 # backward compatibility 5798 if "keepall" in data: 5799 if "keep-all" in data: 5800 XML.SubElement(p, "keepAll").text = str(data.get("keep-all", False)).lower() 5801 logger.warning( 5802 "The value of 'keepall' will be ignored " "in preference to 'keep-all'." 5803 ) 5804 else: 5805 XML.SubElement(p, "keepAll").text = str(data.get("keepall", False)).lower() 5806 logger.warning("'keepall' is deprecated please use 'keep-all'") 5807 else: 5808 XML.SubElement(p, "keepAll").text = str(data.get("keep-all", False)).lower() 5809 5810 5811def docker_stop_container(registry, xml_parent, data): 5812 """yaml: docker-stop-container 5813 This plugin allows removing stopped docker containers. 5814 It requires the :jenkins-plugins:`Docker build step plugin 5815 <docker-build-step>`. 5816 5817 :arg bool remove-stopped-containers: Boolean value to remove 5818 stopped docker containers (default False) 5819 5820 Minimal Example: 5821 .. literalinclude:: /../../tests/ 5822 publishers/fixtures/docker-stop-container-minimal.yaml 5823 5824 Full Example: 5825 .. literalinclude:: /../../tests/ 5826 publishers/fixtures/docker-stop-container-full.yaml 5827 """ 5828 docker_stop_container = XML.SubElement( 5829 xml_parent, 5830 "com.nirima.jenkins.plugins.docker" ".publisher.DockerPublisherControl", 5831 ) 5832 docker_stop_container.set("plugin", "docker-plugin") 5833 mapping = [("remove-stopped-containers", "remove", False)] 5834 helpers.convert_mapping_to_xml( 5835 docker_stop_container, data, mapping, fail_required=False 5836 ) 5837 5838 5839def sitemonitor(registry, xml_parent, data): 5840 """yaml: sitemonitor 5841 This plugin checks the availability of an url. 5842 5843 It requires the :jenkins-plugins:`sitemonitor plugin <sitemonitor>`. 5844 5845 :arg list sites: List of URLs to check 5846 5847 Minimal Example: 5848 5849 .. literalinclude:: 5850 /../../tests/publishers/fixtures/sitemonitor-minimal.yaml 5851 :language: yaml 5852 5853 Full Example: 5854 5855 .. literalinclude:: /../../tests/publishers/fixtures/sitemonitor-full.yaml 5856 :language: yaml 5857 """ 5858 mon = XML.SubElement(xml_parent, "hudson.plugins.sitemonitor.SiteMonitorRecorder") 5859 if data.get("sites"): 5860 sites = XML.SubElement(mon, "mSites") 5861 for siteurl in data.get("sites"): 5862 site = XML.SubElement(sites, "hudson.plugins.sitemonitor.model.Site") 5863 XML.SubElement(site, "mUrl").text = siteurl["url"] 5864 5865 5866def testng(registry, xml_parent, data): 5867 """yaml: testng 5868 This plugin publishes TestNG test reports. 5869 5870 Requires the Jenkins :jenkins-plugins:`TestNG Results Plugin 5871 <testng-plugin>`. 5872 5873 :arg str pattern: filename pattern to locate the TestNG XML report files 5874 (required) 5875 :arg bool escape-test-description: escapes the description string 5876 associated with the test method while displaying test method details 5877 (default true) 5878 :arg bool escape-exception-msg: escapes the test method's exception 5879 messages. (default true) 5880 :arg bool fail-on-failed-test-config: Allows for a distinction between 5881 failing tests and failing configuration methods (>=1.10) (default 5882 false) 5883 :arg bool show-failed-builds: include results from failed builds in the 5884 trend graph (>=1.6) (default false) 5885 :arg int unstable-skips: Build is marked UNSTABLE if the number/percentage 5886 of skipped tests exceeds the specified threshold (>=1.11) (default 100) 5887 :arg int unstable-fails: Build is marked UNSTABLE if the number/percentage 5888 of failed tests exceeds the specified threshold (>=1.11) (default 0) 5889 :arg int failed-skips: Build is marked FAILURE if the number/percentage of 5890 skipped tests exceeds the specified threshold (>=1.11) (default 100) 5891 :arg int failed-fails: Build is marked FAILURE if the number/percentage of 5892 failed tests exceeds the specified threshold (>=1.11) (default 100) 5893 :arg str threshold-mode: Interpret threshold as number of tests or 5894 percentage of tests (>=1.11) (default percentage) 5895 5896 Full Example: 5897 5898 .. literalinclude:: /../../tests/publishers/fixtures/testng-full.yaml 5899 :language: yaml 5900 5901 Minimal Example: 5902 5903 .. literalinclude:: /../../tests/publishers/fixtures/testng-minimal.yaml 5904 :language: yaml 5905 """ 5906 5907 reporter = XML.SubElement(xml_parent, "hudson.plugins.testng.Publisher") 5908 reporter.set("plugin", "testng-plugin") 5909 threshold_modes = {"number": 1, "percentage": 2} 5910 5911 mappings = [ 5912 ("pattern", "reportFilenamePattern", None), 5913 ("escape-test-description", "escapeTestDescp", True), 5914 ("escape-exception-msg", "escapeExceptionMsg", True), 5915 ("fail-on-failed-test-config", "failureOnFailedTestConfig", False), 5916 ("show-failed-builds", "showFailedBuilds", False), 5917 ("unstable-skips", "unstableSkips", 100), 5918 ("unstable-fails", "unstableFails", 0), 5919 ("failed-skips", "failedSkips", 100), 5920 ("failed-fails", "failedFails", 100), 5921 ("threshold-mode", "thresholdMode", "percentage", threshold_modes), 5922 ] 5923 helpers.convert_mapping_to_xml(reporter, data, mappings, fail_required=True) 5924 5925 5926def artifact_deployer(registry, xml_parent, data): 5927 """yaml: artifact-deployer 5928 This plugin makes it possible to copy artifacts to remote locations. 5929 5930 Requires the Jenkins :jenkins-plugins:`ArtifactDeployer Plugin 5931 <artifactdeployer>`. 5932 5933 :arg list entries: 5934 :entries: 5935 * **files** (`str`) - files to deploy 5936 * **basedir** (`str`) - the dir from files are deployed 5937 * **excludes** (`str`) - the mask to exclude files 5938 * **remote** (`str`) - a remote output directory 5939 * **flatten** (`bool`) - ignore the source directory structure 5940 (default false) 5941 * **delete-remote** (`bool`) - clean-up remote directory 5942 before deployment (default false) 5943 * **delete-remote-artifacts** (`bool`) - delete remote artifacts 5944 when the build is deleted (default false) 5945 * **fail-no-files** (`bool`) - fail build if there are no files 5946 (default false) 5947 * **groovy-script** (`str`) - execute a Groovy script 5948 before a build is deleted 5949 5950 :arg bool deploy-if-fail: Deploy if the build is failed (default false) 5951 5952 Example: 5953 5954 .. literalinclude:: /../../tests/publishers/fixtures/artifact-dep.yaml 5955 :language: yaml 5956 """ 5957 5958 deployer = XML.SubElement( 5959 xml_parent, 5960 "org.jenkinsci.plugins.artifactdeployer." "ArtifactDeployerPublisher", 5961 ) 5962 if data is None or "entries" not in data: 5963 raise Exception("entries field is missing") 5964 elif data.get("entries", None) is None: 5965 entries = XML.SubElement(deployer, "entries", {"class": "empty-list"}) 5966 else: 5967 entries = XML.SubElement(deployer, "entries") 5968 for entry in data.get("entries"): 5969 deployer_entry = XML.SubElement( 5970 entries, "org.jenkinsci.plugins.artifactdeployer.ArtifactDeployerEntry" 5971 ) 5972 XML.SubElement(deployer_entry, "includes").text = entry.get("files") 5973 XML.SubElement(deployer_entry, "basedir").text = entry.get("basedir") 5974 XML.SubElement(deployer_entry, "excludes").text = entry.get("excludes") 5975 XML.SubElement(deployer_entry, "remote").text = entry.get("remote") 5976 XML.SubElement(deployer_entry, "flatten").text = str( 5977 entry.get("flatten", False) 5978 ).lower() 5979 XML.SubElement(deployer_entry, "deleteRemote").text = str( 5980 entry.get("delete-remote", False) 5981 ).lower() 5982 XML.SubElement(deployer_entry, "deleteRemoteArtifacts").text = str( 5983 entry.get("delete-remote-artifacts", False) 5984 ).lower() 5985 XML.SubElement(deployer_entry, "failNoFilesDeploy").text = str( 5986 entry.get("fail-no-files", False) 5987 ).lower() 5988 XML.SubElement(deployer_entry, "groovyExpression").text = entry.get( 5989 "groovy-script" 5990 ) 5991 deploy_if_fail = str(data.get("deploy-if-fail", False)).lower() 5992 XML.SubElement(deployer, "deployEvenBuildFail").text = deploy_if_fail 5993 5994 5995def s3(registry, xml_parent, data): 5996 """yaml: s3 5997 Upload build artifacts to Amazon S3. 5998 5999 Requires the Jenkins :jenkins-plugins:`S3 plugin <s3>`. 6000 6001 :arg str s3-profile: Globally-defined S3 profile to use 6002 :arg bool dont-wait-for-concurrent-builds: Don't wait 6003 for completion of concurrent builds before publishing to S3 6004 (default false) 6005 :arg list entries: 6006 :entries: 6007 * **destination-bucket** (`str`) - Destination S3 bucket 6008 * **source-files** (`str`) - Source files (Ant glob syntax) 6009 * **storage-class** (`str`) - S3 storage class; one of "STANDARD" 6010 or "REDUCED_REDUNDANCY" 6011 * **bucket-region** (`str`) - S3 bucket region (capitalized with 6012 underscores) 6013 * **upload-on-failure** (`bool`) - Upload files even if the build 6014 failed (default false) 6015 * **upload-from-slave** (`bool`) - Perform the upload directly from 6016 the Jenkins slave rather than the master node. (default false) 6017 * **managed-artifacts** (`bool`) - Let Jenkins fully manage the 6018 published artifacts, similar to when artifacts are published to 6019 the Jenkins master. (default false) 6020 * **s3-encryption** (`bool`) - Use S3 AES-256 server side encryption 6021 support. (default false) 6022 * **flatten** (`bool`) - Ignore the directory structure of the 6023 artifacts in the source project and copy all matching artifacts 6024 directly into the specified bucket. (default false) 6025 :arg list metadata-tags: 6026 :metadata-tags: 6027 * **key** Metadata key for files from this build. It will be 6028 prefixed by "x-amz-meta-" when uploaded to S3. Can contain macros 6029 (e.g. environment variables). 6030 * **value** Metadata value associated with the key. Can contain macros. 6031 6032 Example: 6033 6034 .. literalinclude:: /../../tests/publishers/fixtures/s3001.yaml 6035 :language: yaml 6036 """ 6037 deployer = XML.SubElement(xml_parent, "hudson.plugins.s3.S3BucketPublisher") 6038 if data is None or not data.get("entries"): 6039 raise JenkinsJobsException("No filesets defined.") 6040 6041 XML.SubElement(deployer, "dontWaitForConcurrentBuildCompletion").text = str( 6042 data.get("dont-wait-for-concurrent-builds", False) 6043 ).lower() 6044 6045 XML.SubElement(deployer, "profileName").text = data.get("s3-profile") 6046 6047 entries = XML.SubElement(deployer, "entries") 6048 6049 for entry in data.get("entries"): 6050 fileset = XML.SubElement(entries, "hudson.plugins.s3.Entry") 6051 6052 # xml keys -> yaml keys 6053 settings = [ 6054 ("bucket", "destination-bucket", ""), 6055 ("sourceFile", "source-files", ""), 6056 ("storageClass", "storage-class", ""), 6057 ("selectedRegion", "bucket-region", ""), 6058 ("noUploadOnFailure", "upload-on-failure", False), 6059 ("uploadFromSlave", "upload-from-slave", False), 6060 ("managedArtifacts", "managed-artifacts", False), 6061 ("useServerSideEncryption", "s3-encryption", False), 6062 ("flatten", "flatten", False), 6063 ] 6064 6065 for xml_key, yaml_key, default in settings: 6066 xml_config = XML.SubElement(fileset, xml_key) 6067 config_value = entry.get(yaml_key, default) 6068 if xml_key == "noUploadOnFailure": 6069 xml_config.text = str(not config_value).lower() 6070 elif isinstance(default, bool): 6071 xml_config.text = str(config_value).lower() 6072 else: 6073 xml_config.text = str(config_value) 6074 6075 metadata = XML.SubElement(deployer, "userMetadata") 6076 for tag in data.get("metadata-tags", []): 6077 pair = XML.SubElement(metadata, "hudson.plugins.s3.MetadataPair") 6078 XML.SubElement(pair, "key").text = tag.get("key") 6079 XML.SubElement(pair, "value").text = tag.get("value") 6080 6081 6082def ruby_metrics(registry, xml_parent, data): 6083 """yaml: ruby-metrics 6084 Rcov plugin parses rcov html report files and 6085 shows it in Jenkins with a trend graph. 6086 6087 Requires the Jenkins :jenkins-plugins:`Ruby metrics plugin 6088 <rubyMetrics>`. 6089 6090 :arg str report-dir: Relative path to the coverage report directory 6091 :arg dict targets: 6092 6093 :targets: (total-coverage, code-coverage) 6094 6095 * **healthy** (`int`): Healthy threshold 6096 * **unhealthy** (`int`): Unhealthy threshold 6097 * **unstable** (`int`): Unstable threshold 6098 6099 Example: 6100 6101 .. literalinclude:: /../../tests/publishers/fixtures/ruby-metrics.yaml 6102 :language: yaml 6103 """ 6104 6105 metrics = XML.SubElement( 6106 xml_parent, "hudson.plugins.rubyMetrics.rcov.RcovPublisher" 6107 ) 6108 report_dir = data.get("report-dir", "") 6109 XML.SubElement(metrics, "reportDir").text = report_dir 6110 targets = XML.SubElement(metrics, "targets") 6111 if "target" in data: 6112 for t in data["target"]: 6113 if not ("code-coverage" in t or "total-coverage" in t): 6114 raise JenkinsJobsException("Unrecognized target name") 6115 el = XML.SubElement( 6116 targets, "hudson.plugins.rubyMetrics.rcov.model.MetricTarget" 6117 ) 6118 if "total-coverage" in t: 6119 XML.SubElement(el, "metric").text = "TOTAL_COVERAGE" 6120 else: 6121 XML.SubElement(el, "metric").text = "CODE_COVERAGE" 6122 for threshold_name, threshold_value in next(iter(t.values())).items(): 6123 elname = threshold_name.lower() 6124 XML.SubElement(el, elname).text = str(threshold_value) 6125 else: 6126 raise JenkinsJobsException("Coverage metric targets must be set") 6127 6128 6129def fitnesse(registry, xml_parent, data): 6130 """yaml: fitnesse 6131 Publish Fitnesse test results 6132 6133 Requires the Jenkins :jenkins-plugins:`Fitnesse plugin <fitnesse>`. 6134 6135 :arg str results: path specifier for results files 6136 6137 Example: 6138 6139 .. literalinclude:: /../../tests/publishers/fixtures/fitnesse001.yaml 6140 :language: yaml 6141 """ 6142 fitnesse = XML.SubElement( 6143 xml_parent, "hudson.plugins.fitnesse.FitnesseResultsRecorder" 6144 ) 6145 results = data.get("results", "") 6146 XML.SubElement(fitnesse, "fitnessePathToXmlResultsIn").text = results 6147 6148 6149def valgrind(registry, xml_parent, data): 6150 """yaml: valgrind 6151 This plugin publishes Valgrind Memcheck XML results. 6152 6153 Requires the Jenkins :jenkins-plugins:`Valgrind Plugin <valgrind>`. 6154 6155 :arg str pattern: Filename pattern to locate the Valgrind XML report files 6156 (required) 6157 :arg dict thresholds: Mark build as failed or unstable if the number of 6158 errors exceeds a threshold. All threshold values are optional. 6159 6160 :thresholds: 6161 * **unstable** (`dict`) 6162 :unstable: * **invalid-read-write** (`int`) 6163 * **definitely-lost** (`int`) 6164 * **total** (`int`) 6165 * **failed** (`dict`) 6166 :failed: * **invalid-read-write** (`int`) 6167 * **definitely-lost** (`int`) 6168 * **total** (`int`) 6169 :arg bool fail-no-reports: Fail build if no reports are found 6170 (default false) 6171 :arg bool fail-invalid-reports: Fail build if reports are malformed 6172 (default false) 6173 :arg bool publish-if-aborted: Publish results for aborted builds 6174 (default false) 6175 :arg bool publish-if-failed: Publish results for failed builds 6176 (default false) 6177 6178 Example: 6179 6180 .. literalinclude:: /../../tests/publishers/fixtures/valgrind001.yaml 6181 :language: yaml 6182 """ 6183 p = XML.SubElement(xml_parent, "org.jenkinsci.plugins.valgrind.ValgrindPublisher") 6184 p = XML.SubElement(p, "valgrindPublisherConfig") 6185 6186 if "pattern" not in data: 6187 raise JenkinsJobsException("A filename pattern must be specified.") 6188 6189 XML.SubElement(p, "pattern").text = data["pattern"] 6190 6191 dthresholds = data.get("thresholds", {}) 6192 6193 for threshold in ["unstable", "failed"]: 6194 dthreshold = dthresholds.get(threshold, {}) 6195 threshold = threshold.replace("failed", "fail") 6196 6197 ThresholdInvalidReadWrite = "%sThresholdInvalidReadWrite" % threshold 6198 ThresholdDefinitelyLost = "%sThresholdDefinitelyLost" % threshold 6199 ThresholdTotal = "%sThresholdTotal" % threshold 6200 6201 threshold_mapping = [ 6202 ("invalid-read-write", ThresholdInvalidReadWrite, ""), 6203 ("definitely-lost", ThresholdDefinitelyLost, ""), 6204 ("total", ThresholdTotal, ""), 6205 ] 6206 helpers.convert_mapping_to_xml( 6207 p, dthreshold, threshold_mapping, fail_required=True 6208 ) 6209 6210 mapping = [ 6211 ("fail-no-reports", "failBuildOnMissingReports", False), 6212 ("fail-invalid-reports", "failBuildOnInvalidReports", False), 6213 ("publish-if-aborted", "publishResultsForAbortedBuilds", False), 6214 ("publish-if-failed", "publishResultsForFailedBuilds", False), 6215 ] 6216 helpers.convert_mapping_to_xml(p, data, mapping, fail_required=True) 6217 6218 6219def pmd(registry, xml_parent, data): 6220 """yaml: pmd 6221 Publish trend reports with PMD. 6222 6223 Requires the Jenkins PMD Plugin (https://github.com/jenkinsci/pmd-plugin). 6224 6225 The PMD component accepts a dictionary with the following values: 6226 6227 :arg str pattern: Report filename pattern (optional) 6228 :arg bool can-run-on-failed: Also runs for failed builds, instead of just 6229 stable or unstable builds (default false) 6230 :arg bool should-detect-modules: Determines if Ant or Maven modules should 6231 be detected for all files that contain warnings (default false) 6232 :arg int healthy: Sunny threshold (optional) 6233 :arg int unhealthy: Stormy threshold (optional) 6234 :arg str health-threshold: Threshold priority for health status 6235 ('low', 'normal' or 'high', defaulted to 'low') 6236 :arg dict thresholds: Mark build as failed or unstable if the number of 6237 errors exceeds a threshold. (optional) 6238 6239 :thresholds: 6240 * **unstable** (`dict`) 6241 :unstable: * **total-all** (`int`) 6242 * **total-high** (`int`) 6243 * **total-normal** (`int`) 6244 * **total-low** (`int`) 6245 * **new-all** (`int`) 6246 * **new-high** (`int`) 6247 * **new-normal** (`int`) 6248 * **new-low** (`int`) 6249 6250 * **failed** (`dict`) 6251 :failed: * **total-all** (`int`) 6252 * **total-high** (`int`) 6253 * **total-normal** (`int`) 6254 * **total-low** (`int`) 6255 * **new-all** (`int`) 6256 * **new-high** (`int`) 6257 * **new-normal** (`int`) 6258 * **new-low** (`int`) 6259 :arg str default-encoding: Encoding for parsing or showing files (optional) 6260 :arg bool do-not-resolve-relative-paths: (default false) 6261 :arg bool dont-compute-new: If set to false, computes new warnings based on 6262 the reference build (default true) 6263 :arg bool use-previous-build-as-reference: determines whether to always 6264 use the previous build as the reference build (default false) 6265 :arg bool use-stable-build-as-reference: The number of new warnings will be 6266 calculated based on the last stable build, allowing reverts of unstable 6267 builds where the number of warnings was decreased. (default false) 6268 :arg bool use-delta-values: If set then the number of new warnings is 6269 calculated by subtracting the total number of warnings of the current 6270 build from the reference build. 6271 (default false) 6272 6273 Example: 6274 6275 .. literalinclude:: /../../tests/publishers/fixtures/pmd001.yaml 6276 :language: yaml 6277 6278 Full example: 6279 6280 .. literalinclude:: /../../tests/publishers/fixtures/pmd002.yaml 6281 :language: yaml 6282 """ 6283 6284 xml_element = XML.SubElement(xml_parent, "hudson.plugins.pmd.PmdPublisher") 6285 6286 helpers.build_trends_publisher("[PMD] ", xml_element, data) 6287 6288 6289def scan_build(registry, xml_parent, data): 6290 """yaml: scan-build 6291 Publishes results from the Clang scan-build static analyzer. 6292 6293 The scan-build report has to be generated in the directory 6294 ``${WORKSPACE}/clangScanBuildReports`` for the publisher to find it. 6295 6296 Requires the Jenkins :jenkins-plugins:`Clang Scan-Build Plugin 6297 <clang-scanbuild>`. 6298 6299 :arg bool mark-unstable: Mark build as unstable if the number of bugs 6300 exceeds a threshold (default false) 6301 :arg int threshold: Threshold for marking builds as unstable (default 0) 6302 :arg str exclude-paths: Comma separated paths to exclude from reports 6303 (>=1.5) (default '') 6304 :arg str report-folder: Folder where generated reports are located 6305 (>=1.7) (default 'clangScanBuildReports') 6306 6307 Full Example: 6308 6309 .. literalinclude:: /../../tests/publishers/fixtures/scan-build-full.yaml 6310 :language: yaml 6311 6312 Minimal Example: 6313 6314 .. literalinclude:: 6315 /../../tests/publishers/fixtures/scan-build-minimal.yaml 6316 :language: yaml 6317 """ 6318 p = XML.SubElement( 6319 xml_parent, "jenkins.plugins.clangscanbuild.publisher.ClangScanBuildPublisher" 6320 ) 6321 p.set("plugin", "clang-scanbuild") 6322 6323 mappings = [ 6324 ("mark-unstable", "markBuildUnstableWhenThresholdIsExceeded", False), 6325 ("threshold", "bugThreshold", 0), 6326 ("exclude-paths", "clangexcludedpaths", ""), 6327 ("report-folder", "reportFolderName", "clangScanBuildReports"), 6328 ] 6329 helpers.convert_mapping_to_xml(p, data, mappings, fail_required=True) 6330 6331 6332def dry(registry, xml_parent, data): 6333 """yaml: dry 6334 Publish trend reports with DRY. 6335 6336 Requires the Jenkins DRY Plugin (https://github.com/jenkinsci/dry-plugin). 6337 6338 The DRY component accepts a dictionary with the following values: 6339 6340 :arg str pattern: Report filename pattern (default '') 6341 :arg bool can-run-on-failed: Also runs for failed builds, instead of just 6342 stable or unstable builds (default false) 6343 :arg bool should-detect-modules: Determines if Ant or Maven modules should 6344 be detected for all files that contain warnings (default false) 6345 :arg int healthy: Sunny threshold (default '') 6346 :arg int unhealthy: Stormy threshold (default '') 6347 :arg str health-threshold: Threshold priority for health status 6348 ('low', 'normal' or 'high', defaulted to 'low') 6349 :arg int high-threshold: Minimum number of duplicated lines for high 6350 priority warnings. (default 50) 6351 :arg int normal-threshold: Minimum number of duplicated lines for normal 6352 priority warnings. (default 25) 6353 :arg dict thresholds: Mark build as failed or unstable if the number of 6354 errors exceeds a threshold. (default '') 6355 6356 :thresholds: 6357 * **unstable** (`dict`) 6358 :unstable: * **total-all** (`int`) 6359 * **total-high** (`int`) 6360 * **total-normal** (`int`) 6361 * **total-low** (`int`) 6362 * **new-all** (`int`) 6363 * **new-high** (`int`) 6364 * **new-normal** (`int`) 6365 * **new-low** (`int`) 6366 6367 * **failed** (`dict`) 6368 :failed: * **total-all** (`int`) 6369 * **total-high** (`int`) 6370 * **total-normal** (`int`) 6371 * **total-low** (`int`) 6372 * **new-all** (`int`) 6373 * **new-high** (`int`) 6374 * **new-normal** (`int`) 6375 * **new-low** (`int`) 6376 :arg str default-encoding: Encoding for parsing or showing files (optional) 6377 :arg bool do-not-resolve-relative-paths: (default false) 6378 :arg bool dont-compute-new: If set to false, computes new warnings based on 6379 the reference build (default true) 6380 :arg bool use-previous-build-as-reference: determines whether to always 6381 use the previous build as the reference build (default false) 6382 :arg bool use-stable-build-as-reference: The number of new warnings will be 6383 calculated based on the last stable build, allowing reverts of unstable 6384 builds where the number of warnings was decreased. (default false) 6385 :arg bool use-delta-values: If set then the number of new warnings is 6386 calculated by subtracting the total number of warnings of the current 6387 build from the reference build. (default false) 6388 6389 Example: 6390 6391 .. literalinclude:: /../../tests/publishers/fixtures/dry001.yaml 6392 :language: yaml 6393 6394 Full example: 6395 6396 .. literalinclude:: /../../tests/publishers/fixtures/dry004.yaml 6397 :language: yaml 6398 """ 6399 6400 xml_element = XML.SubElement(xml_parent, "hudson.plugins.dry.DryPublisher") 6401 6402 helpers.build_trends_publisher("[DRY] ", xml_element, data) 6403 6404 # Add specific settings for this trends publisher 6405 settings = [ 6406 ("high-threshold", "highThreshold", 50), 6407 ("normal-threshold", "normalThreshold", 25), 6408 ] 6409 helpers.convert_mapping_to_xml(xml_element, data, settings, fail_required=True) 6410 6411 6412def shining_panda(registry, xml_parent, data): 6413 """yaml: shining-panda 6414 Publish coverage.py results. Requires the Jenkins 6415 :jenkins-plugins:`ShiningPanda Plugin <shiningpanda>`. 6416 6417 :arg str html-reports-directory: path to coverage.py html results 6418 (optional) 6419 6420 Example: 6421 6422 .. literalinclude:: /../../tests/publishers/fixtures/shiningpanda001.yaml 6423 :language: yaml 6424 """ 6425 shining_panda_plugin = XML.SubElement( 6426 xml_parent, "jenkins.plugins.shiningpanda.publishers.CoveragePublisher" 6427 ) 6428 6429 mapping = [("html-reports-directory", "htmlDir", None)] 6430 helpers.convert_mapping_to_xml( 6431 shining_panda_plugin, data, mapping, fail_required=False 6432 ) 6433 6434 6435def downstream_ext(registry, xml_parent, data): 6436 """yaml: downstream-ext 6437 Trigger multiple downstream jobs when a job is completed and 6438 condition is met. 6439 6440 Requires the Jenkins :jenkins-plugins:`Downstream-Ext Plugin 6441 <downstream-ext>`. 6442 6443 :arg list projects: Projects to build (required) 6444 :arg str condition: comparison condition used for the criteria. 6445 One of 'equal-or-over', 'equal-or-under', 'equal' 6446 (default 'equal-or-over') 6447 :arg str criteria: Trigger downstream job if build results meets 6448 condition. One of 'success', 'unstable', 'failure' or 6449 'aborted' (default 'success') 6450 :arg bool only-on-scm-change: Trigger only if downstream project 6451 has SCM changes (default false) 6452 :arg bool only-on-local-scm-change: Trigger only if current project 6453 has SCM changes (default false) 6454 6455 Example: 6456 6457 .. literalinclude:: 6458 /../../tests/publishers/fixtures/downstream-ext002.yaml 6459 :language: yaml 6460 """ 6461 6462 conditions = { 6463 "equal-or-over": "AND_HIGHER", 6464 "equal-or-under": "AND_LOWER", 6465 "equal": "EXACT", 6466 } 6467 6468 p = XML.SubElement(xml_parent, "hudson.plugins.downstream__ext.DownstreamTrigger") 6469 6470 if "projects" not in data: 6471 raise JenkinsJobsException("Missing list of downstream projects.") 6472 6473 XML.SubElement(p, "childProjects").text = ",".join(data["projects"]) 6474 6475 th = XML.SubElement(p, "threshold") 6476 6477 criteria = data.get("criteria", "success").upper() 6478 6479 wr_threshold = hudson_model.THRESHOLDS[criteria] 6480 if criteria not in hudson_model.THRESHOLDS: 6481 raise JenkinsJobsException( 6482 "criteria must be one of %s" % ", ".join(hudson_model.THRESHOLDS.keys()) 6483 ) 6484 mapping = [ 6485 ("name", "name", None), 6486 ("ordinal", "ordinal", None), 6487 ("color", "color", None), 6488 ("complete", "completeBuild", None), 6489 ] 6490 helpers.convert_mapping_to_xml(th, wr_threshold, mapping, fail_required=True) 6491 6492 condition_mapping = [ 6493 ("condition", "thresholdStrategy", "equal-or-over", conditions), 6494 ("only-on-scm-change", "onlyIfSCMChanges", False), 6495 ("only-on-local-scm-change", "onlyIfLocalSCMChanges", False), 6496 ] 6497 helpers.convert_mapping_to_xml(p, data, condition_mapping, fail_required=True) 6498 6499 6500def rundeck(registry, xml_parent, data): 6501 """yaml: rundeck 6502 Trigger a rundeck job when the build is complete. 6503 6504 Requires the Jenkins :jenkins-plugins:`RunDeck Plugin <rundeck>`. 6505 6506 :arg str job-id: The RunDeck job identifier. (required) 6507 This could be: 6508 * ID example : "42" 6509 * UUID example : "2027ce89-7924-4ecf-a963-30090ada834f" 6510 * reference, in the format : "project:group/job" 6511 :arg str options: List of options for the Rundeck job, in Java-Properties 6512 format: key=value (default "") 6513 :arg str node-filters: List of filters to optionally filter the nodes 6514 included by the job. (default "") 6515 :arg str tag: Used for on-demand job scheduling on rundeck: if a tag is 6516 specified, the job will only execute if the given tag is present in the 6517 SCM changelog. (default "") 6518 :arg bool wait-for-rundeck: If true Jenkins will wait for the job to 6519 complete, if false the job will be started and Jenkins will move on. 6520 (default false) 6521 :arg bool fail-the-build: If true a RunDeck job failure will cause the 6522 Jenkins build to fail. (default false) 6523 6524 Example: 6525 6526 .. literalinclude:: /../../tests/publishers/fixtures/rundeck001.yaml 6527 :language: yaml 6528 6529 Full example: 6530 6531 .. literalinclude:: /../../tests/publishers/fixtures/rundeck002.yaml 6532 :language: yaml 6533 """ 6534 6535 p = XML.SubElement(xml_parent, "org.jenkinsci.plugins.rundeck.RundeckNotifier") 6536 6537 mappings = [ 6538 ("job-id", "jobId", None), 6539 ("options", "options", ""), 6540 ("node-filters", "nodeFilters", ""), 6541 ("tag", "tag", ""), 6542 ("wait-for-rundeck", "shouldWaitForRundeckJob", False), 6543 ("fail-the-build", "shouldFailTheBuild", False), 6544 ] 6545 helpers.convert_mapping_to_xml(p, data, mappings, fail_required=True) 6546 6547 6548def create_publishers(registry, action): 6549 dummy_parent = XML.Element("dummy") 6550 registry.dispatch("publisher", dummy_parent, action) 6551 return list(dummy_parent) 6552 6553 6554def conditional_publisher(registry, xml_parent, data): 6555 """yaml: conditional-publisher 6556 Conditionally execute some post-build steps. Requires the Jenkins 6557 :jenkins-plugins:`Flexible Publish Plugin <flexible-publish>`. 6558 6559 A Flexible Publish list of Conditional Actions is created in Jenkins. 6560 6561 :arg str condition-kind: Condition kind that must be verified before the 6562 action is executed. Valid values and their additional attributes are 6563 described in the conditions_ table. 6564 :arg bool condition-aggregation: If true Matrix Aggregation will be 6565 enabled. (default false) 6566 :arg str condition-aggregation-kind: Condition Aggregation kind that 6567 must be verified before the 6568 action is executed. Valid values and their additional attributes are 6569 described in the conditions_ table. 6570 :arg str on-evaluation-failure: What should be the outcome of the build 6571 if the evaluation of the condition fails. Possible values are `fail`, 6572 `mark-unstable`, `run-and-mark-unstable`, `run` and `dont-run`. 6573 Default is `fail`. 6574 :arg list action: Action to run if the condition is verified. Item 6575 can be any publisher known by Jenkins Job Builder and supported 6576 by the Flexible Publish Plugin. 6577 6578 .. _conditions: 6579 6580 ================== ==================================================== 6581 Condition kind Description 6582 ================== ==================================================== 6583 always Condition is always verified 6584 never Condition is never verified 6585 boolean-expression Run the action if the expression expands to a 6586 representation of true 6587 6588 :condition-expression: Expression to expand 6589 current-status Run the action if the current build status is 6590 within the configured range 6591 6592 :condition-worst: Accepted values are SUCCESS, 6593 UNSTABLE, FAILURE, NOT_BUILD, ABORTED 6594 :condition-best: Accepted values are SUCCESS, 6595 UNSTABLE, FAILURE, NOT_BUILD, ABORTED 6596 6597 shell Run the action if the shell command succeeds 6598 6599 :condition-command: Shell command to execute 6600 windows-shell Similar to shell, except that commands will be 6601 executed by cmd, under Windows 6602 6603 :condition-command: Command to execute 6604 regexp Run the action if a regular expression matches 6605 6606 :condition-expression: Regular Expression 6607 :condition-searchtext: Text to match against 6608 the regular expression 6609 file-exists Run the action if a file exists 6610 6611 :condition-filename: Check existence of this file 6612 :condition-basedir: If condition-filename is 6613 relative, it will be considered relative to 6614 either `workspace`, `artifact-directory`, 6615 or `jenkins-home`. Default is `workspace`. 6616 ================== ==================================================== 6617 6618 Single Conditional Action Example: 6619 6620 .. literalinclude:: \ 6621 /../../tests/publishers/fixtures/conditional-publisher001.yaml 6622 :language: yaml 6623 6624 Multiple Conditional Actions Example 6625 (includes example of multiple actions per condition which requires 6626 v0.13 or higher of the Flexible Publish plugin): 6627 6628 .. literalinclude:: \ 6629 /../../tests/publishers/fixtures/conditional-publisher003.yaml 6630 :language: yaml 6631 6632 :download:`Multiple Conditional Actions Example for pre-v0.13 versions 6633 <../../tests/publishers/fixtures/conditional-publisher002.yaml>` 6634 6635 """ 6636 6637 def publish_condition_tag(cdata, prefix, condition_tag): 6638 kind = cdata["%s-kind" % prefix] 6639 ctag = XML.SubElement(cond_publisher, condition_tag) 6640 class_pkg = "org.jenkins_ci.plugins.run_condition" 6641 6642 if kind == "always": 6643 ctag.set("class", class_pkg + ".core.AlwaysRun") 6644 elif kind == "never": 6645 ctag.set("class", class_pkg + ".core.NeverRun") 6646 elif kind == "boolean-expression": 6647 ctag.set("class", class_pkg + ".core.BooleanCondition") 6648 XML.SubElement(ctag, "token").text = cdata["%s-expression" % prefix] 6649 elif kind == "current-status": 6650 ctag.set("class", class_pkg + ".core.StatusCondition") 6651 wr = XML.SubElement(ctag, "worstResult") 6652 wr_name = cdata["%s-worst" % prefix] 6653 if wr_name not in hudson_model.THRESHOLDS: 6654 raise JenkinsJobsException( 6655 "threshold must be one of %s" 6656 % ", ".join(hudson_model.THRESHOLDS.keys()) 6657 ) 6658 wr_threshold = hudson_model.THRESHOLDS[wr_name] 6659 XML.SubElement(wr, "name").text = wr_threshold["name"] 6660 XML.SubElement(wr, "ordinal").text = wr_threshold["ordinal"] 6661 XML.SubElement(wr, "color").text = wr_threshold["color"] 6662 XML.SubElement(wr, "completeBuild").text = str( 6663 wr_threshold["complete"] 6664 ).lower() 6665 6666 br = XML.SubElement(ctag, "bestResult") 6667 br_name = cdata["%s-best" % prefix] 6668 if br_name not in hudson_model.THRESHOLDS: 6669 raise JenkinsJobsException( 6670 "threshold must be one of %s" 6671 % ", ".join(hudson_model.THRESHOLDS.keys()) 6672 ) 6673 br_threshold = hudson_model.THRESHOLDS[br_name] 6674 XML.SubElement(br, "name").text = br_threshold["name"] 6675 XML.SubElement(br, "ordinal").text = br_threshold["ordinal"] 6676 XML.SubElement(br, "color").text = br_threshold["color"] 6677 XML.SubElement(br, "completeBuild").text = str( 6678 wr_threshold["complete"] 6679 ).lower() 6680 elif kind == "shell": 6681 ctag.set("class", class_pkg + ".contributed.ShellCondition") 6682 XML.SubElement(ctag, "command").text = cdata["%s-command" % prefix] 6683 elif kind == "windows-shell": 6684 ctag.set("class", class_pkg + ".contributed.BatchFileCondition") 6685 XML.SubElement(ctag, "command").text = cdata["%s-command" % prefix] 6686 elif kind == "regexp": 6687 ctag.set("class", class_pkg + ".core.ExpressionCondition") 6688 XML.SubElement(ctag, "expression").text = cdata["%s-expression" % prefix] 6689 XML.SubElement(ctag, "label").text = cdata["%s-searchtext" % prefix] 6690 elif kind == "file-exists": 6691 ctag.set("class", class_pkg + ".core.FileExistsCondition") 6692 XML.SubElement(ctag, "file").text = cdata["%s-filename" % prefix] 6693 basedir = cdata.get("%s-basedir", "workspace") 6694 basedir_tag = XML.SubElement(ctag, "baseDir") 6695 if "workspace" == basedir: 6696 basedir_tag.set("class", class_pkg + ".common.BaseDirectory$Workspace") 6697 elif "artifact-directory" == basedir: 6698 basedir_tag.set( 6699 "class", class_pkg + ".common." "BaseDirectory$ArtifactsDir" 6700 ) 6701 elif "jenkins-home" == basedir: 6702 basedir_tag.set( 6703 "class", class_pkg + ".common." "BaseDirectory$JenkinsHome" 6704 ) 6705 else: 6706 raise JenkinsJobsException( 6707 "%s is not a valid %s-kind " "value." % (kind, prefix) 6708 ) 6709 6710 def publish_condition(cdata): 6711 return publish_condition_tag(cdata, "condition", condition_tag) 6712 6713 def publish_aggregation_condition(cdata): 6714 return publish_condition_tag( 6715 cdata, "condition-aggregation", aggregation_condition_tag 6716 ) 6717 6718 def publish_action(parent, action): 6719 for edited_node in create_publishers(registry, action): 6720 if not use_publisher_list: 6721 edited_node.set("class", edited_node.tag) 6722 # sort attributes alphabetically 6723 attrib = edited_node.attrib 6724 if len(attrib) > 1: 6725 attribs = sorted(attrib.items()) 6726 attrib.clear() 6727 attrib.update(attribs) 6728 edited_node.tag = "publisher" 6729 parent.append(edited_node) 6730 6731 flex_publisher_tag = ( 6732 "org.jenkins__ci.plugins.flexible__publish." "FlexiblePublisher" 6733 ) 6734 cond_publisher_tag = ( 6735 "org.jenkins__ci.plugins.flexible__publish." "ConditionalPublisher" 6736 ) 6737 6738 root_tag = XML.SubElement(xml_parent, flex_publisher_tag) 6739 publishers_tag = XML.SubElement(root_tag, "publishers") 6740 condition_tag = "condition" 6741 aggregation_condition_tag = "aggregationCondition" 6742 6743 evaluation_classes_pkg = "org.jenkins_ci.plugins.run_condition" 6744 evaluation_classes = { 6745 "fail": evaluation_classes_pkg + ".BuildStepRunner$Fail", 6746 "mark-unstable": evaluation_classes_pkg + ".BuildStepRunner$Unstable", 6747 "run-and-mark-unstable": evaluation_classes_pkg 6748 + ".BuildStepRunner$RunUnstable", 6749 "run": evaluation_classes_pkg + ".BuildStepRunner$Run", 6750 "dont-run": evaluation_classes_pkg + ".BuildStepRunner$DontRun", 6751 } 6752 6753 plugin_info = registry.get_plugin_info("Flexible Publish Plugin") 6754 # Note: Assume latest version of plugin is preferred config format 6755 version = pkg_resources.parse_version(plugin_info.get("version", str(sys.maxsize))) 6756 6757 # Support for MatrixAggregator was added in v0.11 6758 # See JENKINS-14494 6759 has_matrix_aggregator = version >= pkg_resources.parse_version("0.11") 6760 6761 for cond_action in data: 6762 cond_publisher = XML.SubElement(publishers_tag, cond_publisher_tag) 6763 publish_condition(cond_action) 6764 condition_aggregation = cond_action.get("condition-aggregation", False) 6765 if condition_aggregation and has_matrix_aggregator: 6766 publish_aggregation_condition(cond_action) 6767 elif condition_aggregation: 6768 raise JenkinsJobsException( 6769 "Matrix Aggregation is not supported " "in your plugin version." 6770 ) 6771 evaluation_flag = cond_action.get("on-evaluation-failure", "fail") 6772 if evaluation_flag not in evaluation_classes.keys(): 6773 raise JenkinsJobsException( 6774 "on-evaluation-failure value " 6775 "specified is not valid. Must be one " 6776 "of: %s" % evaluation_classes.keys() 6777 ) 6778 6779 evaluation_class = evaluation_classes[evaluation_flag] 6780 XML.SubElement(cond_publisher, "runner").set("class", evaluation_class) 6781 6782 if "action" in cond_action: 6783 actions = cond_action["action"] 6784 6785 action_parent = cond_publisher 6786 6787 # XML tag changed from publisher to publisherList in v0.13 6788 # check the plugin version to determine further operations 6789 use_publisher_list = version >= pkg_resources.parse_version("0.13") 6790 6791 if use_publisher_list: 6792 action_parent = XML.SubElement(cond_publisher, "publisherList") 6793 else: 6794 # Check the length of actions list for versions prior to 0.13. 6795 # Flexible Publish will overwrite action if more than one is 6796 # specified. Limit the action list to one element. 6797 if len(actions) != 1: 6798 raise JenkinsJobsException( 6799 "Only one action may be " "specified for each condition." 6800 ) 6801 for action in actions: 6802 publish_action(action_parent, action) 6803 else: 6804 raise JenkinsJobsException("action must be set for each condition") 6805 6806 6807def scoverage(registry, xml_parent, data): 6808 """yaml: scoverage 6809 Publish scoverage results as a trend graph. 6810 Requires the Jenkins :jenkins-plugins:`Scoverage Plugin <scoverage>`. 6811 6812 :arg str report-directory: This is a directory that specifies the locations 6813 where the xml scoverage report is generated (required) 6814 :arg str report-file: This is a file name that is given to the xml 6815 scoverage report (required) 6816 6817 Example: 6818 6819 .. literalinclude:: /../../tests/publishers/fixtures/scoverage001.yaml 6820 :language: yaml 6821 """ 6822 scoverage = XML.SubElement( 6823 xml_parent, "org.jenkinsci.plugins.scoverage.ScoveragePublisher" 6824 ) 6825 scoverage.set("plugin", "scoverage") 6826 6827 mappings = [ 6828 ("report-directory", "reportDir", None), 6829 ("report-file", "reportFile", None), 6830 ] 6831 helpers.convert_mapping_to_xml(scoverage, data, mappings, fail_required=True) 6832 6833 6834def display_upstream_changes(registry, xml_parent, data): 6835 """yaml: display-upstream-changes 6836 Display SCM changes of upstream jobs. Requires the Jenkins 6837 :jenkins-plugins:`Display Upstream Changes Plugin 6838 <display-upstream-changes>`. 6839 6840 Example: 6841 6842 .. literalinclude:: \ 6843 /../../tests/publishers/fixtures/display-upstream-changes.yaml 6844 """ 6845 XML.SubElement( 6846 xml_parent, 6847 "jenkins.plugins.displayupstreamchanges." "DisplayUpstreamChangesRecorder", 6848 ) 6849 6850 6851def gatling(registry, xml_parent, data): 6852 """yaml: gatling 6853 Publish gatling results as a trend graph 6854 Requires the Jenkins :jenkins-plugins:`Gatling Plugin <gatling>`. 6855 6856 Example: 6857 6858 .. literalinclude:: /../../tests/publishers/fixtures/gatling001.yaml 6859 :language: yaml 6860 """ 6861 gatling = XML.SubElement(xml_parent, "io.gatling.jenkins.GatlingPublisher") 6862 mapping = [("", "enabled", "true")] 6863 helpers.convert_mapping_to_xml(gatling, data, mapping, fail_required=True) 6864 6865 6866def logstash(registry, xml_parent, data): 6867 """yaml: logstash 6868 Send job's console log to Logstash for processing and analyis of 6869 your job data. Also stores test metrics from Junit. 6870 Requires the Jenkins :jenkins-plugins:`Logstash Plugin <logstash>`. 6871 6872 :arg int max-lines: The maximum number of log lines to send to Logstash. 6873 (default 1000) 6874 :arg bool fail-build: Mark build as failed if this step fails. 6875 (default false) 6876 6877 Minimal Example: 6878 6879 .. literalinclude:: /../../tests/publishers/fixtures/logstash-min.yaml 6880 :language: yaml 6881 6882 Full Example: 6883 6884 .. literalinclude:: /../../tests/publishers/fixtures/logstash-full.yaml 6885 :language: yaml 6886 """ 6887 6888 logstash = XML.SubElement(xml_parent, "jenkins.plugins.logstash.LogstashNotifier") 6889 logstash.set("plugin", "logstash") 6890 6891 mapping = [("max-lines", "maxLines", 1000), ("fail-build", "failBuild", False)] 6892 helpers.convert_mapping_to_xml(logstash, data, mapping, fail_required=True) 6893 6894 6895def image_gallery(registry, xml_parent, data): 6896 """yaml: image-gallery 6897 Produce an image gallery using Javascript library. Requires the Jenkins 6898 :jenkins-plugins:`Image Gallery Plugin <image-gallery>`. 6899 6900 :arg str gallery-type: 6901 6902 :gallery-type values: 6903 * **archived-images-gallery** (default) 6904 * **in-folder-comparative-gallery** 6905 * **multiple-folder-comparative-gallery** 6906 :arg str title: gallery title (optional) 6907 :arg int image-width: width of the image (optional) 6908 :arg bool unstable-if-no-artifacts: mark build as unstable 6909 if no archived artifacts were found (default false) 6910 :arg str includes: include pattern (valid for archived-images-gallery 6911 gallery) 6912 :arg str base-root-folder: base root dir (valid for comparative gallery) 6913 :arg int image-inner-width: width of the image displayed in the inner 6914 gallery popup (valid for comparative gallery, optional) 6915 6916 Example: 6917 6918 .. literalinclude:: /../../tests/publishers/fixtures/image-gallery001.yaml 6919 6920 """ 6921 6922 def include_comparative_elements(gallery_parent_elem, gallery): 6923 XML.SubElement(gallery_parent_elem, "baseRootFolder").text = str( 6924 gallery.get("base-root-folder", "") 6925 ) 6926 image_inner_width = gallery.get("image-inner-width", "") 6927 if image_inner_width: 6928 XML.SubElement(gallery_parent_elem, "imageInnerWidth").text = str( 6929 image_inner_width 6930 ) 6931 6932 package_prefix = "org.jenkinsci.plugins.imagegallery." 6933 builder = XML.SubElement(xml_parent, package_prefix + "ImageGalleryRecorder") 6934 image_galleries = XML.SubElement(builder, "imageGalleries") 6935 galleries = { 6936 "archived-images-gallery": package_prefix + "imagegallery." 6937 "ArchivedImagesGallery", 6938 "in-folder-comparative-gallery": package_prefix + "comparative." 6939 "InFolderComparativeArchivedImagesGallery", 6940 "multiple-folder-comparative-gallery": package_prefix + "comparative." 6941 "MultipleFolderComparativeArchivedImagesGallery", 6942 } 6943 for gallery_def in data: 6944 gallery_type = gallery_def.get("gallery-type", "archived-images-gallery") 6945 if gallery_type not in galleries: 6946 raise InvalidAttributeError("gallery-type", gallery_type, galleries.keys()) 6947 gallery_config = XML.SubElement(image_galleries, galleries[gallery_type]) 6948 XML.SubElement(gallery_config, "title").text = str(gallery_def.get("title", "")) 6949 image_width = str(gallery_def.get("image-width", "")) 6950 if image_width: 6951 XML.SubElement(gallery_config, "imageWidth").text = str(image_width) 6952 XML.SubElement( 6953 gallery_config, "markBuildAsUnstableIfNoArchivesFound" 6954 ).text = str(gallery_def.get("unstable-if-no-artifacts", False)) 6955 if gallery_type == "archived-images-gallery": 6956 XML.SubElement(gallery_config, "includes").text = str( 6957 gallery_def.get("includes", "") 6958 ) 6959 if gallery_type == "in-folder-comparative-gallery": 6960 include_comparative_elements(gallery_config, gallery_def) 6961 if gallery_type == "multiple-folder-comparative-gallery": 6962 include_comparative_elements(gallery_config, gallery_def) 6963 6964 6965def naginator(registry, xml_parent, data): 6966 """yaml: naginator 6967 Automatically reschedule a build after a build failure 6968 Requires the Jenkins :jenkins-plugins:`Naginator Plugin <naginator>`. 6969 6970 :arg bool rerun-unstable-builds: Rerun build for unstable builds as well 6971 as failures (default false) 6972 :arg bool rerun-matrix-part: Rerun build only for failed parts on the 6973 matrix (>=1.12) (default false) 6974 :arg int fixed-delay: Fixed delay in seconds before retrying build (cannot 6975 be used with progressive-delay-increment or progressive-delay-maximum. 6976 This is the default delay type. (default 0) 6977 :arg int progressive-delay-increment: Progressive delay in seconds before 6978 retrying build increment (cannot be used when fixed-delay is being 6979 used) (default 0) 6980 :arg int progressive-delay-maximum: Progressive delay in seconds before 6981 retrying maximum delay (cannot be used when fixed-delay is being used) 6982 (default 0) 6983 :arg int max-failed-builds: Maximum number of successive failed builds 6984 (default 0) 6985 :arg str regular-expression: Only rerun build if regular expression is 6986 found in output (default '') 6987 6988 Example: 6989 6990 .. literalinclude:: /../../tests/publishers/fixtures/naginator001.yaml 6991 :language: yaml 6992 """ 6993 naginator = XML.SubElement( 6994 xml_parent, "com.chikli.hudson.plugin.naginator.NaginatorPublisher" 6995 ) 6996 XML.SubElement(naginator, "regexpForRerun").text = str( 6997 data.get("regular-expression", "") 6998 ) 6999 XML.SubElement(naginator, "checkRegexp").text = str( 7000 "regular-expression" in data 7001 ).lower() 7002 XML.SubElement(naginator, "rerunIfUnstable").text = str( 7003 data.get("rerun-unstable-builds", False) 7004 ).lower() 7005 XML.SubElement(naginator, "rerunMatrixPart").text = str( 7006 data.get("rerun-matrix-part", False) 7007 ).lower() 7008 progressive_delay = ( 7009 "progressive-delay-increment" in data or "progressive-delay-maximum" in data 7010 ) 7011 if "fixed-delay" in data and progressive_delay: 7012 raise JenkinsJobsException( 7013 "You cannot specify both fixed " "and progressive delays" 7014 ) 7015 if not progressive_delay: 7016 delay = XML.SubElement( 7017 naginator, 7018 "delay", 7019 {"class": "com.chikli.hudson.plugin.naginator.FixedDelay"}, 7020 ) 7021 XML.SubElement(delay, "delay").text = str(data.get("fixed-delay", "0")) 7022 else: 7023 delay = XML.SubElement( 7024 naginator, 7025 "delay", 7026 {"class": "com.chikli.hudson.plugin.naginator.ProgressiveDelay"}, 7027 ) 7028 XML.SubElement(delay, "increment").text = str( 7029 data.get("progressive-delay-increment", "0") 7030 ) 7031 XML.SubElement(delay, "max").text = str( 7032 data.get("progressive-delay-maximum", "0") 7033 ) 7034 XML.SubElement(naginator, "maxSchedule").text = str( 7035 data.get("max-failed-builds", "0") 7036 ) 7037 7038 7039def disable_failed_job(registry, xml_parent, data): 7040 """yaml: disable-failed-job 7041 Automatically disable failed jobs. 7042 7043 Requires the Jenkins :jenkins-plugins:`Disable Failed Job Plugin 7044 <disable-failed-job>`. 7045 7046 :arg str when-to-disable: The condition to disable the job. (required) 7047 Possible values are 7048 7049 * **Only Failure** 7050 * **Failure and Unstable** 7051 * **Unstable** 7052 7053 :arg int no-of-failures: Number of consecutive failures to disable the 7054 job. (optional) 7055 7056 Example: 7057 7058 .. literalinclude:: 7059 /../../tests/publishers/fixtures/disable-failed-job001.yaml 7060 :language: yaml 7061 """ 7062 7063 xml_element = XML.SubElement( 7064 xml_parent, 7065 "disableFailedJob." "disableFailedJob.DisableFailedJob", 7066 {"plugin": "disable-failed-job"}, 7067 ) 7068 7069 valid_conditions = ["Only Failure", "Failure and Unstable", "Only Unstable"] 7070 mapping = [("when-to-disable", "whenDisable", None, valid_conditions)] 7071 helpers.convert_mapping_to_xml(xml_element, data, mapping, fail_required=True) 7072 7073 if "no-of-failures" in data: 7074 mapping = [ 7075 ("no-of-failures", "failureTimes", None), 7076 ("", "optionalBrockChecked", True), 7077 ] 7078 helpers.convert_mapping_to_xml(xml_element, data, mapping, fail_required=True) 7079 else: 7080 XML.SubElement(xml_element, "optionalBrockChecked").text = "false" 7081 7082 7083def google_cloud_storage(registry, xml_parent, data): 7084 """yaml: google-cloud-storage 7085 Upload build artifacts to Google Cloud Storage. Requires the 7086 Jenkins :jenkins-plugins:`Google Cloud Storage plugin 7087 <google-storage-plugin>`. 7088 7089 Apart from the Google Cloud Storage Plugin itself, installation of Google 7090 OAuth Credentials and addition of required credentials to Jenkins is 7091 required. 7092 7093 :arg str credentials-id: The set of Google credentials registered with 7094 the Jenkins Credential Manager for authenticating 7095 with your project. (required) 7096 :arg list uploads: 7097 :uploads: 7098 * **expiring-elements** (`dict`) 7099 :params: 7100 * **bucket-name** (`str`) bucket name to upload artifacts 7101 (required) 7102 * **days-to-retain** (`int`) days to keep artifacts 7103 (required) 7104 * **build-log** (`dict`) 7105 :params: 7106 * **log-name** (`str`) name of the file that the Jenkins 7107 console log to be named (required) 7108 * **storage-location** (`str`) bucket name to upload 7109 artifacts (required) 7110 * **share-publicly** (`bool`) whether to share uploaded 7111 share uploaded artifacts with everyone (default false) 7112 * **upload-for-failed-jobs** (`bool`) whether to upload 7113 artifacts even if the build fails (default false) 7114 * **show-inline** (`bool`) whether to show uploaded build 7115 log inline in web browsers, rather than forcing it to be 7116 downloaded (default true) 7117 * **strip-prefix** (`str`) strip this prefix off the 7118 file names (default not set) 7119 7120 * **classic** (`dict`) 7121 :params: 7122 * **file-pattern** (`str`) ant style globs to match the 7123 files to upload (required) 7124 * **storage-location** (`str`) bucket name to upload 7125 artifacts (required) 7126 * **share-publicly** (`bool`) whether to share uploaded 7127 share uploaded artifacts with everyone (default false) 7128 * **upload-for-failed-jobs** (`bool`) whether to upload 7129 artifacts even if the build fails (default false) 7130 * **show-inline** (`bool`) whether to show uploaded 7131 artifacts inline in web browsers, rather than forcing 7132 them to be downloaded (default false) 7133 * **strip-prefix** (`str`) strip this prefix off the 7134 file names (default not set) 7135 7136 Example: 7137 7138 .. literalinclude:: 7139 /../../tests/publishers/fixtures/google_cloud_storage001.yaml 7140 :language: yaml 7141 7142 Full example: 7143 7144 .. literalinclude:: 7145 /../../tests/publishers/fixtures/google_cloud_storage002.yaml 7146 :language: yaml 7147 """ 7148 7149 def expiring_elements(properties, upload_element, types): 7150 # Handle expiring elements upload action 7151 7152 xml_element = XML.SubElement( 7153 upload_element, 7154 "com.google." "jenkins.plugins.storage." "ExpiringBucketLifecycleManager", 7155 ) 7156 mapping = [ 7157 ("bucket-name", "bucketNameWithVars", None), 7158 ("", "sharedPublicly", False), 7159 ("", "forFailedJobs", False), 7160 ("days-to-retain", "bucketObjectTTL", None), 7161 ] 7162 helpers.convert_mapping_to_xml( 7163 xml_element, properties, mapping, fail_required=True 7164 ) 7165 7166 if types.count("expiring-elements") > 1: 7167 XML.SubElement( 7168 xml_element, 7169 "module", 7170 { 7171 "reference": "../../com.google.jenkins.plugins." 7172 "storage.ExpiringBucketLifecycleManager/module" 7173 }, 7174 ) 7175 else: 7176 XML.SubElement(xml_element, "module") 7177 7178 def build_log(properties, upload_element, types): 7179 # Handle build log upload action 7180 7181 xml_element = XML.SubElement( 7182 upload_element, "com.google.jenkins." "plugins.storage.StdoutUpload" 7183 ) 7184 mapping = [ 7185 ("storage-location", "bucketNameWithVars", None), 7186 ("share-publicly", "sharedPublicly", False), 7187 ("upload-for-failed-jobs", "forFailedJobs", False), 7188 ("show-inline", "showInline", True), 7189 ("strip-prefix", "pathPrefix", ""), 7190 ("log-name", "logName", None), 7191 ] 7192 helpers.convert_mapping_to_xml( 7193 xml_element, properties, mapping, fail_required=True 7194 ) 7195 7196 if types.count("build-log") > 1: 7197 XML.SubElement( 7198 xml_element, 7199 "module", 7200 { 7201 "reference": "../../com.google.jenkins.plugins." 7202 "storage.StdoutUpload/module" 7203 }, 7204 ) 7205 else: 7206 XML.SubElement(xml_element, "module") 7207 7208 def classic(properties, upload_element, types): 7209 # Handle classic upload action 7210 7211 xml_element = XML.SubElement( 7212 upload_element, "com.google.jenkins." "plugins.storage.ClassicUpload" 7213 ) 7214 mapping = [ 7215 ("storage-location", "bucketNameWithVars", None), 7216 ("share-publicly", "sharedPublicly", False), 7217 ("upload-for-failed-jobs", "forFailedJobs", False), 7218 ("show-inline", "showInline", False), 7219 ("strip-prefix", "pathPrefix", ""), 7220 ("file-pattern", "sourceGlobWithVars", None), 7221 ] 7222 helpers.convert_mapping_to_xml( 7223 xml_element, properties, mapping, fail_required=True 7224 ) 7225 7226 if types.count("classic") > 1: 7227 XML.SubElement( 7228 xml_element, 7229 "module", 7230 { 7231 "reference": "../../com.google.jenkins.plugins." 7232 "storage.ClassicUpload/module" 7233 }, 7234 ) 7235 else: 7236 XML.SubElement(xml_element, "module") 7237 7238 uploader = XML.SubElement( 7239 xml_parent, 7240 "com.google.jenkins.plugins.storage." "GoogleCloudStorageUploader", 7241 {"plugin": "google-storage-plugin"}, 7242 ) 7243 7244 mapping = [("credentials-id", "credentialsId", None)] 7245 helpers.convert_mapping_to_xml(uploader, data, mapping, fail_required=True) 7246 7247 valid_upload_types = ["expiring-elements", "build-log", "classic"] 7248 types = [] 7249 7250 upload_element = XML.SubElement(uploader, "uploads") 7251 7252 uploads = data["uploads"] 7253 for upload in uploads: 7254 for upload_type, properties in upload.items(): 7255 types.append(upload_type) 7256 7257 if upload_type not in valid_upload_types: 7258 raise InvalidAttributeError("uploads", upload_type, valid_upload_types) 7259 else: 7260 locals()[upload_type.replace("-", "_")]( 7261 properties, upload_element, types 7262 ) 7263 7264 7265def flowdock(registry, xml_parent, data): 7266 """yaml: flowdock 7267 This plugin publishes job build results to a Flowdock flow. 7268 7269 Requires the Jenkins :jenkins-plugins:`Flowdock Plugin 7270 <jenkins-flowdock-plugin>`. 7271 7272 :arg str token: API token for the targeted flow. 7273 (required) 7274 :arg str tags: Comma-separated list of tags to include in message 7275 (default "") 7276 :arg bool chat-notification: Send chat notification when build fails 7277 (default true) 7278 :arg bool notify-success: Send notification on build success 7279 (default true) 7280 :arg bool notify-failure: Send notification on build failure 7281 (default true) 7282 :arg bool notify-fixed: Send notification when build is fixed 7283 (default true) 7284 :arg bool notify-unstable: Send notification when build is unstable 7285 (default false) 7286 :arg bool notify-aborted: Send notification when build was aborted 7287 (default false) 7288 :arg bool notify-notbuilt: Send notification when build did not occur 7289 (default false) 7290 7291 Example: 7292 7293 .. literalinclude:: /../../tests/publishers/fixtures/flowdock001.yaml 7294 :language: yaml 7295 7296 Full example: 7297 7298 .. literalinclude:: /../../tests/publishers/fixtures/flowdock002.yaml 7299 :language: yaml 7300 """ 7301 7302 def gen_notification_entry(data_item, default, text): 7303 e = XML.SubElement(nm, "entry") 7304 mapping = [ 7305 ("", "com.flowdock.jenkins.BuildResult", text), 7306 (data_item, "boolean", default), 7307 ] 7308 helpers.convert_mapping_to_xml(e, data, mapping, fail_required=True) 7309 7310 parent = XML.SubElement(xml_parent, "com.flowdock.jenkins.FlowdockNotifier") 7311 mapping = [ 7312 ("token", "flowToken", None), 7313 ("tags", "notificationTags", ""), 7314 ("chat-notification", "chatNotification", True), 7315 ("notify-success", "notifySuccess", True), 7316 ("notify-failure", "notifyFailure", True), 7317 ("notify-fixed", "notifyFixed", True), 7318 ("notify-unstable", "notifyUnstable", False), 7319 ("notify-aborted", "notifyAborted", False), 7320 ("notify-notbuilt", "notifyNotBuilt", False), 7321 ] 7322 helpers.convert_mapping_to_xml(parent, data, mapping, fail_required=True) 7323 7324 nm = XML.SubElement(parent, "notifyMap") 7325 7326 # notification entries 7327 gen_notification_entry("notify-success", True, "SUCCESS") 7328 gen_notification_entry("notify-failure", True, "FAILURE") 7329 gen_notification_entry("notify-fixed", True, "FIXED") 7330 gen_notification_entry("notify-unstable", False, "UNSTABLE") 7331 gen_notification_entry("notify-aborted", False, "ABORTED") 7332 gen_notification_entry("notify-notbuilt", False, "NOT_BUILT") 7333 7334 7335def clamav(registry, xml_parent, data): 7336 """yaml: clamav 7337 Check files with ClamAV, an open source antivirus engine. 7338 Requires the Jenkins :jenkins-plugins:`ClamAV Plugin <clamav>`. 7339 7340 :arg str includes: Comma separated list of files that should be scanned. 7341 Must be set for ClamAV to check for artifacts. (default '') 7342 :arg str excludes: Comma separated list of files that should be ignored 7343 (default '') 7344 7345 Full Example: 7346 7347 .. literalinclude:: /../../tests/publishers/fixtures/clamav-full.yaml 7348 :language: yaml 7349 7350 Minimal Example: 7351 7352 .. literalinclude:: /../../tests/publishers/fixtures/clamav-minimal.yaml 7353 :language: yaml 7354 """ 7355 clamav = XML.SubElement(xml_parent, "org.jenkinsci.plugins.clamav.ClamAvRecorder") 7356 clamav.set("plugin", "clamav") 7357 7358 mappings = [("includes", "includes", ""), ("excludes", "excludes", "")] 7359 helpers.convert_mapping_to_xml(clamav, data, mappings, fail_required=True) 7360 7361 7362def testselector(registry, xml_parent, data): 7363 """yaml: testselector 7364 This plugin allows you to choose specific tests you want to run. 7365 7366 Requires the Jenkins :jenkins-plugins:`Tests Selector Plugin 7367 <selected-tests-executor>`. 7368 7369 :arg str name: Environment variable in which selected tests are saved 7370 (required) 7371 :arg str description: Description 7372 (default "") 7373 :arg str properties-file: Contain all your tests 7374 (required) 7375 :arg str enable-field: Imply if the test is enabled or not 7376 (default "") 7377 :arg str groupby: Plugin will group the tests by 7378 (default "") 7379 :arg str field-sperator: Separate between the fields in the tests tree 7380 (default "") 7381 :arg str show-fields: Shown in the tests tree 7382 (default "") 7383 :arg str multiplicity-field: Number of times the test should run 7384 (default "") 7385 7386 Example: 7387 7388 .. literalinclude:: /../../tests/publishers/fixtures/testselector001.yaml 7389 :language: yaml 7390 """ 7391 7392 testselector = XML.SubElement( 7393 xml_parent, "il.ac.technion.jenkins.plugins" "TestExecuter" 7394 ) 7395 7396 mapping = [ 7397 ("name", "name", None), 7398 ("description", "description", ""), 7399 ("properties-file", "propertiesFilePath", None), 7400 ("enable-field", "enableField", ""), 7401 ("groupby", "groupBy", ""), 7402 ("field-separator", "fieldSeparator", ""), 7403 ("show-fields", "showFields", ""), 7404 ("multiplicity-field", "multiplicityField", ""), 7405 ] 7406 helpers.convert_mapping_to_xml(testselector, data, mapping, fail_required=True) 7407 7408 7409def cloudformation(registry, xml_parent, data): 7410 """yaml: cloudformation 7411 Create cloudformation stacks before running a build and optionally 7412 delete them at the end. Requires the Jenkins :jenkins-plugins:`AWS 7413 Cloudformation Plugin <jenkins-cloudformation-plugin>`. 7414 7415 :arg list create-stacks: List of stacks to create 7416 7417 :create-stacks attributes: 7418 * **arg str name** - The name of the stack (Required) 7419 * **arg str description** - Description of the stack (Optional) 7420 * **arg str recipe** - The cloudformation recipe file (Required) 7421 * **arg list parameters** - A list of key/value pairs, will be 7422 joined together into a comma separated string (Optional) 7423 * **arg int timeout** - Number of seconds to wait before giving up 7424 creating a stack (default 0) 7425 * **arg str access-key** - The Amazon API Access Key (Required) 7426 * **arg str secret-key** - The Amazon API Secret Key (Required) 7427 * **arg int sleep** - Number of seconds to wait before continuing 7428 to the next step (default 0) 7429 * **arg array region** - The region to run cloudformation in. 7430 (Required) 7431 7432 :region values: 7433 * **us-east-1** 7434 * **us-west-1** 7435 * **us-west-2** 7436 * **eu-central-1** 7437 * **eu-west-1** 7438 * **ap-southeast-1** 7439 * **ap-southeast-2** 7440 * **ap-northeast-1** 7441 * **sa-east-1** 7442 :arg list delete-stacks: List of stacks to delete 7443 7444 :delete-stacks attributes: 7445 * **arg list name** - The names of the stacks to delete (Required) 7446 * **arg str access-key** - The Amazon API Access Key (Required) 7447 * **arg str secret-key** - The Amazon API Secret Key (Required) 7448 * **arg bool prefix** - If selected the tear down process will look 7449 for the stack that Starts with the stack name with the oldest 7450 creation date and will delete it. (default false) 7451 * **arg array region** - The region to run cloudformation in. 7452 (Required) 7453 7454 :region values: 7455 * **us-east-1** 7456 * **us-west-1** 7457 * **us-west-2** 7458 * **eu-central-1** 7459 * **eu-west-1** 7460 * **ap-southeast-1** 7461 * **ap-southeast-2** 7462 * **ap-northeast-1** 7463 * **sa-east-1** 7464 7465 Example: 7466 7467 .. literalinclude:: /../../tests/publishers/fixtures/cloudformation.yaml 7468 :language: yaml 7469 """ 7470 region_dict = helpers.cloudformation_region_dict() 7471 stacks = helpers.cloudformation_init( 7472 xml_parent, data, "CloudFormationPostBuildNotifier" 7473 ) 7474 for stack in data.get("create-stacks", []): 7475 helpers.cloudformation_stack( 7476 xml_parent, stack, "PostBuildStackBean", stacks, region_dict 7477 ) 7478 delete_stacks = helpers.cloudformation_init( 7479 xml_parent, data, "CloudFormationNotifier" 7480 ) 7481 for delete_stack in data.get("delete-stacks", []): 7482 helpers.cloudformation_stack( 7483 xml_parent, delete_stack, "SimpleStackBean", delete_stacks, region_dict 7484 ) 7485 7486 7487def whitesource(registry, xml_parent, data): 7488 """yaml: whitesource 7489 This plugin brings automatic open source management to Jenkins users. 7490 7491 Requires the Jenkins :jenkins-plugins:`Whitesource Plugin 7492 <whitesource>`. 7493 7494 :arg str product-token: Product name or token to update (default '') 7495 :arg str version: Product version (default '') 7496 :arg str override-token: Override the api token from the global config 7497 (default '') 7498 :arg str project-token: Token uniquely identifying the project to update 7499 (default '') 7500 :arg list includes: list of libraries to include (default '[]') 7501 :arg list excludes: list of libraries to exclude (default '[]') 7502 :arg str policies: Whether to override the global settings. Valid values: 7503 global, enable, disable (default 'global') 7504 :arg str requester-email: Email of the WhiteSource user that requests to 7505 update WhiteSource (>=1.5.1) (default '') 7506 7507 Full Example: 7508 7509 .. literalinclude:: /../../tests/publishers/fixtures/whitesource-full.yaml 7510 :language: yaml 7511 7512 Minimal Example: 7513 7514 .. literalinclude:: 7515 /../../tests/publishers/fixtures/whitesource-minimal.yaml 7516 :language: yaml 7517 """ 7518 whitesource = XML.SubElement( 7519 xml_parent, "org.whitesource.jenkins." "WhiteSourcePublisher" 7520 ) 7521 whitesource.set("plugin", "whitesource") 7522 policies = ["global", "enable", "disable"] 7523 7524 mappings = [ 7525 ("policies", "jobCheckPolicies", "global", policies), 7526 ("override-token", "jobApiToken", ""), 7527 ("product-token", "product", ""), 7528 ("version", "productVersion", ""), 7529 ("project-token", "projectToken", ""), 7530 ("requester-email", "requesterEmail", ""), 7531 ] 7532 helpers.convert_mapping_to_xml(whitesource, data, mappings, fail_required=True) 7533 7534 XML.SubElement(whitesource, "libIncludes").text = " ".join(data.get("includes", [])) 7535 XML.SubElement(whitesource, "libExcludes").text = " ".join(data.get("excludes", [])) 7536 XML.SubElement(whitesource, "ignorePomModules").text = "false" 7537 7538 7539def hipchat(registry, xml_parent, data): 7540 """yaml: hipchat 7541 Publisher that sends hipchat notifications on job events 7542 Requires the Jenkins :jenkins-plugins:`Hipchat Plugin 7543 <hipchat>` version >=1.9 7544 7545 Please see documentation for older plugin version 7546 https://jenkins-job-builder.readthedocs.io/en/latest/hipchat.html 7547 7548 :arg str token: This will override the default auth token (optional) 7549 :arg list rooms: list of HipChat rooms to post messages to, overrides 7550 global default (optional) 7551 :arg bool notify-start: post messages about build start event 7552 (default false) 7553 :arg bool notify-success: post messages about successful build event 7554 (default false) 7555 :arg bool notify-aborted: post messages about aborted build event 7556 (default false) 7557 :arg bool notify-not-built: post messages about build set to NOT_BUILT. 7558 This status code is used in a multi-stage build where a problem in 7559 earlier stage prevented later stages from building. (default false) 7560 :arg bool notify-unstable: post messages about unstable build event 7561 (default false) 7562 :arg bool notify-failure: post messages about build failure event 7563 (default false) 7564 :arg bool notify-back-to-normal: post messages about build being back to 7565 normal after being unstable or failed (default false) 7566 :arg str start-message: This will override the default start message 7567 (optional) 7568 :arg str complete-message: This will override the default complete message 7569 (optional) 7570 7571 Example: 7572 7573 .. literalinclude:: /../../tests/publishers/fixtures/hipchat001.yaml 7574 :language: yaml 7575 """ 7576 hipchat = XML.SubElement(xml_parent, "jenkins.plugins.hipchat.HipChatNotifier") 7577 XML.SubElement(hipchat, "token").text = str(data.get("token", "")) 7578 7579 if "rooms" in data: 7580 XML.SubElement(hipchat, "room").text = str(",".join(data["rooms"])) 7581 7582 mapping = [ 7583 ("notify-start", "startNotification", False), 7584 ("notify-success", "notifySuccess", False), 7585 ("notify-aborted", "notifyAborted", False), 7586 ("notify-not-built", "notifyNotBuilt", False), 7587 ("notify-unstable", "notifyUnstable", False), 7588 ("notify-failure", "notifyFailure", False), 7589 ("notify-back-to-normal", "notifyBackToNormal", False), 7590 ("start-message", "startJobMessage", None), 7591 ("complete-message", "completeJobMessage", None), 7592 ] 7593 helpers.convert_mapping_to_xml(hipchat, data, mapping, fail_required=False) 7594 7595 7596def slack(registry, xml_parent, data): 7597 """yaml: slack 7598 Publisher that sends slack notifications on job events. 7599 7600 Requires the Jenkins :jenkins-plugins:`Slack Plugin <slack>` 7601 7602 When using Slack Plugin version < 2.0, Slack Plugin itself requires a 7603 publisher as well as properties please note that you have to create those 7604 too. When using Slack Plugin version >= 2.0, you should only configure the 7605 publisher. 7606 7607 For backward compatibility, the publisher needs to query version of the 7608 Slack Plugin. Hence the ``query_plugins_info`` parameter shouldn't be set 7609 to ``False`` in the ``jenkins`` section of the configuration file. 7610 7611 :arg str team-domain: Your team's domain at slack. (default '') 7612 :arg str auth-token: The integration token to be used when sending 7613 notifications. (default '') 7614 :arg str auth-token-id: Allows credentials to be stored in Jenkins. 7615 (default '') 7616 :arg str build-server-url: Specify the URL for your server installation. 7617 (default '/') 7618 :arg str room: A comma separated list of rooms / channels to post the 7619 notifications to. (default '') 7620 :arg bool notify-start: Send notification when the job starts (>=2.0). 7621 (default false) 7622 :arg bool notify-success: Send notification on success (>=2.0). 7623 (default false) 7624 :arg bool notify-aborted: Send notification when job is aborted (>=2.0). 7625 (default false) 7626 :arg bool notify-not-built: Send notification when job set to NOT_BUILT 7627 status (>=2.0). (default false) 7628 :arg bool notify-unstable: Send notification when job becomes unstable 7629 (>=2.0). (default false) 7630 :arg bool notify-failure: Send notification when job fails for the first 7631 time (previous build was a success) (>=2.0). (default false) 7632 :arg bool notify-every-failure: Send notification every time a job fails 7633 (>=2.23). (default false) 7634 :arg bool notify-back-to-normal: Send notification when job is succeeding 7635 again after being unstable or failed (>=2.0). (default false) 7636 :arg bool notify-repeated-failure: Send notification when job fails 7637 successively (previous build was also a failure) (>=2.0). 7638 (default false) 7639 :arg bool notify-regression: Send notification when number of failed tests 7640 increased or the failed tests are different than previous build 7641 (>=2.2). (default false) 7642 :arg bool include-failed-tests: includes all failed tests when some tests 7643 failed. does nothing if no failed tests were found (>=2.2). 7644 (default false) 7645 :arg bool include-test-summary: Include the test summary (>=2.0). 7646 (default false) 7647 :arg str commit-info-choice: What commit information to include into 7648 notification message, "NONE" includes nothing about commits, "AUTHORS" 7649 includes commit list with authors only, and "AUTHORS_AND_TITLES" 7650 includes commit list with authors and titles (>=2.0). (default "NONE") 7651 :arg bool include-custom-message: Include a custom message into the 7652 notification (>=2.0). (default false) 7653 :arg str custom-message: Custom message to be included for all statuses 7654 (>=2.0). (default '') 7655 :arg str custom-message-success: Custom message for succesful builds 7656 (>=2.10). (default '') 7657 :arg str custom-message-aborted: Custom message for aborted builds 7658 (>=2.10). (default '') 7659 :arg str custom-message-not-built: Custom message for not-built 7660 (>=2.10). (default '') 7661 :arg str custom-message-unstable: Custom message for unstable builds 7662 (>=2.10). (default '') 7663 :arg str custom-message-failure: Custom message for failed builds 7664 (>=2.10). (default '') 7665 :arg str auth-token-credential-id: The ID for the integration token from 7666 the Credentials plugin to be used to send notifications to Slack. 7667 (>=2.1) (default '') 7668 :arg bool bot-user: This option indicates the token belongs to a bot user 7669 in Slack. (>=2.2) (default False) 7670 :arg str base-url: Your Slack compatible Base URL. ``bot-user`` is not 7671 supported with Base URL. (>=2.2) (default '') 7672 7673 Example (version < 2.0): 7674 7675 .. literalinclude:: 7676 /../../tests/publishers/fixtures/slack001.yaml 7677 :language: yaml 7678 7679 Minimal example (version >= 2.0): 7680 7681 .. literalinclude:: 7682 /../../tests/publishers/fixtures/slack003.yaml 7683 :language: yaml 7684 7685 Full example (version >= 2.10): 7686 7687 .. literalinclude:: 7688 /../../tests/publishers/fixtures/slack005.yaml 7689 :language: yaml 7690 7691 """ 7692 7693 def _add_xml(elem, name, value=""): 7694 if isinstance(value, bool): 7695 value = str(value).lower() 7696 XML.SubElement(elem, name).text = value 7697 7698 logger = logging.getLogger(__name__) 7699 7700 plugin_info = registry.get_plugin_info("Slack Notification Plugin") 7701 # Note: Assume latest version of plugin is preferred config format 7702 plugin_ver = pkg_resources.parse_version( 7703 plugin_info.get("version", str(sys.maxsize)) 7704 ) 7705 7706 mapping = ( 7707 ("team-domain", "teamDomain", ""), 7708 ("auth-token", "authToken", ""), 7709 ("auth-token-id", "authTokenCredentialId", ""), 7710 ("build-server-url", "buildServerUrl", "/"), 7711 ("room", "room", ""), 7712 ) 7713 mapping_20 = ( 7714 ("notify-start", "startNotification", False), 7715 ("notify-success", "notifySuccess", False), 7716 ("notify-aborted", "notifyAborted", False), 7717 ("notify-not-built", "notifyNotBuilt", False), 7718 ("notify-unstable", "notifyUnstable", False), 7719 ("notify-failure", "notifyFailure", False), 7720 ("notify-every-failure", "notifyEveryFailure", False), 7721 ("notify-back-to-normal", "notifyBackToNormal", False), 7722 ("notify-regression", "notifyRegression", False), 7723 ("notify-repeated-failure", "notifyRepeatedFailure", False), 7724 ("include-test-summary", "includeTestSummary", False), 7725 ("include-failed-tests", "includeFailedTests", False), 7726 ("commit-info-choice", "commitInfoChoice", "NONE"), 7727 ("include-custom-message", "includeCustomMessage", False), 7728 ("custom-message", "customMessage", ""), 7729 ("custom-message-success", "customMessageSuccess", ""), 7730 ("custom-message-aborted", "customMessageAborted", ""), 7731 ("custom-message-not-built", "customMessageNotBuilt", ""), 7732 ("custom-message-unstable", "customMessageUnstable", ""), 7733 ("custom-message-failure", "customMessageFailure", ""), 7734 ("auth-token-credential-id", "authTokenCredentialId", ""), 7735 ("bot-user", "botUser", False), 7736 ("base-url", "baseUrl", ""), 7737 ) 7738 7739 commit_info_choices = ["NONE", "AUTHORS", "AUTHORS_AND_TITLES"] 7740 7741 slack = XML.SubElement(xml_parent, "jenkins.plugins.slack.SlackNotifier") 7742 7743 if plugin_ver >= pkg_resources.parse_version("2.0"): 7744 mapping = mapping + mapping_20 7745 7746 if plugin_ver < pkg_resources.parse_version("2.0"): 7747 for yaml_name, _, default_value in mapping: 7748 # All arguments that don't have a default value are mandatory for 7749 # the plugin to work as intended. 7750 if not data.get(yaml_name, default_value): 7751 raise MissingAttributeError(yaml_name) 7752 7753 for yaml_name, _, _ in mapping_20: 7754 if yaml_name in data: 7755 logger.warning( 7756 "'%s' is invalid with plugin version < 2.0, ignored", yaml_name 7757 ) 7758 7759 for yaml_name, xml_name, default_value in mapping: 7760 value = data.get(yaml_name, default_value) 7761 7762 # 'commit-info-choice' is enumerated type 7763 if yaml_name == "commit-info-choice" and value not in commit_info_choices: 7764 raise InvalidAttributeError(yaml_name, value, commit_info_choices) 7765 7766 # Ensure that custom-message is set when include-custom-message is set 7767 # to true. 7768 if ( 7769 yaml_name == "include-custom-message" 7770 and data is False 7771 and not data.get("custom-message", "") 7772 ): 7773 raise MissingAttributeError("custom-message") 7774 7775 _add_xml(slack, xml_name, value) 7776 7777 7778def phabricator(registry, xml_parent, data): 7779 """yaml: phabricator 7780 Integrate with `Phabricator <https://www.phacility.com/>`_ 7781 7782 Requires the Jenkins :jenkins-plugins:`Phabricator Plugin 7783 <phabricator-plugin>`. 7784 7785 :arg bool comment-on-success: Post a *comment* when the build 7786 succeeds. (optional) 7787 :arg bool uberalls-enabled: Integrate with uberalls. (optional) 7788 :arg str comment-file: Include contents of given file if 7789 commenting is enabled. (optional) 7790 :arg int comment-size: Maximum comment character length. (optional) 7791 :arg bool comment-with-console-link-on-failure: Post a *comment* 7792 when the build fails. (optional) 7793 7794 Example: 7795 7796 .. literalinclude:: 7797 /../../tests/publishers/fixtures/phabricator001.yaml 7798 :language: yaml 7799 """ 7800 7801 root = XML.SubElement( 7802 xml_parent, "com.uber.jenkins.phabricator.PhabricatorNotifier" 7803 ) 7804 mapping = [ 7805 ("comment-on-success", "commentOnSuccess", None), 7806 ("uberalls-enabled", "uberallsEnabled", None), 7807 ("comment-file", "commentFile", None), 7808 ("comment-size", "commentSize", None), 7809 ( 7810 "comment-with-console-link-on-failure", 7811 "commentWithConsoleLinkOnFailure", 7812 None, 7813 ), 7814 ] 7815 helpers.convert_mapping_to_xml(root, data, mapping, fail_required=False) 7816 7817 7818def jms_messaging(registry, xml_parent, data): 7819 """yaml: jms-messaging 7820 The JMS Messaging Plugin provides the following functionality: 7821 - A build trigger to submit jenkins jobs upon receipt 7822 of a matching message. 7823 - A builder that may be used to submit a message to the topic 7824 upon the completion of a job 7825 - A post-build action that may be used to submit a message to the topic 7826 upon the completion of a job 7827 7828 7829 JMS Messaging provider types supported: 7830 - ActiveMQ 7831 - FedMsg 7832 7833 Requires the Jenkins :jenkins-plugins:`JMS Messaging Plugin 7834 Pipeline Plugin <jms-messaging>`. 7835 7836 :arg str override-topic: If you need to override the default topic. 7837 (default '') 7838 :arg str provider-name: Name of message provider setup in the 7839 global config. (default '') 7840 :arg str msg-type: A message type 7841 (default 'CodeQualityChecksDone') 7842 :arg str msg-props: Message header to publish. (default '') 7843 :arg str msg-content: Message body to publish. (default '') 7844 7845 7846 Full Example: 7847 7848 .. literalinclude:: 7849 ../../tests/publishers/fixtures/jms-messaging-full.yaml 7850 :language: yaml 7851 7852 Minimal Example: 7853 7854 .. literalinclude:: 7855 ../../tests/publishers/fixtures/jms-messaging-minimal.yaml 7856 :language: yaml 7857 """ 7858 helpers.jms_messaging_common( 7859 xml_parent, "com.redhat.jenkins.plugins.ci." "CIMessageNotifier", data 7860 ) 7861 7862 7863def openshift_build_canceller(registry, xml_parent, data): 7864 r"""yaml: openshift-build-canceller 7865 This action is intended to provide cleanup for a Jenkins job which failed 7866 because a build is hung (instead of terminating with a failure code); 7867 this step will allow you to perform the equivalent of a oc cancel-build 7868 for the provided build config; any builds under that build config which 7869 are not previously terminated (either successfully or unsuccessfully) 7870 or cancelled will be cancelled. 7871 7872 Requires the Jenkins :jenkins-plugins:`OpenShift Pipeline Plugin 7873 <openshift-pipeline>`. 7874 7875 :arg str api-url: this would be the value you specify if you leverage the 7876 --server option on the OpenShift `oc` command. 7877 (default '\https://openshift.default.svc.cluster.local') 7878 :arg str bld-cfg: The value here should be whatever was the output 7879 form `oc project` when you created the BuildConfig you 7880 want to run a Build on (default 'frontend') 7881 :arg str namespace: If you run `oc get bc` for the project listed in 7882 "namespace", that is the value you want to put here. (default 'test') 7883 :arg str auth-token: The value here is what you supply with the --token 7884 option when invoking the OpenShift `oc` command. (default '') 7885 :arg bool verbose: This flag is the toggle for 7886 turning on or off detailed logging in this plug-in. (default false) 7887 7888 Full Example: 7889 7890 .. literalinclude:: 7891 ../../tests/publishers/fixtures/openshift-build-canceller001.yaml 7892 :language: yaml 7893 7894 Minimal Example: 7895 7896 .. literalinclude:: 7897 ../../tests/publishers/fixtures/openshift-build-canceller002.yaml 7898 :language: yaml 7899 """ 7900 7901 osb = XML.SubElement( 7902 xml_parent, "com.openshift.jenkins.plugins.pipeline." "OpenShiftBuildCanceller" 7903 ) 7904 mapping = [ 7905 # option, xml name, default value 7906 ("api-url", "apiURL", "https://openshift.default.svc.cluster.local"), 7907 ("bld-cfg", "bldCfg", "frontend"), 7908 ("namespace", "namespace", "test"), 7909 ("auth-token", "authToken", ""), 7910 ("verbose", "verbose", False), 7911 ] 7912 helpers.convert_mapping_to_xml(osb, data, mapping, fail_required=True) 7913 7914 7915def openshift_deploy_canceller(registry, xml_parent, data): 7916 r"""yaml: openshift-deploy-canceller 7917 This action is intended to provide cleanup for any OpenShift deployments 7918 left running when the Job completes; this step will allow you to perform 7919 the equivalent of a oc deploy --cancel for the provided deployment config. 7920 7921 Requires the Jenkins :jenkins-plugins:`OpenShift Pipeline Plugin 7922 <openshift-pipeline>`. 7923 7924 :arg str api-url: this would be the value you specify if you leverage the 7925 --server option on the OpenShift `oc` command. 7926 (default '\https://openshift.default.svc.cluster.local') 7927 :arg str dep-cfg: The value here should be whatever was the output 7928 form `oc project` when you created the BuildConfig you want to run a 7929 Build on (default frontend) 7930 :arg str namespace: If you run `oc get bc` for the project listed in 7931 "namespace", that is the value you want to put here. (default 'test') 7932 :arg str auth-token: The value here is what you supply with the --token 7933 option when invoking the OpenShift `oc` command. (default '') 7934 :arg bool verbose: This flag is the toggle for 7935 turning on or off detailed logging in this plug-in. (default false) 7936 7937 Full Example: 7938 7939 .. literalinclude:: 7940 ../../tests/publishers/fixtures/openshift-deploy-canceller001.yaml 7941 :language: yaml 7942 7943 Minimal Example: 7944 7945 .. literalinclude:: 7946 ../../tests/publishers/fixtures/openshift-deploy-canceller002.yaml 7947 :language: yaml 7948 """ 7949 7950 osb = XML.SubElement( 7951 xml_parent, "com.openshift.jenkins.plugins.pipeline." "OpenShiftDeployCanceller" 7952 ) 7953 mapping = [ 7954 # option, xml name, default value 7955 ("api-url", "apiURL", "https://openshift.default.svc.cluster.local"), 7956 ("dep-cfg", "depCfg", "frontend"), 7957 ("namespace", "namespace", "test"), 7958 ("auth-token", "authToken", ""), 7959 ("verbose", "verbose", False), 7960 ] 7961 helpers.convert_mapping_to_xml(osb, data, mapping, fail_required=True) 7962 7963 7964def github_pull_request_merge(registry, xml_parent, data): 7965 """yaml: github-pull-request-merge 7966 This action merges the pull request that triggered the build (see the 7967 github pull request trigger) 7968 7969 Requires the Jenkins :jenkins-plugins:`GitHub pull request builder plugin 7970 <ghprb>`. 7971 7972 7973 :arg bool only-admins-merge: if `true` only administrators can merge the 7974 pull request, (default false) 7975 :arg bool disallow-own-code: if `true` will allow merging your own pull 7976 requests, in opposite to needing someone else to trigger the merge. 7977 (default false) 7978 :arg str merge-comment: Comment to set on the merge commit (default '') 7979 :arg bool fail-on-non-merge: fail the job if the merge was unsuccessful 7980 (default false) 7981 :arg bool delete-on-merge: Delete the branch of the pull request on 7982 successful merge (default false) 7983 7984 Full Example: 7985 7986 .. literalinclude:: 7987 ../../tests/publishers/fixtures/github-pull-request-merge001.yaml 7988 :language: yaml 7989 7990 Minimal Example: 7991 7992 .. literalinclude:: 7993 ../../tests/publishers/fixtures/github-pull-request-merge002.yaml 7994 :language: yaml 7995 """ 7996 7997 osb = XML.SubElement( 7998 xml_parent, "org.jenkinsci.plugins.ghprb.GhprbPullRequestMerge" 7999 ) 8000 mapping = [ 8001 # option, xml name, default value 8002 ("only-admins-merge", "onlyAdminsMerge", "false"), 8003 ("disallow-own-code", "disallowOwnCode", "false"), 8004 ("merge-comment", "mergeComment", ""), 8005 ("fail-on-non-merge", "failOnNonMerge", "false"), 8006 ("delete-on-merge", "deleteOnMerge", "false"), 8007 ] 8008 8009 helpers.convert_mapping_to_xml(osb, data, mapping, fail_required=True) 8010 8011 8012def chuck_norris(registry, xml_parent, data): 8013 """yaml: chuck-norris 8014 Displays a picture of Chuck Norris (instead of Jenkins the butler) and a 8015 random Chuck Norris 'The Programmer' fact on each build page. 8016 8017 Requires the Jenkins :jenkins-plugins:`ChuckNorris Plugin <chucknorris>`. 8018 8019 Example: 8020 8021 .. literalinclude:: /../../tests/publishers/fixtures/chuck-norris.yaml 8022 :language: yaml 8023 """ 8024 8025 chuck = XML.SubElement( 8026 xml_parent, "hudson.plugins.chucknorris.CordellWalkerRecorder" 8027 ) 8028 return XML.SubElement(chuck, "factGenerator") 8029 8030 8031def publishers_from(registry, xml_parent, data): 8032 """yaml: publishers-from 8033 Use publishers from another project. 8034 Requires the Jenkins :jenkins-plugins:`Template Project Plugin 8035 <template-project>`. 8036 8037 :arg str project-name: The name of the other project. 8038 8039 Example: 8040 8041 .. literalinclude:: ../../tests/publishers/fixtures/publishers-from.yaml 8042 :language: yaml 8043 """ 8044 pbs = XML.SubElement(xml_parent, "hudson.plugins.templateproject.ProxyPublisher") 8045 mapping = [("project-name", "projectName", None)] 8046 helpers.convert_mapping_to_xml(pbs, data, mapping, fail_required=True) 8047 8048 8049def tasks(registry, xml_parent, data): 8050 """yaml: tasks 8051 8052 Scans the workspace files for open tasks and generates a trend report. 8053 8054 Requires the Jenkins Task Scanner Plugin 8055 (https://github.com/jenkinsci/tasks-plugin). 8056 8057 :arg list files-to-scan: Fileset includes setting that specifies the 8058 workspace files to scan for tasks, such as ``**/*.java``. Basedir of 8059 the fileset is the workspace root. (default '``**/*.java``') 8060 :arg list files-to-exclude: Fileset excludes setting that specifies the 8061 workspace files to exclude scanning for tasks, such as library source 8062 files. Basedir of the fileset is the workspace root. (default '') 8063 :arg list tasks-tags-high: Tags identifiers for high priority that should 8064 be looked for in the workspace files. Only alphanumerical characters 8065 are allowed as tags as these strings are pasted into a regular 8066 expression. (default '') 8067 :arg list tasks-tags-normal: Tags identifiers for normal priority that 8068 should be looked for in the workspace files. Only alphanumerical 8069 characters are allowed as tags as these strings are pasted into a 8070 regular expression. (default '') 8071 :arg list tasks-tags-low: Tags identifiers for low priority that should be 8072 looked for in the workspace files. Only alphanumerical characters are 8073 allowed as tags as these strings are pasted into a regular expression. 8074 (default '') 8075 :arg bool ignore-case: Ignore the case of the the tag identifiers. (default 8076 false) 8077 :arg bool regular-expression: Treat the tag identifiers as regular 8078 expression. Note that the regular expression must contain two capturing 8079 groups, the first one is interpreted as tag name, the second one as 8080 message. An example of such a regular expression would be 8081 ``^.*(TODO(?:[0-9]*))(.*)$``. (default false) 8082 :arg bool run-always: By default, this plug-in runs only for stable or 8083 unstable builds, but not for failed builds. If this plug-in should run 8084 even for failed builds then activate this check box. (default false) 8085 :arg bool detect-module: Determines if Ant or Maven modules should be 8086 detected for all files that contain warnings. Activating this option 8087 may increase your build time since the detector scans the whole 8088 workspace for ``build.xml`` or ``pom.xml`` files in order to assign the 8089 correct module names. (default false) 8090 :arg int health-thresholds-100: Configure the upper thresholds for the 8091 build health. If left empty then no health report is created. If the 8092 actual number of warnings is between the provided thresholds then the 8093 build health is interpolated. (default '') 8094 :arg str health-thresholds-0: Configure the lower thresholds for the build 8095 health. If left empty then no health report is created. If the actual 8096 number of warnings is between the provided thresholds then the build 8097 health is interpolated. (default '') 8098 :arg str health-priorities: Determines which warning priorities should be 8099 considered when evaluating the build health. Can be ``high`` (only 8100 priority high), ``normal`` (priorities high and normal) or ``low`` (all 8101 priorities). (default 'low') 8102 :arg dict status-thresholds: Configure the build status and health. If the 8103 number of total or new warnings is greater than one of these thresholds 8104 then a build is considered as unstable or failed, respectively. I.e., a 8105 value of 0 means that the build status is changed if there is at least 8106 one warning found. Leave this field empty if the state of the build 8107 should not depend on the number of warnings. Note that for new 8108 warnings, you need to enable the next option 8109 (``compute-new-warnings``). 8110 8111 :status-thresholds: 8112 8113 * **unstable-total-all** (`str`): Total number for all priorities, 8114 unstable threshold (default '') 8115 * **unstable-total-high** (`str`): Total number for high priority, 8116 unstable threshold (default '') 8117 * **unstable-total-normal** (`str`): Total number for normal 8118 priority, unstable threshold (default '') 8119 * **unstable-total-low** (`str`): Total number for low priority, 8120 unstable threshold (default '') 8121 * **failed-total-all** (`str`): Total number for all priorities, 8122 failure threshold (default '') 8123 * **failed-total-high** (`str`): Total number for high priority, 8124 failure threshold (default '') 8125 * **failed-total-normal** (`str`): Total number for normal 8126 priority, failure threshold (default '') 8127 * **failed-total-low** (`str`): Total number for low priority, 8128 failure threshold (default '') 8129 * **unstable-new-all** (`str`): New number for all priorities, 8130 unstable threshold (default '') 8131 * **unstable-new-high** (`str`): New number for high priority, 8132 unstable threshold (default '') 8133 * **unstable-new-normal** (`str`): New number for normal priority, 8134 unstable threshold (default '') 8135 * **unstable-new-low** (`str`): New number for low priority, 8136 unstable threshold (default '') 8137 * **failed-new-all** (`str`): New number for all priorities, 8138 failure threshold (default '') 8139 * **failed-new-high** (`str`): New number for high priority, 8140 failure threshold (default '') 8141 * **failed-new-normal** (`str`): New number for normal priority, 8142 failure threshold (default '') 8143 * **failed-new-low** (`str`): New number for low priority, failure 8144 threshold (default '') 8145 8146 :arg bool compute-new-warnings: Compute new warnings (based on the last 8147 successful build unless another reference build is chosen below). 8148 (default false) 8149 :arg bool use-delta: If set the number of new warnings is computed by 8150 subtracting the total number of warnings of the reference build from 8151 the total number of warnings of the current build. This may lead to 8152 wrong results if you have both fixed and new warnings in a build. If 8153 unset the number of new warnings is computed by a more sophisticated 8154 algorithm: instead of using totals an asymmetric set difference of the 8155 warnings in the current build and the warnings in the reference build 8156 is used. This will find all new warnings even if the number of total 8157 warnings has decreased. Note that sometimes false positives will be 8158 reported due to minor changes in a warning (e.g. refactoring of 8159 variables or method names). It is recommended to uncheck this option in 8160 order to get the most accurate results for new warnings. Depends on 8161 ``compute-new-warnings`` option. (default false) 8162 :arg bool use-prev-build-as-ref: If set the number of new warnings will 8163 always be computed based on the previous build, even if that build is 8164 unstable (due to a violated warning threshold). Otherwise the last 8165 build that did not violate any given threshold will be used as 8166 reference. It is recommended to uncheck this option if the plug-in 8167 should ensure that all new warnings will be finally fixed in subsequent 8168 builds. Depends on ``compute-new-warnings`` option. (default false) 8169 :arg bool only-use-stable-as-ref: Use the last stable build as the 8170 reference to compute the number of new warnings against. This allows 8171 you to ignore interim unstable builds for which the number of warnings 8172 decreased. Note that the last stable build is evaluated only by 8173 inspecting the unit test failures. The static analysis results are not 8174 considered. Depends on ``compute-new-warnings`` option. (default false) 8175 :arg str default-encoding: Default encoding when parsing or showing files. 8176 Leave this field empty to use the default encoding of the platform. 8177 (default '') 8178 8179 Minimal Example: 8180 8181 .. literalinclude:: /../../tests/publishers/fixtures/tasks-minimal.yaml 8182 :language: yaml 8183 8184 Full Example: 8185 8186 .. literalinclude:: /../../tests/publishers/fixtures/tasks-full.yaml 8187 :language: yaml 8188 """ 8189 8190 root = XML.SubElement(xml_parent, "hudson.plugins.tasks.TasksPublisher") 8191 root.set("plugin", "tasks") 8192 8193 if "files-to-scan" in data: 8194 XML.SubElement(root, "pattern").text = str(",".join(data["files-to-scan"])) 8195 8196 if "files-to-exclude" in data: 8197 XML.SubElement(root, "excludePattern").text = str( 8198 ",".join(data["files-to-exclude"]) 8199 ) 8200 8201 for prio in ["high", "normal", "low"]: 8202 if "tasks-tags-" + prio in data: 8203 XML.SubElement(root, prio).text = str(",".join(data["tasks-tags-" + prio])) 8204 8205 # on the UI, we can see compute-new-warnings but we need the opposite (XML) 8206 if "compute-new-warnings" in data and data["compute-new-warnings"]: 8207 XML.SubElement(root, "dontComputeNew").text = "false" 8208 else: 8209 XML.SubElement(root, "dontComputeNew").text = "true" 8210 8211 # Two parameters we cannot modify from the UI 8212 XML.SubElement(root, "pluginName").text = "[TASKS] " 8213 XML.SubElement(root, "doNotResolveRelativePaths").text = "false" 8214 8215 mappings = [ 8216 ("ignore-case", "ignoreCase", False), 8217 ("regular-expression", "asRegexp", False), 8218 ("run-always", "canRunOnFailed", False), 8219 ("detect-module", "shouldDetectModules", False), 8220 ("health-thresholds-100", "healthy", ""), 8221 ("health-thresholds-0", "unHealthy", ""), 8222 ("health-priorities", "thresholdLimit", "low"), 8223 ("use-delta", "useDeltaValues", False), 8224 ("use-prev-build-as-ref", "usePreviousBuildAsReference", False), 8225 ("only-use-stable-as-ref", "useStableBuildAsReference", False), 8226 ("default-encoding", "defaultEncoding", ""), 8227 ] 8228 helpers.convert_mapping_to_xml(root, data, mappings, fail_required=True) 8229 8230 thrsh_xml = XML.SubElement(root, "thresholds") 8231 thrsh_xml.set("plugin", "analysis-core") 8232 thrsh_data = data.get("status-thresholds", {}) 8233 thrsh_mappings = [ 8234 ("unstable-total-all", "unstableTotalAll", ""), 8235 ("unstable-total-high", "unstableTotalHigh", ""), 8236 ("unstable-total-normal", "unstableTotalNormal", ""), 8237 ("unstable-total-low", "unstableTotalLow", ""), 8238 ("unstable-new-all", "unstableNewAll", ""), 8239 ("unstable-new-high", "unstableNewHigh", ""), 8240 ("unstable-new-normal", "unstableNewNormal", ""), 8241 ("unstable-new-low", "unstableNewLow", ""), 8242 ("failed-total-all", "failedTotalAll", ""), 8243 ("failed-total-high", "failedTotalHigh", ""), 8244 ("failed-total-normal", "failedTotalNormal", ""), 8245 ("failed-total-low", "failedTotalLow", ""), 8246 ("failed-new-all", "failedNewAll", ""), 8247 ("failed-new-high", "failedNewHigh", ""), 8248 ("failed-new-normal", "failedNewNormal", ""), 8249 ("failed-new-low", "failedNewLow", ""), 8250 ] 8251 helpers.convert_mapping_to_xml( 8252 thrsh_xml, thrsh_data, thrsh_mappings, fail_required=True 8253 ) 8254 8255 8256def packer(registry, xml_parent, data): 8257 """yaml: packer 8258 This plugin allows for a job to publish an image generated Packer 8259 Requires the Jenkins :jenkins-plugins:`Packer Plugin <packer>`. 8260 8261 :arg str name: Name of the packer installation (required) 8262 :arg str json-template: Path to a Packer JSON template file (default '') 8263 :arg str json-template-text: Text of Packer JSON template (default '') 8264 :arg str add-params: Specify which additional parameters 8265 to pass to packer (default '') 8266 :arg bool use-debug: adds -debug argument when packer executes 8267 (default false) 8268 :arg str change-dir: If set, the current directory will be changed 8269 to this before starting packer (default '') 8270 :arg str template-mode: Packer template option used (default global) 8271 8272 :template-mode values: 8273 * **global** 8274 * **file** 8275 * **text** 8276 :arg list file-entries: File entries for the packer 8277 configuration (default []) 8278 :arg str variable-name: Variable name for a file to used in the 8279 configuration JSON (default '') 8280 :arg str contents: File contents of the configuration JSON (default '') 8281 8282 Minimal Example: 8283 8284 .. literalinclude:: 8285 /../../tests/publishers/fixtures/packer-minimal.yaml 8286 :language: yaml 8287 8288 Full Example: 8289 8290 .. literalinclude:: 8291 /../../tests/publishers/fixtures/packer-full.yaml 8292 :language: yaml 8293 """ 8294 8295 root = XML.SubElement( 8296 xml_parent, "biz.neustar.jenkins.plugins.packer.PackerPublisher" 8297 ) 8298 8299 template_valid_types = ["global", "file", "text"] 8300 mapping = [ 8301 ("name", "name", None), 8302 ("json-template", "jsonTemplate", ""), 8303 ("json-template-text", "jsonTemplateText", ""), 8304 ("add-params", "params", ""), 8305 ("use-debug", "useDebug", False), 8306 ("change-dir", "changeDir", ""), 8307 ("template-mode", "templateMode", "global", template_valid_types), 8308 ] 8309 helpers.convert_mapping_to_xml(root, data, mapping, fail_required=True) 8310 8311 format_dict = { 8312 "packer-file-entry": "biz.neustar.jenkins.plugins.packer.PackerFileEntry" 8313 } 8314 if "file-entries" in data: 8315 file_entries_tag = XML.SubElement(root, "fileEntries") 8316 for file_entries in data["file-entries"]: 8317 for file, params in file_entries.items(): 8318 packer_file_entry_tag = XML.SubElement( 8319 file_entries_tag, format_dict.get("packer-file-entry") 8320 ) 8321 XML.SubElement(packer_file_entry_tag, "varFileName").text = params.get( 8322 "variable-name", "" 8323 ) 8324 XML.SubElement(packer_file_entry_tag, "contents").text = params.get( 8325 "contents", "" 8326 ) 8327 8328 8329class Publishers(jenkins_jobs.modules.base.Base): 8330 sequence = 70 8331 8332 component_type = "publisher" 8333 component_list_type = "publishers" 8334 8335 def gen_xml(self, xml_parent, data): 8336 if data.get("project-type", "freestyle") == "pipeline": 8337 logger.debug("Publishers skipped for Pipeline job") 8338 return 8339 8340 publishers = XML.SubElement(xml_parent, "publishers") 8341 8342 for action in data.get("publishers", []): 8343 self.registry.dispatch("publisher", publishers, action) 8344