d352ed9656
Jenkins Wiki has been fully taken off line, so update the remaining links to reference either the relevant plugin page or the github repo. Add extlink target for repo in jenkinsci github org. The sonatype-clm plugin seems to be more-or-less completely deprecated, so update the description to indicate this and link to the nexus-artifact-uploader plugin. Update the jjb sphinx plugin so that it generates references for the yamlfunctions. Change-Id: If2241e751d01a60a8cb4cbaea5b3176aeb92eab4 Signed-off-by: Pat Long <pllong@arista.com>
8344 lines
333 KiB
Python
Executable File
8344 lines
333 KiB
Python
Executable File
# Copyright 2012 Hewlett-Packard Development Company, L.P.
|
|
# Copyright 2012 Varnish Software AS
|
|
# Copyright 2013-2014 Antoine "hashar" Musso
|
|
# Copyright 2013-2014 Wikimedia Foundation Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
|
|
"""
|
|
Publishers define actions that the Jenkins job should perform after
|
|
the build is complete.
|
|
|
|
**Component**: publishers
|
|
:Macro: publisher
|
|
:Entry Point: jenkins_jobs.publishers
|
|
"""
|
|
|
|
import logging
|
|
import pkg_resources
|
|
import sys
|
|
import xml.etree.ElementTree as XML
|
|
|
|
import six
|
|
|
|
from jenkins_jobs.errors import InvalidAttributeError
|
|
from jenkins_jobs.errors import JenkinsJobsException
|
|
from jenkins_jobs.errors import MissingAttributeError
|
|
import jenkins_jobs.modules.base
|
|
from jenkins_jobs.modules import hudson_model
|
|
import jenkins_jobs.modules.helpers as helpers
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def influx_db(registry, xml_parent, data):
|
|
"""yaml: influx-db
|
|
Requires the Jenkins :jenkins-plugins: `Influx DB
|
|
<influxdb>`.
|
|
"""
|
|
|
|
influx_db = XML.SubElement(
|
|
xml_parent,
|
|
"jenkinsci.plugins.influxdb.InfluxDbPublisher",
|
|
{"plugin": "influx-db"},
|
|
)
|
|
|
|
mapping = [
|
|
("selected-target", "selectedTarget", ""),
|
|
("custom-project-name", "customProjectName", ""),
|
|
("custom-prefix", "customPrefix", ""),
|
|
("jenkins-env-parameter-field", "jenkinsEnvParameterField", ""),
|
|
("jenkins-env-parameter-tag", "jenkinsEnvParameterTag", ""),
|
|
]
|
|
|
|
helpers.convert_mapping_to_xml(influx_db, data, mapping, fail_required=True)
|
|
|
|
|
|
def allure(registry, xml_parent, data):
|
|
"""yaml: allure
|
|
|
|
Publish Allure report for the build. Requires the Jenkins
|
|
:jenkins-plugins:`Allure Plugin <allure-jenkins-plugin>`.
|
|
|
|
:arg str jdk: String identifier for a JDK installation in Jenkins
|
|
:arg str commandline: String identifier for a Allure-commandline tool
|
|
installation
|
|
:arg str report-build-policy: String identifier for a report build
|
|
policy enum. Possible values: 'ALWAYS', 'UNSTABLE', 'UNSUCCESSFUL'.
|
|
(By default is 'ALWAYS')
|
|
:arg bool include-properties: Flag to include specified properties
|
|
:arg list results-paths: List of results directories
|
|
:arg list properties: List of key:value property pairs
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/allure-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/allure-full.yaml
|
|
:language: yaml
|
|
|
|
"""
|
|
publisher_class = "ru.yandex.qatools.allure.jenkins.AllureReportPublisher"
|
|
property_class = "ru.yandex.qatools.allure.jenkins.config.PropertyConfig"
|
|
results_class = "ru.yandex.qatools.allure.jenkins.config.ResultsConfig"
|
|
|
|
allure_publisher = XML.SubElement(xml_parent, publisher_class)
|
|
allure_publisher.set("plugin", "allure-jenkins-plugin")
|
|
config = XML.SubElement(allure_publisher, "config")
|
|
|
|
results = XML.SubElement(config, "results")
|
|
if "results-paths" in data:
|
|
for results_path in data["results-paths"]:
|
|
entry = XML.SubElement(results, results_class)
|
|
path = XML.SubElement(entry, "path")
|
|
path.text = results_path["path"]
|
|
|
|
properties = XML.SubElement(config, "properties")
|
|
if "properties" in data:
|
|
property_mapping = [("key", "key", None), ("value", "value", None)]
|
|
for prop in data["properties"]:
|
|
entry = XML.SubElement(properties, property_class)
|
|
helpers.convert_mapping_to_xml(
|
|
entry, prop, property_mapping, fail_required=True
|
|
)
|
|
else:
|
|
properties.set("class", "empty-list")
|
|
|
|
mapping = [
|
|
("jdk", "jdk", ""),
|
|
("commandline", "commandline", ""),
|
|
(
|
|
"report-build-policy",
|
|
"reportBuildPolicy",
|
|
"ALWAYS",
|
|
["ALWAYS", "UNSTABLE", "UNSUCCESSFUL"],
|
|
),
|
|
("include-properties", "includeProperties", False),
|
|
]
|
|
|
|
helpers.convert_mapping_to_xml(config, data, mapping, fail_required=True)
|
|
|
|
|
|
def archive(registry, xml_parent, data):
|
|
"""yaml: archive
|
|
Archive build artifacts
|
|
|
|
:arg str artifacts: path specifier for artifacts to archive
|
|
:arg str excludes: path specifier for artifacts to exclude (optional)
|
|
:arg bool latest-only: only keep the artifacts from the latest
|
|
successful build
|
|
:arg bool allow-empty: pass the build if no artifacts are
|
|
found (default false)
|
|
:arg bool only-if-success: archive artifacts only if build is successful
|
|
(default false)
|
|
:arg bool fingerprint: fingerprint all archived artifacts (default false)
|
|
:arg bool default-excludes: This option allows you to enable or disable the
|
|
default Ant exclusions. (default true)
|
|
:arg bool case-sensitive: Treat include and exclude patterns as case
|
|
sensitive. (default true)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/archive001.yaml
|
|
:language: yaml
|
|
"""
|
|
archiver = XML.SubElement(xml_parent, "hudson.tasks.ArtifactArchiver")
|
|
mapping = [
|
|
("artifacts", "artifacts", None),
|
|
("allow-empty", "allowEmptyArchive", False),
|
|
("only-if-success", "onlyIfSuccessful", False),
|
|
("fingerprint", "fingerprint", False),
|
|
("default-excludes", "defaultExcludes", True),
|
|
("case-sensitive", "caseSensitive", True),
|
|
("latest-only", "latestOnly", False),
|
|
]
|
|
|
|
if "excludes" in data:
|
|
mapping.append(("excludes", "excludes", None))
|
|
helpers.convert_mapping_to_xml(archiver, data, mapping, fail_required=True)
|
|
|
|
|
|
def blame_upstream(registry, xml_parent, data):
|
|
"""yaml: blame-upstream
|
|
Notify upstream committers when build fails
|
|
|
|
Requires the Jenkins :jenkins-github:`Blame Upstream Committers Plugin
|
|
<blame-upstream-commiters-plugin>`.
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/blame001.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
XML.SubElement(
|
|
xml_parent,
|
|
"hudson.plugins.blame__upstream__commiters." "BlameUpstreamCommitersPublisher",
|
|
)
|
|
|
|
|
|
def jclouds(registry, xml_parent, data):
|
|
"""yaml: jclouds
|
|
JClouds Cloud Storage Settings provides a way to store artifacts on
|
|
JClouds supported storage providers. Requires the Jenkins
|
|
:jenkins-plugins:`JClouds Plugin <jclouds-jenkins>`.
|
|
|
|
JClouds Cloud Storage Settings must be configured for the Jenkins instance.
|
|
|
|
:arg str profile: preconfigured storage profile (required)
|
|
:arg str files: files to upload (regex) (required)
|
|
:arg str basedir: the source file path (relative to workspace, Optional)
|
|
:arg str container: the destination container name (required)
|
|
:arg bool hierarchy: keep hierarchy (default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/jclouds001.yaml
|
|
|
|
"""
|
|
|
|
deployer = XML.SubElement(
|
|
xml_parent, "jenkins.plugins.jclouds.blobstore." "BlobStorePublisher"
|
|
)
|
|
entries = XML.SubElement(deployer, "entries")
|
|
deployer_entry = XML.SubElement(
|
|
entries, "jenkins.plugins.jclouds.blobstore." "BlobStoreEntry"
|
|
)
|
|
deployer_mapping = [("profile", "profileName", None)]
|
|
helpers.convert_mapping_to_xml(deployer, data, deployer_mapping, fail_required=True)
|
|
try:
|
|
XML.SubElement(deployer_entry, "container").text = data["container"]
|
|
XML.SubElement(deployer_entry, "sourceFile").text = data["files"]
|
|
except KeyError as e:
|
|
raise JenkinsJobsException("blobstore requires '%s' to be set" % e.args[0])
|
|
deployer_entry_mapping = [
|
|
("hierarchy", "keepHierarchy", False),
|
|
("basedir", "path", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(
|
|
deployer_entry, data, deployer_entry_mapping, fail_required=True
|
|
)
|
|
|
|
|
|
def javadoc(registry, xml_parent, data):
|
|
"""yaml: javadoc
|
|
Publish Javadoc
|
|
Requires the Jenkins :jenkins-plugins:`Javadoc Plugin <javadoc>`.
|
|
|
|
:arg str directory: Directory relative to the root of the workspace,
|
|
such as 'myproject/build/javadoc' (optional)
|
|
:arg bool keep-all-successful: When true, it will retain Javadoc for each
|
|
successful build. This allows you to browse Javadoc for older builds,
|
|
at the expense of additional disk space requirement. If false, it will
|
|
only keep the latest Javadoc, so older Javadoc will be overwritten as
|
|
new builds succeed. (default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/javadoc001.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
root = XML.SubElement(xml_parent, "hudson.tasks.JavadocArchiver")
|
|
|
|
mapping = [
|
|
("directory", "javadocDir", None),
|
|
("keep-all-successful", "keepAll", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(root, data, mapping, fail_required=False)
|
|
|
|
|
|
def jdepend(registry, xml_parent, data):
|
|
"""yaml: jdepend
|
|
Publish jdepend report
|
|
Requires the :jenkins-plugins:`JDepend Plugin <jdepend>`.
|
|
|
|
:arg str file: path to jdepend file (required)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/jdepend001.yaml
|
|
:language: yaml
|
|
"""
|
|
jdepend = XML.SubElement(xml_parent, "hudson.plugins.jdepend.JDependRecorder")
|
|
mapping = [("file", "configuredJDependFile", None)]
|
|
helpers.convert_mapping_to_xml(jdepend, data, mapping, fail_required=True)
|
|
|
|
|
|
def hue_light(registry, xml_parent, data):
|
|
"""yaml: hue-light
|
|
This plugin shows the state of your builds using the awesome Philips hue
|
|
lights.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`hue-light Plugin
|
|
<hue-light>`.
|
|
|
|
:arg int light-id: ID of light. Define multiple lights by a comma as a
|
|
separator (required)
|
|
:arg str pre-build: Colour of building state (default 'blue')
|
|
:arg str good-build: Colour of successful state (default 'green')
|
|
:arg str unstable-build: Colour of unstable state (default 'yellow')
|
|
:arg str bad-build: Colour of unsuccessful state (default 'red')
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/hue-light-full.yaml
|
|
:language: yaml
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/hue-light-minimal.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
hue_light = XML.SubElement(
|
|
xml_parent, "org.jenkinsci.plugins.hue__light.LightNotifier"
|
|
)
|
|
hue_light.set("plugin", "hue-light")
|
|
lightId = XML.SubElement(hue_light, "lightId")
|
|
|
|
id_mapping = [("light-id", "string", None)]
|
|
helpers.convert_mapping_to_xml(lightId, data, id_mapping, fail_required=True)
|
|
|
|
build_mapping = [
|
|
("pre-build", "preBuild", "blue"),
|
|
("good-build", "goodBuild", "green"),
|
|
("unstable-build", "unstableBuild", "yellow"),
|
|
("bad-build", "badBuild", "red"),
|
|
]
|
|
helpers.convert_mapping_to_xml(hue_light, data, build_mapping, fail_required=True)
|
|
|
|
|
|
def campfire(registry, xml_parent, data):
|
|
"""yaml: campfire
|
|
Send build notifications to Campfire rooms.
|
|
Requires the Jenkins :jenkins-plugins:`Campfire Plugin <campfire>`.
|
|
|
|
Campfire notifications global default values must be configured for
|
|
the Jenkins instance. Default values will be used if no specific
|
|
values are specified for each job, so all config params are optional.
|
|
|
|
:arg str subdomain: override the default campfire subdomain
|
|
:arg str token: override the default API token
|
|
:arg bool ssl: override the default 'use SSL'
|
|
:arg str room: override the default room name
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/campfire001.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
root = XML.SubElement(xml_parent, "hudson.plugins.campfire." "CampfireNotifier")
|
|
campfire = XML.SubElement(root, "campfire")
|
|
|
|
mapping = [
|
|
("subdomain", "subdomain", None),
|
|
("token", "token", None),
|
|
("ssl", "ssl", None),
|
|
]
|
|
helpers.convert_mapping_to_xml(campfire, data, mapping, fail_required=False)
|
|
|
|
if "room" in data:
|
|
room = XML.SubElement(root, "room")
|
|
mapping = [("room", "name", None)]
|
|
helpers.convert_mapping_to_xml(room, data, mapping, fail_required=True)
|
|
|
|
XML.SubElement(room, 'campfire reference="../../campfire"')
|
|
|
|
|
|
def mqtt(registry, xml_parent, data):
|
|
"""yaml: mqtt
|
|
This plugin lets you send build notifications to a MQTT message queue.
|
|
Requires the :jenkins-plugins:`MQTT Notification Plugin
|
|
<mqtt-notification-plugin>`.
|
|
|
|
:arg str broker-url: the broker URL, as protocol://address:port (required)
|
|
:arg str credentials-id: credentials to use to connect to the broker
|
|
(optional)
|
|
:arg str topic: the message topic (default "jenkins/$PROJECT_URL")
|
|
:arg str message: the message itself (default "$BUILD_RESULT")
|
|
:arg str qos: one of AT_MOST_ONCE, AT_LEAST_ONCE, or EXACTLY_ONCE
|
|
(default AT_MOST_ONCE)
|
|
:arg bool retain-message: whether to resend message or not when a new
|
|
client connects (default false)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/mqtt-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/mqtt-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
mqtt = XML.SubElement(xml_parent, "jenkins.plugins.mqttnotification.MqttNotifier")
|
|
mqtt.set("plugin", "mqtt-notification-plugin")
|
|
mqtt_mapping = [("broker-url", "brokerUrl", None)]
|
|
helpers.convert_mapping_to_xml(mqtt, data, mqtt_mapping, fail_required=True)
|
|
mqtt_mapping = [
|
|
("credentials-id", "credentialsId", None),
|
|
("topic", "topic", "jenkins/$PROJECT_URL"),
|
|
("message", "message", "$BUILD_RESULT"),
|
|
(
|
|
"qos",
|
|
"qos",
|
|
"AT_MOST_ONCE",
|
|
{"AT_MOST_ONCE": "0", "AT_LEAST_ONCE": "1", "EXACTLY_ONCE": "2"},
|
|
),
|
|
("retain-message", "retainMessage", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(mqtt, data, mqtt_mapping, fail_required=False)
|
|
|
|
|
|
def codecover(registry, xml_parent, data):
|
|
"""yaml: codecover
|
|
This plugin allows you to capture code coverage report from CodeCover.
|
|
Jenkins will generate the trend report of coverage.
|
|
Requires the Jenkins :jenkins-plugins:`CodeCover Plugin <codecover>`.
|
|
|
|
:arg str include: Specify the path to the CodeCover HTML report file,
|
|
relative to the workspace root (default '')
|
|
:arg int min-statement: Minimum statement threshold (default 0)
|
|
:arg int max-statement: Maximum statement threshold (default 90)
|
|
:arg int min-branch: Minimum branch threshold (default 0)
|
|
:arg int max-branch: Maximum branch threshold (default 80)
|
|
:arg int min-loop: Minimum loop threshold (default 0)
|
|
:arg int max-loop: Maximum loop threshold (default 50)
|
|
:arg int min-condition: Minimum condition threshold (default 0)
|
|
:arg int max-condition: Maximum conditon threshold (default 50)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/codecover-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/codecover-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
codecover = XML.SubElement(
|
|
xml_parent, "hudson.plugins.codecover.CodeCoverPublisher"
|
|
)
|
|
codecover.set("plugin", "codecover")
|
|
|
|
XML.SubElement(codecover, "includes").text = str(data.get("include", ""))
|
|
|
|
health_report = XML.SubElement(codecover, "healthReports")
|
|
mapping = [
|
|
("min-statement", "minStatement", 0),
|
|
("max-statement", "maxStatement", 90),
|
|
("min-branch", "minBranch", 0),
|
|
("max-branch", "maxBranch", 80),
|
|
("min-loop", "minLoop", 0),
|
|
("max-loop", "maxLoop", 50),
|
|
("min-condition", "minCondition", 0),
|
|
("max-condition", "maxCondition", 50),
|
|
]
|
|
helpers.convert_mapping_to_xml(health_report, data, mapping, fail_required=True)
|
|
|
|
|
|
def emotional_jenkins(registry, xml_parent, data):
|
|
"""yaml: emotional-jenkins
|
|
Emotional Jenkins. This funny plugin changes the expression of Mr. Jenkins
|
|
in the background when your builds fail.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Emotional Jenkins Plugin
|
|
<emotional-jenkins-plugin>`.
|
|
|
|
Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/emotional-jenkins.yaml
|
|
:language: yaml
|
|
"""
|
|
XML.SubElement(
|
|
xml_parent,
|
|
"org.jenkinsci.plugins.emotional__jenkins." "EmotionalJenkinsPublisher",
|
|
)
|
|
|
|
|
|
def trigger_parameterized_builds(registry, xml_parent, data):
|
|
"""yaml: trigger-parameterized-builds
|
|
Trigger parameterized builds of other jobs.
|
|
Requires the Jenkins :jenkins-plugins:`Parameterized Trigger Plugin
|
|
<parameterized-trigger>`.
|
|
|
|
Use of the `node-label-name` or `node-label` parameters
|
|
requires the Jenkins :jenkins-plugins:`NodeLabel Parameter Plugin
|
|
<nodelabelparameter>`.
|
|
Note: 'node-parameters' overrides the Node that the triggered
|
|
project is tied to.
|
|
|
|
:arg list project: list the jobs to trigger, will generate comma-separated
|
|
string containing the named jobs.
|
|
:arg str predefined-parameters: parameters to pass to the other
|
|
job (optional)
|
|
:arg bool current-parameters: Whether to include the parameters passed
|
|
to the current build to the triggered job (optional)
|
|
:arg bool node-parameters: Use the same Node for the triggered builds
|
|
that was used for this build. (optional)
|
|
:arg bool svn-revision: Pass svn revision to the triggered job (optional)
|
|
:arg bool include-upstream: Include/pass through Upstream SVN Revisons.
|
|
Only valid when 'svn-revision' is true. (default false)
|
|
:arg dict git-revision: Passes git revision to the triggered job
|
|
(optional).
|
|
|
|
* **combine-queued-commits** (bool): Whether to combine queued git
|
|
hashes or not (default false)
|
|
|
|
:arg bool combine-queued-commits: Combine Queued git hashes. Only valid
|
|
when 'git-revision' is true. (default false)
|
|
|
|
.. deprecated:: 1.5.0 Please use `combine-queued-commits` under the
|
|
`git-revision` argument instead.
|
|
|
|
:arg dict boolean-parameters: Pass boolean parameters to the downstream
|
|
jobs. Specify the name and boolean value mapping of the parameters.
|
|
(optional)
|
|
:arg str condition: when to trigger the other job. Can be: 'SUCCESS',
|
|
'UNSTABLE', 'FAILED_OR_BETTER', 'UNSTABLE_OR_BETTER',
|
|
'UNSTABLE_OR_WORSE', 'FAILED', 'ALWAYS'. (default 'ALWAYS')
|
|
:arg str property-file: Use properties from file (optional)
|
|
:arg bool fail-on-missing: Blocks the triggering of the downstream jobs
|
|
if any of the property files are not found in the workspace.
|
|
Only valid when 'property-file' is specified.
|
|
(default 'False')
|
|
:arg bool property-multiline: When enabled properties containing
|
|
newline character(s) are propagated as TextParameterValue which is
|
|
a specialized StringParameterValue commonly used for handling
|
|
multi-line strings in Jenkins. When disabled (default)
|
|
all properties are propagated as StringParameterValue. (default
|
|
'False') (>=2.35.2)
|
|
:arg bool trigger-from-child-projects: Trigger build from child projects.
|
|
Used for matrix projects. (default 'False')
|
|
:arg bool use-matrix-child-files: Use files in workspaces of child
|
|
builds (default 'False')
|
|
:arg str matrix-child-combination-filter: A Groovy expression to filter
|
|
the child builds to look in for files
|
|
:arg bool only-exact-matrix-child-runs: Use only child builds triggered
|
|
exactly by the parent.
|
|
:arg str file-encoding: Encoding of contents of the files. If not
|
|
specified, default encoding of the platform is used. Only valid when
|
|
'property-file' is specified. (optional)
|
|
:arg bool trigger-with-no-params: Trigger a build even when there are
|
|
currently no parameters defined (default 'False')
|
|
:arg str restrict-matrix-project: Filter that restricts the subset
|
|
of the combinations that the downstream project will run (optional)
|
|
:arg str node-label-name: Specify the Name for the NodeLabel parameter.
|
|
(optional)
|
|
:arg str node-label: Specify the Node for the NodeLabel parameter.
|
|
(optional)
|
|
|
|
Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/trigger_parameterized_builds001.yaml
|
|
:language: yaml
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/trigger_parameterized_builds003.yaml
|
|
:language: yaml
|
|
"""
|
|
pt_prefix = "hudson.plugins.parameterizedtrigger."
|
|
tbuilder = XML.SubElement(xml_parent, pt_prefix + "BuildTrigger")
|
|
configs = XML.SubElement(tbuilder, "configs")
|
|
|
|
param_order = helpers.trigger_get_parameter_order(
|
|
registry, "trigger-parameterized-builds"
|
|
)
|
|
|
|
for project_def in data:
|
|
tconfig = XML.SubElement(configs, pt_prefix + "BuildTriggerConfig")
|
|
tconfigs = XML.SubElement(tconfig, "configs")
|
|
|
|
helpers.trigger_project(tconfigs, project_def, registry, param_order)
|
|
|
|
if not list(tconfigs):
|
|
# no child parameter tags added
|
|
tconfigs.set("class", "java.util.Collections$EmptyList")
|
|
|
|
projects = XML.SubElement(tconfig, "projects")
|
|
|
|
if isinstance(project_def["project"], list):
|
|
projects.text = ",".join(project_def["project"])
|
|
else:
|
|
projects.text = project_def["project"]
|
|
|
|
condition = XML.SubElement(tconfig, "condition")
|
|
condition.text = project_def.get("condition", "ALWAYS")
|
|
mapping = [
|
|
("trigger-from-child-projects", "triggerFromChildProjects", False),
|
|
("trigger-with-no-params", "triggerWithNoParameters", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(
|
|
tconfig, project_def, mapping, fail_required=False
|
|
)
|
|
|
|
|
|
def trigger(registry, xml_parent, data):
|
|
"""yaml: trigger
|
|
Trigger non-parametrised builds of other jobs.
|
|
|
|
:arg str project: name of the job to trigger
|
|
:arg str threshold: when to trigger the other job (default 'SUCCESS'),
|
|
alternatives: SUCCESS, UNSTABLE, FAILURE
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/trigger_success.yaml
|
|
:language: yaml
|
|
"""
|
|
tconfig = XML.SubElement(xml_parent, "hudson.tasks.BuildTrigger")
|
|
childProjects = XML.SubElement(tconfig, "childProjects")
|
|
childProjects.text = data["project"]
|
|
|
|
threshold = data.get("threshold", "SUCCESS")
|
|
supported_thresholds = ["SUCCESS", "UNSTABLE", "FAILURE"]
|
|
helpers.trigger_threshold(
|
|
tconfig, "threshold", threshold, supported_thresholds=supported_thresholds
|
|
)
|
|
|
|
|
|
def clone_workspace(registry, xml_parent, data):
|
|
"""yaml: clone-workspace
|
|
Archive the workspace from builds of one project and reuse them as the SCM
|
|
source for another project.
|
|
Requires the Jenkins :jenkins-plugins:`Clone Workspace SCM Plugin
|
|
<clone-workspace-scm>`.
|
|
|
|
:arg str workspace-glob: Files to include in cloned workspace (default '')
|
|
:arg str workspace-exclude-glob: Files to exclude from cloned workspace
|
|
:arg str criteria: Criteria for build to be archived. Can be 'any',
|
|
'not failed', or 'successful'. (default 'any')
|
|
:arg str archive-method: Choose the method to use for archiving the
|
|
workspace. Can be 'tar' or 'zip'. (default 'tar')
|
|
:arg bool override-default-excludes: Override default ant excludes.
|
|
(default false)
|
|
|
|
Minimal example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/clone-workspace001.yaml
|
|
:language: yaml
|
|
|
|
Full example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/clone-workspace002.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
cloneworkspace = XML.SubElement(
|
|
xml_parent, "hudson.plugins.cloneworkspace.CloneWorkspacePublisher"
|
|
)
|
|
cloneworkspace.set("plugin", "clone-workspace-scm")
|
|
|
|
criteria_valid_types = ["Any", "Not Failed", "Successful"]
|
|
archive_valid_types = ["TAR", "ZIP"]
|
|
|
|
mappings = [
|
|
("workspace-glob", "workspaceGlob", ""),
|
|
("override-default-excludes", "overrideDefaultExcludes", False),
|
|
("criteria", "criteria", "Any", criteria_valid_types),
|
|
("archive-method", "archiveMethod", "TAR", archive_valid_types),
|
|
]
|
|
helpers.convert_mapping_to_xml(cloneworkspace, data, mappings, fail_required=True)
|
|
|
|
mappings = [("workspace-exclude-glob", "workspaceExcludeGlob", "")]
|
|
helpers.convert_mapping_to_xml(cloneworkspace, data, mappings, fail_required=False)
|
|
|
|
|
|
def cloud_foundry(parser, xml_parent, data):
|
|
"""yaml: cloudfoundry
|
|
Pushes a project to Cloud Foundry or a CF-based platform (e.g. Stackato) at
|
|
the end of a build. Requires the Jenkins :jenkins-plugins:`Cloud Foundry
|
|
Plugin <cloudfoundry>`.
|
|
|
|
:arg str target: The API endpoint of the platform you want to push to.
|
|
This is the URL you use to access the platform, possibly with ".api"
|
|
added. (required)
|
|
:arg str organization: An org is a development account that an individual
|
|
or multiple collaborators can own and use (required)
|
|
:arg str space: Provide users with access to a shared location for
|
|
application development, deployment, and maintenance (required)
|
|
:arg str credentials-id: credentials-id of the user (required)
|
|
:arg bool self-signed: Allow self-signed SSL certificates from the target
|
|
(default false)
|
|
:arg bool reset-app: Delete app before pushing app's configurations
|
|
(default false)
|
|
:arg int plugin-timeout: The time in seconds before the Cloud Foundry
|
|
plugin stops fetching logs and marks the build a failure (default 120)
|
|
:arg list create-services: Create services automatically (default '')
|
|
|
|
:create-services:
|
|
* **name** ('str') -- Service name (default '')
|
|
* **type** ('str') -- Service type (default '')
|
|
* **plan** ('str') -- Service plan (default '')
|
|
* **reset-service** ('bool') -- Delete the service before creating
|
|
the new one (default false)
|
|
:arg str value: Select to read configuration from manifest file or to enter
|
|
configuration in Jenkins (default 'manifestFile')
|
|
:arg str manifest-file: Path to manifest file (default 'manifest.yml')
|
|
:arg str app-name: The application's name. Default to Jenkins build name.
|
|
(default '')
|
|
:arg int memory: The application's memory usage in MB (default 512)
|
|
:arg str host-name: The hostname of the URI to access your application.
|
|
Default to app-name (default '')
|
|
:arg int instances: Number of instances of your application on creation
|
|
(default 1)
|
|
:arg int manifest-timeout: The time in seconds before the health-manager
|
|
gives up on starting the application (default 60)
|
|
:arg bool no-route: No URI path will be created to access the application
|
|
(default false)
|
|
:arg str app-path: Path to application (default '')
|
|
:arg build-pack: If your application requires a custom buildpack, you can
|
|
use this to specify its URL or name (default '')
|
|
:arg str stack: If your application requires a custom stack, you can use
|
|
this to specify its name. (default '')
|
|
:arg str command: Set a custom start command for your application
|
|
(default '')
|
|
:arg str domain: The domain of the URI to access your application
|
|
(default '')
|
|
:arg list environment-variables: Inject environment variables
|
|
|
|
:environment-variables:
|
|
* **key** ('str') -- Environment variable key (default '')
|
|
* **value** ('str') -- Environment variable value (default '')
|
|
:arg list services-names: Name of service instances
|
|
|
|
:services-names:
|
|
* **name** ('str') -- Name of the service instance (default '')
|
|
|
|
Minimal example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/cloudfoundry-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/cloudfoundry-full.yaml
|
|
:language: yaml
|
|
"""
|
|
cloud_foundry = XML.SubElement(
|
|
xml_parent, "com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher"
|
|
)
|
|
cloud_foundry.set("plugin", "cloudfoundry")
|
|
|
|
mapping = [
|
|
("target", "target", None),
|
|
("organization", "organization", None),
|
|
("space", "cloudSpace", None),
|
|
("credentials-id", "credentialsId", None),
|
|
("self-signed", "selfSigned", False),
|
|
("reset-app", "resetIfExists", False),
|
|
("timeout", "pluginTimeout", 120),
|
|
]
|
|
helpers.convert_mapping_to_xml(cloud_foundry, data, mapping, fail_required=True)
|
|
XML.SubElement(cloud_foundry, "appURIs").text = ""
|
|
|
|
create_services = XML.SubElement(cloud_foundry, "servicesToCreate")
|
|
create_services_mapping = [
|
|
("name", "name", ""),
|
|
("type", "type", ""),
|
|
("plan", "plan", ""),
|
|
("reset-service", "resetService", ""),
|
|
]
|
|
for service in data.get("create-services", ""):
|
|
create_services_sub = XML.SubElement(
|
|
create_services,
|
|
"com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher_-Service",
|
|
)
|
|
helpers.convert_mapping_to_xml(
|
|
create_services_sub, service, create_services_mapping, fail_required=True
|
|
)
|
|
|
|
manifest = XML.SubElement(cloud_foundry, "manifestChoice")
|
|
valid_values = ["manifestFile", "jenkinsConfig"]
|
|
manifest_mapping = [
|
|
("value", "value", "manifestFile", valid_values),
|
|
("manifest-file", "manifestFile", "manifest.yml"),
|
|
("app-name", "appName", ""),
|
|
("memory", "memory", 512),
|
|
("host-name", "hostname", ""),
|
|
("instances", "instances", 1),
|
|
("manifest-timeout", "timeout", 60),
|
|
("no-route", "noRoute", False),
|
|
("app-path", "appPath", ""),
|
|
("build-pack", "buildpack", ""),
|
|
("stack", "stack", ""),
|
|
("command", "command", ""),
|
|
("domain", "domain", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(manifest, data, manifest_mapping, fail_required=True)
|
|
|
|
if "environment-variables" in data:
|
|
env_vars = XML.SubElement(manifest, "envVars")
|
|
env_vars_mapping = [("key", "key", ""), ("value", "value", "")]
|
|
for var in data["environment-variables"]:
|
|
env_vars_sub = XML.SubElement(
|
|
env_vars,
|
|
"com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher_-"
|
|
"EnvironmentVariable",
|
|
)
|
|
helpers.convert_mapping_to_xml(
|
|
env_vars_sub, var, env_vars_mapping, fail_required=True
|
|
)
|
|
|
|
if "services-names" in data:
|
|
services_names = XML.SubElement(manifest, "servicesNames")
|
|
service_name_mapping = [("name", "name", "")]
|
|
for name in data["services-names"]:
|
|
services_names_sub = XML.SubElement(
|
|
services_names,
|
|
"com.hpe.cloudfoundryjenkins.CloudFoundryPushPublisher_-" "ServiceName",
|
|
)
|
|
helpers.convert_mapping_to_xml(
|
|
services_names_sub, name, service_name_mapping, fail_required=True
|
|
)
|
|
|
|
|
|
def cloverphp(registry, xml_parent, data):
|
|
"""yaml: cloverphp
|
|
Capture code coverage reports from PHPUnit
|
|
Requires the Jenkins :jenkins-plugins:`Clover PHP Plugin <cloverphp>`.
|
|
|
|
Your job definition should pass to PHPUnit the --coverage-clover option
|
|
pointing to a file in the workspace (ex: clover-coverage.xml). The filename
|
|
has to be filled in the `xml-location` field.
|
|
|
|
:arg str xml-location: Path to the coverage XML file generated by PHPUnit
|
|
using --coverage-clover. Relative to workspace. (required)
|
|
:arg dict html: When existent, whether the plugin should generate a HTML
|
|
report. Note that PHPUnit already provide a HTML report via its
|
|
--cover-html option which can be set in your builder (optional):
|
|
|
|
* **dir** (str): Directory where HTML report will be generated relative
|
|
to workspace. (required in `html` dict).
|
|
* **archive** (bool): Whether to archive HTML reports (default true).
|
|
|
|
:arg list metric-targets: List of metric targets to reach, must be one of
|
|
**healthy**, **unhealthy** and **failing**. Each metric target can
|
|
takes two parameters:
|
|
|
|
* **method** Target for method coverage
|
|
* **statement** Target for statements coverage
|
|
|
|
Whenever a metric target is not filled in, the Jenkins plugin can fill
|
|
in defaults for you (as of v0.3.3 of the plugin the healthy target will
|
|
have method: 70 and statement: 80 if both are left empty). Jenkins Job
|
|
Builder will mimic that feature to ensure clean configuration diff.
|
|
|
|
Minimal example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/cloverphp001.yaml
|
|
:language: yaml
|
|
|
|
Full example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/cloverphp002.yaml
|
|
:language: yaml
|
|
"""
|
|
cloverphp = XML.SubElement(
|
|
xml_parent, "org.jenkinsci.plugins.cloverphp.CloverPHPPublisher"
|
|
)
|
|
cloverphp.set("plugin", "cloverphp")
|
|
|
|
# The plugin requires clover XML file to parse
|
|
if "xml-location" not in data:
|
|
raise JenkinsJobsException("xml-location must be set")
|
|
|
|
# Whether HTML publishing has been checked
|
|
html_publish = False
|
|
# By default, disableArchiving = false. Note that we use
|
|
# reversed logic.
|
|
html_archive = True
|
|
|
|
if "html" in data:
|
|
html_publish = True
|
|
html_dir = data["html"].get("dir", None)
|
|
html_archive = data["html"].get("archive", html_archive)
|
|
if html_dir is None:
|
|
# No point in going further, the plugin would not work
|
|
raise JenkinsJobsException("htmldir is required in a html block")
|
|
|
|
XML.SubElement(cloverphp, "publishHtmlReport").text = str(html_publish).lower()
|
|
if html_publish:
|
|
XML.SubElement(cloverphp, "reportDir").text = html_dir
|
|
XML.SubElement(cloverphp, "xmlLocation").text = data.get("xml-location")
|
|
XML.SubElement(cloverphp, "disableArchiving").text = str(not html_archive).lower()
|
|
|
|
# Handle targets
|
|
|
|
# Plugin v0.3.3 will fill defaults for us whenever healthy targets are both
|
|
# blanks.
|
|
default_metrics = {"healthy": {"method": 70, "statement": 80}}
|
|
allowed_metrics = ["healthy", "unhealthy", "failing"]
|
|
|
|
metrics = data.get("metric-targets", [])
|
|
# list of dicts to dict
|
|
metrics = dict(kv for m in metrics for kv in m.items())
|
|
|
|
# Populate defaults whenever nothing has been filled by user.
|
|
for default in default_metrics.keys():
|
|
if metrics.get(default, None) is None:
|
|
metrics[default] = default_metrics[default]
|
|
|
|
# The plugin would at least define empty targets so make sure
|
|
# we output them all in the XML regardless of what the user
|
|
# has or has not entered.
|
|
for target in allowed_metrics:
|
|
cur_target = XML.SubElement(cloverphp, target + "Target")
|
|
|
|
for t_type in ["method", "statement"]:
|
|
val = metrics.get(target, {}).get(t_type)
|
|
if val is None or type(val) != int:
|
|
continue
|
|
if val < 0 or val > 100:
|
|
raise JenkinsJobsException(
|
|
"Publisher cloverphp metric target %s:%s = %s "
|
|
"is not in valid range 0-100." % (target, t_type, val)
|
|
)
|
|
XML.SubElement(cur_target, t_type + "Coverage").text = str(val)
|
|
|
|
|
|
def coverage(registry, xml_parent, data):
|
|
"""yaml: coverage
|
|
WARNING: The coverage function is deprecated. Instead, use the
|
|
cobertura function to generate a cobertura coverage report.
|
|
Requires the Jenkins :jenkins-plugins:`Cobertura Coverage Plugin
|
|
<cobertura>`.
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/coverage001.yaml
|
|
:language: yaml
|
|
"""
|
|
logger = logging.getLogger(__name__)
|
|
logger.warning("Coverage function is deprecated. Switch to cobertura.")
|
|
|
|
cobertura = XML.SubElement(
|
|
xml_parent, "hudson.plugins.cobertura.CoberturaPublisher"
|
|
)
|
|
XML.SubElement(cobertura, "coberturaReportFile").text = "**/coverage.xml"
|
|
XML.SubElement(cobertura, "onlyStable").text = "false"
|
|
healthy = XML.SubElement(cobertura, "healthyTarget")
|
|
targets = XML.SubElement(
|
|
healthy,
|
|
"targets",
|
|
{
|
|
"class": "enum-map",
|
|
"enum-type": "hudson.plugins.cobertura.targets.CoverageMetric",
|
|
},
|
|
)
|
|
entry = XML.SubElement(targets, "entry")
|
|
XML.SubElement(
|
|
entry, "hudson.plugins.cobertura.targets.CoverageMetric"
|
|
).text = "CONDITIONAL"
|
|
XML.SubElement(entry, "int").text = "70"
|
|
entry = XML.SubElement(targets, "entry")
|
|
XML.SubElement(
|
|
entry, "hudson.plugins.cobertura.targets.CoverageMetric"
|
|
).text = "LINE"
|
|
XML.SubElement(entry, "int").text = "80"
|
|
entry = XML.SubElement(targets, "entry")
|
|
XML.SubElement(
|
|
entry, "hudson.plugins.cobertura.targets.CoverageMetric"
|
|
).text = "METHOD"
|
|
XML.SubElement(entry, "int").text = "80"
|
|
unhealthy = XML.SubElement(cobertura, "unhealthyTarget")
|
|
targets = XML.SubElement(
|
|
unhealthy,
|
|
"targets",
|
|
{
|
|
"class": "enum-map",
|
|
"enum-type": "hudson.plugins.cobertura.targets.CoverageMetric",
|
|
},
|
|
)
|
|
entry = XML.SubElement(targets, "entry")
|
|
XML.SubElement(
|
|
entry, "hudson.plugins.cobertura.targets.CoverageMetric"
|
|
).text = "CONDITIONAL"
|
|
XML.SubElement(entry, "int").text = "0"
|
|
entry = XML.SubElement(targets, "entry")
|
|
XML.SubElement(
|
|
entry, "hudson.plugins.cobertura.targets.CoverageMetric"
|
|
).text = "LINE"
|
|
XML.SubElement(entry, "int").text = "0"
|
|
entry = XML.SubElement(targets, "entry")
|
|
XML.SubElement(
|
|
entry, "hudson.plugins.cobertura.targets.CoverageMetric"
|
|
).text = "METHOD"
|
|
XML.SubElement(entry, "int").text = "0"
|
|
failing = XML.SubElement(cobertura, "failingTarget")
|
|
targets = XML.SubElement(
|
|
failing,
|
|
"targets",
|
|
{
|
|
"class": "enum-map",
|
|
"enum-type": "hudson.plugins.cobertura.targets.CoverageMetric",
|
|
},
|
|
)
|
|
entry = XML.SubElement(targets, "entry")
|
|
XML.SubElement(
|
|
entry, "hudson.plugins.cobertura.targets.CoverageMetric"
|
|
).text = "CONDITIONAL"
|
|
XML.SubElement(entry, "int").text = "0"
|
|
entry = XML.SubElement(targets, "entry")
|
|
XML.SubElement(
|
|
entry, "hudson.plugins.cobertura.targets.CoverageMetric"
|
|
).text = "LINE"
|
|
XML.SubElement(entry, "int").text = "0"
|
|
entry = XML.SubElement(targets, "entry")
|
|
XML.SubElement(
|
|
entry, "hudson.plugins.cobertura.targets.CoverageMetric"
|
|
).text = "METHOD"
|
|
XML.SubElement(entry, "int").text = "0"
|
|
XML.SubElement(cobertura, "sourceEncoding").text = "ASCII"
|
|
|
|
|
|
def cobertura(registry, xml_parent, data):
|
|
"""yaml: cobertura
|
|
Generate a cobertura coverage report.
|
|
Requires the Jenkins :jenkins-plugins:`Cobertura Coverage Plugin
|
|
<cobertura>`.
|
|
|
|
:arg str report-file: This is a file name pattern that can be used
|
|
to locate the cobertura xml report files (optional)
|
|
:arg bool only-stable: Include only stable builds (default false)
|
|
:arg bool fail-no-reports: fail builds if no coverage reports are found
|
|
(default false)
|
|
:arg bool fail-unhealthy: Unhealthy projects will be failed (default false)
|
|
:arg bool fail-unstable: Unstable projects will be failed (default false)
|
|
:arg bool health-auto-update: Auto update threshold for health on
|
|
successful build (default false)
|
|
:arg bool stability-auto-update: Auto update threshold for stability on
|
|
successful build (default false)
|
|
:arg bool zoom-coverage-chart: Zoom the coverage chart and crop area below
|
|
the minimum and above the maximum coverage of the past reports
|
|
(default false)
|
|
:arg str source-encoding: Override the source encoding (default ASCII)
|
|
:arg dict targets:
|
|
|
|
:targets: (packages, files, classes, method, line, conditional)
|
|
|
|
* **healthy** (`int`): Healthy threshold (default 0)
|
|
* **unhealthy** (`int`): Unhealthy threshold (default 0)
|
|
* **failing** (`int`): Failing threshold (default 0)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/cobertura001.yaml
|
|
:language: yaml
|
|
"""
|
|
cobertura = XML.SubElement(
|
|
xml_parent, "hudson.plugins.cobertura.CoberturaPublisher"
|
|
)
|
|
mapping = [
|
|
("report-file", "coberturaReportFile", "**/coverage.xml"),
|
|
("only-stable", "onlyStable", False),
|
|
("fail-unhealthy", "failUnhealthy", False),
|
|
("fail-unstable", "failUnstable", False),
|
|
("health-auto-update", "autoUpdateHealth", False),
|
|
("stability-auto-update", "autoUpdateStability", False),
|
|
("zoom-coverage-chart", "zoomCoverageChart", False),
|
|
("fail-no-reports", "failNoReports", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(cobertura, data, mapping, fail_required=True)
|
|
|
|
healthy = XML.SubElement(cobertura, "healthyTarget")
|
|
targets = XML.SubElement(
|
|
healthy,
|
|
"targets",
|
|
{
|
|
"class": "enum-map",
|
|
"enum-type": "hudson.plugins.cobertura.targets.CoverageMetric",
|
|
},
|
|
)
|
|
for item in data["targets"]:
|
|
item_name = next(iter(item.keys()))
|
|
item_values = item.get(item_name, 0)
|
|
entry = XML.SubElement(targets, "entry")
|
|
XML.SubElement(
|
|
entry, "hudson.plugins.cobertura.targets." "CoverageMetric"
|
|
).text = str(item_name).upper()
|
|
XML.SubElement(entry, "int").text = str(item_values.get("healthy", 0))
|
|
unhealthy = XML.SubElement(cobertura, "unhealthyTarget")
|
|
targets = XML.SubElement(
|
|
unhealthy,
|
|
"targets",
|
|
{
|
|
"class": "enum-map",
|
|
"enum-type": "hudson.plugins.cobertura.targets.CoverageMetric",
|
|
},
|
|
)
|
|
for item in data["targets"]:
|
|
item_name = next(iter(item.keys()))
|
|
item_values = item.get(item_name, 0)
|
|
entry = XML.SubElement(targets, "entry")
|
|
XML.SubElement(
|
|
entry, "hudson.plugins.cobertura.targets." "CoverageMetric"
|
|
).text = str(item_name).upper()
|
|
XML.SubElement(entry, "int").text = str(item_values.get("unhealthy", 0))
|
|
failing = XML.SubElement(cobertura, "failingTarget")
|
|
targets = XML.SubElement(
|
|
failing,
|
|
"targets",
|
|
{
|
|
"class": "enum-map",
|
|
"enum-type": "hudson.plugins.cobertura.targets.CoverageMetric",
|
|
},
|
|
)
|
|
for item in data["targets"]:
|
|
item_name = next(iter(item.keys()))
|
|
item_values = item.get(item_name, 0)
|
|
entry = XML.SubElement(targets, "entry")
|
|
XML.SubElement(
|
|
entry, "hudson.plugins.cobertura.targets." "CoverageMetric"
|
|
).text = str(item_name).upper()
|
|
XML.SubElement(entry, "int").text = str(item_values.get("failing", 0))
|
|
XML.SubElement(cobertura, "sourceEncoding").text = data.get(
|
|
"source-encoding", "ASCII"
|
|
)
|
|
|
|
|
|
def jacoco(registry, xml_parent, data):
|
|
"""yaml: jacoco
|
|
Generate a JaCoCo coverage report.
|
|
Requires the Jenkins :jenkins-plugins:`JaCoCo Plugin <jacoco>`.
|
|
|
|
:arg str exec-pattern: This is a file name pattern that can be used to
|
|
locate the jacoco report files (default ``**/**.exec``)
|
|
:arg str class-pattern: This is a file name pattern that can be used
|
|
to locate class files (default ``**/classes``)
|
|
:arg str source-pattern: This is a file name pattern that can be used
|
|
to locate source files (default ``**/src/main/java``)
|
|
:arg str source-inclusion-pattern: This is a file name pattern that can
|
|
be used to include certain source files (default ``**/*.java``)
|
|
:arg bool update-build-status: Update the build according to the results
|
|
(default false)
|
|
:arg str inclusion-pattern: This is a file name pattern that can be used
|
|
to include certain class files (default '')
|
|
:arg str exclusion-pattern: This is a file name pattern that can be used
|
|
to exclude certain class files (default '')
|
|
:arg dict targets:
|
|
|
|
:targets: (instruction, branch, complexity, line, method, class)
|
|
|
|
* **healthy** (`int`): Healthy threshold (default 0)
|
|
* **unhealthy** (`int`): Unhealthy threshold (default 0)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/jacoco-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/jacoco-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
jacoco = XML.SubElement(xml_parent, "hudson.plugins.jacoco.JacocoPublisher")
|
|
jacoco.set("plugin", "jacoco")
|
|
|
|
mappings = [
|
|
("exec-pattern", "execPattern", "**/**.exec"),
|
|
("class-pattern", "classPattern", "**/classes"),
|
|
("source-pattern", "sourcePattern", "**/src/main/java"),
|
|
("source-inclusion-pattern", "sourceInclusionPattern", "**/*.java"),
|
|
("update-build-status", "changeBuildStatus", False),
|
|
("inclusion-pattern", "inclusionPattern", ""),
|
|
("exclusion-pattern", "exclusionPattern", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(jacoco, data, mappings, fail_required=True)
|
|
|
|
itemsList = ["instruction", "branch", "complexity", "line", "method", "class"]
|
|
|
|
if "targets" in data:
|
|
for item in data["targets"]:
|
|
item_name = next(iter(item.keys()))
|
|
if item_name not in itemsList:
|
|
raise InvalidAttributeError("targets", item_name, itemsList)
|
|
|
|
item_values = item[item_name]
|
|
if item_values:
|
|
XML.SubElement(
|
|
jacoco, "maximum" + item_name.capitalize() + "Coverage"
|
|
).text = str(item_values.get("healthy", 0))
|
|
XML.SubElement(
|
|
jacoco, "minimum" + item_name.capitalize() + "Coverage"
|
|
).text = str(item_values.get("unhealthy", 0))
|
|
else:
|
|
raise MissingAttributeError(
|
|
["healthy", "unhealthy"], "publishers.jacoco.targets." + item_name
|
|
)
|
|
|
|
|
|
def ftp(registry, xml_parent, data):
|
|
"""yaml: ftp
|
|
Upload files via FTP.
|
|
Requires the Jenkins :jenkins-plugins:`Publish over FTP Plugin
|
|
<publish-over-ftp>`.
|
|
|
|
:arg str site: name of the ftp site (required)
|
|
:arg str target: destination directory (required)
|
|
:arg bool target-is-date-format: whether target is a date format. If true,
|
|
raw text should be quoted (default false)
|
|
:arg bool clean-remote: should the remote directory be deleted before
|
|
transferring files (default false)
|
|
:arg str source: source path specifier (required)
|
|
:arg str excludes: excluded file pattern (optional)
|
|
:arg str remove-prefix: prefix to remove from uploaded file paths
|
|
(optional)
|
|
:arg bool fail-on-error: fail the build if an error occurs (default false).
|
|
:arg bool flatten: only create files on the server, don't create
|
|
directories (default false).
|
|
:arg bool verbose: adds lots of detail useful for debug to the console
|
|
but generally should be left off (default false)
|
|
:arg int retries: the number of times to retry this server in the event of
|
|
failure (optional)
|
|
:arg int retry-delay: the time to wait, in milliseconds, before attempting
|
|
another transfer (default 10000)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/ftp-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/ftp-full.yaml
|
|
:language: yaml
|
|
|
|
"""
|
|
console_prefix = "FTP: "
|
|
plugin_tag = "jenkins.plugins.publish__over__ftp.BapFtpPublisherPlugin"
|
|
publisher_tag = "jenkins.plugins.publish__over__ftp.BapFtpPublisher"
|
|
transfer_tag = "jenkins.plugins.publish__over__ftp.BapFtpTransfer"
|
|
retry_tag = "jenkins.plugins.publish_over_ftp.BapFtpRetry"
|
|
plugin_reference_tag = "jenkins.plugins.publish_over_ftp." "BapFtpPublisherPlugin"
|
|
(_, transfer_node) = base_publish_over(
|
|
xml_parent,
|
|
data,
|
|
console_prefix,
|
|
plugin_tag,
|
|
publisher_tag,
|
|
transfer_tag,
|
|
retry_tag,
|
|
plugin_reference_tag,
|
|
)
|
|
mapping = [("", "asciiMode", "false")]
|
|
helpers.convert_mapping_to_xml(transfer_node, data, mapping, fail_required=True)
|
|
|
|
|
|
def ftp_publisher(registry, xml_parent, data):
|
|
"""yaml: ftp-publisher
|
|
This plugin can be used to upload project artifacts and whole directories
|
|
to an ftp server.
|
|
Requires the Jenkins :jenkins-plugins:`FTP-Publisher Plugin
|
|
<ftppublisher>`.
|
|
|
|
:arg list uploads: List of files to upload
|
|
|
|
:uploads:
|
|
* **file-path** ('str') -- Destination folder. It will be created
|
|
if doesn't exists. Created relative to ftp root directory.
|
|
(default '')
|
|
* **source-file** ('str') -- Source files which will be uploaded
|
|
(default '')
|
|
:arg str site-name: Name of FTP server to upload to (required)
|
|
:arg bool use-timestamps: Use timestamps in the FTP directory path (default
|
|
false)
|
|
:arg bool flatten-files: Flatten files on the FTP host (default false)
|
|
:arg bool skip-publishing: Skip publishing (default false)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/ftp-publisher-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/ftp-publisher-full.yaml
|
|
:language: yaml
|
|
"""
|
|
ftp = XML.SubElement(xml_parent, "com.zanox.hudson.plugins.FTPPublisher")
|
|
ftp.set("plugin", "ftppublisher")
|
|
|
|
entries = XML.SubElement(ftp, "entries")
|
|
if "uploads" in data:
|
|
upload_mapping = [
|
|
("file-path", "filePath", ""),
|
|
("source-file", "sourceFile", ""),
|
|
]
|
|
for upload in data["uploads"]:
|
|
entry = XML.SubElement(entries, "com.zanox.hudson.plugins.Entry")
|
|
helpers.convert_mapping_to_xml(
|
|
entry, upload, upload_mapping, fail_required=True
|
|
)
|
|
|
|
mapping = [
|
|
("site-name", "siteName", None),
|
|
("use-timestamps", "useTimestamps", False),
|
|
("flatten-files", "flatten", False),
|
|
("skip-publishing", "skip", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(ftp, data, mapping, fail_required=True)
|
|
|
|
|
|
def opsgenie(registry, xml_parent, data):
|
|
"""yaml: opsgenie
|
|
OpsGenie notification on build completion,
|
|
Requires the :jenkins-plugins:`OpsGenie Notifier Plugin <opsgenie>`.
|
|
|
|
:arg bool enable-sending-alerts: Send alerts to opsgenie. (default false)
|
|
:arg bool notify-build-start: Send a notification when the build starts. (default false)
|
|
: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 '')
|
|
:arg str tags: Comma-separated list of tags you want to add on alert. (default '')
|
|
:arg str teams: Comma-separated list of teams that get notified from alert. (default '')
|
|
:arg str priority: Set the priority of the alert that's going to be created at OpsGenie, if job's build fails. (default 'P3')
|
|
:arg str build-starts-alerts-priority: Set the priority of the build started alert that's going to be created at OpsGenie. (default 'P3')
|
|
:arg str api-url: Api url that collects the webhook. (default '')
|
|
|
|
Minimal example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/opsgenie-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/opsgenie-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
mapping = [
|
|
("priority", "alertPriority", "P3"),
|
|
("build-starts-alerts-priority", "notifyBuildStartPriority", "P3"),
|
|
("enable-sending-alerts", "enable", "false"),
|
|
("notify-build-start", "notifyBuildStart", "false"),
|
|
("api-key", "apiKey", ""),
|
|
("api-url", "apiUrl", ""),
|
|
("tags", "tags", ""),
|
|
("teams", "teams", ""),
|
|
]
|
|
|
|
opsgenie_notifier = XML.SubElement(
|
|
xml_parent,
|
|
"com.opsgenie.integration.jenkins.OpsGenieNotifier",
|
|
{"plugin": "opsgenie"},
|
|
)
|
|
|
|
helpers.convert_mapping_to_xml(opsgenie_notifier, data, mapping, fail_required=True)
|
|
|
|
|
|
def rocket(registry, xml_parent, data):
|
|
"""yaml: rocket
|
|
RocketChat notification on build completion,
|
|
Requires the :jenkins-plugins:`RocketChat Notifier Plugin
|
|
<rocketchatnotifier>`.
|
|
|
|
:arg str channel: Comma separated list of rooms (e.g. #project)
|
|
or persons (e.g. @john)
|
|
:arg bool abort: Notify abort (default false)
|
|
:arg bool start: Notify start (default false)
|
|
:arg bool success: Notify success (default false)
|
|
:arg bool failure: Notify failure (default false)
|
|
:arg bool repeated-failure: Notify repeated failure (default false)
|
|
:arg bool back-to-normal: Notify back to normal (default false)
|
|
:arg bool not-built: Notify if not built (default false)
|
|
:arg bool unstable: Notify if unstable (default false)
|
|
:arg str webhook-token: Webhook token for posting messages.
|
|
Overrides global authentication data and channel
|
|
:arg str commit-info: What commit information to include into
|
|
notification message.
|
|
|
|
:commit-info values:
|
|
* **none**
|
|
* **authors**
|
|
* **authors-and-titles**
|
|
|
|
:arg str custom-message: Custom text message (default '')
|
|
:arg bool trust-ssl: Trust RocketChat server certificate, if checked,
|
|
the SSL certificate will not be checked (default false)
|
|
:arg str build-server: Build Server URL
|
|
:arg list attachments: Optional list of attachments
|
|
|
|
:attachments:
|
|
* **title** (`str`) Attachment title (required)
|
|
* **title-link** (`str`)
|
|
* **title-link-download** (`bool`)
|
|
* **color** (`str`)
|
|
* **text** (`str`)
|
|
* **collapsed** (`bool`)
|
|
* **message-link** (`str`)
|
|
* **author-name** (`str`)
|
|
* **author-link** (`str`)
|
|
* **author-icon** (`str`)
|
|
* **thumb** (`str`) Thumb URL
|
|
* **image** (`str`) Image URL
|
|
* **audio** (`str`) Audio URL
|
|
* **video** (`str`) Video URL
|
|
|
|
Minimal example using defaults:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/rocket001.yaml
|
|
:language: yaml
|
|
|
|
Full example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/rocket002.yaml
|
|
:language: yaml
|
|
"""
|
|
rocketchat = XML.SubElement(
|
|
xml_parent, "jenkins.plugins.rocketchatnotifier.RocketChatNotifier"
|
|
)
|
|
rocketchat.set("plugin", "rocketchatnotifier")
|
|
required_mapping = [
|
|
("channel", "channel", ""),
|
|
("start", "startNotification", False),
|
|
("success", "notifySuccess", False),
|
|
("abort", "notifyAborted", False),
|
|
("not-built", "notifyNotBuilt", False),
|
|
("unstable", "notifyUnstable", False),
|
|
("failure", "notifyFailure", False),
|
|
("back-to-normal", "notifyBackToNormal", False),
|
|
("repeated-failure", "notifyRepeatedFailure", False),
|
|
("include-test-summary", "includeTestSummary", False),
|
|
("include-test-log", "includeTestLog", False),
|
|
("include-custom-message", "includeCustomMessage", False),
|
|
(
|
|
"commit-info",
|
|
"commitInfoChoice",
|
|
"none",
|
|
{
|
|
"none": "NONE",
|
|
"authors": "AUTHORS",
|
|
"authors-and-titles": "AUTHORS_AND_TITLES",
|
|
},
|
|
),
|
|
("raw-message", "rawMessage", False),
|
|
("webhook-token", "webhookToken", ""),
|
|
("webhook-token-credential-id", "webhookTokenCredentialId", ""),
|
|
]
|
|
optional_mapping = [
|
|
("trust-ssl", "trustSSL", None),
|
|
("build-server", "buildServerUrl", None),
|
|
]
|
|
|
|
helpers.convert_mapping_to_xml(
|
|
rocketchat, data, optional_mapping, fail_required=False
|
|
)
|
|
helpers.convert_mapping_to_xml(
|
|
rocketchat, data, required_mapping, fail_required=True
|
|
)
|
|
|
|
attach_required_mapping = [("title", "title", None)]
|
|
attach_optional_mapping = [
|
|
("title-link", "titleLink", None),
|
|
("title-link-download", "titleLinkDownload", None),
|
|
("color", "color", None),
|
|
("text", "text", None),
|
|
("collapsed", "collapsed", None), # false | true
|
|
("message-link", "messageLink", None),
|
|
("author-name", "authorName", None),
|
|
("author-link", "authorLink", None),
|
|
("author-icon", "authorIcon", None),
|
|
("thumb", "thumbUrl", None),
|
|
("image", "imageUrl", None),
|
|
("audio", "audioUrl", None),
|
|
("video", "videoUrl", None),
|
|
]
|
|
attach_list = data.get("attachments", None)
|
|
|
|
attachments = XML.SubElement(rocketchat, "attachments")
|
|
if attach_list is not None:
|
|
for attach_data in attach_list:
|
|
item = XML.SubElement(
|
|
attachments,
|
|
"jenkins.plugins.rocketchatnotifier.model.MessageAttachment",
|
|
)
|
|
helpers.convert_mapping_to_xml(
|
|
item, attach_data, attach_required_mapping, fail_required=True
|
|
)
|
|
helpers.convert_mapping_to_xml(
|
|
item, attach_data, attach_optional_mapping, fail_required=False
|
|
)
|
|
|
|
XML.SubElement(rocketchat, "customMessage").text = data.get("custom-message", "")
|
|
|
|
|
|
def hp_alm(registry, xml_parent, data):
|
|
"""yaml: hp-alm
|
|
Publish test results to HP-ALM.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Micro Focus Application Automation
|
|
Tools <hp-application-automation-tools-plugin>`.
|
|
|
|
:arg str server-name: The name of the ALM Server. (required)
|
|
:arg str credentials-id: credentials-id of the user (default '')
|
|
:arg str domaine: The Domain of the project to be used. (required)
|
|
:arg str client-type: Client type is required for some ALM above 12.60
|
|
in authentication.(default '')
|
|
:arg str project: The project to be used. (required)
|
|
:arg str testing-framework: The testing framework that is used when
|
|
generate the testing result file. (default Junit)
|
|
:arg str testing-tool: The testing tool that is used when generate
|
|
the testing result file. (default '')
|
|
:arg str folder: The path of the test folder that will contain
|
|
the uploaded test.
|
|
The path doesn't include the Root test folder (Subject).
|
|
For example, sampletestfolder/subfolder means, the tests will be
|
|
uploaded to test folder named 'subfolder', which is under
|
|
the test folder named 'sampletestfolder', and 'sampletestfolder'
|
|
is under the root test folder 'Subject'. (required)
|
|
:arg str set-folder: The path of the testset folder that will contain
|
|
the uploaded testset. The path doesn't include the Root testset folder.
|
|
For example, sampletestsetfolder/subfolder means, the testsets will be
|
|
uploaded to testset folder named 'subfolder', which is under
|
|
the testset folder named 'sampletestsetfolder',
|
|
and 'sampletestsetfolder' is under the root testset folder 'Root'.
|
|
(required)
|
|
:arg str testing-result-file: The condition to find the testing
|
|
result file, start from the root path of the job.
|
|
For example, ``**/junitResult.xml`` to find testing result file
|
|
for Junit Plugin, ``**/testng-results.xml`` to find
|
|
testing result file for TestNG plugin. (required)
|
|
:arg str jenkins-server-url: The HTTP URL of the Jenkins Server,
|
|
form example, http://jenkins.example.org:8080 . (optional)
|
|
|
|
Minimal example using defaults:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/hp-alm001.yaml
|
|
:language: yaml
|
|
|
|
Full example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/hp-alm002.yaml
|
|
:language: yaml
|
|
"""
|
|
alm_uploader = XML.SubElement(
|
|
xml_parent,
|
|
"com.microfocus.application.automation."
|
|
"tools.results.TestResultToALMUploader",
|
|
)
|
|
alm_uploader.set("plugin", "hp-application-automation-tools-plugin")
|
|
mapping = [
|
|
("server-name", "almServerName", None),
|
|
("credentials-id", "credentialsId", ""),
|
|
("domain", "almDomain", None),
|
|
("project", "almProject", None),
|
|
("client-type", "clientType", ""),
|
|
("testing-framework", "testingFramework", "JUnit"),
|
|
("testing-tool", "testingTool", ""),
|
|
("folder", "almTestFolder", None),
|
|
("set-folder", "almTestSetFolder", None),
|
|
("testing-result-file", "testingResultFile", None),
|
|
("jenkins-server-url", "jenkinsServerUrl", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(alm_uploader, data, mapping, fail_required=True)
|
|
|
|
|
|
def junit(registry, xml_parent, data):
|
|
"""yaml: junit
|
|
Publish JUnit test results. Requires the Jenkins :jenkins-plugins:`JUnit
|
|
Plugin <junit>`.
|
|
|
|
:arg str results: results filename (required)
|
|
:arg bool keep-long-stdio: Retain long standard output/error in test
|
|
results (default true).
|
|
:arg float health-scale-factor: Amplification factor to apply to test
|
|
failures when computing the test result contribution to the build
|
|
health score. (default 1.0)
|
|
:arg bool allow-empty-results: Do not fail the build on empty test results
|
|
(default false)
|
|
:arg bool skip-publishing-checks: Do not publish issues to SCM provider
|
|
platforms (default false)
|
|
:arg bool skip-marking-build-unstable: Do not mark build as unstable on
|
|
test failure (default false)
|
|
:arg bool test-stability: Add historical information about test
|
|
results stability (default false).
|
|
Requires the Jenkins :jenkins-plugins:`Test stability Plugin
|
|
<test-stability>`.
|
|
:arg bool claim-build: Allow claiming of failed tests (default false)
|
|
Requires the Jenkins :jenkins-plugins:`Claim Plugin <claim>`.
|
|
:arg bool measurement-plots: Create measurement plots (default false)
|
|
Requires the Jenkins :jenkins-github:`Measurement Plots Plugin
|
|
<measurement-plots-plugin>`.
|
|
:arg bool flaky-test-reports: Publish flaky test reports (default false).
|
|
Requires the Jenkins :jenkins-plugins:`Flaky Test Handler Plugin
|
|
<flaky-test-handler>`.
|
|
:arg bool junit-attachments: Publish test attachments (default false).
|
|
Requires the Jenkins :jenkins-plugins:`JUnit Attachments Plugin
|
|
<junit-attachments>`.
|
|
|
|
|
|
Minimal example using defaults:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/junit001.yaml
|
|
:language: yaml
|
|
|
|
Full example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/junit002.yaml
|
|
:language: yaml
|
|
"""
|
|
junitresult = XML.SubElement(xml_parent, "hudson.tasks.junit.JUnitResultArchiver")
|
|
junitresult.set("plugin", "junit")
|
|
mapping = [
|
|
("results", "testResults", None),
|
|
("keep-long-stdio", "keepLongStdio", True),
|
|
("health-scale-factor", "healthScaleFactor", "1.0"),
|
|
("allow-empty-results", "allowEmptyResults", False),
|
|
("skip-publishing-checks", "skipPublishingChecks", False),
|
|
("skip-marking-build-unstable", "skipMarkingBuildUnstable", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(junitresult, data, mapping, fail_required=True)
|
|
|
|
datapublisher = XML.SubElement(junitresult, "testDataPublishers")
|
|
if str(data.get("test-stability", False)).lower() == "true":
|
|
XML.SubElement(
|
|
datapublisher,
|
|
"de.esailors.jenkins.teststability" ".StabilityTestDataPublisher",
|
|
)
|
|
if str(data.get("claim-build", False)).lower() == "true":
|
|
XML.SubElement(datapublisher, "hudson.plugins.claim.ClaimTestDataPublisher")
|
|
if str(data.get("measurement-plots", False)).lower() == "true":
|
|
XML.SubElement(
|
|
datapublisher, "hudson.plugins.measurement__plots.TestDataPublisher"
|
|
)
|
|
if str(data.get("flaky-test-reports", False)).lower() == "true":
|
|
XML.SubElement(
|
|
datapublisher,
|
|
"com.google.jenkins.flakyTestHandler.plugin" ".JUnitFlakyTestDataPublisher",
|
|
)
|
|
if str(data.get("junit-attachments", False)).lower() == "true":
|
|
XML.SubElement(
|
|
datapublisher, "hudson.plugins.junitattachments.AttachmentPublisher"
|
|
)
|
|
|
|
|
|
def cucumber_reports(registry, xml_parent, data):
|
|
"""yaml: cucumber-reports
|
|
This plugin creates pretty cucumber-jvm html reports on jenkins.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`cucumber reports
|
|
<cucumber-reports>`.
|
|
|
|
:arg str json-reports-path: The path relative to the workspace of
|
|
the json reports generated by cucumber-jvm e.g. target - leave
|
|
empty to scan the whole workspace (default '')
|
|
:arg str file-include-pattern: Include pattern (default '')
|
|
:arg str file-exclude-pattern: Exclude pattern (default '')
|
|
:arg str plugin-url-path: The path to the jenkins user content url
|
|
e.g. :samp:`http://host:port[/jenkins/]plugin` - leave empty if jenkins
|
|
url root is host:port (default '')
|
|
:arg bool skipped-fails: Skipped steps to cause the build to fail
|
|
(default false)
|
|
:arg bool pending-fails: Pending steps to cause the build to fail
|
|
(default false)
|
|
:arg bool undefined-fails: Undefined steps to cause the build to fail
|
|
(default false)
|
|
:arg bool missing-fails: Missing steps to cause the build to fail
|
|
(default false)
|
|
:arg bool no-flash-charts: Use javascript charts instead of flash charts
|
|
(default false)
|
|
:arg bool ignore-failed-tests: Entire build to fail when these tests fail
|
|
(default false)
|
|
:arg bool parallel-testing: Run same test in parallel for multiple devices
|
|
(default false)
|
|
:arg int failed-steps-number: Maximum number of failed steps above which
|
|
build result is changed (default 0)
|
|
:arg int skipped-steps-number: Maximum number of skipped steps above which
|
|
build result is changed (default 0)
|
|
:arg int pending-steps-number: Maximum number of pending steps above which
|
|
build result is changed (default 0)
|
|
:arg int undefined-steps-number: Maximum number of undefined steps above
|
|
which build result is changed (default 0)
|
|
:arg int failed-scenarios-number: Maximum number of failed scenarios above
|
|
which build result is changed (default 0)
|
|
:arg int failed-features-number: Maximum number of failed features above
|
|
which build result is changed (default 0)
|
|
:arg list build-status: Build result to which the build should be set
|
|
when the report becomes failed or unstable (default '')
|
|
:arg int trends-limit: Number of past reports that should be presented.
|
|
Zero means unlimited number of builds (default 0)
|
|
:arg list sorting-method: Result sorting order (default 'NATURAL')
|
|
|
|
Full example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/cucumber-reports-full.yaml
|
|
:language: yaml
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/cucumber-reports-minimal.yaml
|
|
:language: yaml
|
|
"""
|
|
cucumber_reports = XML.SubElement(
|
|
xml_parent, "net.masterthought.jenkins." "CucumberReportPublisher"
|
|
)
|
|
cucumber_reports.set("plugin", "cucumber-reports")
|
|
|
|
valid_build_status = ["", "UNSTABLE", "FAILURE"]
|
|
valid_sorting_method = ["NATURAL", "ALPHABETICAL"]
|
|
mappings = [
|
|
("json-reports-path", "jsonReportDirectory", ""),
|
|
("plugin-url-path", "pluginUrlPath", ""),
|
|
("file-include-pattern", "fileIncludePattern", ""),
|
|
("file-exclude-pattern", "fileExcludePattern", ""),
|
|
("skipped-fails", "skippedFails", False),
|
|
("pending-fails", "pendingFails", False),
|
|
("undefined-fails", "undefinedFails", False),
|
|
("missing-fails", "missingFails", False),
|
|
("no-flash-charts", "noFlashCharts", False),
|
|
("ignore-failed-tests", "ignoreFailedTests", False),
|
|
("parallel-testing", "parallelTesting", False),
|
|
("failed-steps-number", "failedStepsNumber", 0),
|
|
("skipped-steps-number", "skippedStepsNumber", 0),
|
|
("pending-steps-number", "pendingStepsNumber", 0),
|
|
("undefined-steps-number", "undefinedStepsNumber", 0),
|
|
("failed-scenarios-number", "failedScenariosNumber", 0),
|
|
("failed-features-number", "failedFeaturesNumber", 0),
|
|
("build-status", "buildStatus", "", valid_build_status),
|
|
("trends-limit", "trendsLimit", 0),
|
|
("sorting-method", "sortingMethod", "NATURAL", valid_sorting_method),
|
|
]
|
|
helpers.convert_mapping_to_xml(cucumber_reports, data, mappings, fail_required=True)
|
|
|
|
if "sorting-values" in data:
|
|
format_dict = {
|
|
"classifications": "net.masterthought.jenkins"
|
|
".CucumberReportPublisher_-Classification"
|
|
}
|
|
classifications_tag = XML.SubElement(cucumber_reports, "classifications")
|
|
for values in data["sorting-values"]:
|
|
for value, params in values.items():
|
|
cucumber_report_publisher = XML.SubElement(
|
|
classifications_tag, format_dict.get("classifications")
|
|
)
|
|
XML.SubElement(cucumber_report_publisher, "key").text = params.get(
|
|
"key"
|
|
)
|
|
XML.SubElement(cucumber_report_publisher, "value").text = params.get(
|
|
"value"
|
|
)
|
|
|
|
|
|
def cucumber_testresult(registry, xml_parent, data):
|
|
"""yaml: cucumber-testresult
|
|
Publish cucumber test results.
|
|
Requires the Jenkins :jenkins-plugins:`Cucumber testresult
|
|
<cucumber-testresult-plugin>`.
|
|
|
|
:arg str results: Results filename (required)
|
|
:arg bool ignore-bad-steps: Ignore not existed step results (default false)
|
|
|
|
Minimal example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/cucumber-testresult-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/cucumber-testresult-full.yaml
|
|
:language: yaml
|
|
"""
|
|
cucumber_result = XML.SubElement(
|
|
xml_parent,
|
|
"org.jenkinsci.plugins.cucumber."
|
|
"jsontestsupport."
|
|
"CucumberTestResultArchiver",
|
|
)
|
|
cucumber_result.set("plugin", "cucumber-testresult-plugin")
|
|
|
|
mappings = [
|
|
("results", "testResults", None),
|
|
("ignore-bad-steps", "ignoreBadSteps", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(cucumber_result, data, mappings, fail_required=True)
|
|
|
|
|
|
def xunit(registry, xml_parent, data):
|
|
"""yaml: xunit
|
|
Publish tests results. Requires the Jenkins :jenkins-plugins:`xUnit Plugin
|
|
<xunit>`.
|
|
|
|
:arg str thresholdmode: Whether thresholds represents an absolute number
|
|
of tests or a percentage. Either 'number' or 'percent'. (default
|
|
'number')
|
|
:arg list thresholds: Thresholds for both 'failed' and 'skipped' tests.
|
|
|
|
:threshold (`dict`): Threshold values to set, where missing, xUnit
|
|
should default to an internal value of 0. Each test threshold
|
|
should contain the following:
|
|
|
|
* **unstable** (`int`)
|
|
* **unstablenew** (`int`)
|
|
* **failure** (`int`)
|
|
* **failurenew** (`int`)
|
|
|
|
:arg int test-time-margin: Give the report time margin value in ms, before
|
|
to fail if not new unless the option **requireupdate** is set for the
|
|
configured framework. (default 3000)
|
|
:arg list types: Frameworks to configure, and options. Supports the
|
|
following: ``aunit``, ``boosttest``, ``checktype``, ``cpptest``,
|
|
``cppunit``, ``ctest``, ``dotnettest``, ``embunit``, ``fpcunit``,
|
|
``gtest``, ``junit``, ``mstest``, ``nunit``, ``phpunit``, ``tusar``,
|
|
``unittest``, and ``valgrind``.
|
|
|
|
The 'custom' type is not supported.
|
|
|
|
:type (`dict`): each type can be configured using the following:
|
|
|
|
* **pattern** (`str`): An Ant pattern to look for Junit result
|
|
files, relative to the workspace root (default '')
|
|
* **requireupdate** (`bool`): fail the build whenever fresh tests
|
|
results have not been found (default true).
|
|
* **deleteoutput** (`bool`): delete temporary JUnit files
|
|
(default true).
|
|
* **skip-if-no-test-files** (`bool`): Skip parsing this xUnit type
|
|
report if there are no test reports files (default false).
|
|
* **stoponerror** (`bool`): Fail the build whenever an error occur
|
|
during a result file processing (default true).
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/xunit001.yaml
|
|
:language: yaml
|
|
|
|
"""
|
|
info = registry.get_plugin_info("xunit")
|
|
plugin_version = pkg_resources.parse_version(info.get("version", str(sys.maxsize)))
|
|
|
|
logger = logging.getLogger(__name__)
|
|
xunit = XML.SubElement(xml_parent, "xunit")
|
|
xunit.set("plugin", "xunit")
|
|
|
|
# Map our internal types to the XML element names used by Jenkins plugin
|
|
types_to_plugin_types = {
|
|
"aunit": "AUnitJunitHudsonTestType",
|
|
"boosttest": "BoostTestJunitHudsonTestType",
|
|
"checktype": "CheckType",
|
|
"cpptest": "CppTestJunitHudsonTestType",
|
|
"cppunit": "CppUnitJunitHudsonTestType",
|
|
"ctest": "CTestType",
|
|
"dotnettest": "XUnitDotNetTestType", # since plugin v1.93
|
|
"embunit": "EmbUnitType", # since plugin v1.84
|
|
"fpcunit": "FPCUnitJunitHudsonTestType",
|
|
"gtest": "GoogleTestType",
|
|
"junit": "JUnitType",
|
|
"mstest": "MSTestJunitHudsonTestType",
|
|
"nunit": "NUnitJunitHudsonTestType",
|
|
"phpunit": "PHPUnitJunitHudsonTestType",
|
|
"tusar": "TUSARJunitHudsonTestType",
|
|
"unittest": "UnitTestJunitHudsonTestType",
|
|
"valgrind": "ValgrindJunitHudsonTestType",
|
|
# FIXME should implement the 'custom' type
|
|
}
|
|
implemented_types = types_to_plugin_types.keys() # shortcut
|
|
|
|
# Unit framework we are going to generate xml for
|
|
supported_types = []
|
|
|
|
for configured_type in data["types"]:
|
|
type_name = next(iter(configured_type.keys()))
|
|
if type_name not in implemented_types:
|
|
logger.warning("Requested xUnit type '%s' is not yet supported", type_name)
|
|
else:
|
|
# Append for generation
|
|
supported_types.append(configured_type)
|
|
|
|
# Generate XML for each of the supported framework types
|
|
# Note: versions 3+ are now using the 'tools' sub-element instead of 'types'
|
|
if plugin_version < pkg_resources.parse_version("3.0.0"):
|
|
types_name = "types"
|
|
else:
|
|
types_name = "tools"
|
|
|
|
xmltypes = XML.SubElement(xunit, types_name)
|
|
for supported_type in supported_types:
|
|
framework_name = next(iter(supported_type.keys()))
|
|
xmlframework = XML.SubElement(xmltypes, types_to_plugin_types[framework_name])
|
|
|
|
mappings = [
|
|
("pattern", "pattern", ""),
|
|
("requireupdate", "failIfNotNew", True),
|
|
("deleteoutput", "deleteOutputFiles", True),
|
|
("skip-if-no-test-files", "skipNoTestFiles", False),
|
|
("stoponerror", "stopProcessingIfError", True),
|
|
]
|
|
helpers.convert_mapping_to_xml(
|
|
xmlframework, supported_type[framework_name], mappings, fail_required=True
|
|
)
|
|
|
|
xmlthresholds = XML.SubElement(xunit, "thresholds")
|
|
for t in data.get("thresholds", []):
|
|
if not ("failed" in t or "skipped" in t):
|
|
logger.warning("Unrecognized threshold, should be 'failed' or 'skipped'")
|
|
continue
|
|
elname = (
|
|
"org.jenkinsci.plugins.xunit.threshold.%sThreshold"
|
|
% next(iter(t.keys())).title()
|
|
)
|
|
el = XML.SubElement(xmlthresholds, elname)
|
|
for threshold_name, threshold_value in next(iter(t.values())).items():
|
|
# Normalize and craft the element name for this threshold
|
|
elname = "%sThreshold" % threshold_name.lower().replace("new", "New")
|
|
XML.SubElement(el, elname).text = str(threshold_value)
|
|
|
|
# Whether to use percent of exact number of tests.
|
|
# Thresholdmode is either:
|
|
# - 1 : absolute (number of tests), default.
|
|
# - 2 : relative (percentage of tests)
|
|
thresholdmode = "1"
|
|
if "percent" == data.get("thresholdmode", "number"):
|
|
thresholdmode = "2"
|
|
XML.SubElement(xunit, "thresholdMode").text = thresholdmode
|
|
|
|
extra_config = XML.SubElement(xunit, "extraConfiguration")
|
|
XML.SubElement(extra_config, "testTimeMargin").text = str(
|
|
data.get("test-time-margin", "3000")
|
|
)
|
|
|
|
|
|
def _violations_add_entry(xml_parent, name, data):
|
|
vmin = data.get("min", 10)
|
|
vmax = data.get("max", 999)
|
|
vunstable = data.get("unstable", 999)
|
|
pattern = data.get("pattern", None)
|
|
|
|
entry = XML.SubElement(xml_parent, "entry")
|
|
mapping = [("", "string", name)]
|
|
helpers.convert_mapping_to_xml(entry, data, mapping, fail_required=True)
|
|
|
|
tconfig = XML.SubElement(entry, "hudson.plugins.violations.TypeConfig")
|
|
mapping = [
|
|
("", "type", name),
|
|
("", "min", str(vmin)),
|
|
("", "max", str(vmax)),
|
|
("", "unstable", str(vunstable)),
|
|
("", "usePattern", "false"),
|
|
]
|
|
helpers.convert_mapping_to_xml(tconfig, data, mapping, fail_required=True)
|
|
|
|
if pattern:
|
|
XML.SubElement(tconfig, "pattern").text = pattern
|
|
else:
|
|
XML.SubElement(tconfig, "pattern")
|
|
|
|
|
|
def violations(registry, xml_parent, data):
|
|
"""yaml: violations
|
|
Publish code style violations.
|
|
Requires the Jenkins :jenkins-plugins:`Violations Plugin <violations>`.
|
|
|
|
The violations component accepts any number of dictionaries keyed
|
|
by the name of the violations system. The dictionary has the
|
|
following values:
|
|
|
|
:arg int min: sunny threshold
|
|
:arg int max: stormy threshold
|
|
:arg int unstable: unstable threshold
|
|
:arg str pattern: report filename pattern
|
|
|
|
Any system without a dictionary provided will use default values.
|
|
|
|
Valid systems are:
|
|
|
|
checkstyle, codenarc, cpd, cpplint, csslint, findbugs, fxcop,
|
|
gendarme, jcreport, jslint, pep8, perlcritic, pmd, pylint,
|
|
simian, stylecop
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/violations001.yaml
|
|
:language: yaml
|
|
"""
|
|
violations = XML.SubElement(
|
|
xml_parent, "hudson.plugins.violations." "ViolationsPublisher"
|
|
)
|
|
config = XML.SubElement(violations, "config")
|
|
suppressions = XML.SubElement(config, "suppressions", {"class": "tree-set"})
|
|
XML.SubElement(suppressions, "no-comparator")
|
|
configs = XML.SubElement(config, "typeConfigs")
|
|
XML.SubElement(configs, "no-comparator")
|
|
|
|
for name in [
|
|
"checkstyle",
|
|
"codenarc",
|
|
"cpd",
|
|
"cpplint",
|
|
"csslint",
|
|
"findbugs",
|
|
"fxcop",
|
|
"gendarme",
|
|
"jcreport",
|
|
"jslint",
|
|
"pep8",
|
|
"perlcritic",
|
|
"pmd",
|
|
"pylint",
|
|
"simian",
|
|
"stylecop",
|
|
]:
|
|
_violations_add_entry(configs, name, data.get(name, {}))
|
|
mapping = [
|
|
("", "limit", "100"),
|
|
("", "sourcePathPattern", ""),
|
|
("", "fauxProjectPath", ""),
|
|
("", "encoding", "default"),
|
|
]
|
|
helpers.convert_mapping_to_xml(config, data, mapping, fail_required=True)
|
|
|
|
|
|
def findbugs(registry, xml_parent, data):
|
|
r"""yaml: findbugs
|
|
FindBugs reporting for builds
|
|
|
|
Requires the Jenkins FindBugs Plugin
|
|
(https://github.com/jenkinsci/findbugs-plugin).
|
|
|
|
:arg str pattern: specifies the generated raw FindBugs XML report files,
|
|
such as \*\*/findbugs.xml or \*\*/findbugsXml.xml. (default '')
|
|
:arg bool rank-priority: Use rank as priority (default false)
|
|
:arg str include-files: Comma separated list of files to include.
|
|
(default '')
|
|
:arg str exclude-files: Comma separated list of files to exclude.
|
|
(default '')
|
|
:arg bool can-run-on-failed: Weather or not to run plug-in on failed builds
|
|
(default false)
|
|
:arg bool should-detect-modules: Determines if Ant or Maven modules should
|
|
be detected for all files that contain warnings. (default false)
|
|
:arg int healthy: Sunny threshold (default '')
|
|
:arg int unhealthy: Stormy threshold (default '')
|
|
:arg str health-threshold: Threshold priority for health status
|
|
('low', 'normal' or 'high', defaulted to 'low')
|
|
:arg bool dont-compute-new: If set to false, computes new warnings based on
|
|
the reference build (default true)
|
|
:arg bool use-delta-values: Use delta for new warnings. (default false)
|
|
:arg bool use-previous-build-as-reference: If set then the number of new
|
|
warnings will always be calculated based on the previous build.
|
|
Otherwise the reference build. (default false)
|
|
:arg bool use-stable-build-as-reference: The number of new warnings will be
|
|
calculated based on the last stable build, allowing reverts of unstable
|
|
builds where the number of warnings was decreased. (default false)
|
|
:arg dict thresholds:
|
|
:thresholds:
|
|
* **unstable** (`dict`)
|
|
:unstable: * **total-all** (`int`)
|
|
* **total-high** (`int`)
|
|
* **total-normal** (`int`)
|
|
* **total-low** (`int`)
|
|
* **new-all** (`int`)
|
|
* **new-high** (`int`)
|
|
* **new-normal** (`int`)
|
|
* **new-low** (`int`)
|
|
|
|
* **failed** (`dict`)
|
|
:failed: * **total-all** (`int`)
|
|
* **total-high** (`int`)
|
|
* **total-normal** (`int`)
|
|
* **total-low** (`int`)
|
|
* **new-all** (`int`)
|
|
* **new-high** (`int`)
|
|
* **new-normal** (`int`)
|
|
* **new-low** (`int`)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/findbugs-minimal.yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/findbugs-full.yaml
|
|
"""
|
|
findbugs = XML.SubElement(xml_parent, "hudson.plugins.findbugs.FindBugsPublisher")
|
|
findbugs.set("plugin", "findbugs")
|
|
|
|
helpers.findbugs_settings(findbugs, data)
|
|
helpers.build_trends_publisher("[FINDBUGS] ", findbugs, data)
|
|
|
|
|
|
def checkstyle(registry, xml_parent, data):
|
|
"""yaml: checkstyle
|
|
Publish trend reports with Checkstyle.
|
|
|
|
Requires the Jenkins Checkstyle Plugin
|
|
(https://github.com/jenkinsci/checkstyle-plugin).
|
|
|
|
The checkstyle component accepts a dictionary with the
|
|
following values:
|
|
|
|
:arg str pattern: Report filename pattern (default '')
|
|
:arg bool can-run-on-failed: Also runs for failed builds, instead of just
|
|
stable or unstable builds (default false)
|
|
:arg bool should-detect-modules: Determines if Ant or Maven modules should
|
|
be detected for all files that contain warnings (default false)
|
|
:arg int healthy: Sunny threshold (default '')
|
|
:arg int unhealthy: Stormy threshold (default '')
|
|
:arg str health-threshold: Threshold priority for health status
|
|
('low', 'normal' or 'high') (default 'low')
|
|
:arg dict thresholds: Mark build as failed or unstable if the number of
|
|
errors exceeds a threshold. (optional)
|
|
|
|
:thresholds:
|
|
* **unstable** (`dict`)
|
|
:unstable: * **total-all** (`int`)
|
|
* **total-high** (`int`)
|
|
* **total-normal** (`int`)
|
|
* **total-low** (`int`)
|
|
* **new-all** (`int`)
|
|
* **new-high** (`int`)
|
|
* **new-normal** (`int`)
|
|
* **new-low** (`int`)
|
|
|
|
* **failed** (`dict`)
|
|
:failed: * **total-all** (`int`)
|
|
* **total-high** (`int`)
|
|
* **total-normal** (`int`)
|
|
* **total-low** (`int`)
|
|
* **new-all** (`int`)
|
|
* **new-high** (`int`)
|
|
* **new-normal** (`int`)
|
|
* **new-low** (`int`)
|
|
:arg str default-encoding: Encoding for parsing or showing files
|
|
(default '')
|
|
:arg bool do-not-resolve-relative-paths: (default false)
|
|
:arg bool dont-compute-new: If set to false, computes new warnings based on
|
|
the reference build (default true)
|
|
:arg bool use-previous-build-as-reference: determines whether to always
|
|
use the previous build as the reference build (default false)
|
|
:arg bool use-stable-build-as-reference: The number of new warnings will be
|
|
calculated based on the last stable build, allowing reverts of unstable
|
|
builds where the number of warnings was decreased. (default false)
|
|
:arg bool use-delta-values: If set then the number of new warnings is
|
|
calculated by subtracting the total number of warnings of the current
|
|
build from the reference build. (default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/checkstyle004.yaml
|
|
:language: yaml
|
|
|
|
Full example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/checkstyle006.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
def convert_settings(lookup, data):
|
|
"""Helper to convert settings from one key to another."""
|
|
|
|
for old_key in list(data.keys()):
|
|
if old_key in lookup:
|
|
data.setdefault(lookup[old_key], data[old_key])
|
|
del data[old_key]
|
|
|
|
checkstyle = XML.SubElement(
|
|
xml_parent, "hudson.plugins.checkstyle." "CheckStylePublisher"
|
|
)
|
|
checkstyle.set("plugin", "checkstyle")
|
|
|
|
# Convert old style yaml to new style
|
|
convert_settings(
|
|
{
|
|
"unHealthy": "unhealthy",
|
|
"healthThreshold": "health-threshold",
|
|
"defaultEncoding": "default-encoding",
|
|
"canRunOnFailed": "can-run-on-failed",
|
|
"shouldDetectModules": "should-detect-modules",
|
|
},
|
|
data,
|
|
)
|
|
|
|
threshold_data = data.get("thresholds", {})
|
|
for threshold in ["unstable", "failed"]:
|
|
convert_settings(
|
|
{
|
|
"totalAll": "total-all",
|
|
"totalHigh": "total-high",
|
|
"totalNormal": "total-normal",
|
|
"totalLow": "total-low",
|
|
},
|
|
threshold_data.get(threshold, {}),
|
|
)
|
|
|
|
helpers.build_trends_publisher("[CHECKSTYLE] ", checkstyle, data)
|
|
|
|
|
|
def scp(registry, xml_parent, data):
|
|
"""yaml: scp
|
|
Upload files via SCP
|
|
Requires the Jenkins :jenkins-plugins:`SCP Plugin <scp>`.
|
|
|
|
When writing a publisher macro, it is important to keep in mind that
|
|
Jenkins uses Ant's `SCP Task
|
|
<https://ant.apache.org/manual/Tasks/scp.html>`_ via the Jenkins
|
|
:jenkins-plugins:`SCP Plugin <scp>` which relies on `FileSet
|
|
<https://ant.apache.org/manual/Types/fileset.html>`_
|
|
and `DirSet <https://ant.apache.org/manual/Types/dirset.html>`_ patterns.
|
|
The relevant piece of documentation is excerpted below:
|
|
|
|
Source points to files which will be uploaded. You can use ant
|
|
includes syntax, eg. ``folder/dist/*.jar``. Path is constructed from
|
|
workspace root. Note that you cannot point files outside the workspace
|
|
directory. For example providing: ``../myfile.txt`` won't work...
|
|
Destination points to destination folder on remote site. It will be
|
|
created if doesn't exists and relative to root repository path. You
|
|
can define multiple blocks of source/destination pairs.
|
|
|
|
This means that absolute paths, e.g., ``/var/log/**`` will not work and
|
|
will fail to compile. All paths need to be relative to the directory that
|
|
the publisher runs and the paths have to be contained inside of that
|
|
directory. The relative working directory is usually::
|
|
|
|
/home/jenkins/workspace/${JOB_NAME}
|
|
|
|
:arg str site: name of the scp site (required)
|
|
:arg str target: destination directory (required)
|
|
:arg str source: source path specifier (default '')
|
|
:arg bool keep-hierarchy: keep the file hierarchy when uploading
|
|
(default false)
|
|
:arg bool copy-after-failure: copy files even if the job fails
|
|
(default false)
|
|
:arg bool copy-console: copy the console log (default false); if
|
|
specified, omit 'source'
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/scp001.yaml
|
|
:language: yaml
|
|
"""
|
|
scp = XML.SubElement(
|
|
xml_parent, "be.certipost.hudson.plugin.SCPRepositoryPublisher"
|
|
)
|
|
scp.set("plugin", "scp")
|
|
|
|
mappings = [("site", "siteName", None)]
|
|
helpers.convert_mapping_to_xml(scp, data, mappings, fail_required=True)
|
|
|
|
entries = XML.SubElement(scp, "entries")
|
|
for entry in data["files"]:
|
|
entry_e = XML.SubElement(entries, "be.certipost.hudson.plugin.Entry")
|
|
mappings = [
|
|
("target", "filePath", None),
|
|
("source", "sourceFile", ""),
|
|
("keep-hierarchy", "keepHierarchy", False),
|
|
("copy-console", "copyConsoleLog", False),
|
|
("copy-after-failure", "copyAfterFailure", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(entry_e, entry, mappings, fail_required=True)
|
|
|
|
|
|
def ssh(registry, xml_parent, data):
|
|
"""yaml: ssh
|
|
Upload files via SCP.
|
|
Requires the Jenkins :jenkins-plugins:`Publish over SSH Plugin
|
|
<publish-over-ssh>`.
|
|
|
|
:arg str site: name of the ssh site
|
|
:arg str target: destination directory
|
|
:arg bool target-is-date-format: whether target is a date format. If true,
|
|
raw text should be quoted (default false)
|
|
:arg bool clean-remote: should the remote directory be deleted before
|
|
transferring files (default false)
|
|
:arg str source: source path specifier
|
|
:arg str command: a command to execute on the remote server (optional)
|
|
:arg int timeout: timeout in milliseconds for the Exec command (optional)
|
|
:arg bool use-pty: run the exec command in pseudo TTY (default false)
|
|
:arg str excludes: excluded file pattern (optional)
|
|
:arg str remove-prefix: prefix to remove from uploaded file paths
|
|
(optional)
|
|
:arg bool fail-on-error: fail the build if an error occurs (default false).
|
|
:arg bool always-publish-from-master: transfer the files through the master
|
|
before being sent to the remote server (defaults false)
|
|
:arg bool flatten: only create files on the server, don't create
|
|
directories (default false).
|
|
:arg bool verbose: adds lots of detail useful for debug to the console
|
|
but generally should be left off (default false)
|
|
:arg int retries: the number of times to retry this server in the event of
|
|
failure (optional)
|
|
:arg int retry-delay: the time to wait, in milliseconds, before attempting
|
|
another transfer (default 10000)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/ssh-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/ssh-full.yaml
|
|
:language: yaml
|
|
"""
|
|
console_prefix = "SSH: "
|
|
tag_prefix = "jenkins.plugins.publish"
|
|
publisher_tag = "%s__over__ssh.BapSshPublisher" % tag_prefix
|
|
transfer_tag = "%s__over__ssh.BapSshTransfer" % tag_prefix
|
|
retry_tag = "%s_over_ssh.BapSshRetry" % tag_prefix
|
|
reference_tag = "%s_over_ssh.BapSshPublisherPlugin" % tag_prefix
|
|
|
|
if xml_parent.tag == "publishers":
|
|
plugin_tag = "%s__over__ssh.BapSshPublisherPlugin" % tag_prefix
|
|
is_builder = False
|
|
else:
|
|
plugin_tag = "%s__over__ssh.BapSshBuilderPlugin" % tag_prefix
|
|
is_builder = True
|
|
|
|
base_publish_over(
|
|
xml_parent,
|
|
data,
|
|
console_prefix,
|
|
plugin_tag,
|
|
publisher_tag,
|
|
transfer_tag,
|
|
retry_tag,
|
|
reference_tag,
|
|
is_builder,
|
|
)
|
|
|
|
|
|
def pipeline(registry, xml_parent, data):
|
|
"""yaml: pipeline
|
|
Specify a downstream project in a pipeline.
|
|
Requires the Jenkins :jenkins-plugins:`Build Pipeline Plugin
|
|
<build-pipeline-plugin>`.
|
|
|
|
Use of the `node-label-name` or `node-label` parameters
|
|
requires the Jenkins :jenkins-plugins:`NodeLabel Parameter Plugin
|
|
<nodelabelparameter>`.
|
|
Note: 'node-parameters' overrides the Node that the triggered
|
|
project is tied to.
|
|
|
|
:arg list projects: list the jobs to trigger, will generate comma-separated
|
|
string containing the named jobs.
|
|
:arg str predefined-parameters: parameters to pass to the other
|
|
job (optional)
|
|
:arg bool current-parameters: Whether to include the parameters passed
|
|
to the current build to the triggered job (optional)
|
|
:arg bool node-parameters: Use the same Node for the triggered builds
|
|
that was used for this build. (optional)
|
|
:arg bool svn-revision: Pass svn revision to the triggered job (optional)
|
|
:arg bool include-upstream: Include/pass through Upstream SVN Revisons.
|
|
Only valid when 'svn-revision' is true. (default false)
|
|
:arg dict git-revision: Passes git revision to the triggered job
|
|
(optional).
|
|
|
|
* **combine-queued-commits** (bool): Whether to combine queued git
|
|
hashes or not (default false)
|
|
|
|
:arg dict boolean-parameters: Pass boolean parameters to the downstream
|
|
jobs. Specify the name and boolean value mapping of the parameters.
|
|
(optional)
|
|
:arg str property-file: Use properties from file (optional)
|
|
:arg bool fail-on-missing: Blocks the triggering of the downstream jobs
|
|
if any of the property files are not found in the workspace.
|
|
Only valid when 'property-file' is specified.
|
|
(default false)
|
|
:arg str file-encoding: Encoding of contents of the files. If not
|
|
specified, default encoding of the platform is used. Only valid when
|
|
'property-file' is specified. (optional)
|
|
:arg str restrict-matrix-project: Filter that restricts the subset
|
|
of the combinations that the downstream project will run (optional)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/pipeline002.yaml
|
|
:language: yaml
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/pipeline003.yaml
|
|
:language: yaml
|
|
|
|
|
|
You can build pipeline jobs that are re-usable in different pipelines by
|
|
using a :ref:`job-template` to define the pipeline jobs,
|
|
and variable substitution to specify the name of
|
|
the downstream job in the pipeline.
|
|
Job-specific substitutions are useful here (see :ref:`project`).
|
|
|
|
See 'samples/pipeline.yaml' for an example pipeline implementation.
|
|
"""
|
|
logger = logging.getLogger("%s:pipeline" % __name__)
|
|
param_order = helpers.trigger_get_parameter_order(registry, "pipeline")
|
|
|
|
if "project" in data:
|
|
logger.warning(
|
|
"Using 'project' for pipeline definition is deprecated. Please "
|
|
"update your job definition to use 'projects' with a list format."
|
|
)
|
|
|
|
projects = ",".join(data.get("projects", [data.get("project", "")]))
|
|
if projects != "":
|
|
|
|
pippub = XML.SubElement(
|
|
xml_parent,
|
|
"au.com.centrumsystems.hudson.plugin."
|
|
"buildpipeline.trigger.BuildPipelineTrigger",
|
|
)
|
|
|
|
configs = XML.SubElement(pippub, "configs")
|
|
|
|
helpers.trigger_project(configs, data, registry, param_order)
|
|
|
|
XML.SubElement(pippub, "downstreamProjectNames").text = projects
|
|
|
|
|
|
def email(registry, xml_parent, data):
|
|
"""yaml: email
|
|
Email notifications on build failure.
|
|
Requires the Jenkins :jenkins-plugins:`Mailer Plugin <mailer>`.
|
|
|
|
:arg str recipients: Space separated list of recipient email addresses
|
|
(required)
|
|
:arg bool notify-every-unstable-build: Send an email for every
|
|
unstable build (default true)
|
|
:arg bool send-to-individuals: Send an email to the individual
|
|
who broke the build (default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/email-minimal.yaml
|
|
:language: yaml
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/email-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
# TODO: raise exception if this is applied to a maven job
|
|
mailer = XML.SubElement(xml_parent, "hudson.tasks.Mailer")
|
|
mailer.set("plugin", "mailer")
|
|
mapping = [("recipients", "recipients", None)]
|
|
helpers.convert_mapping_to_xml(mailer, data, mapping, fail_required=True)
|
|
|
|
# Note the logic reversal (included here to match the GUI
|
|
if data.get("notify-every-unstable-build", True):
|
|
XML.SubElement(mailer, "dontNotifyEveryUnstableBuild").text = "false"
|
|
else:
|
|
XML.SubElement(mailer, "dontNotifyEveryUnstableBuild").text = "true"
|
|
XML.SubElement(mailer, "sendToIndividuals").text = str(
|
|
data.get("send-to-individuals", False)
|
|
).lower()
|
|
|
|
|
|
def claim_build(registry, xml_parent, data):
|
|
"""yaml: claim-build
|
|
Claim build failures
|
|
Requires the Jenkins :jenkins-plugins:`Claim Plugin <claim>`.
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/claim-build001.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
XML.SubElement(xml_parent, "hudson.plugins.claim.ClaimPublisher")
|
|
|
|
|
|
def base_email_ext(registry, xml_parent, data, ttype):
|
|
trigger = XML.SubElement(
|
|
xml_parent, "hudson.plugins.emailext.plugins.trigger." + ttype
|
|
)
|
|
|
|
info = registry.get_plugin_info("email-ext")
|
|
plugin_version = pkg_resources.parse_version(info.get("version", str(sys.maxsize)))
|
|
|
|
email = XML.SubElement(trigger, "email")
|
|
|
|
if plugin_version < pkg_resources.parse_version("2.39"):
|
|
XML.SubElement(email, "recipientList").text = ""
|
|
XML.SubElement(email, "subject").text = "$PROJECT_DEFAULT_SUBJECT"
|
|
XML.SubElement(email, "body").text = "$PROJECT_DEFAULT_CONTENT"
|
|
if plugin_version >= pkg_resources.parse_version("2.39"):
|
|
XML.SubElement(email, "replyTo").text = "$PROJECT_DEFAULT_REPLYTO"
|
|
XML.SubElement(email, "contentType").text = "project"
|
|
if "send-to" in data:
|
|
recipient_providers = None
|
|
if plugin_version < pkg_resources.parse_version("2.39"):
|
|
XML.SubElement(email, "sendToDevelopers").text = str(
|
|
"developers" in data["send-to"]
|
|
).lower()
|
|
XML.SubElement(email, "sendToRequester").text = str(
|
|
"requester" in data["send-to"]
|
|
).lower()
|
|
XML.SubElement(email, "includeCulprits").text = str(
|
|
"culprits" in data["send-to"]
|
|
).lower()
|
|
XML.SubElement(email, "sendToRecipientList").text = str(
|
|
"recipients" in data["send-to"]
|
|
).lower()
|
|
else:
|
|
for recipient in data["send-to"]:
|
|
if "developers" == recipient:
|
|
if recipient_providers is None:
|
|
recipient_providers = XML.SubElement(
|
|
email, "recipientProviders"
|
|
)
|
|
XML.SubElement(
|
|
recipient_providers,
|
|
"hudson.plugins.emailext.plugins.recipients.DevelopersRecipientProvider",
|
|
).text = ""
|
|
elif "requester" == recipient:
|
|
if recipient_providers is None:
|
|
recipient_providers = XML.SubElement(
|
|
email, "recipientProviders"
|
|
)
|
|
XML.SubElement(
|
|
recipient_providers,
|
|
"hudson.plugins.emailext.plugins.recipients.RequesterRecipientProvider",
|
|
).text = ""
|
|
elif "culprits" == recipient:
|
|
if recipient_providers is None:
|
|
recipient_providers = XML.SubElement(
|
|
email, "recipientProviders"
|
|
)
|
|
XML.SubElement(
|
|
recipient_providers,
|
|
"hudson.plugins.emailext.plugins.recipients.CulpritsRecipientProvider",
|
|
).text = ""
|
|
elif "recipients" == recipient:
|
|
if recipient_providers is None:
|
|
recipient_providers = XML.SubElement(
|
|
email, "recipientProviders"
|
|
)
|
|
XML.SubElement(
|
|
recipient_providers,
|
|
"hudson.plugins.emailext.plugins.recipients.ListRecipientProvider",
|
|
).text = ""
|
|
elif "failing-test-suspects-recipients" == recipient:
|
|
if recipient_providers is None:
|
|
recipient_providers = XML.SubElement(
|
|
email, "recipientProviders"
|
|
)
|
|
XML.SubElement(
|
|
recipient_providers,
|
|
"hudson.plugins.emailext.plugins.recipients.FailingTestSuspectsRecipientProvider",
|
|
).text = ""
|
|
elif "first-failing-build-suspects-recipients" == recipient:
|
|
if recipient_providers is None:
|
|
recipient_providers = XML.SubElement(
|
|
email, "recipientProviders"
|
|
)
|
|
XML.SubElement(
|
|
recipient_providers,
|
|
"hudson.plugins.emailext.plugins.recipients.FirstFailingBuildSuspectsRecipientProvider",
|
|
).text = ""
|
|
# `failureCount` is deprecated and has no effect
|
|
# on email, but the element has been created
|
|
# in order to match the XML generated via UI.
|
|
failure_count_supporters = ["FirstFailureTrigger", "SecondFailureTrigger"]
|
|
if ttype in failure_count_supporters:
|
|
XML.SubElement(trigger, "failureCount").text = "0"
|
|
if "upstream-committers" in data["send-to"]:
|
|
if recipient_providers is None:
|
|
recipient_providers = XML.SubElement(email, "recipientProviders")
|
|
XML.SubElement(
|
|
recipient_providers,
|
|
"hudson.plugins.emailext.plugins.recipients.UpstreamComitterRecipientProvider",
|
|
).text = ""
|
|
else:
|
|
if plugin_version < pkg_resources.parse_version("2.39"):
|
|
XML.SubElement(email, "sendToRequester").text = "false"
|
|
XML.SubElement(email, "sendToDevelopers").text = "false"
|
|
XML.SubElement(email, "includeCulprits").text = "false"
|
|
XML.SubElement(email, "sendToRecipientList").text = "true"
|
|
else:
|
|
recipient_providers = XML.SubElement(email, "recipientProviders")
|
|
XML.SubElement(
|
|
recipient_providers,
|
|
"hudson.plugins.emailext.plugins.recipients.ListRecipientProvider",
|
|
).text = ""
|
|
|
|
if ttype == "ScriptTrigger":
|
|
XML.SubElement(trigger, "triggerScript").text = data["trigger-script"]
|
|
|
|
if plugin_version >= pkg_resources.parse_version("2.39"):
|
|
mappings = [
|
|
("attachments", "attachmentsPattern", ""),
|
|
("attach-build-log", "attachBuildLog", False),
|
|
("compress-log", "compressBuildLog", False),
|
|
]
|
|
|
|
helpers.convert_mapping_to_xml(email, data, mappings, fail_required=True)
|
|
|
|
|
|
def email_ext(registry, xml_parent, data):
|
|
"""yaml: email-ext
|
|
Extend Jenkin's built in email notification
|
|
Requires the Jenkins :jenkins-plugins:`Email-ext Plugin
|
|
<email-ext>`.
|
|
|
|
:arg bool disable-publisher: Disable the publisher, while maintaining the
|
|
settings. The usage model for this is when you want to test things out
|
|
in the build, not send out e-mails during the testing. A message will
|
|
be printed to the build log saying that the publisher is disabled.
|
|
(default false)
|
|
:arg str recipients: Comma separated list of recipient email addresses
|
|
(default '$DEFAULT_RECIPIENTS')
|
|
:arg str reply-to: Comma separated list of email addresses that should be
|
|
in the Reply-To header for this project (default '$DEFAULT_REPLYTO')
|
|
:arg str from: Email address that should be
|
|
in the From header for this project (default '')
|
|
:arg str content-type: The content type of the emails sent. If not set, the
|
|
Jenkins plugin uses the value set on the main configuration page.
|
|
Possible values: 'html', 'text', 'both-html-text' or 'default'
|
|
(default 'default')
|
|
:arg str subject: Subject for the email, can include variables like
|
|
${BUILD_NUMBER} or even groovy or javascript code
|
|
(default '$DEFAULT_SUBJECT')
|
|
:arg str body: Content for the body of the email, can include variables
|
|
like ${BUILD_NUMBER}, but the real magic is using groovy or
|
|
javascript to hook into the Jenkins API itself
|
|
(default '$DEFAULT_CONTENT')
|
|
:arg bool attach-build-log: Include build log in the email (default false)
|
|
:arg bool compress-log: Compress build log in the email (default false)
|
|
:arg str attachments: pattern of files to include as attachment
|
|
(default '')
|
|
:arg bool always: Send an email for every result (default false)
|
|
:arg bool unstable: Send an email for an unstable result (default false)
|
|
:arg bool first-failure: Send an email for just the first failure
|
|
(default false)
|
|
:arg bool first-unstable: Send an email for just the first unstable build
|
|
(default false)
|
|
:arg bool not-built: Send an email if not built (default false)
|
|
:arg bool aborted: Send an email if the build is aborted (default false)
|
|
:arg bool regression: Send an email if there is a regression
|
|
(default false)
|
|
:arg bool failure: Send an email if the build fails (default true)
|
|
:arg bool second-failure: Send an email for the second failure
|
|
(default false)
|
|
:arg bool improvement: Send an email if the build improves (default false)
|
|
:arg bool still-failing: Send an email if the build is still failing
|
|
(default false)
|
|
:arg bool success: Send an email for a successful build (default false)
|
|
:arg bool fixed: Send an email if the build is fixed (default false)
|
|
:arg bool fixed-unhealthy: Send an email if the build status
|
|
changes from "Failure" or "Unstable" to "Success". Intermediate
|
|
"Aborted" builds are ignored. (default false)
|
|
:arg bool still-unstable: Send an email if the build is still unstable
|
|
(default false)
|
|
:arg bool pre-build: Send an email before the build (default false)
|
|
:arg str trigger-script: A Groovy script used to determine if an email
|
|
should be sent.
|
|
:arg str presend-script: A Groovy script executed prior sending the mail.
|
|
(default '')
|
|
:arg str postsend-script: A Goovy script executed after sending the email.
|
|
(default '')
|
|
:arg bool save-output: Save email content to workspace (default false)
|
|
:arg str matrix-trigger: If using matrix projects, when to trigger
|
|
|
|
:matrix-trigger values:
|
|
* **both**
|
|
* **only-parent**
|
|
* **only-configurations**
|
|
:arg list send-to: list of recipients from the predefined groups
|
|
|
|
:send-to values:
|
|
* **developers** (disabled by default)
|
|
* **requester** (disabled by default)
|
|
* **culprits** (disabled by default)
|
|
* **recipients** (enabled by default)
|
|
* **upstream-committers** (>=2.39) (disabled by default)
|
|
* **failing-test-suspects-recipients** (>=2.39) (disabled by default)
|
|
* **first-failing-build-suspects-recipients** (>=2.39) (disabled by default)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/email-ext001.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
emailext = XML.SubElement(
|
|
xml_parent, "hudson.plugins.emailext.ExtendedEmailPublisher"
|
|
)
|
|
|
|
info = registry.get_plugin_info("email-ext")
|
|
plugin_version = pkg_resources.parse_version(info.get("version", str(sys.maxsize)))
|
|
|
|
if "recipients" in data:
|
|
XML.SubElement(emailext, "recipientList").text = data["recipients"]
|
|
else:
|
|
XML.SubElement(emailext, "recipientList").text = "$DEFAULT_RECIPIENTS"
|
|
ctrigger = XML.SubElement(emailext, "configuredTriggers")
|
|
if data.get("always", False):
|
|
base_email_ext(registry, ctrigger, data, "AlwaysTrigger")
|
|
if data.get("unstable", False):
|
|
base_email_ext(registry, ctrigger, data, "UnstableTrigger")
|
|
if data.get("first-failure", False):
|
|
base_email_ext(registry, ctrigger, data, "FirstFailureTrigger")
|
|
if data.get("first-unstable", False):
|
|
base_email_ext(registry, ctrigger, data, "FirstUnstableTrigger")
|
|
if data.get("not-built", False):
|
|
base_email_ext(registry, ctrigger, data, "NotBuiltTrigger")
|
|
if data.get("aborted", False):
|
|
base_email_ext(registry, ctrigger, data, "AbortedTrigger")
|
|
if data.get("regression", False):
|
|
base_email_ext(registry, ctrigger, data, "RegressionTrigger")
|
|
if data.get("failure", True):
|
|
base_email_ext(registry, ctrigger, data, "FailureTrigger")
|
|
if data.get("second-failure", False):
|
|
base_email_ext(registry, ctrigger, data, "SecondFailureTrigger")
|
|
if data.get("improvement", False):
|
|
base_email_ext(registry, ctrigger, data, "ImprovementTrigger")
|
|
if data.get("still-failing", False):
|
|
base_email_ext(registry, ctrigger, data, "StillFailingTrigger")
|
|
if data.get("success", False):
|
|
base_email_ext(registry, ctrigger, data, "SuccessTrigger")
|
|
if data.get("fixed", False):
|
|
base_email_ext(registry, ctrigger, data, "FixedTrigger")
|
|
if data.get("fixed-unhealthy", False):
|
|
base_email_ext(registry, ctrigger, data, "FixedUnhealthyTrigger")
|
|
if data.get("still-unstable", False):
|
|
base_email_ext(registry, ctrigger, data, "StillUnstableTrigger")
|
|
if data.get("pre-build", False):
|
|
base_email_ext(registry, ctrigger, data, "PreBuildTrigger")
|
|
if data.get("trigger-script", False):
|
|
base_email_ext(registry, ctrigger, data, "ScriptTrigger")
|
|
|
|
content_type_mime = {
|
|
"text": "text/plain",
|
|
"html": "text/html",
|
|
"default": "default",
|
|
"both-html-text": "both",
|
|
}
|
|
ctype = data.get("content-type", "default")
|
|
if ctype not in content_type_mime:
|
|
raise InvalidAttributeError(ctype, ctype, content_type_mime.keys())
|
|
XML.SubElement(emailext, "contentType").text = content_type_mime[ctype]
|
|
|
|
mappings = [
|
|
("subject", "defaultSubject", "$DEFAULT_SUBJECT"),
|
|
("body", "defaultContent", "$DEFAULT_CONTENT"),
|
|
("attachments", "attachmentsPattern", ""),
|
|
("presend-script", "presendScript", ""),
|
|
("postsend-script", "postsendScript", ""),
|
|
("attach-build-log", "attachBuildLog", False),
|
|
("compress-log", "compressBuildLog", False),
|
|
("save-output", "saveOutput", False),
|
|
("disable-publisher", "disabled", False),
|
|
("reply-to", "replyTo", "$DEFAULT_REPLYTO"),
|
|
]
|
|
|
|
if plugin_version >= pkg_resources.parse_version("2.39"):
|
|
mappings.append(("from", "from", ""))
|
|
|
|
helpers.convert_mapping_to_xml(emailext, data, mappings, fail_required=True)
|
|
|
|
matrix_dict = {
|
|
"both": "BOTH",
|
|
"only-configurations": "ONLY_CONFIGURATIONS",
|
|
"only-parent": "ONLY_PARENT",
|
|
}
|
|
matrix_trigger = data.get("matrix-trigger", None)
|
|
# If none defined, then do not create entry
|
|
if matrix_trigger is not None:
|
|
if matrix_trigger not in matrix_dict:
|
|
raise InvalidAttributeError(
|
|
matrix_trigger, matrix_trigger, matrix_dict.keys()
|
|
)
|
|
XML.SubElement(emailext, "matrixTriggerMode").text = matrix_dict.get(
|
|
matrix_trigger
|
|
)
|
|
|
|
|
|
def fingerprint(registry, xml_parent, data):
|
|
"""yaml: fingerprint
|
|
Fingerprint files to track them across builds. Requires the
|
|
Jenkins :jenkins-plugins:`Fingerprint Plugin <create-fingerprint>`.
|
|
|
|
:arg str files: files to fingerprint, follows the @includes of Ant fileset
|
|
(default '')
|
|
:arg bool record-artifacts: fingerprint all archived artifacts
|
|
(default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/fingerprint001.yaml
|
|
:language: yaml
|
|
"""
|
|
finger = XML.SubElement(xml_parent, "hudson.tasks.Fingerprinter")
|
|
mappings = [
|
|
("files", "targets", ""),
|
|
("record-artifacts", "recordBuildArtifacts", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(finger, data, mappings, fail_required=True)
|
|
|
|
|
|
def aggregate_tests(registry, xml_parent, data):
|
|
"""yaml: aggregate-tests
|
|
Aggregate downstream test results
|
|
|
|
:arg bool include-failed-builds: whether to include failed builds
|
|
(default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/aggregate-tests001.yaml
|
|
:language: yaml
|
|
"""
|
|
agg = XML.SubElement(xml_parent, "hudson.tasks.test.AggregatedTestResultPublisher")
|
|
mapping = [("include-failed-builds", "includeFailedBuilds", False)]
|
|
helpers.convert_mapping_to_xml(agg, data, mapping, fail_required=True)
|
|
|
|
|
|
def aggregate_flow_tests(registry, xml_parent, data):
|
|
"""yaml: aggregate-flow-tests
|
|
Aggregate downstream test results in a Build Flow job.
|
|
|
|
Requires the Jenkins `Build Flow Test Aggregator Plugin
|
|
<https://github.com/zeroturnaround/build-flow-test-aggregator>`_.
|
|
|
|
:arg bool show-test-results-trend: whether to show test results
|
|
trend graph (default true)
|
|
|
|
Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/aggregate-flow-tests002.yaml
|
|
:language: yaml
|
|
|
|
"""
|
|
agg_flow = XML.SubElement(
|
|
xml_parent,
|
|
"org.zeroturnaround.jenkins." "flowbuildtestaggregator.FlowTestAggregator",
|
|
)
|
|
mapping = [("show-test-results-trend", "showTestResultTrend", True)]
|
|
helpers.convert_mapping_to_xml(agg_flow, data, mapping, fail_required=True)
|
|
|
|
|
|
def cppcheck(registry, xml_parent, data):
|
|
"""yaml: cppcheck
|
|
Cppcheck result publisher
|
|
Requires the Jenkins :jenkins-plugins:`Cppcheck Plugin <cppcheck>`.
|
|
|
|
:arg str pattern: File pattern for cppcheck xml report (required)
|
|
:arg bool ignoreblankfiles: Ignore blank files (default false)
|
|
:arg bool allow-no-report: Do not fail the build if the Cppcheck report
|
|
is not found (default false)
|
|
:arg dict thresholds:
|
|
:thresholds: Configure the build status and health. A build is
|
|
considered as unstable or failure if the new or total number
|
|
of issues exceeds the specified thresholds. The build health
|
|
is also determined by thresholds. If the actual number of issues
|
|
is between the provided thresholds, then the build health is
|
|
interpolated.
|
|
|
|
* **unstable** (`str`): Total number unstable threshold (default '')
|
|
* **new-unstable** (`str`): New number unstable threshold (default '')
|
|
* **failure** (`str`): Total number failure threshold (default '')
|
|
* **new-failure** (`str`): New number failure threshold (default '')
|
|
* **healthy** (`str`): Healthy threshold (default '')
|
|
* **unhealthy** (`str`): Unhealthy threshold (default '')
|
|
|
|
:arg dict severity:
|
|
:severity: Determines which severity of issues should be considered
|
|
when evaluating the build status and health, default all true
|
|
|
|
* **error** (`bool`): Severity error (default true)
|
|
* **warning** (`bool`): Severity warning (default true)
|
|
* **style** (`bool`): Severity style (default true)
|
|
* **performance** (`bool`): Severity performance (default true)
|
|
* **information** (`bool`): Severity information (default true)
|
|
* **nocategory** (`bool`): Severity nocategory (default true)
|
|
* **portability** (`bool`): Severity portability (default true)
|
|
|
|
:arg dict graph:
|
|
:graph: Graph configuration
|
|
|
|
* **xysize** (`array`): Chart width and height (default [500, 200])
|
|
* **num-builds-in-graph** (`int`): Builds number in graph (default 0)
|
|
|
|
:arg dict display
|
|
:display: which errors to display, default only sum
|
|
|
|
* **sum** (`bool`): Display sum of all issues (default true)
|
|
* **error** (`bool`): Display errors (default false)
|
|
* **warning** (`bool`): Display warnings (default false)
|
|
* **style** (`bool`): Display style (default false)
|
|
* **performance** (`bool`): Display performance (default false)
|
|
* **information** (`bool`): Display information (default false)
|
|
* **nocategory** (`bool`): Display no category (default false)
|
|
* **portability** (`bool`): Display portability (default false)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/cppcheck-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/cppcheck-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
cppextbase = XML.SubElement(
|
|
xml_parent, "org.jenkinsci.plugins.cppcheck." "CppcheckPublisher"
|
|
)
|
|
cppextbase.set("plugin", "cppcheck")
|
|
cppext = XML.SubElement(cppextbase, "cppcheckConfig")
|
|
mappings = [
|
|
("pattern", "pattern", None),
|
|
("ignoreblankfiles", "ignoreBlankFiles", False),
|
|
("allow-no-report", "allowNoReport", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(cppext, data, mappings, fail_required=True)
|
|
|
|
csev = XML.SubElement(cppext, "configSeverityEvaluation")
|
|
thrsh = data.get("thresholds", {})
|
|
thrsh_mappings = [
|
|
("unstable", "threshold", ""),
|
|
("new-unstable", "newThreshold", ""),
|
|
("failure", "failureThreshold", ""),
|
|
("new-failure", "newFailureThreshold", ""),
|
|
("healthy", "healthy", ""),
|
|
("unhealthy", "unHealthy", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(csev, thrsh, thrsh_mappings, fail_required=True)
|
|
|
|
sev = thrsh.get("severity", {})
|
|
sev_mappings = [
|
|
("error", "severityError", True),
|
|
("warning", "severityWarning", True),
|
|
("style", "severityStyle", True),
|
|
("performance", "severityPerformance", True),
|
|
("information", "severityInformation", True),
|
|
("nocategory", "severityNoCategory", True),
|
|
("portability", "severityPortability", True),
|
|
]
|
|
helpers.convert_mapping_to_xml(csev, sev, sev_mappings, fail_required=True)
|
|
|
|
graph = data.get("graph", {})
|
|
cgraph = XML.SubElement(cppext, "configGraph")
|
|
x, y = graph.get("xysize", [500, 200])
|
|
XML.SubElement(cgraph, "xSize").text = str(x)
|
|
XML.SubElement(cgraph, "ySize").text = str(y)
|
|
graph_mapping = [("num-builds-in-graph", "numBuildsInGraph", 0)]
|
|
helpers.convert_mapping_to_xml(cgraph, graph, graph_mapping, fail_required=True)
|
|
|
|
gdisplay = graph.get("display", {})
|
|
gdisplay_mappings = [
|
|
("sum", "displayAllErrors", True),
|
|
("error", "displayErrorSeverity", False),
|
|
("warning", "displayWarningSeverity", False),
|
|
("style", "displayStyleSeverity", False),
|
|
("performance", "displayPerformanceSeverity", False),
|
|
("information", "displayInformationSeverity", False),
|
|
("nocategory", "displayNoCategorySeverity", False),
|
|
("portability", "displayPortabilitySeverity", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(
|
|
cgraph, gdisplay, gdisplay_mappings, fail_required=True
|
|
)
|
|
|
|
|
|
def logparser(registry, xml_parent, data):
|
|
"""yaml: logparser
|
|
Requires the Jenkins :jenkins-plugins:`Log Parser Plugin <log-parser>`.
|
|
|
|
:arg str parse-rules: full path to parse rules (default '')
|
|
:arg bool use-project-rules: use project rules instead of global
|
|
(default true)
|
|
:arg bool unstable-on-warning: mark build unstable on warning
|
|
(default false)
|
|
:arg bool fail-on-error: mark build failed on error (default false)
|
|
:arg bool show-graphs: show parser trend graphs (default true)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/logparser-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/logparser-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
clog = XML.SubElement(xml_parent, "hudson.plugins.logparser.LogParserPublisher")
|
|
clog.set("plugin", "log-parser")
|
|
rules_path_element = (
|
|
"projectRulePath" if data.get("use-project-rules", True) else "parsingRulesPath"
|
|
)
|
|
mappings = [
|
|
("unstable-on-warning", "unstableOnWarning", False),
|
|
("fail-on-error", "failBuildOnError", False),
|
|
("show-graphs", "showGraphs", True),
|
|
("use-project-rules", "useProjectRule", True),
|
|
("parse-rules", rules_path_element, ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(clog, data, mappings, fail_required=True)
|
|
|
|
|
|
def copy_to_master(registry, xml_parent, data):
|
|
"""yaml: copy-to-master
|
|
Copy files to master from slave.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Copy To Slave Plugin <copy-to-slave>`.
|
|
|
|
:arg list includes: list of file patterns to copy
|
|
:arg list excludes: list of file patterns to exclude
|
|
:arg str destination: absolute path into which the files will be copied.
|
|
If left blank they will be copied into the workspace of the current job
|
|
(default '')
|
|
:arg bool run-after-result: If this is checked then copying files back to
|
|
master will not run until the build result is finalized.(default true)
|
|
|
|
Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/copy-to-master001.yaml
|
|
:language: yaml
|
|
"""
|
|
cm = XML.SubElement(
|
|
xml_parent,
|
|
"com.michelin." "cio.hudson.plugins.copytoslave.CopyToMasterNotifier",
|
|
)
|
|
cm.set("plugin", "copy-to-slave")
|
|
|
|
XML.SubElement(cm, "includes").text = ",".join(data.get("includes", [""]))
|
|
XML.SubElement(cm, "excludes").text = ",".join(data.get("excludes", [""]))
|
|
mappings = [
|
|
("run-after-result", "runAfterResultFinalised", True),
|
|
("destination", "destinationFolder", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(cm, data, mappings, fail_required=True)
|
|
|
|
if data.get("destination", ""):
|
|
XML.SubElement(cm, "overrideDestinationFolder").text = "true"
|
|
|
|
|
|
def jira(registry, xml_parent, data):
|
|
"""yaml: jira
|
|
Update relevant JIRA issues
|
|
Requires the Jenkins :jenkins-plugins:`JIRA Plugin <jira>`.
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/jira001.yaml
|
|
:language: yaml
|
|
"""
|
|
XML.SubElement(xml_parent, "hudson.plugins.jira.JiraIssueUpdater")
|
|
|
|
|
|
def growl(registry, xml_parent, data):
|
|
"""yaml: growl
|
|
Push notifications to growl client.
|
|
Requires the Jenkins :jenkins-plugins:`Growl Plugin <growl>`.
|
|
|
|
:arg str ip: IP address to send growl notifications to (required)
|
|
:arg bool notify-only-on-fail-or-recovery: send a growl only when build
|
|
fails or recovers from a failure (default false)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/growl-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/growl-full.yaml
|
|
:language: yaml
|
|
"""
|
|
growl = XML.SubElement(xml_parent, "hudson.plugins.growl.GrowlPublisher")
|
|
growl.set("plugin", "growl")
|
|
|
|
mapping = [
|
|
("ip", "IP", None),
|
|
("notify-only-on-fail-or-recovery", "onlyOnFailureOrRecovery", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(growl, data, mapping, fail_required=True)
|
|
|
|
|
|
def groovy_postbuild(registry, xml_parent, data):
|
|
"""yaml: groovy-postbuild
|
|
Execute a groovy script.
|
|
Requires the Jenkins :jenkins-plugins:`Groovy Postbuild Plugin
|
|
<groovy-postbuild>`.
|
|
|
|
Please pay attention on version of plugin you have installed.
|
|
There were incompatible changes between 1.x and 2.x. Please see
|
|
:jenkins-plugins:`home page <groovy-postbuild>` of this plugin
|
|
for full information including migration process.
|
|
|
|
:arg str script: The groovy script to execute
|
|
:arg list classpath: List of additional classpaths (>=1.6)
|
|
:arg str on-failure: In case of script failure leave build as it is
|
|
for "nothing" option, mark build as unstable
|
|
for "unstable" and mark job as failure for "failed"
|
|
(default 'nothing')
|
|
:arg bool matrix-parent: Run script for matrix parent only (>=1.9)
|
|
(default false)
|
|
:arg bool sandbox: Execute script inside of groovy sandbox (>=2.0)
|
|
(default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/groovy-postbuild001.yaml
|
|
:language: yaml
|
|
"""
|
|
logger = logging.getLogger("%s:groovy-postbuild" % __name__)
|
|
# Backward compatibility with old format
|
|
if isinstance(data, six.string_types):
|
|
logger.warning(
|
|
"You use deprecated configuration, please follow documentation "
|
|
"to change configuration. It is not going to be supported in "
|
|
"future releases!"
|
|
)
|
|
data = {"script": data}
|
|
# There are incompatible changes, we need to know version
|
|
info = registry.get_plugin_info("groovy-postbuild")
|
|
# Note: Assume latest version of plugin is preferred config format
|
|
version = pkg_resources.parse_version(info.get("version", str(sys.maxsize)))
|
|
# Version specific predicates
|
|
matrix_parent_support = version >= pkg_resources.parse_version("1.9")
|
|
security_plugin_support = version >= pkg_resources.parse_version("2.0")
|
|
extra_classpath_support = version >= pkg_resources.parse_version("1.6")
|
|
|
|
root_tag = "org.jvnet.hudson.plugins.groovypostbuild.GroovyPostbuildRecorder"
|
|
groovy = XML.SubElement(xml_parent, root_tag)
|
|
|
|
behavior = data.get("on-failure")
|
|
XML.SubElement(groovy, "behavior").text = {"unstable": "1", "failed": "2"}.get(
|
|
behavior, "0"
|
|
)
|
|
|
|
if matrix_parent_support:
|
|
XML.SubElement(groovy, "runForMatrixParent").text = str(
|
|
data.get("matrix-parent", False)
|
|
).lower()
|
|
|
|
classpaths = data.get("classpath", list())
|
|
if security_plugin_support:
|
|
script = XML.SubElement(groovy, "script")
|
|
XML.SubElement(script, "script").text = data.get("script")
|
|
XML.SubElement(script, "sandbox").text = str(data.get("sandbox", False)).lower()
|
|
if classpaths:
|
|
classpath = XML.SubElement(script, "classpath")
|
|
for path in classpaths:
|
|
script_path = XML.SubElement(classpath, "entry")
|
|
XML.SubElement(script_path, "url").text = path
|
|
else:
|
|
XML.SubElement(groovy, "groovyScript").text = data.get("script")
|
|
if extra_classpath_support and classpaths:
|
|
classpath = XML.SubElement(groovy, "classpath")
|
|
for path in classpaths:
|
|
script_path = XML.SubElement(
|
|
classpath,
|
|
"org.jvnet.hudson.plugins.groovypostbuild." "GroovyScriptPath",
|
|
)
|
|
XML.SubElement(script_path, "path").text = path
|
|
|
|
|
|
def base_publish_over(
|
|
xml_parent,
|
|
data,
|
|
console_prefix,
|
|
plugin_tag,
|
|
publisher_tag,
|
|
transferset_tag,
|
|
retry_tag,
|
|
reference_plugin_tag,
|
|
is_builder=False,
|
|
):
|
|
outer = XML.SubElement(xml_parent, plugin_tag)
|
|
# 'Publish over SSH' builder has an extra top delegate element
|
|
if xml_parent.tag == "builders" or is_builder:
|
|
outer = XML.SubElement(outer, "delegate")
|
|
|
|
XML.SubElement(outer, "consolePrefix").text = console_prefix
|
|
delegate = XML.SubElement(outer, "delegate")
|
|
publishers = XML.SubElement(delegate, "publishers")
|
|
|
|
inner = XML.SubElement(publishers, publisher_tag)
|
|
XML.SubElement(inner, "configName").text = data["site"]
|
|
XML.SubElement(inner, "verbose").text = str(data.get("verbose", False)).lower()
|
|
|
|
transfers = XML.SubElement(inner, "transfers")
|
|
transfersset = XML.SubElement(transfers, transferset_tag)
|
|
|
|
XML.SubElement(transfersset, "remoteDirectory").text = data["target"]
|
|
XML.SubElement(transfersset, "sourceFiles").text = data["source"]
|
|
XML.SubElement(transfersset, "excludes").text = data.get("excludes", "")
|
|
XML.SubElement(transfersset, "removePrefix").text = data.get("remove-prefix", "")
|
|
XML.SubElement(transfersset, "remoteDirectorySDF").text = str(
|
|
data.get("target-is-date-format", False)
|
|
).lower()
|
|
XML.SubElement(transfersset, "flatten").text = str(
|
|
data.get("flatten", False)
|
|
).lower()
|
|
XML.SubElement(transfersset, "cleanRemote").text = str(
|
|
data.get("clean-remote", False)
|
|
).lower()
|
|
|
|
if "command" in data:
|
|
XML.SubElement(transfersset, "execCommand").text = data["command"]
|
|
if "timeout" in data:
|
|
XML.SubElement(transfersset, "execTimeout").text = str(data["timeout"])
|
|
if "use-pty" in data:
|
|
XML.SubElement(transfersset, "usePty").text = str(
|
|
data.get("use-pty", False)
|
|
).lower()
|
|
|
|
XML.SubElement(inner, "useWorkspaceInPromotion").text = "false"
|
|
XML.SubElement(inner, "usePromotionTimestamp").text = "false"
|
|
|
|
if "retries" in data:
|
|
retry = XML.SubElement(inner, "retry", {"class": retry_tag})
|
|
XML.SubElement(retry, "retries").text = str(data.get("retries", 0))
|
|
XML.SubElement(retry, "retryDelay").text = str(data.get("retry-delay", 10000))
|
|
|
|
XML.SubElement(delegate, "continueOnError").text = "false"
|
|
XML.SubElement(delegate, "failOnError").text = str(
|
|
data.get("fail-on-error", False)
|
|
).lower()
|
|
XML.SubElement(delegate, "alwaysPublishFromMaster").text = str(
|
|
data.get("always-publish-from-master", False)
|
|
).lower()
|
|
XML.SubElement(
|
|
delegate,
|
|
"hostConfigurationAccess",
|
|
{"class": reference_plugin_tag, "reference": "../.."},
|
|
)
|
|
|
|
return (outer, transfersset)
|
|
|
|
|
|
def cifs(registry, xml_parent, data):
|
|
"""yaml: cifs
|
|
Upload files via CIFS.
|
|
Requires the Jenkins :jenkins-plugins:`Publish over CIFS Plugin
|
|
<publish-over-cifs>`.
|
|
|
|
:arg str site: name of the cifs site/share (required)
|
|
:arg str target: destination directory (required)
|
|
:arg bool target-is-date-format: whether target is a date format. If true,
|
|
raw text should be quoted (default false)
|
|
:arg bool clean-remote: should the remote directory be deleted before
|
|
transferring files (default false)
|
|
:arg str source: source path specifier (required)
|
|
:arg str excludes: excluded file pattern (default '')
|
|
:arg str remove-prefix: prefix to remove from uploaded file paths
|
|
(default '')
|
|
:arg bool fail-on-error: fail the build if an error occurs (default false).
|
|
:arg bool flatten: only create files on the server, don't create
|
|
directories (default false).
|
|
:arg bool verbose: adds lots of detail useful for debug to the console
|
|
but generally should be left off (default false)
|
|
:arg int retries: the number of times to retry this server in the event of
|
|
failure (optional)
|
|
:arg int retry-delay: the time to wait, in milliseconds, before attempting
|
|
another transfer (default 10000)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/cifs-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/cifs-full.yaml
|
|
:language: yaml
|
|
|
|
"""
|
|
console_prefix = "CIFS: "
|
|
if xml_parent.tag == "publishers":
|
|
plugin_tag = "jenkins.plugins.publish__over__cifs.CifsPublisherPlugin"
|
|
is_builder = False
|
|
else:
|
|
plugin_tag = "jenkins.plugins.publish__over__cifs.CifsBuilderPlugin"
|
|
is_builder = True
|
|
publisher_tag = "jenkins.plugins.publish__over__cifs.CifsPublisher"
|
|
transfer_tag = "jenkins.plugins.publish__over__cifs.CifsTransfer"
|
|
retry_tag = "jenkins.plugins.publish_over_cifs.CifsRetry"
|
|
plugin_reference_tag = "jenkins.plugins.publish_over_cifs." "CifsPublisherPlugin"
|
|
base_publish_over(
|
|
xml_parent,
|
|
data,
|
|
console_prefix,
|
|
plugin_tag,
|
|
publisher_tag,
|
|
transfer_tag,
|
|
retry_tag,
|
|
plugin_reference_tag,
|
|
is_builder,
|
|
)
|
|
|
|
|
|
def cigame(registry, xml_parent, data):
|
|
"""yaml: cigame
|
|
This plugin introduces a game where users get points
|
|
for improving the builds.
|
|
Requires the Jenkins Continuous Integration Game
|
|
plugin (https://github.com/jenkinsci/ci-game-plugin).
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/cigame.yaml
|
|
:language: yaml
|
|
"""
|
|
XML.SubElement(xml_parent, "hudson.plugins.cigame.GamePublisher")
|
|
|
|
|
|
def sonar(registry, xml_parent, data):
|
|
"""yaml: sonar
|
|
Sonar plugin support.
|
|
Requires the Jenkins `Sonar Plugin.
|
|
<https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-jenkins>`_
|
|
|
|
:arg str installation-name: name of the Sonar instance to use (optional)
|
|
:arg str jdk: JDK to use (inherited from the job if omitted). (optional)
|
|
:arg str branch: branch onto which the analysis will be posted (default '')
|
|
:arg str language: source code language (default '')
|
|
:arg str root-pom: Root POM (default 'pom.xml')
|
|
:arg bool private-maven-repo: If true, use private Maven repository.
|
|
(default false)
|
|
:arg str maven-opts: options given to maven (default '')
|
|
:arg str additional-properties: sonar analysis parameters (default '')
|
|
:arg str maven-installation-name: the name of the Maven installation
|
|
to use (optional)
|
|
:arg dict skip-global-triggers:
|
|
:Triggers: * **skip-when-scm-change** (`bool`): skip analysis when
|
|
build triggered by scm (default false)
|
|
* **skip-when-upstream-build** (`bool`): skip analysis when
|
|
build triggered by an upstream build (default false)
|
|
* **skip-when-envvar-defined** (`str`): skip analysis when
|
|
the specified environment variable is set to true
|
|
(default '')
|
|
:arg str settings: Path to use as user settings.xml. It is possible to
|
|
provide a ConfigFileProvider settings file, see Example below.
|
|
(optional)
|
|
:arg str global-settings: Path to use as global settings.xml. It is
|
|
possible to provide a ConfigFileProvider settings file, see Example
|
|
below. (optional)
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Config File Provider Plugin
|
|
<config-file-provider>`
|
|
for the Config File Provider "settings" and "global-settings" config.
|
|
|
|
This publisher supports the post-build action exposed by the Jenkins
|
|
Sonar Plugin, which is triggering a Sonar Analysis with Maven.
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/sonar-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/sonar-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
sonar = XML.SubElement(xml_parent, "hudson.plugins.sonar.SonarPublisher")
|
|
sonar.set("plugin", "sonar")
|
|
if "installation-name" in data:
|
|
XML.SubElement(sonar, "installationName").text = data["installation-name"]
|
|
if "jdk" in data:
|
|
XML.SubElement(sonar, "jdk").text = data["jdk"]
|
|
if "maven-installation-name" in data:
|
|
XML.SubElement(sonar, "mavenInstallationName").text = data[
|
|
"maven-installation-name"
|
|
]
|
|
|
|
mappings = [
|
|
("branch", "branch", ""),
|
|
("language", "language", ""),
|
|
("root-pom", "rootPom", "pom.xml"),
|
|
("private-maven-repo", "usePrivateRepository", False),
|
|
("maven-opts", "mavenOpts", ""),
|
|
("additional-properties", "jobAdditionalProperties", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(sonar, data, mappings, fail_required=True)
|
|
|
|
if "skip-global-triggers" in data:
|
|
data_triggers = data["skip-global-triggers"]
|
|
triggers = XML.SubElement(sonar, "triggers")
|
|
triggers_mappings = [
|
|
("skip-when-scm-change", "skipScmCause", False),
|
|
("skip-when-upstream-build", "skipUpstreamCause", False),
|
|
("skip-when-envvar-defined", "envVar", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(
|
|
triggers, data_triggers, triggers_mappings, fail_required=True
|
|
)
|
|
|
|
helpers.config_file_provider_settings(sonar, data)
|
|
|
|
|
|
def sounds(parser, xml_parent, data):
|
|
"""yaml: sounds
|
|
Play audio clips locally through sound hardware,
|
|
remotely by piping them through an operating system command,
|
|
or simultaneously through all browsers on a Jenkins page.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Jenkins Sounds plugin
|
|
<sounds>`
|
|
|
|
:arg dict success: Play on success
|
|
|
|
:success:
|
|
.. _sound_and_cond:
|
|
|
|
* **sound** (`str`) - Sound name
|
|
* **from** (`list`) - Previous build result (default is all)
|
|
:from values:
|
|
* **success**
|
|
* **unstable**
|
|
* **failure**
|
|
* **not_build**
|
|
* **aborted**
|
|
|
|
:arg dict unstable: Play on unstable.
|
|
Specifying sound and conditions see :ref:`above <sound_and_cond>`.
|
|
:arg dict failure: Play on failure.
|
|
Specifying sound and conditions see :ref:`above <sound_and_cond>`.
|
|
:arg dict not_build: Play on not build.
|
|
Specifying sound and conditions see :ref:`above <sound_and_cond>`.
|
|
:arg dict aborted: Play on aborted.
|
|
Specifying sound and conditions see :ref:`above <sound_and_cond>`.
|
|
|
|
Minimal example using defaults:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/sounds001.yaml
|
|
:language: yaml
|
|
|
|
Full example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/sounds003.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
mapping_dict = {
|
|
"success": hudson_model.SUCCESS,
|
|
"unstable": hudson_model.UNSTABLE,
|
|
"failure": hudson_model.FAILURE,
|
|
"not_build": hudson_model.NOTBUILD,
|
|
"aborted": hudson_model.ABORTED,
|
|
}
|
|
sounds = XML.SubElement(
|
|
xml_parent, "net.hurstfrost.hudson." "sounds.HudsonSoundsNotifier"
|
|
)
|
|
events = XML.SubElement(sounds, "soundEvents")
|
|
for status, v in data.items():
|
|
try:
|
|
model = mapping_dict[status]
|
|
except KeyError:
|
|
raise InvalidAttributeError("build status", status, mapping_dict)
|
|
|
|
event = XML.SubElement(
|
|
events, "net.hurstfrost.hudson.sounds." "HudsonSoundsNotifier_-SoundEvent"
|
|
)
|
|
XML.SubElement(event, "soundId").text = v["sound"]
|
|
to_result = XML.SubElement(event, "toResult")
|
|
XML.SubElement(to_result, "name").text = model["name"]
|
|
XML.SubElement(to_result, "ordinal").text = model["ordinal"]
|
|
XML.SubElement(to_result, "color").text = model["color"]
|
|
XML.SubElement(to_result, "completeBuild").text = str(model["complete"]).lower()
|
|
|
|
from_results = XML.SubElement(event, "fromResults")
|
|
results = ["not_build", "success", "aborted", "failure", "unstable"]
|
|
if "from" in v:
|
|
results = v["from"]
|
|
for result in results:
|
|
model = mapping_dict[result]
|
|
from_result = XML.SubElement(from_results, "hudson.model.Result")
|
|
XML.SubElement(from_result, "name").text = model["name"]
|
|
XML.SubElement(from_result, "ordinal").text = model["ordinal"]
|
|
XML.SubElement(from_result, "color").text = model["color"]
|
|
XML.SubElement(from_result, "completeBuild").text = str(
|
|
model["complete"]
|
|
).lower()
|
|
|
|
|
|
def performance(registry, xml_parent, data):
|
|
r"""yaml: performance
|
|
Publish performance test results from jmeter and junit.
|
|
Requires the Jenkins :jenkins-plugins:`Performance Plugin
|
|
<performance>`.
|
|
|
|
:arg int failed-threshold: Specify the error percentage threshold that
|
|
set the build failed. A negative value means don't use this threshold
|
|
(default 0)
|
|
:arg int unstable-threshold: Specify the error percentage threshold that
|
|
set the build unstable. A negative value means don't use this threshold
|
|
(default 0)
|
|
:arg str unstable-response-time-threshold: Average response time threshold
|
|
(default '')
|
|
:arg float failed-threshold-positive: Maximum failed percentage for build
|
|
comparison (default 0.0)
|
|
:arg float failed-threshold-negative: Minimum failed percentage for build
|
|
comparison (default 0.0)
|
|
:arg float unstable-threshold-positive: Maximum unstable percentage for
|
|
build comparison (default 0.0)
|
|
:arg float unstable-threshold-negative: Minimum unstable percentage for
|
|
build comparison (default 0.0)
|
|
:arg int nth-build-number: Build number for build comparison (default 0)
|
|
:arg bool mode-relative-thresholds: Relative threshold mode (default false)
|
|
:arg str config-type: Compare based on (default 'ART')
|
|
|
|
:config-type values:
|
|
* **ART** -- Average Response Time
|
|
* **MRT** -- Median Response Time
|
|
* **PRT** -- Percentile Response Time
|
|
|
|
:arg bool mode-of-threshold: Mode of threshold, true for relative threshold
|
|
and false for error threshold (default false)
|
|
:arg bool fail-build: Fail build when result files are not present
|
|
(default false)
|
|
:arg bool compare-build-previous: Compare with previous build
|
|
(default false)
|
|
:arg bool mode-performance-per-test-case: Performance Per Test Case Mode
|
|
(default true)
|
|
:arg bool mode-thoughput: Show Throughput Chart (default false)
|
|
|
|
:arg dict report:
|
|
|
|
:(jmeter or junit): (`dict` or `str`): Specify a custom report file
|
|
(optional; jmeter default \**/*.jtl, junit default **/TEST-\*.xml)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/performance-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/performance-full.yaml
|
|
:language: yaml
|
|
"""
|
|
perf = XML.SubElement(
|
|
xml_parent, "hudson.plugins.performance." "PerformancePublisher"
|
|
)
|
|
perf.set("plugin", "performance")
|
|
types = ["ART", "MRT", "PRT"]
|
|
mappings = [
|
|
("failed-threshold", "errorFailedThreshold", 0),
|
|
("unstable-threshold", "errorUnstableThreshold", 0),
|
|
("unstable-response-time-threshold", "errorUnstableResponseTimeThreshold", ""),
|
|
("failed-threshold-positive", "relativeFailedThresholdPositive", "0.0"),
|
|
("failed-threshold-negative", "relativeFailedThresholdNegative", "0.0"),
|
|
("unstable-threshold-positive", "relativeUnstableThresholdPositive", "0.0"),
|
|
("unstable-threshold-negative", "relativeUnstableThresholdNegative", "0.0"),
|
|
("nth-build-number", "nthBuildNumber", 0),
|
|
("mode-relative-thresholds", "modeRelativeThresholds", False),
|
|
("config-type", "configType", "ART", types),
|
|
("mode-of-threshold", "modeOfThreshold", False),
|
|
("fail-build", "failBuildIfNoResultFile", False),
|
|
("compare-build-previous", "compareBuildPrevious", False),
|
|
("mode-performance-per-test-case", "modePerformancePerTestCase", True),
|
|
("mode-thoughput", "modeThroughput", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(perf, data, mappings, fail_required=True)
|
|
|
|
parsers = XML.SubElement(perf, "parsers")
|
|
if "report" in data:
|
|
for item in data["report"]:
|
|
if isinstance(item, dict):
|
|
item_name = next(iter(item.keys()))
|
|
item_values = item.get(item_name, None)
|
|
if item_name == "jmeter":
|
|
jmhold = XML.SubElement(
|
|
parsers, "hudson.plugins." "performance." "JMeterParser"
|
|
)
|
|
XML.SubElement(jmhold, "glob").text = str(item_values)
|
|
elif item_name == "junit":
|
|
juhold = XML.SubElement(
|
|
parsers, "hudson.plugins." "performance." "JUnitParser"
|
|
)
|
|
XML.SubElement(juhold, "glob").text = str(item_values)
|
|
else:
|
|
raise JenkinsJobsException(
|
|
"You have not specified jmeter "
|
|
"or junit, or you have "
|
|
"incorrectly assigned the key "
|
|
"value."
|
|
)
|
|
elif isinstance(item, str):
|
|
if item == "jmeter":
|
|
jmhold = XML.SubElement(
|
|
parsers, "hudson.plugins." "performance." "JMeterParser"
|
|
)
|
|
XML.SubElement(jmhold, "glob").text = "**/*.jtl"
|
|
elif item == "junit":
|
|
juhold = XML.SubElement(
|
|
parsers, "hudson.plugins." "performance." "JUnitParser"
|
|
)
|
|
XML.SubElement(juhold, "glob").text = "**/TEST-*.xml"
|
|
else:
|
|
raise JenkinsJobsException(
|
|
"You have not specified jmeter "
|
|
"or junit, or you have "
|
|
"incorrectly assigned the key "
|
|
"value."
|
|
)
|
|
|
|
|
|
def join_trigger(registry, xml_parent, data):
|
|
"""yaml: join-trigger
|
|
Trigger a job after all the immediate downstream jobs have completed.
|
|
Requires the Jenkins :jenkins-plugins:`Join Plugin <join>`.
|
|
|
|
:arg list projects: list of projects to trigger
|
|
:arg list publishers: list of triggers from publishers module that
|
|
defines projects that need to be triggered
|
|
:arg str threshold: result threshold to trigger jobs (optional).
|
|
Valid values are "success", "unstable", "failure", and "aborted".
|
|
:arg bool even-if-unstable: if true jobs will trigger even if some
|
|
downstream jobs are marked as unstable (default false) (DEPRECATED)
|
|
|
|
Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/join-trigger001.yaml
|
|
:language: yaml
|
|
"""
|
|
jointrigger = XML.SubElement(xml_parent, "join.JoinTrigger")
|
|
|
|
joinProjectsText = ",".join(data.get("projects", [""]))
|
|
XML.SubElement(jointrigger, "joinProjects").text = joinProjectsText
|
|
|
|
publishers = XML.SubElement(jointrigger, "joinPublishers")
|
|
for pub in data.get("publishers", []):
|
|
for edited_node in create_publishers(registry, pub):
|
|
publishers.append(edited_node)
|
|
|
|
unstable = str(data.get("even-if-unstable", "")).lower()
|
|
if unstable:
|
|
XML.SubElement(jointrigger, "evenIfDownstreamUnstable").text = unstable
|
|
|
|
threshold = data.get("threshold", "")
|
|
if threshold:
|
|
helpers.trigger_threshold(jointrigger, "resultThreshold", threshold)
|
|
|
|
|
|
def jabber(registry, xml_parent, data):
|
|
"""yaml: jabber
|
|
Integrates Jenkins with the Jabber/XMPP instant messaging protocol
|
|
Requires the Jenkins :jenkins-plugins:`Jabber Plugin <jabber>`.
|
|
|
|
:arg bool notify-on-build-start: Whether to send notifications
|
|
to channels when a build starts (default false)
|
|
:arg bool notify-scm-committers: Whether to send notifications
|
|
to the users that are suspected of having broken this build
|
|
(default false)
|
|
:arg bool notify-scm-culprits: Also send notifications to 'culprits'
|
|
from previous unstable/failed builds (default false)
|
|
:arg bool notify-upstream-committers: Whether to send notifications to
|
|
upstream committers if no committers were found for a broken build
|
|
(default false)
|
|
:arg bool notify-scm-fixers: Whether to send notifications to the users
|
|
that have fixed a broken build (default false)
|
|
:arg list group-targets: List of group targets to notify
|
|
:arg list individual-targets: List of individual targets to notify
|
|
:arg dict strategy: When to send notifications (default all)
|
|
|
|
:strategy values:
|
|
* **all** -- Always
|
|
* **failure** -- On any failure
|
|
* **failure-fixed** -- On failure and fixes
|
|
* **new-failure-fixed** -- On new failure and fixes
|
|
* **change** -- Only on state change
|
|
:arg dict message: Channel notification message (default summary-scm)
|
|
|
|
:message values:
|
|
* **summary-scm** -- Summary + SCM changes
|
|
* **summary** -- Just summary
|
|
* **summary-build** -- Summary and build parameters
|
|
* **summary-scm-fail** -- Summary, SCM changes, and failed tests
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/jabber-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/jabber-full.yaml
|
|
:language: yaml
|
|
"""
|
|
j = XML.SubElement(
|
|
xml_parent, "hudson.plugins.jabber.im.transport." "JabberPublisher"
|
|
)
|
|
j.set("plugin", "jabber")
|
|
|
|
t = XML.SubElement(j, "targets")
|
|
if "group-targets" in data:
|
|
for group in data["group-targets"]:
|
|
gcimt = XML.SubElement(t, "hudson.plugins.im." "GroupChatIMMessageTarget")
|
|
gcimt.set("plugin", "instant-messaging")
|
|
XML.SubElement(gcimt, "name").text = group
|
|
XML.SubElement(gcimt, "notificationOnly").text = "false"
|
|
if "individual-targets" in data:
|
|
for individual in data["individual-targets"]:
|
|
dimt = XML.SubElement(t, "hudson.plugins.im." "DefaultIMMessageTarget")
|
|
dimt.set("plugin", "instant-messaging")
|
|
XML.SubElement(dimt, "value").text = individual
|
|
strategy = data.get("strategy", "all")
|
|
strategydict = {
|
|
"all": "ALL",
|
|
"failure": "ANY_FAILURE",
|
|
"failure-fixed": "FAILURE_AND_FIXED",
|
|
"new-failure-fixed": "NEW_FAILURE_AND_FIXED",
|
|
"change": "STATECHANGE_ONLY",
|
|
}
|
|
if strategy not in strategydict:
|
|
raise JenkinsJobsException(
|
|
"Strategy entered is not valid, must be "
|
|
+ "one of: all, failure, failure-fixed, or "
|
|
"change"
|
|
)
|
|
XML.SubElement(j, "strategy").text = strategydict[strategy]
|
|
|
|
mappings = [
|
|
("notify-on-build-start", "notifyOnBuildStart", False),
|
|
("notify-scm-committers", "notifySuspects", False),
|
|
("notify-scm-culprits", "notifyCulprits", False),
|
|
("notify-scm-fixers", "notifyFixers", False),
|
|
("notify-upstream-committers", "notifyUpstreamCommitters", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(j, data, mappings, fail_required=True)
|
|
|
|
message = data.get("message", "summary-scm")
|
|
messagedict = {
|
|
"summary-scm": "DefaultBuildToChatNotifier",
|
|
"summary": "SummaryOnlyBuildToChatNotifier",
|
|
"summary-build": "BuildParametersBuildToChatNotifier",
|
|
"summary-scm-fail": "PrintFailingTestsBuildToChatNotifier",
|
|
}
|
|
if message not in messagedict:
|
|
raise JenkinsJobsException(
|
|
"Message entered is not valid, must be one "
|
|
"of: summary-scm, summary, summary-build "
|
|
"or summary-scm-fail"
|
|
)
|
|
XML.SubElement(
|
|
j,
|
|
"buildToChatNotifier",
|
|
{"class": "hudson.plugins.im.build_notify." + messagedict[message]},
|
|
)
|
|
XML.SubElement(j, "matrixMultiplier").text = "ONLY_CONFIGURATIONS"
|
|
|
|
|
|
def workspace_cleanup(registry, xml_parent, data):
|
|
"""yaml: workspace-cleanup (post-build)
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Workspace Cleanup Plugin
|
|
<ws-cleanup>`.
|
|
|
|
The pre-build workspace-cleanup is available as a wrapper.
|
|
|
|
:arg list include: list of files to be included
|
|
:arg list exclude: list of files to be excluded
|
|
:arg bool dirmatch: Apply pattern to directories too (default false)
|
|
:arg list clean-if: clean depending on build status
|
|
|
|
:clean-if values:
|
|
* **success** (`bool`) (default true)
|
|
* **unstable** (`bool`) (default true)
|
|
* **failure** (`bool`) (default true)
|
|
* **aborted** (`bool`) (default true)
|
|
* **not-built** (`bool`) (default true)
|
|
:arg bool fail-build: Fail the build if the cleanup fails (default true)
|
|
:arg bool clean-parent: Cleanup matrix parent workspace (default false)
|
|
:arg str external-deletion-command: external deletion command to run
|
|
against files and directories
|
|
:arg bool disable-deferred-wipeout: Disable improved deferred wipeout
|
|
method (default false)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/workspace-cleanup-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/workspace-cleanup-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
p = XML.SubElement(xml_parent, "hudson.plugins.ws__cleanup.WsCleanup")
|
|
p.set("plugin", "ws-cleanup")
|
|
if "include" in data or "exclude" in data:
|
|
patterns = XML.SubElement(p, "patterns")
|
|
|
|
for inc in data.get("include", []):
|
|
ptrn = XML.SubElement(patterns, "hudson.plugins.ws__cleanup.Pattern")
|
|
XML.SubElement(ptrn, "pattern").text = inc
|
|
XML.SubElement(ptrn, "type").text = "INCLUDE"
|
|
|
|
for exc in data.get("exclude", []):
|
|
ptrn = XML.SubElement(patterns, "hudson.plugins.ws__cleanup.Pattern")
|
|
XML.SubElement(ptrn, "pattern").text = exc
|
|
XML.SubElement(ptrn, "type").text = "EXCLUDE"
|
|
|
|
mappings = [
|
|
("dirmatch", "deleteDirs", False),
|
|
("clean-parent", "cleanupMatrixParent", False),
|
|
("external-deletion-command", "externalDelete", ""),
|
|
("disable-deferred-wipeout", "disableDeferredWipeout", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(p, data, mappings, fail_required=True)
|
|
|
|
mask = [
|
|
("success", "cleanWhenSuccess"),
|
|
("unstable", "cleanWhenUnstable"),
|
|
("failure", "cleanWhenFailure"),
|
|
("not-built", "cleanWhenNotBuilt"),
|
|
("aborted", "cleanWhenAborted"),
|
|
]
|
|
clean = data.get("clean-if", [])
|
|
cdict = dict()
|
|
for d in clean:
|
|
cdict.update(d)
|
|
for k, v in mask:
|
|
XML.SubElement(p, v).text = str(cdict.pop(k, True)).lower()
|
|
|
|
if len(cdict) > 0:
|
|
raise ValueError("clean-if must be one of: %r" % list(mask.keys()))
|
|
|
|
if str(data.get("fail-build", False)).lower() == "false":
|
|
XML.SubElement(p, "notFailBuild").text = "true"
|
|
else:
|
|
XML.SubElement(p, "notFailBuild").text = "false"
|
|
|
|
|
|
def maven_deploy(registry, xml_parent, data):
|
|
"""yaml: maven-deploy
|
|
Deploy artifacts to Maven repository.
|
|
|
|
:arg str id: Repository ID
|
|
:arg str url: Repository URL (optional)
|
|
:arg bool unique-version: Assign unique versions to snapshots
|
|
(default true)
|
|
:arg bool deploy-unstable: Deploy even if the build is unstable
|
|
(default false)
|
|
:arg str release-env-var: If the given variable name is set to "true",
|
|
the deploy steps are skipped. (optional)
|
|
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/maven-deploy001.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
p = XML.SubElement(xml_parent, "hudson.maven.RedeployPublisher")
|
|
if "id" in data:
|
|
XML.SubElement(p, "id").text = data["id"]
|
|
if "url" in data:
|
|
XML.SubElement(p, "url").text = data["url"]
|
|
XML.SubElement(p, "uniqueVersion").text = str(
|
|
data.get("unique-version", True)
|
|
).lower()
|
|
XML.SubElement(p, "evenIfUnstable").text = str(
|
|
data.get("deploy-unstable", False)
|
|
).lower()
|
|
if "release-env-var" in data:
|
|
XML.SubElement(p, "releaseEnvVar").text = data["release-env-var"]
|
|
|
|
|
|
def artifactory(registry, xml_parent, data):
|
|
"""yaml: artifactory
|
|
Uses/requires the Artifactory plugin to deploy artifacts to
|
|
Artifactory Server.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Artifactory Plugin
|
|
<artifactory>`.
|
|
|
|
:arg str url: Artifactory server url (default '')
|
|
:arg str name: Artifactory user with permissions use for
|
|
connected to the selected Artifactory Server (default '')
|
|
:arg str release-repo-key: Release repository name (default '')
|
|
:arg str snapshot-repo-key: Snapshots repository name (default '')
|
|
:arg bool publish-build-info: Push build metadata with artifacts
|
|
(default false)
|
|
:arg bool discard-old-builds:
|
|
Remove older build info from Artifactory (default false)
|
|
:arg bool discard-build-artifacts:
|
|
Remove older build artifacts from Artifactory (default false)
|
|
:arg bool even-if-unstable: Deploy artifacts even when the build
|
|
is unstable (default false)
|
|
:arg bool run-checks: Run automatic license scanning check after the
|
|
build is complete (default false)
|
|
:arg bool include-publish-artifacts: Include the build's published
|
|
module artifacts in the license violation checks if they are
|
|
also used as dependencies for other modules in this build
|
|
(default false)
|
|
:arg bool pass-identified-downstream: When true, a build parameter
|
|
named ARTIFACTORY_BUILD_ROOT with a value of
|
|
${JOB_NAME}-${BUILD_NUMBER} will be sent to downstream builds
|
|
(default false)
|
|
:arg bool license-auto-discovery: Tells Artifactory not to try
|
|
and automatically analyze and tag the build's dependencies
|
|
with license information upon deployment (default true)
|
|
:arg bool enable-issue-tracker-integration: When the Jenkins
|
|
JIRA plugin is enabled, synchronize information about JIRA
|
|
issues to Artifactory and attach issue information to build
|
|
artifacts (default false)
|
|
:arg bool aggregate-build-issues: When the Jenkins JIRA plugin
|
|
is enabled, include all issues from previous builds up to the
|
|
latest build status defined in "Aggregation Build Status"
|
|
(default false)
|
|
:arg bool allow-promotion-of-non-staged-builds: The build
|
|
promotion operation will be available to all successful builds
|
|
instead of only staged ones (default false)
|
|
:arg bool filter-excluded-artifacts-from-build: Add the excluded
|
|
files to the excludedArtifacts list and remove them from the
|
|
artifacts list in the build info (default false)
|
|
:arg str scopes: A list of dependency scopes/configurations to run
|
|
license violation checks on. If left empty all dependencies from
|
|
all scopes will be checked (default '')
|
|
:arg str violation-recipients: Recipients that need to be notified
|
|
of license violations in the build info (default '')
|
|
:arg list matrix-params: Semicolon-separated list of properties to
|
|
attach to all deployed artifacts in addition to the default ones:
|
|
build.name, build.number, and vcs.revision (default [])
|
|
:arg str black-duck-app-name: The existing Black Duck Code Center
|
|
application name (default '')
|
|
:arg str black-duck-app-version: The existing Black Duck Code Center
|
|
application version (default '')
|
|
:arg str black-duck-report-recipients: Recipients that will be emailed
|
|
a report after the automatic Black Duck Code Center compliance checks
|
|
finished (default '')
|
|
:arg str black-duck-scopes: A list of dependency scopes/configurations
|
|
to run Black Duck Code Center compliance checks on. If left empty
|
|
all dependencies from all scopes will be checked (default '')
|
|
:arg bool black-duck-run-checks: Automatic Black Duck Code Center
|
|
compliance checks will occur after the build completes
|
|
(default false)
|
|
:arg bool black-duck-include-published-artifacts: Include the build's
|
|
published module artifacts in the license violation checks if they
|
|
are also used as dependencies for other modules in this build
|
|
(default false)
|
|
:arg bool auto-create-missing-component-requests: Auto create
|
|
missing components in Black Duck Code Center application after
|
|
the build is completed and deployed in Artifactory
|
|
(default true)
|
|
:arg bool auto-discard-stale-component-requests: Auto discard
|
|
stale components in Black Duck Code Center application after
|
|
the build is completed and deployed in Artifactory
|
|
(default true)
|
|
:arg bool deploy-artifacts: Push artifacts to the Artifactory
|
|
Server. Use deployment-include-patterns and
|
|
deployment-exclude-patterns to filter deploy artifacts. (default true)
|
|
:arg list deployment-include-patterns: New line or comma separated mappings
|
|
of build artifacts to published artifacts. Supports Ant-style wildcards
|
|
mapping to target directories. E.g.: */*.zip=>dir (default [])
|
|
:arg list deployment-exclude-patterns: New line or comma separated patterns
|
|
for excluding artifacts from deployment to Artifactory (default [])
|
|
:arg bool env-vars-include: Include all environment variables
|
|
accessible by the build process. Jenkins-specific env variables
|
|
are always included. Use env-vars-include-patterns and
|
|
env-vars-exclude-patterns to filter variables to publish,
|
|
(default false)
|
|
:arg list env-vars-include-patterns: Comma or space-separated list of
|
|
environment variables that will be included as part of the published
|
|
build info. Environment variables may contain the * and the ? wildcards
|
|
(default [])
|
|
:arg list env-vars-exclude-patterns: Comma or space-separated list of
|
|
environment variables that will be excluded from the published
|
|
build info (default [])
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/artifactory01.yaml
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/artifactory02.yaml
|
|
|
|
"""
|
|
|
|
artifactory = XML.SubElement(
|
|
xml_parent, "org.jfrog.hudson.ArtifactoryRedeployPublisher"
|
|
)
|
|
|
|
# optional_props
|
|
helpers.artifactory_optional_props(artifactory, data, "publishers")
|
|
|
|
XML.SubElement(artifactory, "matrixParams").text = ",".join(
|
|
data.get("matrix-params", [])
|
|
)
|
|
|
|
# details
|
|
details = XML.SubElement(artifactory, "details")
|
|
helpers.artifactory_common_details(details, data)
|
|
|
|
mapping = [
|
|
("release-repo-key", "repositoryKey", ""),
|
|
("snapshot-repo-key", "snapshotsRepositoryKey", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(details, data, mapping, fail_required=True)
|
|
|
|
plugin = XML.SubElement(details, "stagingPlugin")
|
|
XML.SubElement(plugin, "pluginName").text = "None"
|
|
|
|
# artifactDeploymentPatterns
|
|
helpers.artifactory_deployment_patterns(artifactory, data)
|
|
|
|
# envVarsPatterns
|
|
helpers.artifactory_env_vars_patterns(artifactory, data)
|
|
|
|
|
|
def test_fairy(registry, xml_parent, data):
|
|
"""yaml: test-fairy
|
|
This plugin helps you to upload Android APKs or iOS IPA files to
|
|
www.testfairy.com.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Test Fairy Plugin
|
|
<TestFairy>`.
|
|
|
|
:arg str platform: Select platform to upload to, **android** or **ios**
|
|
(required)
|
|
|
|
Android Only:
|
|
|
|
:arg str proguard-file: Path to Proguard file. Path of mapping.txt from
|
|
your proguard output directory. (default '')
|
|
:arg str storepass: Password for the keystore (default android)
|
|
:arg str alias: alias for key (default androiddebugkey)
|
|
:arg str keypass: password for the key (default '')
|
|
:arg str keystorepath: Path to Keystore file (required)
|
|
|
|
IOS Only:
|
|
|
|
:arg str dSYM-file: Path to .dSYM.zip file (default '')
|
|
|
|
All:
|
|
|
|
:arg str apikey: TestFairy API_KEY. Find it in your TestFairy account
|
|
settings (required)
|
|
:arg str appfile: Path to App file (.apk) or (.ipa). For example:
|
|
$WORKSPACE/[YOUR_FILE_NAME].apk or full path to the apk file.
|
|
(required)
|
|
:arg str tester-groups: Tester groups to notify (default '')
|
|
:arg bool notify-testers: Send email with changelogs to testers
|
|
(default false)
|
|
:arg bool autoupdate: Automatic update (default false)
|
|
:arg str max-duration: Duration of the session (default 10m)
|
|
|
|
:max-duration values:
|
|
* **10m**
|
|
* **60m**
|
|
* **300m**
|
|
* **1440m**
|
|
:arg bool record-on-background: Record on background (default false)
|
|
:arg bool data-only-wifi: Record data only in wifi (default false)
|
|
:arg bool video-enabled: Record video (default true)
|
|
:arg int screenshot-interval: Time interval between screenshots
|
|
(default 1)
|
|
|
|
:screenshot-interval values:
|
|
* **1**
|
|
* **2**
|
|
* **5**
|
|
:arg str video-quality: Video quality (default high)
|
|
|
|
:video-quality values:
|
|
* **high**
|
|
* **medium**
|
|
* **low**
|
|
:arg bool cpu: Enable CPU metrics (default true)
|
|
:arg bool memory: Enable memory metrics (default true)
|
|
:arg bool logs: Enable logs metrics (default true)
|
|
:arg bool network: Enable network metrics (default false)
|
|
:arg bool phone-signal: Enable phone signal metrics (default false)
|
|
:arg bool wifi: Enable wifi metrics (default false)
|
|
:arg bool gps: Enable gps metrics (default false)
|
|
:arg bool battery: Enable battery metrics (default false)
|
|
:arg bool opengl: Enable opengl metrics (default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/test-fairy-android-minimal.yaml
|
|
:language: yaml
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/test-fairy-android001.yaml
|
|
:language: yaml
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/test-fairy-ios-minimal.yaml
|
|
:language: yaml
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/test-fairy-ios001.yaml
|
|
:language: yaml
|
|
"""
|
|
platform = data.get("platform")
|
|
valid_platforms = ["android", "ios"]
|
|
|
|
if "platform" not in data:
|
|
raise MissingAttributeError("platform")
|
|
if platform == "android":
|
|
root = XML.SubElement(
|
|
xml_parent, "org.jenkinsci.plugins.testfairy.TestFairyAndroidRecorder"
|
|
)
|
|
helpers.test_fairy_common(root, data)
|
|
|
|
mappings = [
|
|
("proguard-file", "mappingFile", ""),
|
|
("keystorepath", "keystorePath", None),
|
|
("storepass", "storepass", "android"),
|
|
("alias", "alias", "androiddebugkey"),
|
|
("keypass", "keypass", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(root, data, mappings, fail_required=True)
|
|
elif platform == "ios":
|
|
root = XML.SubElement(
|
|
xml_parent, "org.jenkinsci.plugins.testfairy.TestFairyIosRecorder"
|
|
)
|
|
helpers.test_fairy_common(root, data)
|
|
|
|
mappings = [("dSYM-file", "mappingFile", "")]
|
|
helpers.convert_mapping_to_xml(root, data, mappings, fail_required=True)
|
|
else:
|
|
raise InvalidAttributeError("platform", platform, valid_platforms)
|
|
|
|
|
|
def text_finder(registry, xml_parent, data):
|
|
"""yaml: text-finder
|
|
This plugin lets you search keywords in the files you specified and
|
|
additionally check build status
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Text-finder Plugin
|
|
<text-finder>`.
|
|
|
|
:arg str regexp: Specify a regular expression (required)
|
|
:arg str fileset: Specify the path to search (optional)
|
|
:arg bool also-check-console-output:
|
|
Search the console output (default false)
|
|
:arg bool succeed-if-found:
|
|
Force a build to succeed if a string was found (default false)
|
|
:arg bool unstable-if-found:
|
|
Set build unstable instead of failing the build (default false)
|
|
:arg bool not-built-if-found:
|
|
Set build to "Not Built" instead of failing the build (default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/text-finder001.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
finder = XML.SubElement(xml_parent, "hudson.plugins.textfinder.TextFinderPublisher")
|
|
finder.set("plugin", "text-finder")
|
|
if "fileset" in data:
|
|
XML.SubElement(finder, "fileSet").text = data["fileset"]
|
|
mappings = [
|
|
("regexp", "regexp", None),
|
|
("also-check-console-output", "alsoCheckConsoleOutput", False),
|
|
("succeed-if-found", "succeedIfFound", False),
|
|
("unstable-if-found", "unstableIfFound", False),
|
|
("not-built-if-found", "notBuiltIfFound", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(finder, data, mappings, fail_required=True)
|
|
|
|
|
|
def html_publisher(registry, xml_parent, data):
|
|
"""yaml: html-publisher
|
|
This plugin publishes HTML reports.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`HTML Publisher Plugin
|
|
<htmlpublisher>`.
|
|
|
|
:arg str name: Report name (required)
|
|
:arg str dir: HTML directory to archive (required)
|
|
:arg str files: Specify the pages to display (required)
|
|
:arg bool keep-all: keep HTML reports for each past build (default false)
|
|
:arg bool allow-missing: Allow missing HTML reports (default false)
|
|
:arg bool link-to-last-build: If this and 'keep-all' both are true, it
|
|
publishes the link on project level even if build failed.
|
|
(default false)
|
|
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/html-publisher001.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
reporter = XML.SubElement(xml_parent, "htmlpublisher.HtmlPublisher")
|
|
targets = XML.SubElement(reporter, "reportTargets")
|
|
ptarget = XML.SubElement(targets, "htmlpublisher.HtmlPublisherTarget")
|
|
|
|
mapping = [
|
|
("name", "reportName", None),
|
|
("dir", "reportDir", None),
|
|
("files", "reportFiles", None),
|
|
("link-to-last-build", "alwaysLinkToLastBuild", False),
|
|
("keep-all", "keepAll", False),
|
|
("allow-missing", "allowMissing", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(ptarget, data, mapping, fail_required=True)
|
|
XML.SubElement(ptarget, "wrapperName").text = "htmlpublisher-wrapper.html"
|
|
|
|
|
|
def rich_text_publisher(registry, xml_parent, data):
|
|
"""yaml: rich-text-publisher
|
|
This plugin puts custom rich text message to the Build pages and Job main
|
|
page.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Rich Text Publisher Plugin
|
|
<rich-text-publisher-plugin>`.
|
|
|
|
:arg str stable-text: The stable text (required)
|
|
:arg str unstable-text: The unstable text if different from stable
|
|
(default '')
|
|
:arg bool unstable-as-stable: The same text block is used for stable and
|
|
unstable builds (default true)
|
|
:arg str failed-text: The failed text if different from stable (default '')
|
|
:arg bool failed-as-stable: The same text block is used for stable and
|
|
failed builds (default true)
|
|
:arg str parser-name: HTML, Confluence or WikiText (default 'WikiText')
|
|
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/richtext-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/richtext-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
parsers = ["HTML", "Confluence", "WikiText"]
|
|
reporter = XML.SubElement(
|
|
xml_parent, "org.korosoft.jenkins.plugin.rtp.RichTextPublisher"
|
|
)
|
|
reporter.set("plugin", "rich-text-publisher-plugin")
|
|
|
|
mappings = [
|
|
("stable-text", "stableText", None),
|
|
("unstable-text", "unstableText", ""),
|
|
("failed-text", "failedText", ""),
|
|
("unstable-as-stable", "unstableAsStable", True),
|
|
("failed-as-stable", "failedAsStable", True),
|
|
("parser-name", "parserName", "WikiText", parsers),
|
|
]
|
|
helpers.convert_mapping_to_xml(reporter, data, mappings, fail_required=True)
|
|
|
|
|
|
def tap(registry, xml_parent, data):
|
|
"""yaml: tap
|
|
Adds support to TAP test result files
|
|
|
|
Requires the Jenkins :jenkins-plugins:`TAP Plugin <tap>`.
|
|
|
|
:arg str results: TAP test result files (required)
|
|
:arg bool fail-if-no-results: Fail if no result (default false)
|
|
:arg bool failed-tests-mark-build-as-failure:
|
|
Mark build as failure if test fails (default false)
|
|
:arg bool output-tap-to-console: Output tap to console (default true)
|
|
:arg bool enable-subtests: Enable subtests (default true)
|
|
:arg bool discard-old-reports: Discard old reports (default false)
|
|
:arg bool todo-is-failure: Handle TODO's as failures (default true)
|
|
:arg bool include-comment-diagnostics: Include comment diagnostics (#) in
|
|
the results table (>=1.12) (default false)
|
|
:arg bool validate-tests: Validate number of tests (>=1.13) (default false)
|
|
:arg bool plan-required: TAP plan required? (>=1.17) (default true)
|
|
:arg bool verbose: Print a message for each TAP stream file (>=1.17)
|
|
(default true)
|
|
:arg bool show-only-failures: show only test failures (>=1.17)
|
|
(default false)
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/tap-full.yaml
|
|
:language: yaml
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/tap-minimal.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
tap = XML.SubElement(xml_parent, "org.tap4j.plugin.TapPublisher")
|
|
tap.set("plugin", "tap")
|
|
|
|
mappings = [
|
|
("results", "testResults", None),
|
|
("fail-if-no-results", "failIfNoResults", False),
|
|
("failed-tests-mark-build-as-failure", "failedTestsMarkBuildAsFailure", False),
|
|
("output-tap-to-console", "outputTapToConsole", True),
|
|
("enable-subtests", "enableSubtests", True),
|
|
("discard-old-reports", "discardOldReports", False),
|
|
("todo-is-failure", "todoIsFailure", True),
|
|
("include-comment-diagnostics", "includeCommentDiagnostics", False),
|
|
("validate-tests", "validateNumberOfTests", False),
|
|
("plan-required", "planRequired", True),
|
|
("verbose", "verbose", True),
|
|
("show-only-failures", "showOnlyFailures", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(tap, data, mappings, fail_required=True)
|
|
|
|
|
|
def post_tasks(registry, xml_parent, data):
|
|
"""yaml: post-tasks
|
|
Adds support to post build task plugin
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Post Build Task plugin
|
|
<postbuild-task>`.
|
|
|
|
:arg dict task: Post build task definition
|
|
:arg list task[matches]: list of matches when to run the task
|
|
:arg dict task[matches][*]: match definition
|
|
:arg str task[matches][*][log-text]: text to match against the log
|
|
:arg str task[matches][*][operator]: operator to apply with the next match
|
|
|
|
:task[matches][*][operator] values (default 'AND'):
|
|
* **AND**
|
|
* **OR**
|
|
|
|
:arg bool task[escalate-status]: Escalate the task status to the job
|
|
(default 'false')
|
|
:arg bool task[run-if-job-successful]: Run only if the job was successful
|
|
(default 'false')
|
|
:arg str task[script]: Shell script to run (default '')
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/post-tasks001.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
pb_xml = XML.SubElement(xml_parent, "hudson.plugins.postbuildtask.PostbuildTask")
|
|
tasks_xml = XML.SubElement(pb_xml, "tasks")
|
|
for task in data:
|
|
task_xml = XML.SubElement(
|
|
tasks_xml, "hudson.plugins.postbuildtask.TaskProperties"
|
|
)
|
|
matches_xml = XML.SubElement(task_xml, "logTexts")
|
|
for match in task.get("matches", []):
|
|
lt_xml = XML.SubElement(
|
|
matches_xml, "hudson.plugins.postbuildtask.LogProperties"
|
|
)
|
|
XML.SubElement(lt_xml, "logText").text = str(
|
|
match.get("log-text", False) or ""
|
|
)
|
|
XML.SubElement(lt_xml, "operator").text = str(
|
|
match.get("operator", "AND")
|
|
).upper()
|
|
mapping = [
|
|
("escalate-status", "EscalateStatus", False),
|
|
("run-if-job-successful", "RunIfJobSuccessful", False),
|
|
("script", "script", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(task_xml, task, mapping, fail_required=True)
|
|
|
|
|
|
def postbuildscript(registry, xml_parent, data):
|
|
"""yaml: postbuildscript
|
|
Executes additional builders, script or Groovy after the build is
|
|
complete.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Post Build Script plugin
|
|
<postbuildscript>`.
|
|
|
|
:arg list generic-script: Series of Batch/Shell scripts to to run
|
|
|
|
:generic-script: * **file-path** (`str`) - Path to Batch/Shell scripts
|
|
* **role** (`str`) - Execute scripts on. One of
|
|
MASTER / SLAVE / BOTH. (default 'BOTH')
|
|
* **build-on** (`list`) - Build statuses which trigger
|
|
the scripts. Valid options:
|
|
SUCCESS / UNSTABLE / FAILURE / NOT_BUILT / ABORTED
|
|
(default 'SUCCESS')
|
|
* ** execute-on (`str`) - For matrix projects, scripts
|
|
can be run after each axis is built (`axes`), after
|
|
all axis of the matrix are built (`matrix`) or after
|
|
each axis AND the matrix are built (`both`). (default `both`)
|
|
|
|
:arg list groovy-script: Paths to Groovy scripts
|
|
|
|
:groovy-script: * **file-path** (`str`) - Path to Groovy scripts
|
|
* **role** (`str`) - Execute scripts on. One of
|
|
MASTER / SLAVE / BOTH. (default 'BOTH')
|
|
* **build-on** (`list`) - Build statuses which trigger
|
|
the scripts. Valid options:
|
|
SUCCESS / UNSTABLE / FAILURE / NOT_BUILT / ABORTED
|
|
(default 'SUCCESS')
|
|
* ** execute-on (`str`) - For matrix projects, scripts
|
|
can be run after each axis is built (`axes`), after
|
|
all axis of the matrix are built (`matrix`) or after
|
|
each axis AND the matrix are built (`both`). (default `both`)
|
|
|
|
:arg list groovy: Inline Groovy
|
|
|
|
:groovy: * **content** (`str`) - Inline Groovy script.
|
|
* **role** (`str`) - Execute scripts on. One of
|
|
MASTER / SLAVE / BOTH. (default 'BOTH')
|
|
* **build-on** (`list`) - Build statuses which trigger
|
|
the scripts. Valid options:
|
|
SUCCESS / UNSTABLE / FAILURE / NOT_BUILT / ABORTED
|
|
(default 'SUCCESS')
|
|
* ** execute-on (`str`) - For matrix projects, scripts
|
|
can be run after each axis is built (`axes`), after
|
|
all axis of the matrix are built (`matrix`) or after
|
|
each axis AND the matrix are built (`both`). (default `both`)
|
|
|
|
:arg list builders: Execute any number of supported Jenkins builders.
|
|
|
|
:builders: * **build-steps** (`str`) - Any supported builders,
|
|
see :doc:`builders`.
|
|
* **role** (`str`) - Execute scripts on. One of
|
|
MASTER / SLAVE / BOTH. (default 'BOTH')
|
|
* **build-on** (`list`) - Build statuses which trigger
|
|
the scripts. Valid options:
|
|
SUCCESS / UNSTABLE / FAILURE / NOT_BUILT / ABORTED
|
|
(default 'SUCCESS')
|
|
* ** execute-on (`str`) - For matrix projects, scripts
|
|
can be run after each axis is built (`axes`), after
|
|
all axis of the matrix are built (`matrix`) or after
|
|
each axis AND the matrix are built (`both`). (default `both`)
|
|
|
|
:arg bool mark-unstable-if-failed: Build will be marked unstable
|
|
if job will be successfully completed but publishing script will return
|
|
non zero exit code (default false)
|
|
|
|
Deprecated Options for versions < 2.0 of plugin:
|
|
|
|
:arg bool onsuccess: Deprecated, replaced with script-only-if-succeeded
|
|
:arg bool script-only-if-succeeded: Scripts and builders are run only if
|
|
the build succeeded (default true)
|
|
:arg bool onfailure: Deprecated, replaced with script-only-if-failed
|
|
:arg bool script-only-if-failed: Scripts and builders are run only if the
|
|
build failed (default false)
|
|
:arg str execute-on: For matrix projects, scripts can be run after each
|
|
axis is built (`axes`), after all axis of the matrix are built
|
|
(`matrix`) or after each axis AND the matrix are built (`both`).
|
|
|
|
The `script-only-if-succeeded` and `bool script-only-if-failed` options are
|
|
confusing. If you want the post build to always run regardless of the build
|
|
status, you should set them both to `false`.
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/postbuildscript-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/postbuildscript-full.yaml
|
|
:language: yaml
|
|
|
|
Example(s) versions < 2.0:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/postbuildscript001.yaml
|
|
:language: yaml
|
|
|
|
You can also execute :doc:`builders </builders>`:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/postbuildscript002.yaml
|
|
:language: yaml
|
|
|
|
Run once after the whole matrix (all axes) is built:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/postbuildscript003.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
pbs_xml = XML.SubElement(
|
|
xml_parent, "org.jenkinsci.plugins.postbuildscript.PostBuildScript"
|
|
)
|
|
|
|
info = registry.get_plugin_info("postbuildscript")
|
|
# Note: Assume latest version of plugin is preferred config format
|
|
version = pkg_resources.parse_version(info.get("version", str(sys.maxsize)))
|
|
if version >= pkg_resources.parse_version("2.0"):
|
|
pbs_xml = XML.SubElement(pbs_xml, "config")
|
|
|
|
mapping = [("mark-unstable-if-failed", "markBuildUnstable", False)]
|
|
helpers.convert_mapping_to_xml(pbs_xml, data, mapping, fail_required=True)
|
|
|
|
if version >= pkg_resources.parse_version("2.0"):
|
|
|
|
def add_execute_on(bs_data, result_xml):
|
|
valid_values = ("matrix", "axes", "both")
|
|
execute_on = bs_data.get("execute-on")
|
|
if not execute_on:
|
|
return
|
|
if execute_on not in valid_values:
|
|
raise JenkinsJobsException(
|
|
"execute-on must be one of %s, got %s" % valid_values, execute_on
|
|
)
|
|
execute_on_xml = XML.SubElement(result_xml, "executeOn")
|
|
execute_on_xml.text = execute_on.upper()
|
|
|
|
################
|
|
# Script Files #
|
|
################
|
|
|
|
script_mapping = [("role", "role", "BOTH"), ("file-path", "filePath", False)]
|
|
sf_path = "org.jenkinsci.plugins.postbuildscript.model.ScriptFile"
|
|
sf_xml = XML.SubElement(pbs_xml, "scriptFiles")
|
|
|
|
for gs_data in data.get("generic-script", []):
|
|
x = XML.SubElement(sf_xml, sf_path)
|
|
results_xml = XML.SubElement(x, "results")
|
|
|
|
for result in gs_data.get("build-on", ["SUCCESS"]):
|
|
XML.SubElement(results_xml, "string").text = result
|
|
|
|
add_execute_on(gs_data, x)
|
|
|
|
helpers.convert_mapping_to_xml(
|
|
x, gs_data, script_mapping, fail_required=True
|
|
)
|
|
XML.SubElement(x, "scriptType").text = "GENERIC"
|
|
|
|
for gs_data in data.get("groovy-script", []):
|
|
x = XML.SubElement(sf_xml, sf_path)
|
|
results_xml = XML.SubElement(x, "results")
|
|
|
|
for result in gs_data.get("build-on", ["SUCCESS"]):
|
|
XML.SubElement(results_xml, "string").text = result
|
|
|
|
add_execute_on(gs_data, x)
|
|
|
|
helpers.convert_mapping_to_xml(
|
|
x, gs_data, script_mapping, fail_required=True
|
|
)
|
|
XML.SubElement(x, "scriptType").text = "GROOVY"
|
|
|
|
#################
|
|
# Inline Groovy #
|
|
#################
|
|
|
|
groovy_mapping = [("role", "role", "BOTH"), ("content", "content", False)]
|
|
gs_path = "org.jenkinsci.plugins.postbuildscript.model.Script"
|
|
gs_xml = XML.SubElement(pbs_xml, "groovyScripts")
|
|
for gs_data in data.get("groovy", []):
|
|
x = XML.SubElement(gs_xml, gs_path)
|
|
results_xml = XML.SubElement(x, "results")
|
|
|
|
for result in gs_data.get("build-on", ["SUCCESS"]):
|
|
XML.SubElement(results_xml, "string").text = result
|
|
|
|
add_execute_on(gs_data, x)
|
|
|
|
helpers.convert_mapping_to_xml(
|
|
x, gs_data, groovy_mapping, fail_required=True
|
|
)
|
|
|
|
############
|
|
# Builders #
|
|
############
|
|
|
|
builder_mapping = [("role", "role", "BOTH")]
|
|
bs_path = "org.jenkinsci.plugins.postbuildscript.model.PostBuildStep"
|
|
bs_xml = XML.SubElement(pbs_xml, "buildSteps")
|
|
for bs_data in data.get("builders", []):
|
|
x = XML.SubElement(bs_xml, bs_path)
|
|
results_xml = XML.SubElement(x, "results")
|
|
|
|
for result in bs_data.get("build-on", ["SUCCESS"]):
|
|
XML.SubElement(results_xml, "string").text = result
|
|
|
|
add_execute_on(bs_data, x)
|
|
|
|
helpers.convert_mapping_to_xml(
|
|
x, bs_data, builder_mapping, fail_required=True
|
|
)
|
|
|
|
build_steps_xml = XML.SubElement(x, "buildSteps")
|
|
for builder in bs_data.get("build-steps"):
|
|
registry.dispatch("builder", build_steps_xml, builder)
|
|
|
|
else: # Options below are all deprecated in version < 2.0 of plugin
|
|
|
|
# Shell/Groovy in a file
|
|
script_types = {
|
|
"generic-script": "GenericScript",
|
|
"groovy-script": "GroovyScriptFile",
|
|
}
|
|
|
|
# Assuming yaml preserves order of input data make sure
|
|
# corresponding XML steps are generated in the same order
|
|
build_scripts = [
|
|
(k, v)
|
|
for k, v in data.items()
|
|
if k in script_types or k in ["groovy", "builders"]
|
|
]
|
|
|
|
for step, script_data in build_scripts:
|
|
if step in script_types:
|
|
scripts_xml = XML.SubElement(
|
|
pbs_xml, step[: -len("-script")] + "ScriptFileList"
|
|
)
|
|
for shell_script in script_data:
|
|
script_xml = XML.SubElement(
|
|
scripts_xml,
|
|
"org.jenkinsci.plugins.postbuildscript." + script_types[step],
|
|
)
|
|
file_path_xml = XML.SubElement(script_xml, "filePath")
|
|
file_path_xml.text = shell_script
|
|
|
|
# Inlined Groovy
|
|
if step == "groovy":
|
|
groovy_inline_xml = XML.SubElement(pbs_xml, "groovyScriptContentList")
|
|
for groovy in script_data:
|
|
groovy_xml = XML.SubElement(
|
|
groovy_inline_xml,
|
|
"org.jenkinsci.plugins.postbuildscript." "GroovyScriptContent",
|
|
)
|
|
groovy_content = XML.SubElement(groovy_xml, "content")
|
|
groovy_content.text = groovy
|
|
|
|
# Inject builders
|
|
if step == "builders":
|
|
build_steps_xml = XML.SubElement(pbs_xml, "buildSteps")
|
|
for builder in script_data:
|
|
registry.dispatch("builder", build_steps_xml, builder)
|
|
|
|
# When to run the build? Note the plugin let one specify both options
|
|
# although they are antinomic
|
|
# onsuccess and onfailure parameters are deprecated, this is to keep
|
|
# backwards compatability
|
|
success_xml = XML.SubElement(pbs_xml, "scriptOnlyIfSuccess")
|
|
if "script-only-if-succeeded" in data:
|
|
success_xml.text = str(data.get("script-only-if-succeeded", True)).lower()
|
|
else:
|
|
success_xml.text = str(data.get("onsuccess", True)).lower()
|
|
|
|
failure_xml = XML.SubElement(pbs_xml, "scriptOnlyIfFailure")
|
|
if "script-only-if-failed" in data:
|
|
failure_xml.text = str(data.get("script-only-if-failed", False)).lower()
|
|
else:
|
|
failure_xml.text = str(data.get("onfailure", False)).lower()
|
|
|
|
# TODO: we may want to avoid setting "execute-on" on non-matrix jobs,
|
|
# either by skipping this part or by raising an error to let the user
|
|
# know an attempt was made to set execute-on on a non-matrix job.
|
|
# There are currently no easy ways to check for this though.
|
|
if "execute-on" in data:
|
|
valid_values = ("matrix", "axes", "both")
|
|
execute_on = data["execute-on"].lower()
|
|
if execute_on not in valid_values:
|
|
raise JenkinsJobsException(
|
|
"execute-on must be one of %s, got %s" % valid_values, execute_on
|
|
)
|
|
execute_on_xml = XML.SubElement(pbs_xml, "executeOn")
|
|
execute_on_xml.text = execute_on.upper()
|
|
|
|
|
|
def xml_summary(registry, xml_parent, data):
|
|
"""yaml: xml-summary
|
|
Adds support for the Summary Display Plugin
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Summary Display Plugin
|
|
<summary_report>`.
|
|
|
|
:arg str files: Files to parse (required)
|
|
:arg bool shown-on-project-page: Display summary on project page
|
|
(default false)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/xml-summary-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/xml-summary-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
summary = XML.SubElement(
|
|
xml_parent, "hudson.plugins.summary__report.ACIPluginPublisher"
|
|
)
|
|
summary.set("plugin", "summary_report")
|
|
|
|
mapping = [
|
|
("files", "name", None),
|
|
("shown-on-project-page", "shownOnProjectPage", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(summary, data, mapping, fail_required=True)
|
|
|
|
|
|
def robot(registry, xml_parent, data):
|
|
"""yaml: robot
|
|
Adds support for the Robot Framework Plugin
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Robot Framework Plugin <robot>`.
|
|
|
|
:arg str output-path: Path to directory containing robot xml and html files
|
|
relative to build workspace. (required)
|
|
:arg str log-file-link: Name of log or report file to be linked on jobs
|
|
front page (default '')
|
|
:arg str report-html: Name of the html file containing robot test report
|
|
(default 'report.html')
|
|
:arg str log-html: Name of the html file containing detailed robot test log
|
|
(default 'log.html')
|
|
:arg str output-xml: Name of the xml file containing robot output
|
|
(default 'output.xml')
|
|
:arg str pass-threshold: Minimum percentage of passed tests to consider
|
|
the build successful (default 0.0)
|
|
:arg str unstable-threshold: Minimum percentage of passed test to
|
|
consider the build as not failed (default 0.0)
|
|
:arg bool only-critical: Take only critical tests into account when
|
|
checking the thresholds (default true)
|
|
:arg list other-files: list other files to archive (default '')
|
|
:arg bool archive-output-xml: Archive output xml file to server
|
|
(default true)
|
|
:arg bool enable-cache: Enable cache for test results (default true)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/robot-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/robot-full.yaml
|
|
:language: yaml
|
|
"""
|
|
parent = XML.SubElement(xml_parent, "hudson.plugins.robot.RobotPublisher")
|
|
parent.set("plugin", "robot")
|
|
mappings = [
|
|
("output-path", "outputPath", None),
|
|
("log-file-link", "logFileLink", ""),
|
|
("report-html", "reportFileName", "report.html"),
|
|
("log-html", "logFileName", "log.html"),
|
|
("output-xml", "outputFileName", "output.xml"),
|
|
("pass-threshold", "passThreshold", "0.0"),
|
|
("unstable-threshold", "unstableThreshold", "0.0"),
|
|
("only-critical", "onlyCritical", True),
|
|
("enable-cache", "enableCache", True),
|
|
]
|
|
helpers.convert_mapping_to_xml(parent, data, mappings, fail_required=True)
|
|
|
|
other_files = XML.SubElement(parent, "otherFiles")
|
|
for other_file in data.get("other-files", []):
|
|
XML.SubElement(other_files, "string").text = str(other_file)
|
|
XML.SubElement(parent, "disableArchiveOutput").text = str(
|
|
not data.get("archive-output-xml", True)
|
|
).lower()
|
|
|
|
|
|
def warnings(registry, xml_parent, data):
|
|
"""yaml: warnings
|
|
Generate trend report for compiler warnings in the console log or
|
|
in log files.
|
|
|
|
Requires the Jenkins Warnings Plugin
|
|
(https://github.com/jenkinsci/warnings-plugin).
|
|
|
|
:arg list console-log-parsers: The parser to use to scan the console
|
|
log (default '')
|
|
:arg dict workspace-file-scanners:
|
|
|
|
:workspace-file-scanners:
|
|
* **file-pattern** (`str`) -- Fileset 'includes' setting that
|
|
specifies the files to scan for warnings (required)
|
|
* **scanner** (`str`) -- The parser to use to scan the files
|
|
provided in workspace-file-pattern (default '')
|
|
:arg str files-to-include: Comma separated list of regular
|
|
expressions that specifies the files to include in the report
|
|
(based on their absolute filename). By default all files are
|
|
included
|
|
:arg str files-to-ignore: Comma separated list of regular expressions
|
|
that specifies the files to exclude from the report (based on their
|
|
absolute filename). (default '')
|
|
:arg str messages-to-ignore: Newline separated list of regular
|
|
expressions that specifies the warning messages to exclude form the
|
|
report (based on the warning messages). By default all warning
|
|
messages are included
|
|
:arg str categories-to-ignore: Newline separated list of regular
|
|
expressions that specifies the warning messages to exclude form the
|
|
report (based on the warning categories). By default all warning
|
|
categories are included
|
|
:arg bool run-always: By default, this plug-in runs only for stable or
|
|
unstable builds, but not for failed builds. Set to true if the
|
|
plug-in should run even for failed builds. (default false)
|
|
:arg bool detect-modules: Determines if Ant or Maven modules should be
|
|
detected for all files that contain warnings. Activating this
|
|
option may increase your build time since the detector scans
|
|
the whole workspace for 'build.xml' or 'pom.xml' files in order
|
|
to assign the correct module names. (default false)
|
|
:arg bool resolve-relative-paths: Determines if relative paths in
|
|
warnings should be resolved using a time expensive operation that
|
|
scans the whole workspace for matching files. Deactivate this
|
|
option if you encounter performance problems. (default false)
|
|
:arg int health-threshold-high: The upper threshold for the build
|
|
health. If left empty then no health report is created. If
|
|
the actual number of warnings is between the provided
|
|
thresholds then the build health is interpolated (default '')
|
|
:arg int health-threshold-low: The lower threshold for the build
|
|
health. See health-threshold-high. (default '')
|
|
:arg dict health-priorities: Determines which warning priorities
|
|
should be considered when evaluating the build health (default
|
|
all-priorities)
|
|
|
|
:health-priorities values:
|
|
* **priority-high** -- Only priority high
|
|
* **high-and-normal** -- Priorities high and normal
|
|
* **all-priorities** -- All priorities
|
|
:arg dict total-thresholds: If the number of total warnings is greater
|
|
than one of these thresholds then a build is considered as unstable
|
|
or failed, respectively. (default '')
|
|
|
|
:total-thresholds:
|
|
* **unstable** (`dict`)
|
|
:unstable: * **total-all** (`int`)
|
|
* **total-high** (`int`)
|
|
* **total-normal** (`int`)
|
|
* **total-low** (`int`)
|
|
* **failed** (`dict`)
|
|
:failed: * **total-all** (`int`)
|
|
* **total-high** (`int`)
|
|
* **total-normal** (`int`)
|
|
* **total-low** (`int`)
|
|
:arg dict new-thresholds: If the specified number of new warnings exceeds
|
|
one of these thresholds then a build is considered as unstable or
|
|
failed, respectively. (default '')
|
|
|
|
:new-thresholds:
|
|
* **unstable** (`dict`)
|
|
:unstable: * **new-all** (`int`)
|
|
* **new-high** (`int`)
|
|
* **new-normal** (`int`)
|
|
* **new-low** (`int`)
|
|
* **failed** (`dict`)
|
|
:failed: * **new-all** (`int`)
|
|
* **new-high** (`int`)
|
|
* **new-normal** (`int`)
|
|
* **new-high** (`int`)
|
|
:arg bool use-delta-for-new-warnings: If set then the number of new
|
|
warnings is calculated by subtracting the total number of warnings
|
|
of the current build from the reference build. This may lead to wrong
|
|
results if you have both fixed and new warnings in a build. If not set,
|
|
then the number of new warnings is calculated by an asymmetric set
|
|
difference of the warnings in the current and reference build. This
|
|
will find all new warnings even if the number of total warnings is
|
|
decreasing. However, sometimes false positives will be reported due
|
|
to minor changes in a warning (refactoring of variable of method
|
|
names, etc.) (default false)
|
|
:arg bool use-previous-build-as-reference: If set the number of new
|
|
warnings will always be computed based on the previous build, even if
|
|
that build is unstable (due to a violated warning threshold).
|
|
Otherwise the last build that did not violate any given threshold will
|
|
be used as
|
|
reference. It is recommended to uncheck this option if the plug-in
|
|
should ensure that all new warnings will be finally fixed in subsequent
|
|
builds. (default false)
|
|
:arg bool only-use-stable-builds-as-reference: The number of new warnings
|
|
will be calculated based on the last stable build, allowing reverts
|
|
of unstable builds where the number of warnings was decreased.
|
|
(default false)
|
|
:arg str default-encoding: Default encoding when parsing or showing files
|
|
Leave empty to use default encoding of platform (default '')
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/warnings-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/warnings-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
warnings = XML.SubElement(
|
|
xml_parent, "hudson.plugins.warnings." "WarningsPublisher"
|
|
)
|
|
warnings.set("plugin", "warnings")
|
|
console = XML.SubElement(warnings, "consoleParsers")
|
|
for parser in data.get("console-log-parsers", []):
|
|
console_parser = XML.SubElement(
|
|
console, "hudson.plugins.warnings." "ConsoleParser"
|
|
)
|
|
XML.SubElement(console_parser, "parserName").text = parser
|
|
workspace = XML.SubElement(warnings, "parserConfigurations")
|
|
for wfs in data.get("workspace-file-scanners", []):
|
|
workspace_pattern = XML.SubElement(
|
|
workspace, "hudson.plugins.warnings." "ParserConfiguration"
|
|
)
|
|
workspace_pattern_mappings = [
|
|
("file-pattern", "pattern", None),
|
|
("scanner", "parserName", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(
|
|
workspace_pattern, wfs, workspace_pattern_mappings, fail_required=True
|
|
)
|
|
prioritiesDict = {
|
|
"priority-high": "high",
|
|
"high-and-normal": "normal",
|
|
"all-priorities": "low",
|
|
}
|
|
warnings_mappings = [
|
|
("files-to-include", "includePattern", ""),
|
|
("files-to-ignore", "excludePattern", ""),
|
|
("messages-to-ignore", "messagesPattern", ""),
|
|
("categories-to-ignore", "categoriesPattern", ""),
|
|
("plugin-name", "pluginName", "[WARNINGS]"),
|
|
("run-always", "canRunOnFailed", False),
|
|
("detect-modules", "shouldDetectModules", False),
|
|
("health-threshold-high", "healthy", ""),
|
|
("health-threshold-low", "unHealthy", ""),
|
|
("health-priorities", "thresholdLimit", "all-priorities", prioritiesDict),
|
|
("default-encoding", "defaultEncoding", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(
|
|
warnings, data, warnings_mappings, fail_required=True
|
|
)
|
|
# Note the logic reversal (included here to match the GUI)
|
|
XML.SubElement(warnings, "doNotResolveRelativePaths").text = str(
|
|
not data.get("resolve-relative-paths", False)
|
|
).lower()
|
|
td = XML.SubElement(warnings, "thresholds")
|
|
for base in ["total", "new"]:
|
|
thresholds = data.get("%s-thresholds" % base, {})
|
|
for status in ["unstable", "failed"]:
|
|
bystatus = thresholds.get(status, {})
|
|
for level in ["all", "high", "normal", "low"]:
|
|
val = str(bystatus.get("%s-%s" % (base, level), ""))
|
|
XML.SubElement(
|
|
td, "%s%s%s" % (status, base.capitalize(), level.capitalize())
|
|
).text = val
|
|
if data.get("new-thresholds"):
|
|
XML.SubElement(warnings, "dontComputeNew").text = "false"
|
|
delta = data.get("use-delta-for-new-warnings", False)
|
|
XML.SubElement(warnings, "useDeltaValues").text = str(delta).lower()
|
|
use_previous_build = data.get("use-previous-build-as-reference", False)
|
|
XML.SubElement(warnings, "usePreviousBuildAsReference").text = str(
|
|
use_previous_build
|
|
).lower()
|
|
use_stable_builds = data.get("only-use-stable-builds-as-reference", False)
|
|
XML.SubElement(warnings, "useStableBuildAsReference").text = str(
|
|
use_stable_builds
|
|
).lower()
|
|
else:
|
|
XML.SubElement(warnings, "dontComputeNew").text = "true"
|
|
XML.SubElement(warnings, "useDeltaValues").text = "false"
|
|
XML.SubElement(warnings, "usePreviousBuildAsReference").text = "false"
|
|
XML.SubElement(warnings, "useStableBuildAsReference").text = "false"
|
|
|
|
|
|
def sloccount(registry, xml_parent, data):
|
|
r"""yaml: sloccount
|
|
Generates the trend report for SLOCCount
|
|
|
|
Requires the Jenkins :jenkins-plugins:`SLOCCount Plugin <sloccount>`.
|
|
|
|
:arg str report-files: Setting that specifies the generated raw
|
|
SLOCCount report files. Be sure not to include any non-report files
|
|
into this pattern. The report files must have been generated by
|
|
sloccount using the "--wide --details" options.
|
|
(default '\*\*/sloccount.sc')
|
|
:arg str charset: The character encoding to be used to read the SLOCCount
|
|
result files. (default 'UTF-8')
|
|
:arg int builds-in-graph: Maximal number of last successful builds, that
|
|
are displayed in the trend graphs. (default 0)
|
|
:arg bool comment-is-code: This option is considered only in the cloc
|
|
report parser and is ignored in the SLOCCount one. (default false)
|
|
:arg bool ignore-build-failure: Try to process the report files even if
|
|
the build is not successful. (default false)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/sloccount-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/sloccount-full.yaml
|
|
:language: yaml
|
|
"""
|
|
top = XML.SubElement(xml_parent, "hudson.plugins.sloccount.SloccountPublisher")
|
|
top.set("plugin", "sloccount")
|
|
mappings = [
|
|
("report-files", "pattern", "**/sloccount.sc"),
|
|
("charset", "encoding", "UTF-8"),
|
|
("builds-in-graph", "numBuildsInGraph", 0),
|
|
("comment-is-code", "commentIsCode", False),
|
|
("ignore-build-failure", "ignoreBuildFailure", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(top, data, mappings, fail_required=True)
|
|
|
|
|
|
def ircbot(registry, xml_parent, data):
|
|
"""yaml: ircbot
|
|
ircbot enables Jenkins to send build notifications via IRC and lets you
|
|
interact with Jenkins via an IRC bot.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`IRC Plugin <ircbot>`.
|
|
|
|
:arg str strategy: When to send notifications
|
|
|
|
:strategy values:
|
|
* **all** always (default)
|
|
* **any-failure** on any failure
|
|
* **failure-and-fixed** on failure and fixes
|
|
* **new-failure-and-fixed** on new failure and fixes
|
|
* **statechange-only** only on state change
|
|
:arg bool notify-start: Whether to send notifications to channels when a
|
|
build starts (default false)
|
|
:arg bool notify-committers: Whether to send notifications to the users
|
|
that are suspected of having broken this build (default false)
|
|
:arg bool notify-culprits: Also send notifications to 'culprits' from
|
|
previous unstable/failed builds (default false)
|
|
:arg bool notify-upstream: Whether to send notifications to upstream
|
|
committers if no committers were found for a broken build
|
|
(default false)
|
|
:arg bool notify-fixers: Whether to send notifications to the users that
|
|
have fixed a broken build (default false)
|
|
:arg str message-type: Channel Notification Message.
|
|
|
|
:message-type values:
|
|
* **summary-scm** for summary and SCM changes (default)
|
|
* **summary** for summary only
|
|
* **summary-params** for summary and build parameters
|
|
* **summary-scm-fail** for summary, SCM changes, failures)
|
|
:arg list channels: list channels definitions
|
|
If empty, it takes channel from Jenkins configuration.
|
|
(default empty)
|
|
WARNING: the IRC plugin requires the channel to be configured in the
|
|
system wide configuration or the jobs will fail to emit notifications
|
|
to the channel
|
|
|
|
:Channel: * **name** (`str`) Channel name
|
|
* **password** (`str`) Channel password (optional)
|
|
* **notify-only** (`bool`) Set to true if you want to
|
|
disallow bot commands (default false)
|
|
:arg str matrix-notifier: notify for matrix projects
|
|
instant-messaging-plugin injects an additional
|
|
field in the configuration form whenever the
|
|
project is a multi-configuration project
|
|
|
|
:matrix-notifier values:
|
|
* **all**
|
|
* **only-configurations** (default)
|
|
* **only-parent**
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/ircbot-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/ircbot-full.yaml
|
|
:language: yaml
|
|
"""
|
|
top = XML.SubElement(xml_parent, "hudson.plugins.ircbot.IrcPublisher")
|
|
top.set("plugin", "ircbot")
|
|
message_dict = {
|
|
"summary-scm": "DefaultBuildToChatNotifier",
|
|
"summary": "SummaryOnlyBuildToChatNotifier",
|
|
"summary-params": "BuildParametersBuildToChatNotifier",
|
|
"summary-scm-fail": "PrintFailingTestsBuildToChatNotifier",
|
|
}
|
|
message = data.get("message-type", "summary-scm")
|
|
if message not in message_dict:
|
|
raise JenkinsJobsException(
|
|
"message-type entered is not valid, must "
|
|
"be one of: %s" % ", ".join(message_dict.keys())
|
|
)
|
|
message = "hudson.plugins.im.build_notify." + message_dict.get(message)
|
|
XML.SubElement(top, "buildToChatNotifier", attrib={"class": message})
|
|
targets = XML.SubElement(top, "targets")
|
|
channels = data.get("channels", [])
|
|
for channel in channels:
|
|
sub = XML.SubElement(targets, "hudson.plugins.im.GroupChatIMMessageTarget")
|
|
sub_mappings = [
|
|
("name", "name", ""),
|
|
("password", "password", ""),
|
|
("notify-only", "notificationOnly", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(sub, channel, sub_mappings, fail_required=True)
|
|
strategy_dict = {
|
|
"all": "ALL",
|
|
"any-failure": "ANY_FAILURE",
|
|
"failure-and-fixed": "FAILURE_AND_FIXED",
|
|
"new-failure-and-fixed": "NEW_FAILURE_AND_FIXED",
|
|
"statechange-only": "STATECHANGE_ONLY",
|
|
}
|
|
matrix_dict = {
|
|
"all": "ALL",
|
|
"only-configurations": "ONLY_CONFIGURATIONS",
|
|
"only-parent": "ONLY_PARENT",
|
|
}
|
|
mappings = [
|
|
("strategy", "strategy", "all", strategy_dict),
|
|
("notify-start", "notifyOnBuildStart", False),
|
|
("notify-committers", "notifySuspects", False),
|
|
("notify-culprits", "notifyCulprits", False),
|
|
("notify-fixers", "notifyFixers", False),
|
|
("notify-upstream", "notifyUpstreamCommitters", False),
|
|
("matrix-notifier", "matrixMultiplier", "only-configurations", matrix_dict),
|
|
]
|
|
helpers.convert_mapping_to_xml(top, data, mappings, fail_required=True)
|
|
|
|
|
|
def plot(registry, xml_parent, data):
|
|
"""yaml: plot
|
|
Plot provides generic plotting (or graphing).
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Plot Plugin <plot>`.
|
|
|
|
:arg str title: title for the graph (default '')
|
|
:arg str yaxis: title of Y axis (default '')
|
|
:arg int width: the width of the plot in pixels (default 750)
|
|
:arg int height: the height of the plot in pixels (default 450)
|
|
:arg str group: name of the group to which the plot belongs (required)
|
|
:arg int num-builds: number of builds to plot across
|
|
(default plot all builds)
|
|
:arg str style: Specifies the graph style of the plot
|
|
Can be: area, bar, bar3d, line, line3d, stackedArea, stackedbar,
|
|
stackedbar3d, waterfall (default 'line')
|
|
:arg bool use-description: When false, the X-axis labels are formed using
|
|
build numbers and dates, and the corresponding tooltips contain the
|
|
build descriptions. When enabled, the contents of the labels and
|
|
tooltips are swapped, with the descriptions used as X-axis labels and
|
|
the build number and date used for tooltips. (default false)
|
|
:arg bool exclude-zero-yaxis: When false, Y-axis contains the value zero
|
|
even if it is not included in the data series. When true, the value
|
|
zero is not automatically included. (default false)
|
|
:arg bool logarithmic-yaxis: When true, the Y-axis will use a logarithmic
|
|
scale. By default, the Y-axis uses a linear scale. (default false)
|
|
:arg bool keep-records: When true, show all builds up to 'Number of
|
|
builds to include'. (default false)
|
|
:arg str csv-file-name: Use for choosing the file name in which the data
|
|
will be persisted. If none specified and random name is generated as
|
|
done in the Jenkins Plot plugin. (default random generated .csv
|
|
filename, same behaviour as the Jenkins Plot plugin)
|
|
:arg list series: list data series definitions
|
|
|
|
:Series: * **file** (`str`) : files to include
|
|
* **inclusion-flag** filtering mode for CSV files. Possible
|
|
values are:
|
|
|
|
* **off** (default)
|
|
* **include-by-string**
|
|
* **exclude-by-string**
|
|
* **include-by-column**
|
|
* **exclude-by-column**
|
|
|
|
* **exclude** (`str`) : exclude pattern for CSV file.
|
|
* **url** (`str`) : for 'csv' and 'xml' file types
|
|
used when you click on a point (default empty)
|
|
* **display-table** (`bool`) : for 'csv' file type
|
|
if true, original CSV will be shown above plot (default false)
|
|
* **label** (`str`) : used by 'properties' file type
|
|
Specifies the legend label for this data series.
|
|
(default empty)
|
|
* **format** (`str`) : Type of file where we get datas.
|
|
Can be: properties, csv, xml
|
|
* **xpath-type** (`str`) : The result type of the expression must
|
|
be supplied due to limitations in the java.xml.xpath parsing.
|
|
The result can be: node, nodeset, boolean, string, or number.
|
|
Strings and numbers will be converted to double. Boolean will
|
|
be converted to 1 for true, and 0 for false. (default 'node')
|
|
* **xpath** (`str`) : used by 'xml' file type
|
|
Xpath which selects the values that should be plotted.
|
|
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/plot-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/plot-full.yaml
|
|
:language: yaml
|
|
"""
|
|
top = XML.SubElement(xml_parent, "hudson.plugins.plot.PlotPublisher")
|
|
plots = XML.SubElement(top, "plots")
|
|
format_dict = {
|
|
"properties": "hudson.plugins.plot.PropertiesSeries",
|
|
"csv": "hudson.plugins.plot.CSVSeries",
|
|
"xml": "hudson.plugins.plot.XMLSeries",
|
|
}
|
|
xpath_dict = {
|
|
"nodeset": "NODESET",
|
|
"node": "NODE",
|
|
"string": "STRING",
|
|
"boolean": "BOOLEAN",
|
|
"number": "NUMBER",
|
|
}
|
|
inclusion_dict = {
|
|
"off": "OFF",
|
|
"include-by-string": "INCLUDE_BY_STRING",
|
|
"exclude-by-string": "EXCLUDE_BY_STRING",
|
|
"include-by-column": "INCLUDE_BY_COLUMN",
|
|
"exclude-by-column": "EXCLUDE_BY_COLUMN",
|
|
}
|
|
|
|
style_list = [
|
|
"area",
|
|
"bar",
|
|
"bar3d",
|
|
"line",
|
|
"line3d",
|
|
"stackedArea",
|
|
"stackedbar",
|
|
"stackedbar3d",
|
|
"waterfall",
|
|
]
|
|
|
|
plot_mappings = [
|
|
("title", "title", ""),
|
|
("yaxis", "yaxis", ""),
|
|
("width", "width", "750"),
|
|
("height", "height", "450"),
|
|
("csv-file-name", "csvFileName", ""),
|
|
("group", "group", None),
|
|
("use-description", "useDescr", False),
|
|
("exclude-zero-yaxis", "exclZero", False),
|
|
("logarithmic-yaxis", "logarithmic", False),
|
|
("keep-records", "keepRecords", False),
|
|
("num-builds", "numBuilds", ""),
|
|
("style", "style", "line", style_list),
|
|
]
|
|
|
|
plot_csv_mappings = [
|
|
("inclusion-flag", "inclusionFlag", "off", inclusion_dict),
|
|
("exclude", "exclusionValues", ""),
|
|
("url", "url", ""),
|
|
("display-table", "displayTableFlag", False),
|
|
]
|
|
|
|
plot_xml_mappings = [
|
|
("url", "url", ""),
|
|
("xpath", "xpathString", ""),
|
|
("xpath-type", "nodeTypeString", "node", xpath_dict),
|
|
]
|
|
|
|
for plot in data:
|
|
plugin = XML.SubElement(plots, "hudson.plugins.plot.Plot")
|
|
helpers.convert_mapping_to_xml(plugin, plot, plot_mappings, fail_required=True)
|
|
|
|
topseries = XML.SubElement(plugin, "series")
|
|
series = plot["series"]
|
|
for serie in series:
|
|
format_data = serie.get("format")
|
|
if format_data not in format_dict:
|
|
raise JenkinsJobsException(
|
|
"format entered is not valid, must "
|
|
"be one of: %s" % " , ".join(format_dict.keys())
|
|
)
|
|
subserie = XML.SubElement(topseries, format_dict.get(format_data))
|
|
XML.SubElement(subserie, "file").text = serie.get("file")
|
|
if format_data == "properties":
|
|
XML.SubElement(subserie, "label").text = serie.get("label", "")
|
|
if format_data == "csv":
|
|
helpers.convert_mapping_to_xml(
|
|
subserie, serie, plot_csv_mappings, fail_required=True
|
|
)
|
|
if serie.get("exclude", ""):
|
|
exclude_strings = serie.get("exclude", "").split(",")
|
|
exclusionset = XML.SubElement(subserie, "strExclusionSet")
|
|
for exclude_string in exclude_strings:
|
|
XML.SubElement(exclusionset, "string").text = exclude_string
|
|
if format_data == "xml":
|
|
helpers.convert_mapping_to_xml(
|
|
subserie, serie, plot_xml_mappings, fail_required=True
|
|
)
|
|
XML.SubElement(subserie, "fileType").text = serie.get("format")
|
|
|
|
|
|
def git(registry, xml_parent, data):
|
|
"""yaml: git
|
|
This plugin will configure the Jenkins Git plugin to
|
|
push merge results, tags, and/or branches to
|
|
remote repositories after the job completes.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Git Plugin <git>`.
|
|
|
|
:arg bool push-merge: push merges back to the origin specified in the
|
|
pre-build merge options (default false)
|
|
:arg bool push-only-if-success: Only push to remotes if the build succeeds
|
|
- otherwise, nothing will be pushed.
|
|
(default true)
|
|
:arg bool force-push: Add force option to git push (default false)
|
|
:arg list tags: tags to push at the completion of the build
|
|
|
|
:tag: * **remote** (`str`) remote repo name to push to
|
|
(default 'origin')
|
|
* **name** (`str`) name of tag to push
|
|
* **message** (`str`) message content of the tag
|
|
* **create-tag** (`bool`) whether or not to create the tag
|
|
after the build, if this is False then the tag needs to
|
|
exist locally (default false)
|
|
* **update-tag** (`bool`) whether to overwrite a remote tag
|
|
or not (default false)
|
|
|
|
:arg list branches: branches to push at the completion of the build
|
|
|
|
:branch: * **remote** (`str`) remote repo name to push to
|
|
(default 'origin')
|
|
* **name** (`str`) name of remote branch to push to
|
|
|
|
:arg list notes: notes to push at the completion of the build
|
|
|
|
:note: * **remote** (`str`) remote repo name to push to
|
|
(default 'origin')
|
|
* **message** (`str`) content of the note
|
|
* **namespace** (`str`) namespace of the note
|
|
(default master)
|
|
* **replace-note** (`bool`) whether to overwrite a note or not
|
|
(default false)
|
|
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/git-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/git-full.yaml
|
|
:language: yaml
|
|
"""
|
|
mappings = [
|
|
("push-merge", "pushMerge", False),
|
|
("push-only-if-success", "pushOnlyIfSuccess", True),
|
|
("force-push", "forcePush", False),
|
|
]
|
|
|
|
tag_mappings = [
|
|
("remote", "targetRepoName", "origin"),
|
|
("name", "tagName", None),
|
|
("message", "tagMessage", ""),
|
|
("create-tag", "createTag", False),
|
|
("update-tag", "updateTag", False),
|
|
]
|
|
|
|
branch_mappings = [
|
|
("remote", "targetRepoName", "origin"),
|
|
("name", "branchName", None),
|
|
]
|
|
|
|
note_mappings = [
|
|
("remote", "targetRepoName", "origin"),
|
|
("message", "noteMsg", None),
|
|
("namespace", "noteNamespace", "master"),
|
|
("replace-note", "noteReplace", False),
|
|
]
|
|
|
|
top = XML.SubElement(xml_parent, "hudson.plugins.git.GitPublisher")
|
|
XML.SubElement(top, "configVersion").text = "2"
|
|
helpers.convert_mapping_to_xml(top, data, mappings, fail_required=True)
|
|
|
|
tags = data.get("tags", [])
|
|
if tags:
|
|
xml_tags = XML.SubElement(top, "tagsToPush")
|
|
for tag in tags:
|
|
xml_tag = XML.SubElement(
|
|
xml_tags, "hudson.plugins.git.GitPublisher_-TagToPush"
|
|
)
|
|
helpers.convert_mapping_to_xml(
|
|
xml_tag, tag["tag"], tag_mappings, fail_required=True
|
|
)
|
|
|
|
branches = data.get("branches", [])
|
|
if branches:
|
|
xml_branches = XML.SubElement(top, "branchesToPush")
|
|
for branch in branches:
|
|
xml_branch = XML.SubElement(
|
|
xml_branches, "hudson.plugins.git.GitPublisher_-BranchToPush"
|
|
)
|
|
helpers.convert_mapping_to_xml(
|
|
xml_branch, branch["branch"], branch_mappings, fail_required=True
|
|
)
|
|
|
|
notes = data.get("notes", [])
|
|
if notes:
|
|
xml_notes = XML.SubElement(top, "notesToPush")
|
|
for note in notes:
|
|
xml_note = XML.SubElement(
|
|
xml_notes, "hudson.plugins.git.GitPublisher_-NoteToPush"
|
|
)
|
|
helpers.convert_mapping_to_xml(
|
|
xml_note, note["note"], note_mappings, fail_required=True
|
|
)
|
|
|
|
|
|
def github_notifier(registry, xml_parent, data):
|
|
"""yaml: github-notifier
|
|
Set build status on Github commit.
|
|
Requires the Jenkins :jenkins-plugins:`Github Plugin <github>`.
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/github-notifier.yaml
|
|
:language: yaml
|
|
"""
|
|
XML.SubElement(xml_parent, "com.cloudbees.jenkins.GitHubCommitNotifier")
|
|
|
|
|
|
def gitlab_notifier(registry, xml_parent, data):
|
|
"""yaml: gitlab-notifier
|
|
Set build status on GitLab commit.
|
|
Requires the Jenkins :jenkins-plugins:`GitLab Plugin <gitlab-plugin>`.
|
|
|
|
:arg str name: The name of the build in GitLab. With this you can
|
|
distinguish different Jenkins jobs for the same commit in GitLab.
|
|
(default 'jenkins')
|
|
:arg bool mark-unstable-as-success: (default false)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/gitlab-notifier-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/gitlab-notifier-full.yaml
|
|
:language: yaml
|
|
"""
|
|
top = XML.SubElement(
|
|
xml_parent, "com.dabsquared.gitlabjenkins.publisher.GitLabCommitStatusPublisher"
|
|
)
|
|
top.set("plugin", "gitlab-plugin")
|
|
|
|
mappings = [
|
|
("name", "name", "jenkins"),
|
|
("mark-unstable-as-success", "markUnstableAsSuccess", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(top, data, mappings, fail_required=True)
|
|
|
|
|
|
def gitlab_vote(registry, xml_parent, data):
|
|
"""yaml: gitlab-vote
|
|
Set vote for build status on GitLab merge request.
|
|
Requires the Jenkins :jenkins-plugins:`GitLab Plugin <gitlab-plugin>`.
|
|
|
|
Example:
|
|
|
|
.. literalinclude::
|
|
../../tests/publishers/fixtures/gitlab-vote.yaml
|
|
:language: yaml
|
|
"""
|
|
XML.SubElement(
|
|
xml_parent, "com.dabsquared.gitlabjenkins.publisher.GitLabVotePublisher"
|
|
)
|
|
|
|
|
|
def gitlab_message(registry, xml_parent, data):
|
|
"""yaml: gitlab-message
|
|
Add note with build status on GitLab merge request.
|
|
Requires the Jenkins :jenkins-plugins:`GitLab Plugin <gitlab-plugin>`.
|
|
|
|
:arg bool failure-only: make a comment only on failure (default false)
|
|
:arg bool success-note: make a comment on GitLab Merge Request
|
|
if build succeeds (default false)
|
|
:arg bool failure-note: make a comment on GitLab Merge Request
|
|
if build failed (default false)
|
|
:arg bool abort-note: make a comment on GitLab Merge Request
|
|
if build aborted (default false)
|
|
:arg bool unstable-note: make a comment on GitLab Merge Request
|
|
if build unstable (default false)
|
|
|
|
:arg str success-note-text: text of comment on success build (default '')
|
|
:arg str failure-note-text: text of comment on failed build (default '')
|
|
:arg str abort-note-text: text of comment on aborted build (default '')
|
|
:arg str unstable-note-text: text of comment on unstable build (default '')
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/gitlab-message-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/gitlab-message-full.yaml
|
|
:language: yaml
|
|
"""
|
|
gitlab = XML.SubElement(
|
|
xml_parent, "com.dabsquared.gitlabjenkins.publisher.GitLabMessagePublisher"
|
|
)
|
|
gitlab.set("plugin", "gitlab-plugin")
|
|
|
|
mapping = [
|
|
("failure-only", "onlyForFailure", False),
|
|
("success-note", "replaceSuccessNote", False),
|
|
("failure-note", "replaceFailureNote", False),
|
|
("abort-note", "replaceAbortNote", False),
|
|
("unstable-note", "replaceUnstableNote", False),
|
|
("success-note-text", "successNoteText", ""),
|
|
("failure-note-text", "failureNoteText", ""),
|
|
("abort-note-text", "abortNoteText", ""),
|
|
("unstable-note-text", "unstableNoteText", ""),
|
|
]
|
|
|
|
helpers.convert_mapping_to_xml(gitlab, data, mapping, fail_required=True)
|
|
|
|
|
|
def zulip(registry, xml_parent, data):
|
|
"""yaml: zulip
|
|
Set build status on zulip.
|
|
Requires the Jenkins :jenkins-plugins:`Humbug Plugin <humbug>`.
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/zulip.yaml
|
|
:language: yaml
|
|
"""
|
|
XML.SubElement(xml_parent, "hudson.plugins.humbug.HumbugNotifier")
|
|
|
|
|
|
def build_publisher(registry, xml_parent, data):
|
|
"""yaml: build-publisher
|
|
This plugin allows records from one Jenkins to be published
|
|
on another Jenkins.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Build Publisher Plugin
|
|
<build-publisher>`.
|
|
|
|
:arg bool publish-unstable-builds: publish unstable builds (default true)
|
|
:arg bool publish-failed-builds: publish failed builds (default true)
|
|
:arg int days-to-keep: days to keep when publishing results (optional)
|
|
:arg int num-to-keep: number of jobs to keep in the published results
|
|
(optional)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/build-publisher-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/build-publisher-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
reporter = XML.SubElement(
|
|
xml_parent, "hudson.plugins.build__publisher.BuildPublisher"
|
|
)
|
|
|
|
mappings = [
|
|
("publish-unstable-builds", "publishUnstableBuilds", True),
|
|
("publish-failed-builds", "publishFailedBuilds", True),
|
|
]
|
|
helpers.convert_mapping_to_xml(reporter, data, mappings, fail_required=True)
|
|
if "days-to-keep" in data or "num-to-keep" in data:
|
|
logrotator = XML.SubElement(reporter, "logRotator")
|
|
mappings = [
|
|
("days-to-keep", "daysToKeep", -1),
|
|
("num-to-keep", "numToKeep", -1),
|
|
# hardcoded to -1 to emulate what the build publisher
|
|
# plugin seem to do.
|
|
("", "artifactDaysToKeep", -1),
|
|
("", "artifactNumToKeep", -1),
|
|
]
|
|
helpers.convert_mapping_to_xml(logrotator, data, mappings, fail_required=True)
|
|
|
|
|
|
def stash(registry, xml_parent, data):
|
|
"""yaml: stash
|
|
This plugin will configure the Jenkins BitBucket Server Notifier plugin to
|
|
notify Atlassian BitBucket after job completes.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Bitbucket Server Notifier Plugin
|
|
<stashNotifier>`.
|
|
|
|
:arg str url: Base url of Stash Server (default "")
|
|
:arg str username: Username of Stash Server (default "")
|
|
:arg str password: Password of Stash Server (default "")
|
|
:arg str credentials-id: Credentials of Stash Server (optional)
|
|
:arg bool ignore-ssl: Ignore unverified SSL certificate (default false)
|
|
:arg str commit-sha1: Commit SHA1 to notify (default "")
|
|
:arg bool include-build-number: Include build number in key
|
|
(default false)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/stash-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/stash-full.yaml
|
|
:language: yaml
|
|
"""
|
|
top = XML.SubElement(
|
|
xml_parent, "org.jenkinsci.plugins.stashNotifier.StashNotifier"
|
|
)
|
|
|
|
XML.SubElement(top, "stashServerBaseUrl").text = data.get("url", "")
|
|
if data.get("credentials-id") is not None:
|
|
XML.SubElement(top, "credentialsId").text = str(data.get("credentials-id"))
|
|
else:
|
|
XML.SubElement(
|
|
top, "stashUserName"
|
|
).text = helpers.get_value_from_yaml_or_config_file(
|
|
"username", "stash", data, registry.jjb_config
|
|
)
|
|
XML.SubElement(
|
|
top, "stashUserPassword"
|
|
).text = helpers.get_value_from_yaml_or_config_file(
|
|
"password", "stash", data, registry.jjb_config
|
|
)
|
|
mappings = [
|
|
("ignore-ssl", "ignoreUnverifiedSSLPeer", False),
|
|
("commit-sha1", "commitSha1", ""),
|
|
("include-build-number", "includeBuildNumberInKey", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(top, data, mappings, fail_required=True)
|
|
|
|
|
|
def dependency_check(registry, xml_parent, data):
|
|
"""yaml: dependency-check
|
|
Dependency-Check is an open source utility that identifies project
|
|
dependencies and checks if there are any known, publicly disclosed,
|
|
vulnerabilities.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`OWASP Dependency-Check Plugin
|
|
<dependency-check-jenkins-plugin>`.
|
|
|
|
:arg str pattern: Report filename pattern (optional)
|
|
:arg bool can-run-on-failed: Also runs for failed builds, instead of just
|
|
stable or unstable builds (default false)
|
|
:arg bool should-detect-modules: Determines if Ant or Maven modules should
|
|
be detected for all files that contain warnings (default false)
|
|
:arg int healthy: Sunny threshold (optional)
|
|
:arg int unhealthy: Stormy threshold (optional)
|
|
:arg str health-threshold: Threshold priority for health status
|
|
('low', 'normal' or 'high', defaulted to 'low')
|
|
:arg dict thresholds: Mark build as failed or unstable if the number of
|
|
errors exceeds a threshold. (optional)
|
|
|
|
:thresholds:
|
|
* **unstable** (`dict`)
|
|
:unstable: * **total-all** (`int`)
|
|
* **total-high** (`int`)
|
|
* **total-normal** (`int`)
|
|
* **total-low** (`int`)
|
|
* **new-all** (`int`)
|
|
* **new-high** (`int`)
|
|
* **new-normal** (`int`)
|
|
* **new-low** (`int`)
|
|
|
|
* **failed** (`dict`)
|
|
:failed: * **total-all** (`int`)
|
|
* **total-high** (`int`)
|
|
* **total-normal** (`int`)
|
|
* **total-low** (`int`)
|
|
* **new-all** (`int`)
|
|
* **new-high** (`int`)
|
|
* **new-normal** (`int`)
|
|
* **new-low** (`int`)
|
|
:arg str default-encoding: Encoding for parsing or showing files (optional)
|
|
:arg bool do-not-resolve-relative-paths: (default false)
|
|
:arg bool dont-compute-new: If set to false, computes new warnings based on
|
|
the reference build (default true)
|
|
:arg bool use-previous-build-as-reference: determines whether to always
|
|
use the previous build as the reference build (default false)
|
|
:arg bool use-stable-build-as-reference: The number of new warnings will be
|
|
calculated based on the last stable build, allowing reverts of unstable
|
|
builds where the number of warnings was decreased. (default false)
|
|
:arg bool use-delta-values: If set then the number of new warnings is
|
|
calculated by subtracting the total number of warnings of the current
|
|
build from the reference build.
|
|
(default false)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/dependency-check-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/dependency-check-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
dependency_check = XML.SubElement(
|
|
xml_parent, "org.jenkinsci.plugins.DependencyCheck.DependencyCheckPublisher"
|
|
)
|
|
|
|
# trends
|
|
helpers.build_trends_publisher("[DEPENDENCYCHECK] ", dependency_check, data)
|
|
|
|
|
|
def description_setter(registry, xml_parent, data):
|
|
"""yaml: description-setter
|
|
This plugin sets the description for each build,
|
|
based upon a RegEx test of the build log file.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Description Setter Plugin
|
|
<description-setter>`.
|
|
|
|
:arg str regexp: A RegEx which is used to scan the build log file
|
|
(default '')
|
|
:arg str regexp-for-failed: A RegEx which is used for failed builds
|
|
(default '')
|
|
:arg str description: The description to set on the build (optional)
|
|
:arg str description-for-failed: The description to set on
|
|
the failed builds (optional)
|
|
:arg bool set-for-matrix: Also set the description on
|
|
a multi-configuration build (default false)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/description-setter-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/description-setter-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
descriptionsetter = XML.SubElement(
|
|
xml_parent, "hudson.plugins.descriptionsetter.DescriptionSetterPublisher"
|
|
)
|
|
mappings = [
|
|
("regexp", "regexp", ""),
|
|
("regexp-for-failed", "regexpForFailed", ""),
|
|
("description", "description", None),
|
|
("description-for-failed", "descriptionForFailed", None),
|
|
("set-for-matrix", "setForMatrix", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(
|
|
descriptionsetter, data, mappings, fail_required=False
|
|
)
|
|
|
|
|
|
def doxygen(registry, xml_parent, data):
|
|
"""yaml: doxygen
|
|
This plugin parses the Doxygen descriptor (Doxyfile) and provides a link to
|
|
the generated Doxygen documentation.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Doxygen Plugin <doxygen>`.
|
|
|
|
:arg str doxyfile: The doxyfile path (required)
|
|
:arg str slave: The node or label to pull the doxygen HTML files from
|
|
(default '')
|
|
:arg bool keep-all: Retain doxygen generation for each successful build
|
|
(default false)
|
|
:arg str folder: Folder where you run doxygen (default '')
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/doxygen-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/doxygen-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
logger = logging.getLogger(__name__)
|
|
p = XML.SubElement(xml_parent, "hudson.plugins.doxygen.DoxygenArchiver")
|
|
mappings = [
|
|
("doxyfile", "doxyfilePath", None),
|
|
("slave", "runOnChild", ""),
|
|
("folder", "folderWhereYouRunDoxygen", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(p, data, mappings, fail_required=True)
|
|
# backward compatibility
|
|
if "keepall" in data:
|
|
if "keep-all" in data:
|
|
XML.SubElement(p, "keepAll").text = str(data.get("keep-all", False)).lower()
|
|
logger.warning(
|
|
"The value of 'keepall' will be ignored " "in preference to 'keep-all'."
|
|
)
|
|
else:
|
|
XML.SubElement(p, "keepAll").text = str(data.get("keepall", False)).lower()
|
|
logger.warning("'keepall' is deprecated please use 'keep-all'")
|
|
else:
|
|
XML.SubElement(p, "keepAll").text = str(data.get("keep-all", False)).lower()
|
|
|
|
|
|
def docker_stop_container(registry, xml_parent, data):
|
|
"""yaml: docker-stop-container
|
|
This plugin allows removing stopped docker containers.
|
|
It requires the :jenkins-plugins:`Docker build step plugin
|
|
<docker-build-step>`.
|
|
|
|
:arg bool remove-stopped-containers: Boolean value to remove
|
|
stopped docker containers (default False)
|
|
|
|
Minimal Example:
|
|
.. literalinclude:: /../../tests/
|
|
publishers/fixtures/docker-stop-container-minimal.yaml
|
|
|
|
Full Example:
|
|
.. literalinclude:: /../../tests/
|
|
publishers/fixtures/docker-stop-container-full.yaml
|
|
"""
|
|
docker_stop_container = XML.SubElement(
|
|
xml_parent,
|
|
"com.nirima.jenkins.plugins.docker" ".publisher.DockerPublisherControl",
|
|
)
|
|
docker_stop_container.set("plugin", "docker-plugin")
|
|
mapping = [("remove-stopped-containers", "remove", False)]
|
|
helpers.convert_mapping_to_xml(
|
|
docker_stop_container, data, mapping, fail_required=False
|
|
)
|
|
|
|
|
|
def sitemonitor(registry, xml_parent, data):
|
|
"""yaml: sitemonitor
|
|
This plugin checks the availability of an url.
|
|
|
|
It requires the :jenkins-plugins:`sitemonitor plugin <sitemonitor>`.
|
|
|
|
:arg list sites: List of URLs to check
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/sitemonitor-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/sitemonitor-full.yaml
|
|
:language: yaml
|
|
"""
|
|
mon = XML.SubElement(xml_parent, "hudson.plugins.sitemonitor.SiteMonitorRecorder")
|
|
if data.get("sites"):
|
|
sites = XML.SubElement(mon, "mSites")
|
|
for siteurl in data.get("sites"):
|
|
site = XML.SubElement(sites, "hudson.plugins.sitemonitor.model.Site")
|
|
XML.SubElement(site, "mUrl").text = siteurl["url"]
|
|
|
|
|
|
def testng(registry, xml_parent, data):
|
|
"""yaml: testng
|
|
This plugin publishes TestNG test reports.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`TestNG Results Plugin
|
|
<testng-plugin>`.
|
|
|
|
:arg str pattern: filename pattern to locate the TestNG XML report files
|
|
(required)
|
|
:arg bool escape-test-description: escapes the description string
|
|
associated with the test method while displaying test method details
|
|
(default true)
|
|
:arg bool escape-exception-msg: escapes the test method's exception
|
|
messages. (default true)
|
|
:arg bool fail-on-failed-test-config: Allows for a distinction between
|
|
failing tests and failing configuration methods (>=1.10) (default
|
|
false)
|
|
:arg bool show-failed-builds: include results from failed builds in the
|
|
trend graph (>=1.6) (default false)
|
|
:arg int unstable-skips: Build is marked UNSTABLE if the number/percentage
|
|
of skipped tests exceeds the specified threshold (>=1.11) (default 100)
|
|
:arg int unstable-fails: Build is marked UNSTABLE if the number/percentage
|
|
of failed tests exceeds the specified threshold (>=1.11) (default 0)
|
|
:arg int failed-skips: Build is marked FAILURE if the number/percentage of
|
|
skipped tests exceeds the specified threshold (>=1.11) (default 100)
|
|
:arg int failed-fails: Build is marked FAILURE if the number/percentage of
|
|
failed tests exceeds the specified threshold (>=1.11) (default 100)
|
|
:arg str threshold-mode: Interpret threshold as number of tests or
|
|
percentage of tests (>=1.11) (default percentage)
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/testng-full.yaml
|
|
:language: yaml
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/testng-minimal.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
reporter = XML.SubElement(xml_parent, "hudson.plugins.testng.Publisher")
|
|
reporter.set("plugin", "testng-plugin")
|
|
threshold_modes = {"number": 1, "percentage": 2}
|
|
|
|
mappings = [
|
|
("pattern", "reportFilenamePattern", None),
|
|
("escape-test-description", "escapeTestDescp", True),
|
|
("escape-exception-msg", "escapeExceptionMsg", True),
|
|
("fail-on-failed-test-config", "failureOnFailedTestConfig", False),
|
|
("show-failed-builds", "showFailedBuilds", False),
|
|
("unstable-skips", "unstableSkips", 100),
|
|
("unstable-fails", "unstableFails", 0),
|
|
("failed-skips", "failedSkips", 100),
|
|
("failed-fails", "failedFails", 100),
|
|
("threshold-mode", "thresholdMode", "percentage", threshold_modes),
|
|
]
|
|
helpers.convert_mapping_to_xml(reporter, data, mappings, fail_required=True)
|
|
|
|
|
|
def artifact_deployer(registry, xml_parent, data):
|
|
"""yaml: artifact-deployer
|
|
This plugin makes it possible to copy artifacts to remote locations.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`ArtifactDeployer Plugin
|
|
<artifactdeployer>`.
|
|
|
|
:arg list entries:
|
|
:entries:
|
|
* **files** (`str`) - files to deploy
|
|
* **basedir** (`str`) - the dir from files are deployed
|
|
* **excludes** (`str`) - the mask to exclude files
|
|
* **remote** (`str`) - a remote output directory
|
|
* **flatten** (`bool`) - ignore the source directory structure
|
|
(default false)
|
|
* **delete-remote** (`bool`) - clean-up remote directory
|
|
before deployment (default false)
|
|
* **delete-remote-artifacts** (`bool`) - delete remote artifacts
|
|
when the build is deleted (default false)
|
|
* **fail-no-files** (`bool`) - fail build if there are no files
|
|
(default false)
|
|
* **groovy-script** (`str`) - execute a Groovy script
|
|
before a build is deleted
|
|
|
|
:arg bool deploy-if-fail: Deploy if the build is failed (default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/artifact-dep.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
deployer = XML.SubElement(
|
|
xml_parent,
|
|
"org.jenkinsci.plugins.artifactdeployer." "ArtifactDeployerPublisher",
|
|
)
|
|
if data is None or "entries" not in data:
|
|
raise Exception("entries field is missing")
|
|
elif data.get("entries", None) is None:
|
|
entries = XML.SubElement(deployer, "entries", {"class": "empty-list"})
|
|
else:
|
|
entries = XML.SubElement(deployer, "entries")
|
|
for entry in data.get("entries"):
|
|
deployer_entry = XML.SubElement(
|
|
entries, "org.jenkinsci.plugins.artifactdeployer.ArtifactDeployerEntry"
|
|
)
|
|
XML.SubElement(deployer_entry, "includes").text = entry.get("files")
|
|
XML.SubElement(deployer_entry, "basedir").text = entry.get("basedir")
|
|
XML.SubElement(deployer_entry, "excludes").text = entry.get("excludes")
|
|
XML.SubElement(deployer_entry, "remote").text = entry.get("remote")
|
|
XML.SubElement(deployer_entry, "flatten").text = str(
|
|
entry.get("flatten", False)
|
|
).lower()
|
|
XML.SubElement(deployer_entry, "deleteRemote").text = str(
|
|
entry.get("delete-remote", False)
|
|
).lower()
|
|
XML.SubElement(deployer_entry, "deleteRemoteArtifacts").text = str(
|
|
entry.get("delete-remote-artifacts", False)
|
|
).lower()
|
|
XML.SubElement(deployer_entry, "failNoFilesDeploy").text = str(
|
|
entry.get("fail-no-files", False)
|
|
).lower()
|
|
XML.SubElement(deployer_entry, "groovyExpression").text = entry.get(
|
|
"groovy-script"
|
|
)
|
|
deploy_if_fail = str(data.get("deploy-if-fail", False)).lower()
|
|
XML.SubElement(deployer, "deployEvenBuildFail").text = deploy_if_fail
|
|
|
|
|
|
def s3(registry, xml_parent, data):
|
|
"""yaml: s3
|
|
Upload build artifacts to Amazon S3.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`S3 plugin <s3>`.
|
|
|
|
:arg str s3-profile: Globally-defined S3 profile to use
|
|
:arg bool dont-wait-for-concurrent-builds: Don't wait
|
|
for completion of concurrent builds before publishing to S3
|
|
(default false)
|
|
:arg list entries:
|
|
:entries:
|
|
* **destination-bucket** (`str`) - Destination S3 bucket
|
|
* **source-files** (`str`) - Source files (Ant glob syntax)
|
|
* **storage-class** (`str`) - S3 storage class; one of "STANDARD"
|
|
or "REDUCED_REDUNDANCY"
|
|
* **bucket-region** (`str`) - S3 bucket region (capitalized with
|
|
underscores)
|
|
* **upload-on-failure** (`bool`) - Upload files even if the build
|
|
failed (default false)
|
|
* **upload-from-slave** (`bool`) - Perform the upload directly from
|
|
the Jenkins slave rather than the master node. (default false)
|
|
* **managed-artifacts** (`bool`) - Let Jenkins fully manage the
|
|
published artifacts, similar to when artifacts are published to
|
|
the Jenkins master. (default false)
|
|
* **s3-encryption** (`bool`) - Use S3 AES-256 server side encryption
|
|
support. (default false)
|
|
* **flatten** (`bool`) - Ignore the directory structure of the
|
|
artifacts in the source project and copy all matching artifacts
|
|
directly into the specified bucket. (default false)
|
|
:arg list metadata-tags:
|
|
:metadata-tags:
|
|
* **key** Metadata key for files from this build. It will be
|
|
prefixed by "x-amz-meta-" when uploaded to S3. Can contain macros
|
|
(e.g. environment variables).
|
|
* **value** Metadata value associated with the key. Can contain macros.
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/s3001.yaml
|
|
:language: yaml
|
|
"""
|
|
deployer = XML.SubElement(xml_parent, "hudson.plugins.s3.S3BucketPublisher")
|
|
if data is None or not data.get("entries"):
|
|
raise JenkinsJobsException("No filesets defined.")
|
|
|
|
XML.SubElement(deployer, "dontWaitForConcurrentBuildCompletion").text = str(
|
|
data.get("dont-wait-for-concurrent-builds", False)
|
|
).lower()
|
|
|
|
XML.SubElement(deployer, "profileName").text = data.get("s3-profile")
|
|
|
|
entries = XML.SubElement(deployer, "entries")
|
|
|
|
for entry in data.get("entries"):
|
|
fileset = XML.SubElement(entries, "hudson.plugins.s3.Entry")
|
|
|
|
# xml keys -> yaml keys
|
|
settings = [
|
|
("bucket", "destination-bucket", ""),
|
|
("sourceFile", "source-files", ""),
|
|
("storageClass", "storage-class", ""),
|
|
("selectedRegion", "bucket-region", ""),
|
|
("noUploadOnFailure", "upload-on-failure", False),
|
|
("uploadFromSlave", "upload-from-slave", False),
|
|
("managedArtifacts", "managed-artifacts", False),
|
|
("useServerSideEncryption", "s3-encryption", False),
|
|
("flatten", "flatten", False),
|
|
]
|
|
|
|
for xml_key, yaml_key, default in settings:
|
|
xml_config = XML.SubElement(fileset, xml_key)
|
|
config_value = entry.get(yaml_key, default)
|
|
if xml_key == "noUploadOnFailure":
|
|
xml_config.text = str(not config_value).lower()
|
|
elif isinstance(default, bool):
|
|
xml_config.text = str(config_value).lower()
|
|
else:
|
|
xml_config.text = str(config_value)
|
|
|
|
metadata = XML.SubElement(deployer, "userMetadata")
|
|
for tag in data.get("metadata-tags", []):
|
|
pair = XML.SubElement(metadata, "hudson.plugins.s3.MetadataPair")
|
|
XML.SubElement(pair, "key").text = tag.get("key")
|
|
XML.SubElement(pair, "value").text = tag.get("value")
|
|
|
|
|
|
def ruby_metrics(registry, xml_parent, data):
|
|
"""yaml: ruby-metrics
|
|
Rcov plugin parses rcov html report files and
|
|
shows it in Jenkins with a trend graph.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Ruby metrics plugin
|
|
<rubyMetrics>`.
|
|
|
|
:arg str report-dir: Relative path to the coverage report directory
|
|
:arg dict targets:
|
|
|
|
:targets: (total-coverage, code-coverage)
|
|
|
|
* **healthy** (`int`): Healthy threshold
|
|
* **unhealthy** (`int`): Unhealthy threshold
|
|
* **unstable** (`int`): Unstable threshold
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/ruby-metrics.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
metrics = XML.SubElement(
|
|
xml_parent, "hudson.plugins.rubyMetrics.rcov.RcovPublisher"
|
|
)
|
|
report_dir = data.get("report-dir", "")
|
|
XML.SubElement(metrics, "reportDir").text = report_dir
|
|
targets = XML.SubElement(metrics, "targets")
|
|
if "target" in data:
|
|
for t in data["target"]:
|
|
if not ("code-coverage" in t or "total-coverage" in t):
|
|
raise JenkinsJobsException("Unrecognized target name")
|
|
el = XML.SubElement(
|
|
targets, "hudson.plugins.rubyMetrics.rcov.model.MetricTarget"
|
|
)
|
|
if "total-coverage" in t:
|
|
XML.SubElement(el, "metric").text = "TOTAL_COVERAGE"
|
|
else:
|
|
XML.SubElement(el, "metric").text = "CODE_COVERAGE"
|
|
for threshold_name, threshold_value in next(iter(t.values())).items():
|
|
elname = threshold_name.lower()
|
|
XML.SubElement(el, elname).text = str(threshold_value)
|
|
else:
|
|
raise JenkinsJobsException("Coverage metric targets must be set")
|
|
|
|
|
|
def fitnesse(registry, xml_parent, data):
|
|
"""yaml: fitnesse
|
|
Publish Fitnesse test results
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Fitnesse plugin <fitnesse>`.
|
|
|
|
:arg str results: path specifier for results files
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/fitnesse001.yaml
|
|
:language: yaml
|
|
"""
|
|
fitnesse = XML.SubElement(
|
|
xml_parent, "hudson.plugins.fitnesse.FitnesseResultsRecorder"
|
|
)
|
|
results = data.get("results", "")
|
|
XML.SubElement(fitnesse, "fitnessePathToXmlResultsIn").text = results
|
|
|
|
|
|
def valgrind(registry, xml_parent, data):
|
|
"""yaml: valgrind
|
|
This plugin publishes Valgrind Memcheck XML results.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Valgrind Plugin <valgrind>`.
|
|
|
|
:arg str pattern: Filename pattern to locate the Valgrind XML report files
|
|
(required)
|
|
:arg dict thresholds: Mark build as failed or unstable if the number of
|
|
errors exceeds a threshold. All threshold values are optional.
|
|
|
|
:thresholds:
|
|
* **unstable** (`dict`)
|
|
:unstable: * **invalid-read-write** (`int`)
|
|
* **definitely-lost** (`int`)
|
|
* **total** (`int`)
|
|
* **failed** (`dict`)
|
|
:failed: * **invalid-read-write** (`int`)
|
|
* **definitely-lost** (`int`)
|
|
* **total** (`int`)
|
|
:arg bool fail-no-reports: Fail build if no reports are found
|
|
(default false)
|
|
:arg bool fail-invalid-reports: Fail build if reports are malformed
|
|
(default false)
|
|
:arg bool publish-if-aborted: Publish results for aborted builds
|
|
(default false)
|
|
:arg bool publish-if-failed: Publish results for failed builds
|
|
(default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/valgrind001.yaml
|
|
:language: yaml
|
|
"""
|
|
p = XML.SubElement(xml_parent, "org.jenkinsci.plugins.valgrind.ValgrindPublisher")
|
|
p = XML.SubElement(p, "valgrindPublisherConfig")
|
|
|
|
if "pattern" not in data:
|
|
raise JenkinsJobsException("A filename pattern must be specified.")
|
|
|
|
XML.SubElement(p, "pattern").text = data["pattern"]
|
|
|
|
dthresholds = data.get("thresholds", {})
|
|
|
|
for threshold in ["unstable", "failed"]:
|
|
dthreshold = dthresholds.get(threshold, {})
|
|
threshold = threshold.replace("failed", "fail")
|
|
|
|
ThresholdInvalidReadWrite = "%sThresholdInvalidReadWrite" % threshold
|
|
ThresholdDefinitelyLost = "%sThresholdDefinitelyLost" % threshold
|
|
ThresholdTotal = "%sThresholdTotal" % threshold
|
|
|
|
threshold_mapping = [
|
|
("invalid-read-write", ThresholdInvalidReadWrite, ""),
|
|
("definitely-lost", ThresholdDefinitelyLost, ""),
|
|
("total", ThresholdTotal, ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(
|
|
p, dthreshold, threshold_mapping, fail_required=True
|
|
)
|
|
|
|
mapping = [
|
|
("fail-no-reports", "failBuildOnMissingReports", False),
|
|
("fail-invalid-reports", "failBuildOnInvalidReports", False),
|
|
("publish-if-aborted", "publishResultsForAbortedBuilds", False),
|
|
("publish-if-failed", "publishResultsForFailedBuilds", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(p, data, mapping, fail_required=True)
|
|
|
|
|
|
def pmd(registry, xml_parent, data):
|
|
"""yaml: pmd
|
|
Publish trend reports with PMD.
|
|
|
|
Requires the Jenkins PMD Plugin (https://github.com/jenkinsci/pmd-plugin).
|
|
|
|
The PMD component accepts a dictionary with the following values:
|
|
|
|
:arg str pattern: Report filename pattern (optional)
|
|
:arg bool can-run-on-failed: Also runs for failed builds, instead of just
|
|
stable or unstable builds (default false)
|
|
:arg bool should-detect-modules: Determines if Ant or Maven modules should
|
|
be detected for all files that contain warnings (default false)
|
|
:arg int healthy: Sunny threshold (optional)
|
|
:arg int unhealthy: Stormy threshold (optional)
|
|
:arg str health-threshold: Threshold priority for health status
|
|
('low', 'normal' or 'high', defaulted to 'low')
|
|
:arg dict thresholds: Mark build as failed or unstable if the number of
|
|
errors exceeds a threshold. (optional)
|
|
|
|
:thresholds:
|
|
* **unstable** (`dict`)
|
|
:unstable: * **total-all** (`int`)
|
|
* **total-high** (`int`)
|
|
* **total-normal** (`int`)
|
|
* **total-low** (`int`)
|
|
* **new-all** (`int`)
|
|
* **new-high** (`int`)
|
|
* **new-normal** (`int`)
|
|
* **new-low** (`int`)
|
|
|
|
* **failed** (`dict`)
|
|
:failed: * **total-all** (`int`)
|
|
* **total-high** (`int`)
|
|
* **total-normal** (`int`)
|
|
* **total-low** (`int`)
|
|
* **new-all** (`int`)
|
|
* **new-high** (`int`)
|
|
* **new-normal** (`int`)
|
|
* **new-low** (`int`)
|
|
:arg str default-encoding: Encoding for parsing or showing files (optional)
|
|
:arg bool do-not-resolve-relative-paths: (default false)
|
|
:arg bool dont-compute-new: If set to false, computes new warnings based on
|
|
the reference build (default true)
|
|
:arg bool use-previous-build-as-reference: determines whether to always
|
|
use the previous build as the reference build (default false)
|
|
:arg bool use-stable-build-as-reference: The number of new warnings will be
|
|
calculated based on the last stable build, allowing reverts of unstable
|
|
builds where the number of warnings was decreased. (default false)
|
|
:arg bool use-delta-values: If set then the number of new warnings is
|
|
calculated by subtracting the total number of warnings of the current
|
|
build from the reference build.
|
|
(default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/pmd001.yaml
|
|
:language: yaml
|
|
|
|
Full example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/pmd002.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
xml_element = XML.SubElement(xml_parent, "hudson.plugins.pmd.PmdPublisher")
|
|
|
|
helpers.build_trends_publisher("[PMD] ", xml_element, data)
|
|
|
|
|
|
def scan_build(registry, xml_parent, data):
|
|
"""yaml: scan-build
|
|
Publishes results from the Clang scan-build static analyzer.
|
|
|
|
The scan-build report has to be generated in the directory
|
|
``${WORKSPACE}/clangScanBuildReports`` for the publisher to find it.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Clang Scan-Build Plugin
|
|
<clang-scanbuild>`.
|
|
|
|
:arg bool mark-unstable: Mark build as unstable if the number of bugs
|
|
exceeds a threshold (default false)
|
|
:arg int threshold: Threshold for marking builds as unstable (default 0)
|
|
:arg str exclude-paths: Comma separated paths to exclude from reports
|
|
(>=1.5) (default '')
|
|
:arg str report-folder: Folder where generated reports are located
|
|
(>=1.7) (default 'clangScanBuildReports')
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/scan-build-full.yaml
|
|
:language: yaml
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/scan-build-minimal.yaml
|
|
:language: yaml
|
|
"""
|
|
p = XML.SubElement(
|
|
xml_parent, "jenkins.plugins.clangscanbuild.publisher.ClangScanBuildPublisher"
|
|
)
|
|
p.set("plugin", "clang-scanbuild")
|
|
|
|
mappings = [
|
|
("mark-unstable", "markBuildUnstableWhenThresholdIsExceeded", False),
|
|
("threshold", "bugThreshold", 0),
|
|
("exclude-paths", "clangexcludedpaths", ""),
|
|
("report-folder", "reportFolderName", "clangScanBuildReports"),
|
|
]
|
|
helpers.convert_mapping_to_xml(p, data, mappings, fail_required=True)
|
|
|
|
|
|
def dry(registry, xml_parent, data):
|
|
"""yaml: dry
|
|
Publish trend reports with DRY.
|
|
|
|
Requires the Jenkins DRY Plugin (https://github.com/jenkinsci/dry-plugin).
|
|
|
|
The DRY component accepts a dictionary with the following values:
|
|
|
|
:arg str pattern: Report filename pattern (default '')
|
|
:arg bool can-run-on-failed: Also runs for failed builds, instead of just
|
|
stable or unstable builds (default false)
|
|
:arg bool should-detect-modules: Determines if Ant or Maven modules should
|
|
be detected for all files that contain warnings (default false)
|
|
:arg int healthy: Sunny threshold (default '')
|
|
:arg int unhealthy: Stormy threshold (default '')
|
|
:arg str health-threshold: Threshold priority for health status
|
|
('low', 'normal' or 'high', defaulted to 'low')
|
|
:arg int high-threshold: Minimum number of duplicated lines for high
|
|
priority warnings. (default 50)
|
|
:arg int normal-threshold: Minimum number of duplicated lines for normal
|
|
priority warnings. (default 25)
|
|
:arg dict thresholds: Mark build as failed or unstable if the number of
|
|
errors exceeds a threshold. (default '')
|
|
|
|
:thresholds:
|
|
* **unstable** (`dict`)
|
|
:unstable: * **total-all** (`int`)
|
|
* **total-high** (`int`)
|
|
* **total-normal** (`int`)
|
|
* **total-low** (`int`)
|
|
* **new-all** (`int`)
|
|
* **new-high** (`int`)
|
|
* **new-normal** (`int`)
|
|
* **new-low** (`int`)
|
|
|
|
* **failed** (`dict`)
|
|
:failed: * **total-all** (`int`)
|
|
* **total-high** (`int`)
|
|
* **total-normal** (`int`)
|
|
* **total-low** (`int`)
|
|
* **new-all** (`int`)
|
|
* **new-high** (`int`)
|
|
* **new-normal** (`int`)
|
|
* **new-low** (`int`)
|
|
:arg str default-encoding: Encoding for parsing or showing files (optional)
|
|
:arg bool do-not-resolve-relative-paths: (default false)
|
|
:arg bool dont-compute-new: If set to false, computes new warnings based on
|
|
the reference build (default true)
|
|
:arg bool use-previous-build-as-reference: determines whether to always
|
|
use the previous build as the reference build (default false)
|
|
:arg bool use-stable-build-as-reference: The number of new warnings will be
|
|
calculated based on the last stable build, allowing reverts of unstable
|
|
builds where the number of warnings was decreased. (default false)
|
|
:arg bool use-delta-values: If set then the number of new warnings is
|
|
calculated by subtracting the total number of warnings of the current
|
|
build from the reference build. (default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/dry001.yaml
|
|
:language: yaml
|
|
|
|
Full example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/dry004.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
xml_element = XML.SubElement(xml_parent, "hudson.plugins.dry.DryPublisher")
|
|
|
|
helpers.build_trends_publisher("[DRY] ", xml_element, data)
|
|
|
|
# Add specific settings for this trends publisher
|
|
settings = [
|
|
("high-threshold", "highThreshold", 50),
|
|
("normal-threshold", "normalThreshold", 25),
|
|
]
|
|
helpers.convert_mapping_to_xml(xml_element, data, settings, fail_required=True)
|
|
|
|
|
|
def shining_panda(registry, xml_parent, data):
|
|
"""yaml: shining-panda
|
|
Publish coverage.py results. Requires the Jenkins
|
|
:jenkins-plugins:`ShiningPanda Plugin <shiningpanda>`.
|
|
|
|
:arg str html-reports-directory: path to coverage.py html results
|
|
(optional)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/shiningpanda001.yaml
|
|
:language: yaml
|
|
"""
|
|
shining_panda_plugin = XML.SubElement(
|
|
xml_parent, "jenkins.plugins.shiningpanda.publishers.CoveragePublisher"
|
|
)
|
|
|
|
mapping = [("html-reports-directory", "htmlDir", None)]
|
|
helpers.convert_mapping_to_xml(
|
|
shining_panda_plugin, data, mapping, fail_required=False
|
|
)
|
|
|
|
|
|
def downstream_ext(registry, xml_parent, data):
|
|
"""yaml: downstream-ext
|
|
Trigger multiple downstream jobs when a job is completed and
|
|
condition is met.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Downstream-Ext Plugin
|
|
<downstream-ext>`.
|
|
|
|
:arg list projects: Projects to build (required)
|
|
:arg str condition: comparison condition used for the criteria.
|
|
One of 'equal-or-over', 'equal-or-under', 'equal'
|
|
(default 'equal-or-over')
|
|
:arg str criteria: Trigger downstream job if build results meets
|
|
condition. One of 'success', 'unstable', 'failure' or
|
|
'aborted' (default 'success')
|
|
:arg bool only-on-scm-change: Trigger only if downstream project
|
|
has SCM changes (default false)
|
|
:arg bool only-on-local-scm-change: Trigger only if current project
|
|
has SCM changes (default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/downstream-ext002.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
conditions = {
|
|
"equal-or-over": "AND_HIGHER",
|
|
"equal-or-under": "AND_LOWER",
|
|
"equal": "EXACT",
|
|
}
|
|
|
|
p = XML.SubElement(xml_parent, "hudson.plugins.downstream__ext.DownstreamTrigger")
|
|
|
|
if "projects" not in data:
|
|
raise JenkinsJobsException("Missing list of downstream projects.")
|
|
|
|
XML.SubElement(p, "childProjects").text = ",".join(data["projects"])
|
|
|
|
th = XML.SubElement(p, "threshold")
|
|
|
|
criteria = data.get("criteria", "success").upper()
|
|
|
|
wr_threshold = hudson_model.THRESHOLDS[criteria]
|
|
if criteria not in hudson_model.THRESHOLDS:
|
|
raise JenkinsJobsException(
|
|
"criteria must be one of %s" % ", ".join(hudson_model.THRESHOLDS.keys())
|
|
)
|
|
mapping = [
|
|
("name", "name", None),
|
|
("ordinal", "ordinal", None),
|
|
("color", "color", None),
|
|
("complete", "completeBuild", None),
|
|
]
|
|
helpers.convert_mapping_to_xml(th, wr_threshold, mapping, fail_required=True)
|
|
|
|
condition_mapping = [
|
|
("condition", "thresholdStrategy", "equal-or-over", conditions),
|
|
("only-on-scm-change", "onlyIfSCMChanges", False),
|
|
("only-on-local-scm-change", "onlyIfLocalSCMChanges", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(p, data, condition_mapping, fail_required=True)
|
|
|
|
|
|
def rundeck(registry, xml_parent, data):
|
|
"""yaml: rundeck
|
|
Trigger a rundeck job when the build is complete.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`RunDeck Plugin <rundeck>`.
|
|
|
|
:arg str job-id: The RunDeck job identifier. (required)
|
|
This could be:
|
|
* ID example : "42"
|
|
* UUID example : "2027ce89-7924-4ecf-a963-30090ada834f"
|
|
* reference, in the format : "project:group/job"
|
|
:arg str options: List of options for the Rundeck job, in Java-Properties
|
|
format: key=value (default "")
|
|
:arg str node-filters: List of filters to optionally filter the nodes
|
|
included by the job. (default "")
|
|
:arg str tag: Used for on-demand job scheduling on rundeck: if a tag is
|
|
specified, the job will only execute if the given tag is present in the
|
|
SCM changelog. (default "")
|
|
:arg bool wait-for-rundeck: If true Jenkins will wait for the job to
|
|
complete, if false the job will be started and Jenkins will move on.
|
|
(default false)
|
|
:arg bool fail-the-build: If true a RunDeck job failure will cause the
|
|
Jenkins build to fail. (default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/rundeck001.yaml
|
|
:language: yaml
|
|
|
|
Full example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/rundeck002.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
p = XML.SubElement(xml_parent, "org.jenkinsci.plugins.rundeck.RundeckNotifier")
|
|
|
|
mappings = [
|
|
("job-id", "jobId", None),
|
|
("options", "options", ""),
|
|
("node-filters", "nodeFilters", ""),
|
|
("tag", "tag", ""),
|
|
("wait-for-rundeck", "shouldWaitForRundeckJob", False),
|
|
("fail-the-build", "shouldFailTheBuild", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(p, data, mappings, fail_required=True)
|
|
|
|
|
|
def create_publishers(registry, action):
|
|
dummy_parent = XML.Element("dummy")
|
|
registry.dispatch("publisher", dummy_parent, action)
|
|
return list(dummy_parent)
|
|
|
|
|
|
def conditional_publisher(registry, xml_parent, data):
|
|
"""yaml: conditional-publisher
|
|
Conditionally execute some post-build steps. Requires the Jenkins
|
|
:jenkins-plugins:`Flexible Publish Plugin <flexible-publish>`.
|
|
|
|
A Flexible Publish list of Conditional Actions is created in Jenkins.
|
|
|
|
:arg str condition-kind: Condition kind that must be verified before the
|
|
action is executed. Valid values and their additional attributes are
|
|
described in the conditions_ table.
|
|
:arg bool condition-aggregation: If true Matrix Aggregation will be
|
|
enabled. (default false)
|
|
:arg str condition-aggregation-kind: Condition Aggregation kind that
|
|
must be verified before the
|
|
action is executed. Valid values and their additional attributes are
|
|
described in the conditions_ table.
|
|
:arg str on-evaluation-failure: What should be the outcome of the build
|
|
if the evaluation of the condition fails. Possible values are `fail`,
|
|
`mark-unstable`, `run-and-mark-unstable`, `run` and `dont-run`.
|
|
Default is `fail`.
|
|
:arg list action: Action to run if the condition is verified. Item
|
|
can be any publisher known by Jenkins Job Builder and supported
|
|
by the Flexible Publish Plugin.
|
|
|
|
.. _conditions:
|
|
|
|
================== ====================================================
|
|
Condition kind Description
|
|
================== ====================================================
|
|
always Condition is always verified
|
|
never Condition is never verified
|
|
boolean-expression Run the action if the expression expands to a
|
|
representation of true
|
|
|
|
:condition-expression: Expression to expand
|
|
current-status Run the action if the current build status is
|
|
within the configured range
|
|
|
|
:condition-worst: Accepted values are SUCCESS,
|
|
UNSTABLE, FAILURE, NOT_BUILD, ABORTED
|
|
:condition-best: Accepted values are SUCCESS,
|
|
UNSTABLE, FAILURE, NOT_BUILD, ABORTED
|
|
|
|
shell Run the action if the shell command succeeds
|
|
|
|
:condition-command: Shell command to execute
|
|
windows-shell Similar to shell, except that commands will be
|
|
executed by cmd, under Windows
|
|
|
|
:condition-command: Command to execute
|
|
regexp Run the action if a regular expression matches
|
|
|
|
:condition-expression: Regular Expression
|
|
:condition-searchtext: Text to match against
|
|
the regular expression
|
|
file-exists Run the action if a file exists
|
|
|
|
:condition-filename: Check existence of this file
|
|
:condition-basedir: If condition-filename is
|
|
relative, it will be considered relative to
|
|
either `workspace`, `artifact-directory`,
|
|
or `jenkins-home`. Default is `workspace`.
|
|
================== ====================================================
|
|
|
|
Single Conditional Action Example:
|
|
|
|
.. literalinclude:: \
|
|
/../../tests/publishers/fixtures/conditional-publisher001.yaml
|
|
:language: yaml
|
|
|
|
Multiple Conditional Actions Example
|
|
(includes example of multiple actions per condition which requires
|
|
v0.13 or higher of the Flexible Publish plugin):
|
|
|
|
.. literalinclude:: \
|
|
/../../tests/publishers/fixtures/conditional-publisher003.yaml
|
|
:language: yaml
|
|
|
|
:download:`Multiple Conditional Actions Example for pre-v0.13 versions
|
|
<../../tests/publishers/fixtures/conditional-publisher002.yaml>`
|
|
|
|
"""
|
|
|
|
def publish_condition_tag(cdata, prefix, condition_tag):
|
|
kind = cdata["%s-kind" % prefix]
|
|
ctag = XML.SubElement(cond_publisher, condition_tag)
|
|
class_pkg = "org.jenkins_ci.plugins.run_condition"
|
|
|
|
if kind == "always":
|
|
ctag.set("class", class_pkg + ".core.AlwaysRun")
|
|
elif kind == "never":
|
|
ctag.set("class", class_pkg + ".core.NeverRun")
|
|
elif kind == "boolean-expression":
|
|
ctag.set("class", class_pkg + ".core.BooleanCondition")
|
|
XML.SubElement(ctag, "token").text = cdata["%s-expression" % prefix]
|
|
elif kind == "current-status":
|
|
ctag.set("class", class_pkg + ".core.StatusCondition")
|
|
wr = XML.SubElement(ctag, "worstResult")
|
|
wr_name = cdata["%s-worst" % prefix]
|
|
if wr_name not in hudson_model.THRESHOLDS:
|
|
raise JenkinsJobsException(
|
|
"threshold must be one of %s"
|
|
% ", ".join(hudson_model.THRESHOLDS.keys())
|
|
)
|
|
wr_threshold = hudson_model.THRESHOLDS[wr_name]
|
|
XML.SubElement(wr, "name").text = wr_threshold["name"]
|
|
XML.SubElement(wr, "ordinal").text = wr_threshold["ordinal"]
|
|
XML.SubElement(wr, "color").text = wr_threshold["color"]
|
|
XML.SubElement(wr, "completeBuild").text = str(
|
|
wr_threshold["complete"]
|
|
).lower()
|
|
|
|
br = XML.SubElement(ctag, "bestResult")
|
|
br_name = cdata["%s-best" % prefix]
|
|
if br_name not in hudson_model.THRESHOLDS:
|
|
raise JenkinsJobsException(
|
|
"threshold must be one of %s"
|
|
% ", ".join(hudson_model.THRESHOLDS.keys())
|
|
)
|
|
br_threshold = hudson_model.THRESHOLDS[br_name]
|
|
XML.SubElement(br, "name").text = br_threshold["name"]
|
|
XML.SubElement(br, "ordinal").text = br_threshold["ordinal"]
|
|
XML.SubElement(br, "color").text = br_threshold["color"]
|
|
XML.SubElement(br, "completeBuild").text = str(
|
|
wr_threshold["complete"]
|
|
).lower()
|
|
elif kind == "shell":
|
|
ctag.set("class", class_pkg + ".contributed.ShellCondition")
|
|
XML.SubElement(ctag, "command").text = cdata["%s-command" % prefix]
|
|
elif kind == "windows-shell":
|
|
ctag.set("class", class_pkg + ".contributed.BatchFileCondition")
|
|
XML.SubElement(ctag, "command").text = cdata["%s-command" % prefix]
|
|
elif kind == "regexp":
|
|
ctag.set("class", class_pkg + ".core.ExpressionCondition")
|
|
XML.SubElement(ctag, "expression").text = cdata["%s-expression" % prefix]
|
|
XML.SubElement(ctag, "label").text = cdata["%s-searchtext" % prefix]
|
|
elif kind == "file-exists":
|
|
ctag.set("class", class_pkg + ".core.FileExistsCondition")
|
|
XML.SubElement(ctag, "file").text = cdata["%s-filename" % prefix]
|
|
basedir = cdata.get("%s-basedir", "workspace")
|
|
basedir_tag = XML.SubElement(ctag, "baseDir")
|
|
if "workspace" == basedir:
|
|
basedir_tag.set("class", class_pkg + ".common.BaseDirectory$Workspace")
|
|
elif "artifact-directory" == basedir:
|
|
basedir_tag.set(
|
|
"class", class_pkg + ".common." "BaseDirectory$ArtifactsDir"
|
|
)
|
|
elif "jenkins-home" == basedir:
|
|
basedir_tag.set(
|
|
"class", class_pkg + ".common." "BaseDirectory$JenkinsHome"
|
|
)
|
|
else:
|
|
raise JenkinsJobsException(
|
|
"%s is not a valid %s-kind " "value." % (kind, prefix)
|
|
)
|
|
|
|
def publish_condition(cdata):
|
|
return publish_condition_tag(cdata, "condition", condition_tag)
|
|
|
|
def publish_aggregation_condition(cdata):
|
|
return publish_condition_tag(
|
|
cdata, "condition-aggregation", aggregation_condition_tag
|
|
)
|
|
|
|
def publish_action(parent, action):
|
|
for edited_node in create_publishers(registry, action):
|
|
if not use_publisher_list:
|
|
edited_node.set("class", edited_node.tag)
|
|
# sort attributes alphabetically
|
|
attrib = edited_node.attrib
|
|
if len(attrib) > 1:
|
|
attribs = sorted(attrib.items())
|
|
attrib.clear()
|
|
attrib.update(attribs)
|
|
edited_node.tag = "publisher"
|
|
parent.append(edited_node)
|
|
|
|
flex_publisher_tag = (
|
|
"org.jenkins__ci.plugins.flexible__publish." "FlexiblePublisher"
|
|
)
|
|
cond_publisher_tag = (
|
|
"org.jenkins__ci.plugins.flexible__publish." "ConditionalPublisher"
|
|
)
|
|
|
|
root_tag = XML.SubElement(xml_parent, flex_publisher_tag)
|
|
publishers_tag = XML.SubElement(root_tag, "publishers")
|
|
condition_tag = "condition"
|
|
aggregation_condition_tag = "aggregationCondition"
|
|
|
|
evaluation_classes_pkg = "org.jenkins_ci.plugins.run_condition"
|
|
evaluation_classes = {
|
|
"fail": evaluation_classes_pkg + ".BuildStepRunner$Fail",
|
|
"mark-unstable": evaluation_classes_pkg + ".BuildStepRunner$Unstable",
|
|
"run-and-mark-unstable": evaluation_classes_pkg
|
|
+ ".BuildStepRunner$RunUnstable",
|
|
"run": evaluation_classes_pkg + ".BuildStepRunner$Run",
|
|
"dont-run": evaluation_classes_pkg + ".BuildStepRunner$DontRun",
|
|
}
|
|
|
|
plugin_info = registry.get_plugin_info("Flexible Publish Plugin")
|
|
# Note: Assume latest version of plugin is preferred config format
|
|
version = pkg_resources.parse_version(plugin_info.get("version", str(sys.maxsize)))
|
|
|
|
# Support for MatrixAggregator was added in v0.11
|
|
# See JENKINS-14494
|
|
has_matrix_aggregator = version >= pkg_resources.parse_version("0.11")
|
|
|
|
for cond_action in data:
|
|
cond_publisher = XML.SubElement(publishers_tag, cond_publisher_tag)
|
|
publish_condition(cond_action)
|
|
condition_aggregation = cond_action.get("condition-aggregation", False)
|
|
if condition_aggregation and has_matrix_aggregator:
|
|
publish_aggregation_condition(cond_action)
|
|
elif condition_aggregation:
|
|
raise JenkinsJobsException(
|
|
"Matrix Aggregation is not supported " "in your plugin version."
|
|
)
|
|
evaluation_flag = cond_action.get("on-evaluation-failure", "fail")
|
|
if evaluation_flag not in evaluation_classes.keys():
|
|
raise JenkinsJobsException(
|
|
"on-evaluation-failure value "
|
|
"specified is not valid. Must be one "
|
|
"of: %s" % evaluation_classes.keys()
|
|
)
|
|
|
|
evaluation_class = evaluation_classes[evaluation_flag]
|
|
XML.SubElement(cond_publisher, "runner").set("class", evaluation_class)
|
|
|
|
if "action" in cond_action:
|
|
actions = cond_action["action"]
|
|
|
|
action_parent = cond_publisher
|
|
|
|
# XML tag changed from publisher to publisherList in v0.13
|
|
# check the plugin version to determine further operations
|
|
use_publisher_list = version >= pkg_resources.parse_version("0.13")
|
|
|
|
if use_publisher_list:
|
|
action_parent = XML.SubElement(cond_publisher, "publisherList")
|
|
else:
|
|
# Check the length of actions list for versions prior to 0.13.
|
|
# Flexible Publish will overwrite action if more than one is
|
|
# specified. Limit the action list to one element.
|
|
if len(actions) != 1:
|
|
raise JenkinsJobsException(
|
|
"Only one action may be " "specified for each condition."
|
|
)
|
|
for action in actions:
|
|
publish_action(action_parent, action)
|
|
else:
|
|
raise JenkinsJobsException("action must be set for each condition")
|
|
|
|
|
|
def scoverage(registry, xml_parent, data):
|
|
"""yaml: scoverage
|
|
Publish scoverage results as a trend graph.
|
|
Requires the Jenkins :jenkins-plugins:`Scoverage Plugin <scoverage>`.
|
|
|
|
:arg str report-directory: This is a directory that specifies the locations
|
|
where the xml scoverage report is generated (required)
|
|
:arg str report-file: This is a file name that is given to the xml
|
|
scoverage report (required)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/scoverage001.yaml
|
|
:language: yaml
|
|
"""
|
|
scoverage = XML.SubElement(
|
|
xml_parent, "org.jenkinsci.plugins.scoverage.ScoveragePublisher"
|
|
)
|
|
scoverage.set("plugin", "scoverage")
|
|
|
|
mappings = [
|
|
("report-directory", "reportDir", None),
|
|
("report-file", "reportFile", None),
|
|
]
|
|
helpers.convert_mapping_to_xml(scoverage, data, mappings, fail_required=True)
|
|
|
|
|
|
def display_upstream_changes(registry, xml_parent, data):
|
|
"""yaml: display-upstream-changes
|
|
Display SCM changes of upstream jobs. Requires the Jenkins
|
|
:jenkins-plugins:`Display Upstream Changes Plugin
|
|
<display-upstream-changes>`.
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: \
|
|
/../../tests/publishers/fixtures/display-upstream-changes.yaml
|
|
"""
|
|
XML.SubElement(
|
|
xml_parent,
|
|
"jenkins.plugins.displayupstreamchanges." "DisplayUpstreamChangesRecorder",
|
|
)
|
|
|
|
|
|
def gatling(registry, xml_parent, data):
|
|
"""yaml: gatling
|
|
Publish gatling results as a trend graph
|
|
Requires the Jenkins :jenkins-plugins:`Gatling Plugin <gatling>`.
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/gatling001.yaml
|
|
:language: yaml
|
|
"""
|
|
gatling = XML.SubElement(xml_parent, "io.gatling.jenkins.GatlingPublisher")
|
|
mapping = [("", "enabled", "true")]
|
|
helpers.convert_mapping_to_xml(gatling, data, mapping, fail_required=True)
|
|
|
|
|
|
def logstash(registry, xml_parent, data):
|
|
"""yaml: logstash
|
|
Send job's console log to Logstash for processing and analyis of
|
|
your job data. Also stores test metrics from Junit.
|
|
Requires the Jenkins :jenkins-plugins:`Logstash Plugin <logstash>`.
|
|
|
|
:arg int max-lines: The maximum number of log lines to send to Logstash.
|
|
(default 1000)
|
|
:arg bool fail-build: Mark build as failed if this step fails.
|
|
(default false)
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/logstash-min.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/logstash-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
logstash = XML.SubElement(xml_parent, "jenkins.plugins.logstash.LogstashNotifier")
|
|
logstash.set("plugin", "logstash")
|
|
|
|
mapping = [("max-lines", "maxLines", 1000), ("fail-build", "failBuild", False)]
|
|
helpers.convert_mapping_to_xml(logstash, data, mapping, fail_required=True)
|
|
|
|
|
|
def image_gallery(registry, xml_parent, data):
|
|
"""yaml: image-gallery
|
|
Produce an image gallery using Javascript library. Requires the Jenkins
|
|
:jenkins-plugins:`Image Gallery Plugin <image-gallery>`.
|
|
|
|
:arg str gallery-type:
|
|
|
|
:gallery-type values:
|
|
* **archived-images-gallery** (default)
|
|
* **in-folder-comparative-gallery**
|
|
* **multiple-folder-comparative-gallery**
|
|
:arg str title: gallery title (optional)
|
|
:arg int image-width: width of the image (optional)
|
|
:arg bool unstable-if-no-artifacts: mark build as unstable
|
|
if no archived artifacts were found (default false)
|
|
:arg str includes: include pattern (valid for archived-images-gallery
|
|
gallery)
|
|
:arg str base-root-folder: base root dir (valid for comparative gallery)
|
|
:arg int image-inner-width: width of the image displayed in the inner
|
|
gallery popup (valid for comparative gallery, optional)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/image-gallery001.yaml
|
|
|
|
"""
|
|
|
|
def include_comparative_elements(gallery_parent_elem, gallery):
|
|
XML.SubElement(gallery_parent_elem, "baseRootFolder").text = str(
|
|
gallery.get("base-root-folder", "")
|
|
)
|
|
image_inner_width = gallery.get("image-inner-width", "")
|
|
if image_inner_width:
|
|
XML.SubElement(gallery_parent_elem, "imageInnerWidth").text = str(
|
|
image_inner_width
|
|
)
|
|
|
|
package_prefix = "org.jenkinsci.plugins.imagegallery."
|
|
builder = XML.SubElement(xml_parent, package_prefix + "ImageGalleryRecorder")
|
|
image_galleries = XML.SubElement(builder, "imageGalleries")
|
|
galleries = {
|
|
"archived-images-gallery": package_prefix + "imagegallery."
|
|
"ArchivedImagesGallery",
|
|
"in-folder-comparative-gallery": package_prefix + "comparative."
|
|
"InFolderComparativeArchivedImagesGallery",
|
|
"multiple-folder-comparative-gallery": package_prefix + "comparative."
|
|
"MultipleFolderComparativeArchivedImagesGallery",
|
|
}
|
|
for gallery_def in data:
|
|
gallery_type = gallery_def.get("gallery-type", "archived-images-gallery")
|
|
if gallery_type not in galleries:
|
|
raise InvalidAttributeError("gallery-type", gallery_type, galleries.keys())
|
|
gallery_config = XML.SubElement(image_galleries, galleries[gallery_type])
|
|
XML.SubElement(gallery_config, "title").text = str(gallery_def.get("title", ""))
|
|
image_width = str(gallery_def.get("image-width", ""))
|
|
if image_width:
|
|
XML.SubElement(gallery_config, "imageWidth").text = str(image_width)
|
|
XML.SubElement(
|
|
gallery_config, "markBuildAsUnstableIfNoArchivesFound"
|
|
).text = str(gallery_def.get("unstable-if-no-artifacts", False))
|
|
if gallery_type == "archived-images-gallery":
|
|
XML.SubElement(gallery_config, "includes").text = str(
|
|
gallery_def.get("includes", "")
|
|
)
|
|
if gallery_type == "in-folder-comparative-gallery":
|
|
include_comparative_elements(gallery_config, gallery_def)
|
|
if gallery_type == "multiple-folder-comparative-gallery":
|
|
include_comparative_elements(gallery_config, gallery_def)
|
|
|
|
|
|
def naginator(registry, xml_parent, data):
|
|
"""yaml: naginator
|
|
Automatically reschedule a build after a build failure
|
|
Requires the Jenkins :jenkins-plugins:`Naginator Plugin <naginator>`.
|
|
|
|
:arg bool rerun-unstable-builds: Rerun build for unstable builds as well
|
|
as failures (default false)
|
|
:arg bool rerun-matrix-part: Rerun build only for failed parts on the
|
|
matrix (>=1.12) (default false)
|
|
:arg int fixed-delay: Fixed delay in seconds before retrying build (cannot
|
|
be used with progressive-delay-increment or progressive-delay-maximum.
|
|
This is the default delay type. (default 0)
|
|
:arg int progressive-delay-increment: Progressive delay in seconds before
|
|
retrying build increment (cannot be used when fixed-delay is being
|
|
used) (default 0)
|
|
:arg int progressive-delay-maximum: Progressive delay in seconds before
|
|
retrying maximum delay (cannot be used when fixed-delay is being used)
|
|
(default 0)
|
|
:arg int max-failed-builds: Maximum number of successive failed builds
|
|
(default 0)
|
|
:arg str regular-expression: Only rerun build if regular expression is
|
|
found in output (default '')
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/naginator001.yaml
|
|
:language: yaml
|
|
"""
|
|
naginator = XML.SubElement(
|
|
xml_parent, "com.chikli.hudson.plugin.naginator.NaginatorPublisher"
|
|
)
|
|
XML.SubElement(naginator, "regexpForRerun").text = str(
|
|
data.get("regular-expression", "")
|
|
)
|
|
XML.SubElement(naginator, "checkRegexp").text = str(
|
|
"regular-expression" in data
|
|
).lower()
|
|
XML.SubElement(naginator, "rerunIfUnstable").text = str(
|
|
data.get("rerun-unstable-builds", False)
|
|
).lower()
|
|
XML.SubElement(naginator, "rerunMatrixPart").text = str(
|
|
data.get("rerun-matrix-part", False)
|
|
).lower()
|
|
progressive_delay = (
|
|
"progressive-delay-increment" in data or "progressive-delay-maximum" in data
|
|
)
|
|
if "fixed-delay" in data and progressive_delay:
|
|
raise JenkinsJobsException(
|
|
"You cannot specify both fixed " "and progressive delays"
|
|
)
|
|
if not progressive_delay:
|
|
delay = XML.SubElement(
|
|
naginator,
|
|
"delay",
|
|
{"class": "com.chikli.hudson.plugin.naginator.FixedDelay"},
|
|
)
|
|
XML.SubElement(delay, "delay").text = str(data.get("fixed-delay", "0"))
|
|
else:
|
|
delay = XML.SubElement(
|
|
naginator,
|
|
"delay",
|
|
{"class": "com.chikli.hudson.plugin.naginator.ProgressiveDelay"},
|
|
)
|
|
XML.SubElement(delay, "increment").text = str(
|
|
data.get("progressive-delay-increment", "0")
|
|
)
|
|
XML.SubElement(delay, "max").text = str(
|
|
data.get("progressive-delay-maximum", "0")
|
|
)
|
|
XML.SubElement(naginator, "maxSchedule").text = str(
|
|
data.get("max-failed-builds", "0")
|
|
)
|
|
|
|
|
|
def disable_failed_job(registry, xml_parent, data):
|
|
"""yaml: disable-failed-job
|
|
Automatically disable failed jobs.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Disable Failed Job Plugin
|
|
<disable-failed-job>`.
|
|
|
|
:arg str when-to-disable: The condition to disable the job. (required)
|
|
Possible values are
|
|
|
|
* **Only Failure**
|
|
* **Failure and Unstable**
|
|
* **Unstable**
|
|
|
|
:arg int no-of-failures: Number of consecutive failures to disable the
|
|
job. (optional)
|
|
|
|
Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/disable-failed-job001.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
xml_element = XML.SubElement(
|
|
xml_parent,
|
|
"disableFailedJob." "disableFailedJob.DisableFailedJob",
|
|
{"plugin": "disable-failed-job"},
|
|
)
|
|
|
|
valid_conditions = ["Only Failure", "Failure and Unstable", "Only Unstable"]
|
|
mapping = [("when-to-disable", "whenDisable", None, valid_conditions)]
|
|
helpers.convert_mapping_to_xml(xml_element, data, mapping, fail_required=True)
|
|
|
|
if "no-of-failures" in data:
|
|
mapping = [
|
|
("no-of-failures", "failureTimes", None),
|
|
("", "optionalBrockChecked", True),
|
|
]
|
|
helpers.convert_mapping_to_xml(xml_element, data, mapping, fail_required=True)
|
|
else:
|
|
XML.SubElement(xml_element, "optionalBrockChecked").text = "false"
|
|
|
|
|
|
def google_cloud_storage(registry, xml_parent, data):
|
|
"""yaml: google-cloud-storage
|
|
Upload build artifacts to Google Cloud Storage. Requires the
|
|
Jenkins :jenkins-plugins:`Google Cloud Storage plugin
|
|
<google-storage-plugin>`.
|
|
|
|
Apart from the Google Cloud Storage Plugin itself, installation of Google
|
|
OAuth Credentials and addition of required credentials to Jenkins is
|
|
required.
|
|
|
|
:arg str credentials-id: The set of Google credentials registered with
|
|
the Jenkins Credential Manager for authenticating
|
|
with your project. (required)
|
|
:arg list uploads:
|
|
:uploads:
|
|
* **expiring-elements** (`dict`)
|
|
:params:
|
|
* **bucket-name** (`str`) bucket name to upload artifacts
|
|
(required)
|
|
* **days-to-retain** (`int`) days to keep artifacts
|
|
(required)
|
|
* **build-log** (`dict`)
|
|
:params:
|
|
* **log-name** (`str`) name of the file that the Jenkins
|
|
console log to be named (required)
|
|
* **storage-location** (`str`) bucket name to upload
|
|
artifacts (required)
|
|
* **share-publicly** (`bool`) whether to share uploaded
|
|
share uploaded artifacts with everyone (default false)
|
|
* **upload-for-failed-jobs** (`bool`) whether to upload
|
|
artifacts even if the build fails (default false)
|
|
* **show-inline** (`bool`) whether to show uploaded build
|
|
log inline in web browsers, rather than forcing it to be
|
|
downloaded (default true)
|
|
* **strip-prefix** (`str`) strip this prefix off the
|
|
file names (default not set)
|
|
|
|
* **classic** (`dict`)
|
|
:params:
|
|
* **file-pattern** (`str`) ant style globs to match the
|
|
files to upload (required)
|
|
* **storage-location** (`str`) bucket name to upload
|
|
artifacts (required)
|
|
* **share-publicly** (`bool`) whether to share uploaded
|
|
share uploaded artifacts with everyone (default false)
|
|
* **upload-for-failed-jobs** (`bool`) whether to upload
|
|
artifacts even if the build fails (default false)
|
|
* **show-inline** (`bool`) whether to show uploaded
|
|
artifacts inline in web browsers, rather than forcing
|
|
them to be downloaded (default false)
|
|
* **strip-prefix** (`str`) strip this prefix off the
|
|
file names (default not set)
|
|
|
|
Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/google_cloud_storage001.yaml
|
|
:language: yaml
|
|
|
|
Full example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/google_cloud_storage002.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
def expiring_elements(properties, upload_element, types):
|
|
# Handle expiring elements upload action
|
|
|
|
xml_element = XML.SubElement(
|
|
upload_element,
|
|
"com.google." "jenkins.plugins.storage." "ExpiringBucketLifecycleManager",
|
|
)
|
|
mapping = [
|
|
("bucket-name", "bucketNameWithVars", None),
|
|
("", "sharedPublicly", False),
|
|
("", "forFailedJobs", False),
|
|
("days-to-retain", "bucketObjectTTL", None),
|
|
]
|
|
helpers.convert_mapping_to_xml(
|
|
xml_element, properties, mapping, fail_required=True
|
|
)
|
|
|
|
if types.count("expiring-elements") > 1:
|
|
XML.SubElement(
|
|
xml_element,
|
|
"module",
|
|
{
|
|
"reference": "../../com.google.jenkins.plugins."
|
|
"storage.ExpiringBucketLifecycleManager/module"
|
|
},
|
|
)
|
|
else:
|
|
XML.SubElement(xml_element, "module")
|
|
|
|
def build_log(properties, upload_element, types):
|
|
# Handle build log upload action
|
|
|
|
xml_element = XML.SubElement(
|
|
upload_element, "com.google.jenkins." "plugins.storage.StdoutUpload"
|
|
)
|
|
mapping = [
|
|
("storage-location", "bucketNameWithVars", None),
|
|
("share-publicly", "sharedPublicly", False),
|
|
("upload-for-failed-jobs", "forFailedJobs", False),
|
|
("show-inline", "showInline", True),
|
|
("strip-prefix", "pathPrefix", ""),
|
|
("log-name", "logName", None),
|
|
]
|
|
helpers.convert_mapping_to_xml(
|
|
xml_element, properties, mapping, fail_required=True
|
|
)
|
|
|
|
if types.count("build-log") > 1:
|
|
XML.SubElement(
|
|
xml_element,
|
|
"module",
|
|
{
|
|
"reference": "../../com.google.jenkins.plugins."
|
|
"storage.StdoutUpload/module"
|
|
},
|
|
)
|
|
else:
|
|
XML.SubElement(xml_element, "module")
|
|
|
|
def classic(properties, upload_element, types):
|
|
# Handle classic upload action
|
|
|
|
xml_element = XML.SubElement(
|
|
upload_element, "com.google.jenkins." "plugins.storage.ClassicUpload"
|
|
)
|
|
mapping = [
|
|
("storage-location", "bucketNameWithVars", None),
|
|
("share-publicly", "sharedPublicly", False),
|
|
("upload-for-failed-jobs", "forFailedJobs", False),
|
|
("show-inline", "showInline", False),
|
|
("strip-prefix", "pathPrefix", ""),
|
|
("file-pattern", "sourceGlobWithVars", None),
|
|
]
|
|
helpers.convert_mapping_to_xml(
|
|
xml_element, properties, mapping, fail_required=True
|
|
)
|
|
|
|
if types.count("classic") > 1:
|
|
XML.SubElement(
|
|
xml_element,
|
|
"module",
|
|
{
|
|
"reference": "../../com.google.jenkins.plugins."
|
|
"storage.ClassicUpload/module"
|
|
},
|
|
)
|
|
else:
|
|
XML.SubElement(xml_element, "module")
|
|
|
|
uploader = XML.SubElement(
|
|
xml_parent,
|
|
"com.google.jenkins.plugins.storage." "GoogleCloudStorageUploader",
|
|
{"plugin": "google-storage-plugin"},
|
|
)
|
|
|
|
mapping = [("credentials-id", "credentialsId", None)]
|
|
helpers.convert_mapping_to_xml(uploader, data, mapping, fail_required=True)
|
|
|
|
valid_upload_types = ["expiring-elements", "build-log", "classic"]
|
|
types = []
|
|
|
|
upload_element = XML.SubElement(uploader, "uploads")
|
|
|
|
uploads = data["uploads"]
|
|
for upload in uploads:
|
|
for upload_type, properties in upload.items():
|
|
types.append(upload_type)
|
|
|
|
if upload_type not in valid_upload_types:
|
|
raise InvalidAttributeError("uploads", upload_type, valid_upload_types)
|
|
else:
|
|
locals()[upload_type.replace("-", "_")](
|
|
properties, upload_element, types
|
|
)
|
|
|
|
|
|
def flowdock(registry, xml_parent, data):
|
|
"""yaml: flowdock
|
|
This plugin publishes job build results to a Flowdock flow.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Flowdock Plugin
|
|
<jenkins-flowdock-plugin>`.
|
|
|
|
:arg str token: API token for the targeted flow.
|
|
(required)
|
|
:arg str tags: Comma-separated list of tags to include in message
|
|
(default "")
|
|
:arg bool chat-notification: Send chat notification when build fails
|
|
(default true)
|
|
:arg bool notify-success: Send notification on build success
|
|
(default true)
|
|
:arg bool notify-failure: Send notification on build failure
|
|
(default true)
|
|
:arg bool notify-fixed: Send notification when build is fixed
|
|
(default true)
|
|
:arg bool notify-unstable: Send notification when build is unstable
|
|
(default false)
|
|
:arg bool notify-aborted: Send notification when build was aborted
|
|
(default false)
|
|
:arg bool notify-notbuilt: Send notification when build did not occur
|
|
(default false)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/flowdock001.yaml
|
|
:language: yaml
|
|
|
|
Full example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/flowdock002.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
def gen_notification_entry(data_item, default, text):
|
|
e = XML.SubElement(nm, "entry")
|
|
mapping = [
|
|
("", "com.flowdock.jenkins.BuildResult", text),
|
|
(data_item, "boolean", default),
|
|
]
|
|
helpers.convert_mapping_to_xml(e, data, mapping, fail_required=True)
|
|
|
|
parent = XML.SubElement(xml_parent, "com.flowdock.jenkins.FlowdockNotifier")
|
|
mapping = [
|
|
("token", "flowToken", None),
|
|
("tags", "notificationTags", ""),
|
|
("chat-notification", "chatNotification", True),
|
|
("notify-success", "notifySuccess", True),
|
|
("notify-failure", "notifyFailure", True),
|
|
("notify-fixed", "notifyFixed", True),
|
|
("notify-unstable", "notifyUnstable", False),
|
|
("notify-aborted", "notifyAborted", False),
|
|
("notify-notbuilt", "notifyNotBuilt", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(parent, data, mapping, fail_required=True)
|
|
|
|
nm = XML.SubElement(parent, "notifyMap")
|
|
|
|
# notification entries
|
|
gen_notification_entry("notify-success", True, "SUCCESS")
|
|
gen_notification_entry("notify-failure", True, "FAILURE")
|
|
gen_notification_entry("notify-fixed", True, "FIXED")
|
|
gen_notification_entry("notify-unstable", False, "UNSTABLE")
|
|
gen_notification_entry("notify-aborted", False, "ABORTED")
|
|
gen_notification_entry("notify-notbuilt", False, "NOT_BUILT")
|
|
|
|
|
|
def clamav(registry, xml_parent, data):
|
|
"""yaml: clamav
|
|
Check files with ClamAV, an open source antivirus engine.
|
|
Requires the Jenkins :jenkins-plugins:`ClamAV Plugin <clamav>`.
|
|
|
|
:arg str includes: Comma separated list of files that should be scanned.
|
|
Must be set for ClamAV to check for artifacts. (default '')
|
|
:arg str excludes: Comma separated list of files that should be ignored
|
|
(default '')
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/clamav-full.yaml
|
|
:language: yaml
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/clamav-minimal.yaml
|
|
:language: yaml
|
|
"""
|
|
clamav = XML.SubElement(xml_parent, "org.jenkinsci.plugins.clamav.ClamAvRecorder")
|
|
clamav.set("plugin", "clamav")
|
|
|
|
mappings = [("includes", "includes", ""), ("excludes", "excludes", "")]
|
|
helpers.convert_mapping_to_xml(clamav, data, mappings, fail_required=True)
|
|
|
|
|
|
def testselector(registry, xml_parent, data):
|
|
"""yaml: testselector
|
|
This plugin allows you to choose specific tests you want to run.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Tests Selector Plugin
|
|
<selected-tests-executor>`.
|
|
|
|
:arg str name: Environment variable in which selected tests are saved
|
|
(required)
|
|
:arg str description: Description
|
|
(default "")
|
|
:arg str properties-file: Contain all your tests
|
|
(required)
|
|
:arg str enable-field: Imply if the test is enabled or not
|
|
(default "")
|
|
:arg str groupby: Plugin will group the tests by
|
|
(default "")
|
|
:arg str field-sperator: Separate between the fields in the tests tree
|
|
(default "")
|
|
:arg str show-fields: Shown in the tests tree
|
|
(default "")
|
|
:arg str multiplicity-field: Number of times the test should run
|
|
(default "")
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/testselector001.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
testselector = XML.SubElement(
|
|
xml_parent, "il.ac.technion.jenkins.plugins" "TestExecuter"
|
|
)
|
|
|
|
mapping = [
|
|
("name", "name", None),
|
|
("description", "description", ""),
|
|
("properties-file", "propertiesFilePath", None),
|
|
("enable-field", "enableField", ""),
|
|
("groupby", "groupBy", ""),
|
|
("field-separator", "fieldSeparator", ""),
|
|
("show-fields", "showFields", ""),
|
|
("multiplicity-field", "multiplicityField", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(testselector, data, mapping, fail_required=True)
|
|
|
|
|
|
def cloudformation(registry, xml_parent, data):
|
|
"""yaml: cloudformation
|
|
Create cloudformation stacks before running a build and optionally
|
|
delete them at the end. Requires the Jenkins :jenkins-plugins:`AWS
|
|
Cloudformation Plugin <jenkins-cloudformation-plugin>`.
|
|
|
|
:arg list create-stacks: List of stacks to create
|
|
|
|
:create-stacks attributes:
|
|
* **arg str name** - The name of the stack (Required)
|
|
* **arg str description** - Description of the stack (Optional)
|
|
* **arg str recipe** - The cloudformation recipe file (Required)
|
|
* **arg list parameters** - A list of key/value pairs, will be
|
|
joined together into a comma separated string (Optional)
|
|
* **arg int timeout** - Number of seconds to wait before giving up
|
|
creating a stack (default 0)
|
|
* **arg str access-key** - The Amazon API Access Key (Required)
|
|
* **arg str secret-key** - The Amazon API Secret Key (Required)
|
|
* **arg int sleep** - Number of seconds to wait before continuing
|
|
to the next step (default 0)
|
|
* **arg array region** - The region to run cloudformation in.
|
|
(Required)
|
|
|
|
:region values:
|
|
* **us-east-1**
|
|
* **us-west-1**
|
|
* **us-west-2**
|
|
* **eu-central-1**
|
|
* **eu-west-1**
|
|
* **ap-southeast-1**
|
|
* **ap-southeast-2**
|
|
* **ap-northeast-1**
|
|
* **sa-east-1**
|
|
:arg list delete-stacks: List of stacks to delete
|
|
|
|
:delete-stacks attributes:
|
|
* **arg list name** - The names of the stacks to delete (Required)
|
|
* **arg str access-key** - The Amazon API Access Key (Required)
|
|
* **arg str secret-key** - The Amazon API Secret Key (Required)
|
|
* **arg bool prefix** - If selected the tear down process will look
|
|
for the stack that Starts with the stack name with the oldest
|
|
creation date and will delete it. (default false)
|
|
* **arg array region** - The region to run cloudformation in.
|
|
(Required)
|
|
|
|
:region values:
|
|
* **us-east-1**
|
|
* **us-west-1**
|
|
* **us-west-2**
|
|
* **eu-central-1**
|
|
* **eu-west-1**
|
|
* **ap-southeast-1**
|
|
* **ap-southeast-2**
|
|
* **ap-northeast-1**
|
|
* **sa-east-1**
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/cloudformation.yaml
|
|
:language: yaml
|
|
"""
|
|
region_dict = helpers.cloudformation_region_dict()
|
|
stacks = helpers.cloudformation_init(
|
|
xml_parent, data, "CloudFormationPostBuildNotifier"
|
|
)
|
|
for stack in data.get("create-stacks", []):
|
|
helpers.cloudformation_stack(
|
|
xml_parent, stack, "PostBuildStackBean", stacks, region_dict
|
|
)
|
|
delete_stacks = helpers.cloudformation_init(
|
|
xml_parent, data, "CloudFormationNotifier"
|
|
)
|
|
for delete_stack in data.get("delete-stacks", []):
|
|
helpers.cloudformation_stack(
|
|
xml_parent, delete_stack, "SimpleStackBean", delete_stacks, region_dict
|
|
)
|
|
|
|
|
|
def whitesource(registry, xml_parent, data):
|
|
"""yaml: whitesource
|
|
This plugin brings automatic open source management to Jenkins users.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Whitesource Plugin
|
|
<whitesource>`.
|
|
|
|
:arg str product-token: Product name or token to update (default '')
|
|
:arg str version: Product version (default '')
|
|
:arg str override-token: Override the api token from the global config
|
|
(default '')
|
|
:arg str project-token: Token uniquely identifying the project to update
|
|
(default '')
|
|
:arg list includes: list of libraries to include (default '[]')
|
|
:arg list excludes: list of libraries to exclude (default '[]')
|
|
:arg str policies: Whether to override the global settings. Valid values:
|
|
global, enable, disable (default 'global')
|
|
:arg str requester-email: Email of the WhiteSource user that requests to
|
|
update WhiteSource (>=1.5.1) (default '')
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/whitesource-full.yaml
|
|
:language: yaml
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/whitesource-minimal.yaml
|
|
:language: yaml
|
|
"""
|
|
whitesource = XML.SubElement(
|
|
xml_parent, "org.whitesource.jenkins." "WhiteSourcePublisher"
|
|
)
|
|
whitesource.set("plugin", "whitesource")
|
|
policies = ["global", "enable", "disable"]
|
|
|
|
mappings = [
|
|
("policies", "jobCheckPolicies", "global", policies),
|
|
("override-token", "jobApiToken", ""),
|
|
("product-token", "product", ""),
|
|
("version", "productVersion", ""),
|
|
("project-token", "projectToken", ""),
|
|
("requester-email", "requesterEmail", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(whitesource, data, mappings, fail_required=True)
|
|
|
|
XML.SubElement(whitesource, "libIncludes").text = " ".join(data.get("includes", []))
|
|
XML.SubElement(whitesource, "libExcludes").text = " ".join(data.get("excludes", []))
|
|
XML.SubElement(whitesource, "ignorePomModules").text = "false"
|
|
|
|
|
|
def hipchat(registry, xml_parent, data):
|
|
"""yaml: hipchat
|
|
Publisher that sends hipchat notifications on job events
|
|
Requires the Jenkins :jenkins-plugins:`Hipchat Plugin
|
|
<hipchat>` version >=1.9
|
|
|
|
Please see documentation for older plugin version
|
|
https://jenkins-job-builder.readthedocs.io/en/latest/hipchat.html
|
|
|
|
:arg str token: This will override the default auth token (optional)
|
|
:arg list rooms: list of HipChat rooms to post messages to, overrides
|
|
global default (optional)
|
|
:arg bool notify-start: post messages about build start event
|
|
(default false)
|
|
:arg bool notify-success: post messages about successful build event
|
|
(default false)
|
|
:arg bool notify-aborted: post messages about aborted build event
|
|
(default false)
|
|
:arg bool notify-not-built: post messages about build set to NOT_BUILT.
|
|
This status code is used in a multi-stage build where a problem in
|
|
earlier stage prevented later stages from building. (default false)
|
|
:arg bool notify-unstable: post messages about unstable build event
|
|
(default false)
|
|
:arg bool notify-failure: post messages about build failure event
|
|
(default false)
|
|
:arg bool notify-back-to-normal: post messages about build being back to
|
|
normal after being unstable or failed (default false)
|
|
:arg str start-message: This will override the default start message
|
|
(optional)
|
|
:arg str complete-message: This will override the default complete message
|
|
(optional)
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/hipchat001.yaml
|
|
:language: yaml
|
|
"""
|
|
hipchat = XML.SubElement(xml_parent, "jenkins.plugins.hipchat.HipChatNotifier")
|
|
XML.SubElement(hipchat, "token").text = str(data.get("token", ""))
|
|
|
|
if "rooms" in data:
|
|
XML.SubElement(hipchat, "room").text = str(",".join(data["rooms"]))
|
|
|
|
mapping = [
|
|
("notify-start", "startNotification", False),
|
|
("notify-success", "notifySuccess", False),
|
|
("notify-aborted", "notifyAborted", False),
|
|
("notify-not-built", "notifyNotBuilt", False),
|
|
("notify-unstable", "notifyUnstable", False),
|
|
("notify-failure", "notifyFailure", False),
|
|
("notify-back-to-normal", "notifyBackToNormal", False),
|
|
("start-message", "startJobMessage", None),
|
|
("complete-message", "completeJobMessage", None),
|
|
]
|
|
helpers.convert_mapping_to_xml(hipchat, data, mapping, fail_required=False)
|
|
|
|
|
|
def slack(registry, xml_parent, data):
|
|
"""yaml: slack
|
|
Publisher that sends slack notifications on job events.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Slack Plugin <slack>`
|
|
|
|
When using Slack Plugin version < 2.0, Slack Plugin itself requires a
|
|
publisher as well as properties please note that you have to create those
|
|
too. When using Slack Plugin version >= 2.0, you should only configure the
|
|
publisher.
|
|
|
|
For backward compatibility, the publisher needs to query version of the
|
|
Slack Plugin. Hence the ``query_plugins_info`` parameter shouldn't be set
|
|
to ``False`` in the ``jenkins`` section of the configuration file.
|
|
|
|
:arg str team-domain: Your team's domain at slack. (default '')
|
|
:arg str auth-token: The integration token to be used when sending
|
|
notifications. (default '')
|
|
:arg str auth-token-id: Allows credentials to be stored in Jenkins.
|
|
(default '')
|
|
:arg str build-server-url: Specify the URL for your server installation.
|
|
(default '/')
|
|
:arg str room: A comma separated list of rooms / channels to post the
|
|
notifications to. (default '')
|
|
:arg bool notify-start: Send notification when the job starts (>=2.0).
|
|
(default false)
|
|
:arg bool notify-success: Send notification on success (>=2.0).
|
|
(default false)
|
|
:arg bool notify-aborted: Send notification when job is aborted (>=2.0).
|
|
(default false)
|
|
:arg bool notify-not-built: Send notification when job set to NOT_BUILT
|
|
status (>=2.0). (default false)
|
|
:arg bool notify-unstable: Send notification when job becomes unstable
|
|
(>=2.0). (default false)
|
|
:arg bool notify-failure: Send notification when job fails for the first
|
|
time (previous build was a success) (>=2.0). (default false)
|
|
:arg bool notify-every-failure: Send notification every time a job fails
|
|
(>=2.23). (default false)
|
|
:arg bool notify-back-to-normal: Send notification when job is succeeding
|
|
again after being unstable or failed (>=2.0). (default false)
|
|
:arg bool notify-repeated-failure: Send notification when job fails
|
|
successively (previous build was also a failure) (>=2.0).
|
|
(default false)
|
|
:arg bool notify-regression: Send notification when number of failed tests
|
|
increased or the failed tests are different than previous build
|
|
(>=2.2). (default false)
|
|
:arg bool include-failed-tests: includes all failed tests when some tests
|
|
failed. does nothing if no failed tests were found (>=2.2).
|
|
(default false)
|
|
:arg bool include-test-summary: Include the test summary (>=2.0).
|
|
(default false)
|
|
:arg str commit-info-choice: What commit information to include into
|
|
notification message, "NONE" includes nothing about commits, "AUTHORS"
|
|
includes commit list with authors only, and "AUTHORS_AND_TITLES"
|
|
includes commit list with authors and titles (>=2.0). (default "NONE")
|
|
:arg bool include-custom-message: Include a custom message into the
|
|
notification (>=2.0). (default false)
|
|
:arg str custom-message: Custom message to be included for all statuses
|
|
(>=2.0). (default '')
|
|
:arg str custom-message-success: Custom message for succesful builds
|
|
(>=2.10). (default '')
|
|
:arg str custom-message-aborted: Custom message for aborted builds
|
|
(>=2.10). (default '')
|
|
:arg str custom-message-not-built: Custom message for not-built
|
|
(>=2.10). (default '')
|
|
:arg str custom-message-unstable: Custom message for unstable builds
|
|
(>=2.10). (default '')
|
|
:arg str custom-message-failure: Custom message for failed builds
|
|
(>=2.10). (default '')
|
|
:arg str auth-token-credential-id: The ID for the integration token from
|
|
the Credentials plugin to be used to send notifications to Slack.
|
|
(>=2.1) (default '')
|
|
:arg bool bot-user: This option indicates the token belongs to a bot user
|
|
in Slack. (>=2.2) (default False)
|
|
:arg str base-url: Your Slack compatible Base URL. ``bot-user`` is not
|
|
supported with Base URL. (>=2.2) (default '')
|
|
|
|
Example (version < 2.0):
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/slack001.yaml
|
|
:language: yaml
|
|
|
|
Minimal example (version >= 2.0):
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/slack003.yaml
|
|
:language: yaml
|
|
|
|
Full example (version >= 2.10):
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/slack005.yaml
|
|
:language: yaml
|
|
|
|
"""
|
|
|
|
def _add_xml(elem, name, value=""):
|
|
if isinstance(value, bool):
|
|
value = str(value).lower()
|
|
XML.SubElement(elem, name).text = value
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
plugin_info = registry.get_plugin_info("Slack Notification Plugin")
|
|
# Note: Assume latest version of plugin is preferred config format
|
|
plugin_ver = pkg_resources.parse_version(
|
|
plugin_info.get("version", str(sys.maxsize))
|
|
)
|
|
|
|
mapping = (
|
|
("team-domain", "teamDomain", ""),
|
|
("auth-token", "authToken", ""),
|
|
("auth-token-id", "authTokenCredentialId", ""),
|
|
("build-server-url", "buildServerUrl", "/"),
|
|
("room", "room", ""),
|
|
)
|
|
mapping_20 = (
|
|
("notify-start", "startNotification", False),
|
|
("notify-success", "notifySuccess", False),
|
|
("notify-aborted", "notifyAborted", False),
|
|
("notify-not-built", "notifyNotBuilt", False),
|
|
("notify-unstable", "notifyUnstable", False),
|
|
("notify-failure", "notifyFailure", False),
|
|
("notify-every-failure", "notifyEveryFailure", False),
|
|
("notify-back-to-normal", "notifyBackToNormal", False),
|
|
("notify-regression", "notifyRegression", False),
|
|
("notify-repeated-failure", "notifyRepeatedFailure", False),
|
|
("include-test-summary", "includeTestSummary", False),
|
|
("include-failed-tests", "includeFailedTests", False),
|
|
("commit-info-choice", "commitInfoChoice", "NONE"),
|
|
("include-custom-message", "includeCustomMessage", False),
|
|
("custom-message", "customMessage", ""),
|
|
("custom-message-success", "customMessageSuccess", ""),
|
|
("custom-message-aborted", "customMessageAborted", ""),
|
|
("custom-message-not-built", "customMessageNotBuilt", ""),
|
|
("custom-message-unstable", "customMessageUnstable", ""),
|
|
("custom-message-failure", "customMessageFailure", ""),
|
|
("auth-token-credential-id", "authTokenCredentialId", ""),
|
|
("bot-user", "botUser", False),
|
|
("base-url", "baseUrl", ""),
|
|
)
|
|
|
|
commit_info_choices = ["NONE", "AUTHORS", "AUTHORS_AND_TITLES"]
|
|
|
|
slack = XML.SubElement(xml_parent, "jenkins.plugins.slack.SlackNotifier")
|
|
|
|
if plugin_ver >= pkg_resources.parse_version("2.0"):
|
|
mapping = mapping + mapping_20
|
|
|
|
if plugin_ver < pkg_resources.parse_version("2.0"):
|
|
for yaml_name, _, default_value in mapping:
|
|
# All arguments that don't have a default value are mandatory for
|
|
# the plugin to work as intended.
|
|
if not data.get(yaml_name, default_value):
|
|
raise MissingAttributeError(yaml_name)
|
|
|
|
for yaml_name, _, _ in mapping_20:
|
|
if yaml_name in data:
|
|
logger.warning(
|
|
"'%s' is invalid with plugin version < 2.0, ignored", yaml_name
|
|
)
|
|
|
|
for yaml_name, xml_name, default_value in mapping:
|
|
value = data.get(yaml_name, default_value)
|
|
|
|
# 'commit-info-choice' is enumerated type
|
|
if yaml_name == "commit-info-choice" and value not in commit_info_choices:
|
|
raise InvalidAttributeError(yaml_name, value, commit_info_choices)
|
|
|
|
# Ensure that custom-message is set when include-custom-message is set
|
|
# to true.
|
|
if (
|
|
yaml_name == "include-custom-message"
|
|
and data is False
|
|
and not data.get("custom-message", "")
|
|
):
|
|
raise MissingAttributeError("custom-message")
|
|
|
|
_add_xml(slack, xml_name, value)
|
|
|
|
|
|
def phabricator(registry, xml_parent, data):
|
|
"""yaml: phabricator
|
|
Integrate with `Phabricator <https://www.phacility.com/>`_
|
|
|
|
Requires the Jenkins :jenkins-plugins:`Phabricator Plugin
|
|
<phabricator-plugin>`.
|
|
|
|
:arg bool comment-on-success: Post a *comment* when the build
|
|
succeeds. (optional)
|
|
:arg bool uberalls-enabled: Integrate with uberalls. (optional)
|
|
:arg str comment-file: Include contents of given file if
|
|
commenting is enabled. (optional)
|
|
:arg int comment-size: Maximum comment character length. (optional)
|
|
:arg bool comment-with-console-link-on-failure: Post a *comment*
|
|
when the build fails. (optional)
|
|
|
|
Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/phabricator001.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
root = XML.SubElement(
|
|
xml_parent, "com.uber.jenkins.phabricator.PhabricatorNotifier"
|
|
)
|
|
mapping = [
|
|
("comment-on-success", "commentOnSuccess", None),
|
|
("uberalls-enabled", "uberallsEnabled", None),
|
|
("comment-file", "commentFile", None),
|
|
("comment-size", "commentSize", None),
|
|
(
|
|
"comment-with-console-link-on-failure",
|
|
"commentWithConsoleLinkOnFailure",
|
|
None,
|
|
),
|
|
]
|
|
helpers.convert_mapping_to_xml(root, data, mapping, fail_required=False)
|
|
|
|
|
|
def jms_messaging(registry, xml_parent, data):
|
|
"""yaml: jms-messaging
|
|
The JMS Messaging Plugin provides the following functionality:
|
|
- A build trigger to submit jenkins jobs upon receipt
|
|
of a matching message.
|
|
- A builder that may be used to submit a message to the topic
|
|
upon the completion of a job
|
|
- A post-build action that may be used to submit a message to the topic
|
|
upon the completion of a job
|
|
|
|
|
|
JMS Messaging provider types supported:
|
|
- ActiveMQ
|
|
- FedMsg
|
|
|
|
Requires the Jenkins :jenkins-plugins:`JMS Messaging Plugin
|
|
Pipeline Plugin <jms-messaging>`.
|
|
|
|
:arg str override-topic: If you need to override the default topic.
|
|
(default '')
|
|
:arg str provider-name: Name of message provider setup in the
|
|
global config. (default '')
|
|
:arg str msg-type: A message type
|
|
(default 'CodeQualityChecksDone')
|
|
:arg str msg-props: Message header to publish. (default '')
|
|
:arg str msg-content: Message body to publish. (default '')
|
|
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
../../tests/publishers/fixtures/jms-messaging-full.yaml
|
|
:language: yaml
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
../../tests/publishers/fixtures/jms-messaging-minimal.yaml
|
|
:language: yaml
|
|
"""
|
|
helpers.jms_messaging_common(
|
|
xml_parent, "com.redhat.jenkins.plugins.ci." "CIMessageNotifier", data
|
|
)
|
|
|
|
|
|
def openshift_build_canceller(registry, xml_parent, data):
|
|
r"""yaml: openshift-build-canceller
|
|
This action is intended to provide cleanup for a Jenkins job which failed
|
|
because a build is hung (instead of terminating with a failure code);
|
|
this step will allow you to perform the equivalent of a oc cancel-build
|
|
for the provided build config; any builds under that build config which
|
|
are not previously terminated (either successfully or unsuccessfully)
|
|
or cancelled will be cancelled.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`OpenShift Pipeline Plugin
|
|
<openshift-pipeline>`.
|
|
|
|
:arg str api-url: this would be the value you specify if you leverage the
|
|
--server option on the OpenShift `oc` command.
|
|
(default '\https://openshift.default.svc.cluster.local')
|
|
:arg str bld-cfg: The value here should be whatever was the output
|
|
form `oc project` when you created the BuildConfig you
|
|
want to run a Build on (default 'frontend')
|
|
:arg str namespace: If you run `oc get bc` for the project listed in
|
|
"namespace", that is the value you want to put here. (default 'test')
|
|
:arg str auth-token: The value here is what you supply with the --token
|
|
option when invoking the OpenShift `oc` command. (default '')
|
|
:arg bool verbose: This flag is the toggle for
|
|
turning on or off detailed logging in this plug-in. (default false)
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
../../tests/publishers/fixtures/openshift-build-canceller001.yaml
|
|
:language: yaml
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
../../tests/publishers/fixtures/openshift-build-canceller002.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
osb = XML.SubElement(
|
|
xml_parent, "com.openshift.jenkins.plugins.pipeline." "OpenShiftBuildCanceller"
|
|
)
|
|
mapping = [
|
|
# option, xml name, default value
|
|
("api-url", "apiURL", "https://openshift.default.svc.cluster.local"),
|
|
("bld-cfg", "bldCfg", "frontend"),
|
|
("namespace", "namespace", "test"),
|
|
("auth-token", "authToken", ""),
|
|
("verbose", "verbose", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(osb, data, mapping, fail_required=True)
|
|
|
|
|
|
def openshift_deploy_canceller(registry, xml_parent, data):
|
|
r"""yaml: openshift-deploy-canceller
|
|
This action is intended to provide cleanup for any OpenShift deployments
|
|
left running when the Job completes; this step will allow you to perform
|
|
the equivalent of a oc deploy --cancel for the provided deployment config.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`OpenShift Pipeline Plugin
|
|
<openshift-pipeline>`.
|
|
|
|
:arg str api-url: this would be the value you specify if you leverage the
|
|
--server option on the OpenShift `oc` command.
|
|
(default '\https://openshift.default.svc.cluster.local')
|
|
:arg str dep-cfg: The value here should be whatever was the output
|
|
form `oc project` when you created the BuildConfig you want to run a
|
|
Build on (default frontend)
|
|
:arg str namespace: If you run `oc get bc` for the project listed in
|
|
"namespace", that is the value you want to put here. (default 'test')
|
|
:arg str auth-token: The value here is what you supply with the --token
|
|
option when invoking the OpenShift `oc` command. (default '')
|
|
:arg bool verbose: This flag is the toggle for
|
|
turning on or off detailed logging in this plug-in. (default false)
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
../../tests/publishers/fixtures/openshift-deploy-canceller001.yaml
|
|
:language: yaml
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
../../tests/publishers/fixtures/openshift-deploy-canceller002.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
osb = XML.SubElement(
|
|
xml_parent, "com.openshift.jenkins.plugins.pipeline." "OpenShiftDeployCanceller"
|
|
)
|
|
mapping = [
|
|
# option, xml name, default value
|
|
("api-url", "apiURL", "https://openshift.default.svc.cluster.local"),
|
|
("dep-cfg", "depCfg", "frontend"),
|
|
("namespace", "namespace", "test"),
|
|
("auth-token", "authToken", ""),
|
|
("verbose", "verbose", False),
|
|
]
|
|
helpers.convert_mapping_to_xml(osb, data, mapping, fail_required=True)
|
|
|
|
|
|
def github_pull_request_merge(registry, xml_parent, data):
|
|
"""yaml: github-pull-request-merge
|
|
This action merges the pull request that triggered the build (see the
|
|
github pull request trigger)
|
|
|
|
Requires the Jenkins :jenkins-plugins:`GitHub pull request builder plugin
|
|
<ghprb>`.
|
|
|
|
|
|
:arg bool only-admins-merge: if `true` only administrators can merge the
|
|
pull request, (default false)
|
|
:arg bool disallow-own-code: if `true` will allow merging your own pull
|
|
requests, in opposite to needing someone else to trigger the merge.
|
|
(default false)
|
|
:arg str merge-comment: Comment to set on the merge commit (default '')
|
|
:arg bool fail-on-non-merge: fail the job if the merge was unsuccessful
|
|
(default false)
|
|
:arg bool delete-on-merge: Delete the branch of the pull request on
|
|
successful merge (default false)
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
../../tests/publishers/fixtures/github-pull-request-merge001.yaml
|
|
:language: yaml
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
../../tests/publishers/fixtures/github-pull-request-merge002.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
osb = XML.SubElement(
|
|
xml_parent, "org.jenkinsci.plugins.ghprb.GhprbPullRequestMerge"
|
|
)
|
|
mapping = [
|
|
# option, xml name, default value
|
|
("only-admins-merge", "onlyAdminsMerge", "false"),
|
|
("disallow-own-code", "disallowOwnCode", "false"),
|
|
("merge-comment", "mergeComment", ""),
|
|
("fail-on-non-merge", "failOnNonMerge", "false"),
|
|
("delete-on-merge", "deleteOnMerge", "false"),
|
|
]
|
|
|
|
helpers.convert_mapping_to_xml(osb, data, mapping, fail_required=True)
|
|
|
|
|
|
def chuck_norris(registry, xml_parent, data):
|
|
"""yaml: chuck-norris
|
|
Displays a picture of Chuck Norris (instead of Jenkins the butler) and a
|
|
random Chuck Norris 'The Programmer' fact on each build page.
|
|
|
|
Requires the Jenkins :jenkins-plugins:`ChuckNorris Plugin <chucknorris>`.
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/chuck-norris.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
chuck = XML.SubElement(
|
|
xml_parent, "hudson.plugins.chucknorris.CordellWalkerRecorder"
|
|
)
|
|
return XML.SubElement(chuck, "factGenerator")
|
|
|
|
|
|
def publishers_from(registry, xml_parent, data):
|
|
"""yaml: publishers-from
|
|
Use publishers from another project.
|
|
Requires the Jenkins :jenkins-plugins:`Template Project Plugin
|
|
<template-project>`.
|
|
|
|
:arg str project-name: The name of the other project.
|
|
|
|
Example:
|
|
|
|
.. literalinclude:: ../../tests/publishers/fixtures/publishers-from.yaml
|
|
:language: yaml
|
|
"""
|
|
pbs = XML.SubElement(xml_parent, "hudson.plugins.templateproject.ProxyPublisher")
|
|
mapping = [("project-name", "projectName", None)]
|
|
helpers.convert_mapping_to_xml(pbs, data, mapping, fail_required=True)
|
|
|
|
|
|
def tasks(registry, xml_parent, data):
|
|
"""yaml: tasks
|
|
|
|
Scans the workspace files for open tasks and generates a trend report.
|
|
|
|
Requires the Jenkins Task Scanner Plugin
|
|
(https://github.com/jenkinsci/tasks-plugin).
|
|
|
|
:arg list files-to-scan: Fileset includes setting that specifies the
|
|
workspace files to scan for tasks, such as ``**/*.java``. Basedir of
|
|
the fileset is the workspace root. (default '``**/*.java``')
|
|
:arg list files-to-exclude: Fileset excludes setting that specifies the
|
|
workspace files to exclude scanning for tasks, such as library source
|
|
files. Basedir of the fileset is the workspace root. (default '')
|
|
:arg list tasks-tags-high: Tags identifiers for high priority that should
|
|
be looked for in the workspace files. Only alphanumerical characters
|
|
are allowed as tags as these strings are pasted into a regular
|
|
expression. (default '')
|
|
:arg list tasks-tags-normal: Tags identifiers for normal priority that
|
|
should be looked for in the workspace files. Only alphanumerical
|
|
characters are allowed as tags as these strings are pasted into a
|
|
regular expression. (default '')
|
|
:arg list tasks-tags-low: Tags identifiers for low priority that should be
|
|
looked for in the workspace files. Only alphanumerical characters are
|
|
allowed as tags as these strings are pasted into a regular expression.
|
|
(default '')
|
|
:arg bool ignore-case: Ignore the case of the the tag identifiers. (default
|
|
false)
|
|
:arg bool regular-expression: Treat the tag identifiers as regular
|
|
expression. Note that the regular expression must contain two capturing
|
|
groups, the first one is interpreted as tag name, the second one as
|
|
message. An example of such a regular expression would be
|
|
``^.*(TODO(?:[0-9]*))(.*)$``. (default false)
|
|
:arg bool run-always: By default, this plug-in runs only for stable or
|
|
unstable builds, but not for failed builds. If this plug-in should run
|
|
even for failed builds then activate this check box. (default false)
|
|
:arg bool detect-module: Determines if Ant or Maven modules should be
|
|
detected for all files that contain warnings. Activating this option
|
|
may increase your build time since the detector scans the whole
|
|
workspace for ``build.xml`` or ``pom.xml`` files in order to assign the
|
|
correct module names. (default false)
|
|
:arg int health-thresholds-100: Configure the upper thresholds for the
|
|
build health. If left empty then no health report is created. If the
|
|
actual number of warnings is between the provided thresholds then the
|
|
build health is interpolated. (default '')
|
|
:arg str health-thresholds-0: Configure the lower thresholds for the build
|
|
health. If left empty then no health report is created. If the actual
|
|
number of warnings is between the provided thresholds then the build
|
|
health is interpolated. (default '')
|
|
:arg str health-priorities: Determines which warning priorities should be
|
|
considered when evaluating the build health. Can be ``high`` (only
|
|
priority high), ``normal`` (priorities high and normal) or ``low`` (all
|
|
priorities). (default 'low')
|
|
:arg dict status-thresholds: Configure the build status and health. If the
|
|
number of total or new warnings is greater than one of these thresholds
|
|
then a build is considered as unstable or failed, respectively. I.e., a
|
|
value of 0 means that the build status is changed if there is at least
|
|
one warning found. Leave this field empty if the state of the build
|
|
should not depend on the number of warnings. Note that for new
|
|
warnings, you need to enable the next option
|
|
(``compute-new-warnings``).
|
|
|
|
:status-thresholds:
|
|
|
|
* **unstable-total-all** (`str`): Total number for all priorities,
|
|
unstable threshold (default '')
|
|
* **unstable-total-high** (`str`): Total number for high priority,
|
|
unstable threshold (default '')
|
|
* **unstable-total-normal** (`str`): Total number for normal
|
|
priority, unstable threshold (default '')
|
|
* **unstable-total-low** (`str`): Total number for low priority,
|
|
unstable threshold (default '')
|
|
* **failed-total-all** (`str`): Total number for all priorities,
|
|
failure threshold (default '')
|
|
* **failed-total-high** (`str`): Total number for high priority,
|
|
failure threshold (default '')
|
|
* **failed-total-normal** (`str`): Total number for normal
|
|
priority, failure threshold (default '')
|
|
* **failed-total-low** (`str`): Total number for low priority,
|
|
failure threshold (default '')
|
|
* **unstable-new-all** (`str`): New number for all priorities,
|
|
unstable threshold (default '')
|
|
* **unstable-new-high** (`str`): New number for high priority,
|
|
unstable threshold (default '')
|
|
* **unstable-new-normal** (`str`): New number for normal priority,
|
|
unstable threshold (default '')
|
|
* **unstable-new-low** (`str`): New number for low priority,
|
|
unstable threshold (default '')
|
|
* **failed-new-all** (`str`): New number for all priorities,
|
|
failure threshold (default '')
|
|
* **failed-new-high** (`str`): New number for high priority,
|
|
failure threshold (default '')
|
|
* **failed-new-normal** (`str`): New number for normal priority,
|
|
failure threshold (default '')
|
|
* **failed-new-low** (`str`): New number for low priority, failure
|
|
threshold (default '')
|
|
|
|
:arg bool compute-new-warnings: Compute new warnings (based on the last
|
|
successful build unless another reference build is chosen below).
|
|
(default false)
|
|
:arg bool use-delta: If set the number of new warnings is computed by
|
|
subtracting the total number of warnings of the reference build from
|
|
the total number of warnings of the current build. This may lead to
|
|
wrong results if you have both fixed and new warnings in a build. If
|
|
unset the number of new warnings is computed by a more sophisticated
|
|
algorithm: instead of using totals an asymmetric set difference of the
|
|
warnings in the current build and the warnings in the reference build
|
|
is used. This will find all new warnings even if the number of total
|
|
warnings has decreased. Note that sometimes false positives will be
|
|
reported due to minor changes in a warning (e.g. refactoring of
|
|
variables or method names). It is recommended to uncheck this option in
|
|
order to get the most accurate results for new warnings. Depends on
|
|
``compute-new-warnings`` option. (default false)
|
|
:arg bool use-prev-build-as-ref: If set the number of new warnings will
|
|
always be computed based on the previous build, even if that build is
|
|
unstable (due to a violated warning threshold). Otherwise the last
|
|
build that did not violate any given threshold will be used as
|
|
reference. It is recommended to uncheck this option if the plug-in
|
|
should ensure that all new warnings will be finally fixed in subsequent
|
|
builds. Depends on ``compute-new-warnings`` option. (default false)
|
|
:arg bool only-use-stable-as-ref: Use the last stable build as the
|
|
reference to compute the number of new warnings against. This allows
|
|
you to ignore interim unstable builds for which the number of warnings
|
|
decreased. Note that the last stable build is evaluated only by
|
|
inspecting the unit test failures. The static analysis results are not
|
|
considered. Depends on ``compute-new-warnings`` option. (default false)
|
|
:arg str default-encoding: Default encoding when parsing or showing files.
|
|
Leave this field empty to use the default encoding of the platform.
|
|
(default '')
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/tasks-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude:: /../../tests/publishers/fixtures/tasks-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
root = XML.SubElement(xml_parent, "hudson.plugins.tasks.TasksPublisher")
|
|
root.set("plugin", "tasks")
|
|
|
|
if "files-to-scan" in data:
|
|
XML.SubElement(root, "pattern").text = str(",".join(data["files-to-scan"]))
|
|
|
|
if "files-to-exclude" in data:
|
|
XML.SubElement(root, "excludePattern").text = str(
|
|
",".join(data["files-to-exclude"])
|
|
)
|
|
|
|
for prio in ["high", "normal", "low"]:
|
|
if "tasks-tags-" + prio in data:
|
|
XML.SubElement(root, prio).text = str(",".join(data["tasks-tags-" + prio]))
|
|
|
|
# on the UI, we can see compute-new-warnings but we need the opposite (XML)
|
|
if "compute-new-warnings" in data and data["compute-new-warnings"]:
|
|
XML.SubElement(root, "dontComputeNew").text = "false"
|
|
else:
|
|
XML.SubElement(root, "dontComputeNew").text = "true"
|
|
|
|
# Two parameters we cannot modify from the UI
|
|
XML.SubElement(root, "pluginName").text = "[TASKS] "
|
|
XML.SubElement(root, "doNotResolveRelativePaths").text = "false"
|
|
|
|
mappings = [
|
|
("ignore-case", "ignoreCase", False),
|
|
("regular-expression", "asRegexp", False),
|
|
("run-always", "canRunOnFailed", False),
|
|
("detect-module", "shouldDetectModules", False),
|
|
("health-thresholds-100", "healthy", ""),
|
|
("health-thresholds-0", "unHealthy", ""),
|
|
("health-priorities", "thresholdLimit", "low"),
|
|
("use-delta", "useDeltaValues", False),
|
|
("use-prev-build-as-ref", "usePreviousBuildAsReference", False),
|
|
("only-use-stable-as-ref", "useStableBuildAsReference", False),
|
|
("default-encoding", "defaultEncoding", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(root, data, mappings, fail_required=True)
|
|
|
|
thrsh_xml = XML.SubElement(root, "thresholds")
|
|
thrsh_xml.set("plugin", "analysis-core")
|
|
thrsh_data = data.get("status-thresholds", {})
|
|
thrsh_mappings = [
|
|
("unstable-total-all", "unstableTotalAll", ""),
|
|
("unstable-total-high", "unstableTotalHigh", ""),
|
|
("unstable-total-normal", "unstableTotalNormal", ""),
|
|
("unstable-total-low", "unstableTotalLow", ""),
|
|
("unstable-new-all", "unstableNewAll", ""),
|
|
("unstable-new-high", "unstableNewHigh", ""),
|
|
("unstable-new-normal", "unstableNewNormal", ""),
|
|
("unstable-new-low", "unstableNewLow", ""),
|
|
("failed-total-all", "failedTotalAll", ""),
|
|
("failed-total-high", "failedTotalHigh", ""),
|
|
("failed-total-normal", "failedTotalNormal", ""),
|
|
("failed-total-low", "failedTotalLow", ""),
|
|
("failed-new-all", "failedNewAll", ""),
|
|
("failed-new-high", "failedNewHigh", ""),
|
|
("failed-new-normal", "failedNewNormal", ""),
|
|
("failed-new-low", "failedNewLow", ""),
|
|
]
|
|
helpers.convert_mapping_to_xml(
|
|
thrsh_xml, thrsh_data, thrsh_mappings, fail_required=True
|
|
)
|
|
|
|
|
|
def packer(registry, xml_parent, data):
|
|
"""yaml: packer
|
|
This plugin allows for a job to publish an image generated Packer
|
|
Requires the Jenkins :jenkins-plugins:`Packer Plugin <packer>`.
|
|
|
|
:arg str name: Name of the packer installation (required)
|
|
:arg str json-template: Path to a Packer JSON template file (default '')
|
|
:arg str json-template-text: Text of Packer JSON template (default '')
|
|
:arg str add-params: Specify which additional parameters
|
|
to pass to packer (default '')
|
|
:arg bool use-debug: adds -debug argument when packer executes
|
|
(default false)
|
|
:arg str change-dir: If set, the current directory will be changed
|
|
to this before starting packer (default '')
|
|
:arg str template-mode: Packer template option used (default global)
|
|
|
|
:template-mode values:
|
|
* **global**
|
|
* **file**
|
|
* **text**
|
|
:arg list file-entries: File entries for the packer
|
|
configuration (default [])
|
|
:arg str variable-name: Variable name for a file to used in the
|
|
configuration JSON (default '')
|
|
:arg str contents: File contents of the configuration JSON (default '')
|
|
|
|
Minimal Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/packer-minimal.yaml
|
|
:language: yaml
|
|
|
|
Full Example:
|
|
|
|
.. literalinclude::
|
|
/../../tests/publishers/fixtures/packer-full.yaml
|
|
:language: yaml
|
|
"""
|
|
|
|
root = XML.SubElement(
|
|
xml_parent, "biz.neustar.jenkins.plugins.packer.PackerPublisher"
|
|
)
|
|
|
|
template_valid_types = ["global", "file", "text"]
|
|
mapping = [
|
|
("name", "name", None),
|
|
("json-template", "jsonTemplate", ""),
|
|
("json-template-text", "jsonTemplateText", ""),
|
|
("add-params", "params", ""),
|
|
("use-debug", "useDebug", False),
|
|
("change-dir", "changeDir", ""),
|
|
("template-mode", "templateMode", "global", template_valid_types),
|
|
]
|
|
helpers.convert_mapping_to_xml(root, data, mapping, fail_required=True)
|
|
|
|
format_dict = {
|
|
"packer-file-entry": "biz.neustar.jenkins.plugins.packer.PackerFileEntry"
|
|
}
|
|
if "file-entries" in data:
|
|
file_entries_tag = XML.SubElement(root, "fileEntries")
|
|
for file_entries in data["file-entries"]:
|
|
for file, params in file_entries.items():
|
|
packer_file_entry_tag = XML.SubElement(
|
|
file_entries_tag, format_dict.get("packer-file-entry")
|
|
)
|
|
XML.SubElement(packer_file_entry_tag, "varFileName").text = params.get(
|
|
"variable-name", ""
|
|
)
|
|
XML.SubElement(packer_file_entry_tag, "contents").text = params.get(
|
|
"contents", ""
|
|
)
|
|
|
|
|
|
class Publishers(jenkins_jobs.modules.base.Base):
|
|
sequence = 70
|
|
|
|
component_type = "publisher"
|
|
component_list_type = "publishers"
|
|
|
|
def gen_xml(self, xml_parent, data):
|
|
if data.get("project-type", "freestyle") == "pipeline":
|
|
logger.debug("Publishers skipped for Pipeline job")
|
|
return
|
|
|
|
publishers = XML.SubElement(xml_parent, "publishers")
|
|
|
|
for action in data.get("publishers", []):
|
|
self.registry.dispatch("publisher", publishers, action)
|