diff options
50 files changed, 966 insertions, 167 deletions
diff --git a/jenkins_jobs/modules/builders.py b/jenkins_jobs/modules/builders.py index c80d046b..7a8efcd7 100644 --- a/jenkins_jobs/modules/builders.py +++ b/jenkins_jobs/modules/builders.py @@ -878,6 +878,79 @@ def inject(parser, xml_parent, data): info, 'scriptContent', data.get('script-content')) +def kmap(parser, xml_parent, data): + """yaml: kmap + Publish mobile applications to your Keivox KMAP Private Mobile App Store. + Requires the Jenkins :jenkins-wiki:`Keivox KMAP Private Mobile App Store + Plugin <Keivox+KMAP+Private+Mobile+App+Store+Plugin>`. + + :arg str username: KMAP's user email with permissions to upload/publish + applications to KMAP (required) + :arg str password: Password for the KMAP user uploading/publishing + applications (required) + :arg str url: KMAP's url. This url must always end with "/kmap-client/". + For example: http://testing.keivox.com/kmap-client/ (required) + :arg str categories: Categories' names. If you want to add the application + to more than one category, write the categories between commas. + (required) + :arg str file-path: Path to the application's file (required) + :arg str app-name: KMAP's application name (required) + :arg str bundle: Bundle indentifier (default '') + :arg str version: Application's version (required) + :arg str description: Application's description (default '') + :arg str icon-path: Path to the application's icon (default '') + :arg bool publish-optional: Publish application after it has been uploaded + to KMAP (default false) + + :publish-optional: + * **groups** ('str') -- groups' names to publish the application + (default '') + * **users** ('str') -- users' names to publish the application + (default '') + * **notify-users** ('bool') -- Send notifications to the users and + groups when publishing the application (default false) + + Minimal Example: + + .. literalinclude:: ../../tests/builders/fixtures/kmap-minimal.yaml + :language: yaml + + Full Example: + + .. literalinclude:: ../../tests/builders/fixtures/kmap-full.yaml + :language: yaml + """ + kmap = XML.SubElement( + xml_parent, 'org.jenkinsci.plugins.KmapJenkinsBuilder') + + kmap.set('plugin', 'kmap-jenkins') + publish = data.get('publish-optional', False) + + mapping = [ + ('username', 'username', None), + ('password', 'password', None), + ('url', 'kmapClient', None), + ('categories', 'categories', None), + ('file-path', 'filePath', None), + ('app-name', 'appName', None), + ('bundle', 'bundle', ''), + ('version', 'version', None), + ('description', 'description', ''), + ('icon-path', 'iconPath', ''), + ] + convert_mapping_to_xml(kmap, data, mapping, fail_required=True) + + if publish is True: + publish_optional = XML.SubElement(kmap, 'publishOptional') + publish_mapping = [ + ('groups', 'teams', ''), + ('users', 'users', ''), + ('notify-users', 'sendNotifications', False), + ] + convert_mapping_to_xml( + publish_optional, data, publish_mapping, fail_required=True) + + def artifact_resolver(parser, xml_parent, data): """yaml: artifact-resolver Allows one to resolve artifacts from a maven repository like nexus @@ -1633,10 +1706,10 @@ def maven_builder(parser, xml_parent, data): Requires the Jenkins :jenkins-wiki:`Artifactory Plugin <Artifactory+Plugin>`. - :arg str name: Name of maven installation from the configuration + :arg str name: Name of maven installation from the configuration (required) :arg str pom: Location of pom.xml (default 'pom.xml') - :arg str goals: Goals to execute - :arg str maven-opts: Additional options for maven (optional) + :arg str goals: Goals to execute (required) + :arg str maven-opts: Additional options for maven (default '') Example: @@ -1645,15 +1718,13 @@ def maven_builder(parser, xml_parent, data): """ maven = XML.SubElement(xml_parent, 'org.jfrog.hudson.maven3.Maven3Builder') - try: - XML.SubElement(maven, 'mavenName').text = data['name'] - XML.SubElement(maven, 'goals').text = data['goals'] - except KeyError as e: - # exception will contain the missing key name - raise MissingAttributeError(e.arg[0]) - - XML.SubElement(maven, 'rootPom').text = data.get('pom', 'pom.xml') - XML.SubElement(maven, 'mavenOpts').text = data.get('maven-opts', '') + mapping = [ + ('name', 'mavenName', None), + ('goals', 'goals', None), + ('pom', 'rootPom', 'pom.xml'), + ('maven-opts', 'mavenOpts', ''), + ] + convert_mapping_to_xml(maven, data, mapping, fail_required=True) def maven_target(parser, xml_parent, data): @@ -2705,6 +2776,136 @@ def sonar(parser, xml_parent, data): XML.SubElement(sonar, 'jdk').text = data['jdk'] +def xcode(parser, xml_parent, data): + """yaml: xcode + This step allows to execute an xcode build step. Requires the Jenkins + :jenkins-wiki:`Xcode Plugin <Xcode+Plugin>`. + + :arg str developer-profile: the jenkins credential id for a + ios developer profile. (optional) + :arg bool clean-build: if true will delete the build directories + before invoking the build. (default false) + :arg bool clean-test-reports: UNKNOWN. (default false) + :arg bool archive: if true will generate an xcarchive of the specified + scheme. A workspace and scheme are are also needed for archives. + (default false) + :arg str configuration: This is the name of the configuration + as defined in the Xcode project. (default 'Release') + :arg str configuration-directory: The value to use for + CONFIGURATION_BUILD_DIR setting. (default '') + :arg str target: Leave empty for all targets. (default '') + :arg str sdk: Leave empty for default SDK. (default '') + :arg str symroot: Leave empty for default SYMROOT. (default '') + :arg str project-path: Relative path within the workspace + that contains the xcode project file(s). (default '') + :arg str project-file: Only needed if there is more than one + project file in the Xcode Project Directory. (default '') + :arg str build-arguments: Extra commandline arguments provided + to the xcode builder. (default '') + :arg str schema: Only needed if you want to compile for a + specific schema instead of a target. (default '') + :arg str workspace: Only needed if you want to compile a + workspace instead of a project. (default '') + :arg str profile: The relative path to the mobileprovision to embed, + leave blank for no embedded profile. (default '') + :arg str codesign-id: Override the code signing identity specified + in the project. (default '') + :arg bool allow-failing: if true will prevent this build step from + failing if xcodebuild exits with a non-zero return code. (default + false) + :arg str version-technical: The value to use for CFBundleVersion. + Leave blank to use project's technical number. (default '') + :arg str version-marketing: The value to use for + CFBundleShortVersionString. Leave blank to use project's + marketing number. (default '') + :arg str ipa-version: A pattern for the ipa file name. You may use + ${VERSION} and ${BUILD_DATE} (yyyy.MM.dd) in this string. + (default '') + :arg str ipa-output: The output directory for the .ipa file, + relative to the build directory. (default '') + :arg str keychain-name: The globally configured keychain to unlock for + this build. (default '') + :arg str keychain-path: The path of the keychain to use to sign the IPA. + (default '') + :arg str keychain-password: The password to use to unlock the keychain. + (default '') + :arg str keychain-unlock: Unlocks the keychain during use. + (default false) + + Example: + + .. literalinclude:: /../../tests/builders/fixtures/xcode.yaml + :language: yaml + """ + + if data.get('developer-profile'): + profile = XML.SubElement(xml_parent, 'au.com.rayh.' + 'DeveloperProfileLoader') + XML.SubElement(profile, 'id').text = str( + data['developer-profile']) + + xcode = XML.SubElement(xml_parent, 'au.com.rayh.XCodeBuilder') + + XML.SubElement(xcode, 'cleanBeforeBuild').text = str( + data.get('clean-build', False)).lower() + XML.SubElement(xcode, 'cleanTestReports').text = str( + data.get('clean-test-reports', False)).lower() + XML.SubElement(xcode, 'generateArchive').text = str( + data.get('archive', False)).lower() + + XML.SubElement(xcode, 'configuration').text = str( + data.get('configuration', 'Release')) + XML.SubElement(xcode, 'configurationBuildDir').text = str( + data.get('configuration-directory', '')) + XML.SubElement(xcode, 'target').text = str(data.get('target', '')) + XML.SubElement(xcode, 'sdk').text = str(data.get('sdk', '')) + XML.SubElement(xcode, 'symRoot').text = str(data.get('symroot', '')) + + XML.SubElement(xcode, 'xcodeProjectPath').text = str( + data.get('project-path', '')) + XML.SubElement(xcode, 'xcodeProjectFile').text = str( + data.get('project-file', '')) + XML.SubElement(xcode, 'xcodebuildArguments').text = str( + data.get('build-arguments', '')) + XML.SubElement(xcode, 'xcodeSchema').text = str(data.get('schema', '')) + XML.SubElement(xcode, 'xcodeWorkspaceFile').text = str( + data.get('workspace', '')) + XML.SubElement(xcode, 'embeddedProfileFile').text = str( + data.get('profile', '')) + + XML.SubElement(xcode, 'codeSigningIdentity').text = str( + data.get('codesign-id', '')) + XML.SubElement(xcode, 'allowFailingBuildResults').text = str( + data.get('allow-failing', False)).lower() + + version = XML.SubElement(xcode, 'provideApplicationVersion') + version_technical = XML.SubElement(xcode, + 'cfBundleVersionValue') + version_marketing = XML.SubElement(xcode, + 'cfBundleShortVersionStringValue') + if data.get('version-technical') or data.get('version-marketing'): + version.text = 'true' + version_technical.text = data.get('version-technical', '') + version_marketing.text = data.get('version-marketing', '') + else: + version.text = 'false' + + XML.SubElement(xcode, 'buildIpa').text = str( + bool(data.get('ipa-version')) or False).lower() + XML.SubElement(xcode, 'ipaName').text = data.get('ipa-version', '') + XML.SubElement(xcode, 'ipaOutputDirectory').text = str( + data.get('ipa-output', '')) + + XML.SubElement(xcode, 'keychainName').text = str( + data.get('keychain-name', '')) + XML.SubElement(xcode, 'keychainPath').text = str( + data.get('keychain-path', '')) + XML.SubElement(xcode, 'keychainPwd').text = str( + data.get('keychain-password', '')) + XML.SubElement(xcode, 'unlockKeychain').text = str( + data.get('keychain-unlock', False)).lower() + + def sonatype_clm(parser, xml_parent, data): """yaml: sonatype-clm Requires the Jenkins :jenkins-wiki:`Sonatype CLM Plugin @@ -3257,20 +3458,26 @@ def runscope(parser, xml_parent, data): :arg str access-token: OAuth Personal Access token. (required) :arg int timeout: Timeout for test duration in seconds. (default 60) - Example: + Minimal Example: - .. literalinclude:: /../../tests/builders/fixtures/runscope.yaml + .. literalinclude:: /../../tests/builders/fixtures/runscope-minimal.yaml + :language: yaml + + Full Example: + + .. literalinclude:: /../../tests/builders/fixtures/runscope-full.yaml :language: yaml """ runscope = XML.SubElement(xml_parent, 'com.runscope.jenkins.Runscope.RunscopeBuilder') - try: - XML.SubElement(runscope, 'triggerEndPoint').text = data[ - "test-trigger-url"] - XML.SubElement(runscope, 'accessToken').text = data["access-token"] - except KeyError as e: - raise MissingAttributeError(e.args[0]) - XML.SubElement(runscope, 'timeout').text = str(data.get('timeout', '60')) + runscope.set('plugin', 'runscope') + + mapping = [ + ('test-trigger-url', 'triggerEndPoint', None), + ('access-token', 'accessToken', None), + ('timeout', 'timeout', 60), + ] + convert_mapping_to_xml(runscope, data, mapping, fail_required=True) def description_setter(parser, xml_parent, data): @@ -3325,26 +3532,18 @@ def docker_build_publish(parse, xml_parent, data): 'com.cloudbees.dockerpublish.DockerBuilder') db.set('plugin', 'docker-build-publish') - try: - XML.SubElement(db, 'repoName').text = str(data['repo-name']) - except KeyError: - raise MissingAttributeError('repo-name') - - XML.SubElement(db, 'repoTag').text = str(data.get('repo-tag', '')) - XML.SubElement(db, 'noCache').text = str( - data.get('no-cache', False)).lower() - XML.SubElement(db, 'noForcePull').text = str( - data.get('no-force-pull', False)).lower() - XML.SubElement(db, 'skipBuild').text = str( - data.get('skip-build', False)).lower() - XML.SubElement(db, 'skipDecorate').text = str( - data.get('skip-decorate', False)).lower() - XML.SubElement(db, 'skipTagLatest').text = str( - data.get('skip-tag-latest', False)).lower() - XML.SubElement(db, 'skipPush').text = str( - data.get('skip-push', False)).lower() - XML.SubElement(db, 'dockerfilePath').text = str( - data.get('file-path', '')) + mapping = [ + ('repo-name', 'repoName', None), + ('repo-tag', 'repoTag', ''), + ('no-cache', 'noCache', False), + ('no-force-pull', 'noForcePull', False), + ('skip-build', 'skipBuild', False), + ('skip-decorate', 'skipDecorate', False), + ('skip-tag-latest', 'skipTagLatest', False), + ('skip-push', 'skipPush', False), + ('file-path', 'dockerfilePath', ''), + ] + convert_mapping_to_xml(db, data, mapping, fail_required=True) def build_name_setter(parser, xml_parent, data): @@ -3377,13 +3576,12 @@ def build_name_setter(parser, xml_parent, data): build_name_setter = XML.SubElement( xml_parent, 'org.jenkinsci.plugins.buildnameupdater.BuildNameUpdater') - XML.SubElement(build_name_setter, 'buildName').text = data.get( - 'name', 'version.txt') - XML.SubElement(build_name_setter, 'macroTemplate').text = data.get( - 'template', '#${BUILD_NUMBER}') - XML.SubElement(build_name_setter, 'fromFile').text = str( - data.get('file', False)).lower() - XML.SubElement(build_name_setter, 'fromMacro').text = str( - data.get('macro', False)).lower() - XML.SubElement(build_name_setter, 'macroFirst').text = str( - data.get('macro-first', False)).lower() + mapping = [ + ('name', 'buildName', 'version.txt'), + ('template', 'macroTemplate', '#${BUILD_NUMBER}'), + ('file', 'fromFile', False), + ('macro', 'fromMacro', False), + ('macro-first', 'macroFirst', False), + ] + convert_mapping_to_xml( + build_name_setter, data, mapping, fail_required=True) diff --git a/jenkins_jobs/modules/helpers.py b/jenkins_jobs/modules/helpers.py index 9b9f597c..41ca8c73 100644 --- a/jenkins_jobs/modules/helpers.py +++ b/jenkins_jobs/modules/helpers.py @@ -95,15 +95,12 @@ def config_file_provider_builder(xml_parent, data): for file in files: xml_file = XML.SubElement(xml_files, 'org.jenkinsci.plugins.' 'configfiles.buildwrapper.ManagedFile') - file_id = file.get('file-id') - if file_id is None: - raise JenkinsJobsException("file-id is required for each " - "managed configuration file") - XML.SubElement(xml_file, 'fileId').text = str(file_id) - XML.SubElement(xml_file, 'targetLocation').text = file.get( - 'target', '') - XML.SubElement(xml_file, 'variable').text = file.get( - 'variable', '') + mapping = [ + ('file-id', 'fileId', None), + ('target', 'targetLocation', ''), + ('variable', 'variable', ''), + ] + convert_mapping_to_xml(xml_file, file, mapping, fail_required=True) def config_file_provider_settings(xml_parent, data): @@ -242,12 +239,12 @@ def copyartifact_build_selector(xml_parent, data, select_tag='selector'): def findbugs_settings(xml_parent, data): # General Options - rank_priority = str(data.get('rank-priority', False)).lower() - XML.SubElement(xml_parent, 'isRankActivated').text = rank_priority - include_files = data.get('include-files', '') - XML.SubElement(xml_parent, 'includePattern').text = include_files - exclude_files = data.get('exclude-files', '') - XML.SubElement(xml_parent, 'excludePattern').text = exclude_files + mapping = [ + ('rank-priority', 'isRankActivated', False), + ('include-files', 'includePattern', ''), + ('exclude-files', 'excludePattern', ''), + ] + convert_mapping_to_xml(xml_parent, data, mapping, fail_required=True) def get_value_from_yaml_or_config_file(key, section, data, parser): @@ -484,14 +481,23 @@ def convert_mapping_to_xml(parent, data, mapping, fail_required=False): valid_options provides a way to check if the value the user input is from a list of available options. When the user pass a value that is not supported from the list, it raise an InvalidAttributeError. + + valid_dict provides a way to set options through their key and value. If + the user input corresponds to a key, the XML tag will use the key's value + for its element. When the user pass a value that there are no keys for, + it raise an InvalidAttributeError. """ for elem in mapping: (optname, xmlname, val) = elem[:3] val = data.get(optname, val) valid_options = [] + valid_dict = {} if len(elem) == 4: - valid_options = elem[3] + if type(elem[3]) is list: + valid_options = elem[3] + if type(elem[3]) is dict: + valid_dict = elem[3] # Use fail_required setting to allow support for optional parameters # we will phase this out in the future as we rework plugins so that @@ -505,10 +511,18 @@ def convert_mapping_to_xml(parent, data, mapping, fail_required=False): if val is None and fail_required is False: continue + if valid_dict: + if val not in valid_dict: + raise InvalidAttributeError(optname, val, valid_dict.keys()) + if valid_options: if val not in valid_options: raise InvalidAttributeError(optname, val, valid_options) if type(val) == bool: val = str(val).lower() - XML.SubElement(parent, xmlname).text = str(val) + + if val in valid_dict: + XML.SubElement(parent, xmlname).text = str(valid_dict[val]) + else: + XML.SubElement(parent, xmlname).text = str(val) diff --git a/jenkins_jobs/modules/properties.py b/jenkins_jobs/modules/properties.py index 5e6bdcc2..5f7df3ce 100644 --- a/jenkins_jobs/modules/properties.py +++ b/jenkins_jobs/modules/properties.py @@ -39,6 +39,7 @@ 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.helpers import convert_mapping_to_xml def builds_chain_fingerprinter(parser, xml_parent, data): @@ -616,20 +617,28 @@ def delivery_pipeline(parser, xml_parent, data): :arg str description: task description template for this job (default '') - Example: + Minimal Example: .. literalinclude:: - /../../tests/properties/fixtures/delivery-pipeline1.yaml + /../../tests/properties/fixtures/delivery-pipeline-minimal.yaml :language: yaml + Full Example: + + .. literalinclude:: + /../../tests/properties/fixtures/delivery-pipeline-full.yaml + :language: yaml """ - pipeline = XML.SubElement(xml_parent, - 'se.diabol.jenkins.pipeline.' - 'PipelineProperty') - XML.SubElement(pipeline, 'stageName').text = data.get('stage', '') - XML.SubElement(pipeline, 'taskName').text = data.get('task', '') - XML.SubElement(pipeline, 'descriptionTemplate').text = str( - data.get('description', '')) + pipeline = XML.SubElement( + xml_parent, 'se.diabol.jenkins.pipeline.PipelineProperty') + pipeline.set('plugin', 'delivery-pipeline-plugin') + + mapping = [ + ('stage', 'stageName', ''), + ('task', 'taskName', ''), + ('description', 'descriptionTemplate', ''), + ] + convert_mapping_to_xml(pipeline, data, mapping, fail_required=True) def zeromq_event(parser, xml_parent, data): diff --git a/jenkins_jobs/modules/publishers.py b/jenkins_jobs/modules/publishers.py index dc68e1b1..4ef18435 100644 --- a/jenkins_jobs/modules/publishers.py +++ b/jenkins_jobs/modules/publishers.py @@ -297,6 +297,55 @@ def campfire(parser, xml_parent, data): XML.SubElement(room, 'campfire reference="../../campfire"') +def codecover(parser, 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-wiki:`CodeCover Plugin <CodeCover+Plugin>`. + + :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(parser, xml_parent, data): """yaml: emotional-jenkins Emotional Jenkins. This funny plugin changes the expression of Mr. Jenkins @@ -852,22 +901,19 @@ def cobertura(parser, xml_parent, data): """ cobertura = XML.SubElement(xml_parent, 'hudson.plugins.cobertura.CoberturaPublisher') - XML.SubElement(cobertura, 'coberturaReportFile').text = data.get( - 'report-file', '**/coverage.xml') - XML.SubElement(cobertura, 'onlyStable').text = str( - data.get('only-stable', False)).lower() - XML.SubElement(cobertura, 'failUnhealthy').text = str( - data.get('fail-unhealthy', False)).lower() - XML.SubElement(cobertura, 'failUnstable').text = str( - data.get('fail-unstable', False)).lower() - XML.SubElement(cobertura, 'autoUpdateHealth').text = str( - data.get('health-auto-update', False)).lower() - XML.SubElement(cobertura, 'autoUpdateStability').text = str( - data.get('stability-auto-update', False)).lower() - XML.SubElement(cobertura, 'zoomCoverageChart').text = str( - data.get('zoom-coverage-chart', False)).lower() - XML.SubElement(cobertura, 'failNoReports').text = str( - data.get('fail-no-reports', False)).lower() + 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', @@ -1026,6 +1072,8 @@ def junit(parser, xml_parent, data): :arg str results: results filename :arg bool keep-long-stdio: Retain long standard output/error in test results (default true). + :arg bool allow-empty-results: Do not fail builds if no junit reports + are found (default false) :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) @@ -1060,6 +1108,8 @@ def junit(parser, xml_parent, data): XML.SubElement(junitresult, 'testResults').text = data['results'] XML.SubElement(junitresult, 'keepLongStdio').text = str( data.get('keep-long-stdio', True)).lower() + XML.SubElement(junitresult, 'allowEmptyResults').text = str( + data.get('allow-empty-results', False)).lower() XML.SubElement(junitresult, 'healthScaleFactor').text = str( data.get('health-scale-factor', '1.0')) XML.SubElement(junitresult, 'allowEmptyResults').text = str( @@ -2158,6 +2208,35 @@ def jira(parser, xml_parent, data): XML.SubElement(xml_parent, 'hudson.plugins.jira.JiraIssueUpdater') +def growl(parser, xml_parent, data): + """yaml: growl + Push notifications to growl client. + Requires the Jenkins :jenkins-wiki:`Growl Plugin <Growl+Plugin>`. + + :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(parser, xml_parent, data): """yaml: groovy-postbuild Execute a groovy script. @@ -3925,19 +4004,9 @@ def git(parser, xml_parent, data): ('namespace', 'noteNamespace', 'master'), ('replace-note', 'noteReplace', False)] - def handle_entity_children(entity, entity_xml, child_mapping): - for prop in child_mapping: - opt, xmlopt, default_val = prop[:3] - val = entity.get(opt, default_val) - if val is None: - raise JenkinsJobsException('Required option missing: %s' % opt) - if type(val) == bool: - val = str(val).lower() - XML.SubElement(entity_xml, xmlopt).text = val - top = XML.SubElement(xml_parent, 'hudson.plugins.git.GitPublisher') XML.SubElement(top, 'configVersion').text = '2' - handle_entity_children(data, top, mappings) + helpers.convert_mapping_to_xml(top, data, mappings, fail_required=True) tags = data.get('tags', []) if tags: @@ -3946,7 +4015,8 @@ def git(parser, xml_parent, data): xml_tag = XML.SubElement( xml_tags, 'hudson.plugins.git.GitPublisher_-TagToPush') - handle_entity_children(tag['tag'], xml_tag, tag_mappings) + helpers.convert_mapping_to_xml( + xml_tag, tag['tag'], tag_mappings, fail_required=True) branches = data.get('branches', []) if branches: @@ -3955,8 +4025,10 @@ def git(parser, xml_parent, data): xml_branch = XML.SubElement( xml_branches, 'hudson.plugins.git.GitPublisher_-BranchToPush') - handle_entity_children(branch['branch'], xml_branch, - branch_mappings) + helpers.convert_mapping_to_xml(xml_branch, + branch['branch'], + branch_mappings, + fail_required=True) notes = data.get('notes', []) if notes: @@ -3965,7 +4037,8 @@ def git(parser, xml_parent, data): xml_note = XML.SubElement( xml_notes, 'hudson.plugins.git.GitPublisher_-NoteToPush') - handle_entity_children(note['note'], xml_note, note_mappings) + helpers.convert_mapping_to_xml( + xml_note, note['note'], note_mappings, fail_required=True) def github_notifier(parser, xml_parent, data): @@ -5248,28 +5321,31 @@ def logstash(parser, xml_parent, data): your job data. Also stores test metrics from Junit. Requires the Jenkins :jenkins-wiki:`Logstash Plugin <Logstash+Plugin>`. - :arg num max-lines: The maximum number of log lines to send to Logstash. - ( default 1000 ) + :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 ) + (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') - XML.SubElement(logstash, 'maxLines').text = str( - data.get('max-lines', 1000)) + logstash.set('plugin', 'logstash') - XML.SubElement(logstash, 'failBuild').text = str( - data.get('fail-build', False)) + mapping = [ + ('max-lines', 'maxLines', 1000), + ('fail-build', 'failBuild', False), + ] + helpers.convert_mapping_to_xml(logstash, data, mapping, fail_required=True) def image_gallery(parser, xml_parent, data): diff --git a/jenkins_jobs/modules/triggers.py b/jenkins_jobs/modules/triggers.py index b1d506d5..270be46b 100644 --- a/jenkins_jobs/modules/triggers.py +++ b/jenkins_jobs/modules/triggers.py @@ -30,6 +30,7 @@ Example:: """ import logging +import pkg_resources import re import xml.etree.ElementTree as XML @@ -1058,34 +1059,88 @@ def gitlab_merge_request(parser, xml_parent, data): def gitlab(parser, xml_parent, data): """yaml: gitlab - Makes Jenkins act like a GitlabCI server - Requires the Jenkins :jenkins-wiki:`Gitlab Plugin. - <Gitlab+Plugin>`. + Makes Jenkins act like a GitLab CI server. + Requires the Jenkins :jenkins-wiki:`GitLab Plugin + <GitLab+Plugin>`. :arg bool trigger-push: Build on Push Events (default true) :arg bool trigger-merge-request: Build on Merge Request Events (default - True) - :arg bool trigger-open-merge-request-push: Rebuild open Merge Requests on - Push Events (default true) - :arg bool ci-skip: Enable [ci-skip] (default true) + true) + :arg str trigger-open-merge-request-push: Rebuild open Merge Requests + on Push Events. + + :trigger-open-merge-request-push values (< 1.1.26): + * **true** (default) + * **false** + :trigger-open-merge-request-push values (>= 1.1.26): + * **never** (default) + * **source** + * **both** + :arg bool trigger-note: Build when comment is added with defined phrase + (>= 1.2.4) (default true) + :arg str note-regex: Phrase that triggers the build (>= 1.2.4) (default + 'Jenkins please retry a build') + :arg bool ci-skip: Enable skipping builds of commits that contain + [ci-skip] in the commit message (default true) + :arg bool wip-skip: Enable skipping builds of WIP Merge Requests (>= 1.2.4) + (default false) :arg bool set-build-description: Set build description to build cause - (eg. Merge request or Git Push ) (default true) + (eg. Merge request or Git Push) (default true) :arg bool add-note-merge-request: Add note with build status on merge requests (default true) :arg bool add-vote-merge-request: Vote added to note with build status - on merge requests (default true) - :arg bool add-ci-message: Add CI build status (default false) + on merge requests (>= 1.1.27) (default true) + :arg bool accept-merge-request-on-success: Automatically accept the Merge + Request if the build is successful (>= 1.1.27) (default false) + :arg bool add-ci-message: Add CI build status (1.1.28 - 1.2.0) (default + false) :arg bool allow-all-branches: Allow all branches (Ignoring Filtered - Branches) (default false) + Branches) (< 1.1.29) (default false) + :arg str branch-filter-type: Filter branches that can trigger a build. + Valid values and their additional attributes are described in the + `branch filter type`_ table (>= 1.1.29) (default 'All'). :arg list include-branches: Defined list of branches to include (default []) :arg list exclude-branches: Defined list of branches to exclude (default []) + :arg str target-branch-regex: Regular expression to select branches + + .. _`branch filter type`: + + ================== ==================================================== + Branch filter type Description + ================== ==================================================== + All All branches are allowed to trigger this job. + NameBasedFilter Filter branches by name. + List source branches that are allowed to trigger a + build from a Push event or a Merge Request event. If + both fields are left empty, all branches are allowed + to trigger this job. For Merge Request events only + the target branch name is filtered out by the + **include-branches** and **exclude-branches** lists. + + RegexBasedFilter Filter branches by regex + The target branch regex allows to limit the + execution of this job to certain branches. Any + branch matching the specified pattern in + **target-branch-regex** triggers the job. No + filtering is performed if the field is left empty. + ================== ==================================================== + + Example (version < 1.1.26): + + .. literalinclude:: /../../tests/triggers/fixtures/gitlab001.yaml + :language: yaml - Example: + Minimal example (version >= 1.1.26): - .. literalinclude:: - /../../tests/triggers/fixtures/gitlab001.yaml + .. literalinclude:: /../../tests/triggers/fixtures/gitlab005.yaml + :language: yaml + + Full example (version >= 1.1.26): + + .. literalinclude:: /../../tests/triggers/fixtures/gitlab004.yaml + :language: yaml """ def _add_xml(elem, name, value): XML.SubElement(elem, name).text = value @@ -1093,29 +1148,57 @@ def gitlab(parser, xml_parent, data): gitlab = XML.SubElement( xml_parent, 'com.dabsquared.gitlabjenkins.GitLabPushTrigger' ) + plugin_info = parser.registry.get_plugin_info('GitLab Plugin') + plugin_ver = pkg_resources.parse_version(plugin_info.get('version', "0")) + valid_merge_request = ['never', 'source', 'both'] + + if plugin_ver >= pkg_resources.parse_version("1.1.26"): + mapping = [ + ('trigger-open-merge-request-push', + 'triggerOpenMergeRequestOnPush', 'never', valid_merge_request)] + convert_mapping_to_xml(gitlab, data, mapping, fail_required=True) + else: + mapping = [ + ('trigger-open-merge-request-push', + 'triggerOpenMergeRequestOnPush', True)] + convert_mapping_to_xml(gitlab, data, mapping, fail_required=True) + + if plugin_ver == pkg_resources.parse_version('1.1.29'): + if data.get('branch-filter-type', '') == 'All': + data['branch-filter-type'] = '' + valid_filters = ['', 'NameBasedFilter', 'RegexBasedFilter'] + mapping = [ + ('branch-filter-type', 'branchFilterName', '', valid_filters)] + convert_mapping_to_xml(gitlab, data, mapping, fail_required=True) + else: + valid_filters = ['All', 'NameBasedFilter', 'RegexBasedFilter'] + mapping = [ + ('branch-filter-type', 'branchFilterType', 'All', valid_filters)] + convert_mapping_to_xml(gitlab, data, mapping, fail_required=True) - bool_mapping = ( + XML.SubElement(gitlab, 'spec').text = '' + mapping = [ ('trigger-push', 'triggerOnPush', True), ('trigger-merge-request', 'triggerOnMergeRequest', True), - ('trigger-open-merge-request-push', 'triggerOpenMergeRequestOnPush', - True), + ('trigger-note', 'triggerOnNoteRequest', True), + ('note-regex', 'noteRegex', 'Jenkins please retry a build'), ('ci-skip', 'ciSkip', True), + ('wip-skip', 'skipWorkInProgressMergeRequest', True), ('set-build-description', 'setBuildDescription', True), ('add-note-merge-request', 'addNoteOnMergeRequest', True), ('add-vote-merge-request', 'addVoteOnMergeRequest', True), + ('accept-merge-request-on-success', 'acceptMergeRequestOnSuccess', + False), ('add-ci-message', 'addCiMessage', False), ('allow-all-branches', 'allowAllBranches', False), - ) + ('target-branch-regex', 'targetBranchRegex', '') + ] + list_mapping = ( ('include-branches', 'includeBranchesSpec', []), ('exclude-branches', 'excludeBranchesSpec', []), ) - - XML.SubElement(gitlab, 'spec').text = '' - - for yaml_name, xml_name, default_val in bool_mapping: - value = str(data.get(yaml_name, default_val)).lower() - _add_xml(gitlab, xml_name, value) + convert_mapping_to_xml(gitlab, data, mapping, fail_required=True) for yaml_name, xml_name, default_val in list_mapping: value = ', '.join(data.get(yaml_name, default_val)) diff --git a/jenkins_jobs/modules/wrappers.py b/jenkins_jobs/modules/wrappers.py index 027c99e8..060ef2aa 100644 --- a/jenkins_jobs/modules/wrappers.py +++ b/jenkins_jobs/modules/wrappers.py @@ -1089,11 +1089,10 @@ def jclouds(parser, xml_parent, data): count: 2 stop-on-terminate: False """ - buildWrapper = XML.SubElement(xml_parent, - 'jenkins.plugins.jclouds.compute.' - 'JCloudsBuildWrapper') - instances = XML.SubElement(buildWrapper, 'instancesToRun') if 'instances' in data: + buildWrapper = XML.SubElement( + xml_parent, 'jenkins.plugins.jclouds.compute.JCloudsBuildWrapper') + instances = XML.SubElement(buildWrapper, 'instancesToRun') for foo in data['instances']: for template, params in foo.items(): instance = XML.SubElement(instances, @@ -1521,18 +1520,27 @@ def delivery_pipeline(parser, xml_parent, data): :arg bool set-display-name: Set the generated version as the display name for the build (default false) - Example: + Minimal Example: + + .. literalinclude:: + /../../tests/wrappers/fixtures/delivery-pipeline-minimal.yaml + :language: yaml - .. literalinclude:: /../../tests/wrappers/fixtures/delivery-pipeline1.yaml + Full Example: + .. literalinclude:: + /../../tests/wrappers/fixtures/delivery-pipeline-full.yaml + :language: yaml """ - pvc = XML.SubElement(xml_parent, - 'se.diabol.jenkins.pipeline.' - 'PipelineVersionContributor') - XML.SubElement(pvc, 'versionTemplate').text = data.get( - 'version-template', '') - XML.SubElement(pvc, 'updateDisplayName').text = str(data.get( - 'set-display-name', False)).lower() + pvc = XML.SubElement( + xml_parent, 'se.diabol.jenkins.pipeline.PipelineVersionContributor') + pvc.set('plugin', 'delivery-pipeline-plugin') + + mapping = [ + ('version-template', 'versionTemplate', ''), + ('set-display-name', 'updateDisplayName', False), + ] + convert_mapping_to_xml(pvc, data, mapping, fail_required=True) def matrix_tie_parent(parser, xml_parent, data): diff --git a/tests/builders/fixtures/kmap-full.xml b/tests/builders/fixtures/kmap-full.xml new file mode 100644 index 00000000..2ea0c573 --- /dev/null +++ b/tests/builders/fixtures/kmap-full.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <builders> + <org.jenkinsci.plugins.KmapJenkinsBuilder plugin="kmap-jenkins"> + <username>user@user.com</username> + <password>password</password> + <kmapClient>http://foo.com/kmap-client/</kmapClient> + <categories>Productivity</categories> + <filePath>${WORKSPACE}/path/to/file.extension</filePath> + <appName>AppName</appName> + <bundle>foo.apk</bundle> + <version>b${BUILD_NUMBER}_r${SVN_REVISION}</version> + <description>description</description> + <iconPath>${WORKSPACE}/target/application.png</iconPath> + <publishOptional> + <teams>MobileUsers</teams> + <users>user@user.com</users> + <sendNotifications>true</sendNotifications> + </publishOptional> + </org.jenkinsci.plugins.KmapJenkinsBuilder> + </builders> +</project> diff --git a/tests/builders/fixtures/kmap-full.yaml b/tests/builders/fixtures/kmap-full.yaml new file mode 100644 index 00000000..21500203 --- /dev/null +++ b/tests/builders/fixtures/kmap-full.yaml @@ -0,0 +1,16 @@ +builders: + - kmap: + username: user@user.com + password: password + url: http://foo.com/kmap-client/ + categories: Productivity + file-path: ${WORKSPACE}/path/to/file.extension + app-name: AppName + bundle: foo.apk + version: b${BUILD_NUMBER}_r${SVN_REVISION} + description: description + icon-path: ${WORKSPACE}/target/application.png + publish-optional: true + groups: MobileUsers + users: user@user.com + notify-users: true diff --git a/tests/builders/fixtures/kmap-minimal.xml b/tests/builders/fixtures/kmap-minimal.xml new file mode 100644 index 00000000..aad463f8 --- /dev/null +++ b/tests/builders/fixtures/kmap-minimal.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <builders> + <org.jenkinsci.plugins.KmapJenkinsBuilder plugin="kmap-jenkins"> + <username>user@user.com</username> + <password>password</password> + <kmapClient>http://foo.com/kmap-client/</kmapClient> + <categories>Productivity</categories> + <filePath>${WORKSPACE}/path/to/file.extension</filePath> + <appName>AppName</appName> + <bundle/> + <version>b${BUILD_NUMBER}_r${SVN_REVISION}</version> + <description/> + <iconPath/> + </org.jenkinsci.plugins.KmapJenkinsBuilder> + </builders> +</project> diff --git a/tests/builders/fixtures/kmap-minimal.yaml b/tests/builders/fixtures/kmap-minimal.yaml new file mode 100644 index 00000000..9d550047 --- /dev/null +++ b/tests/builders/fixtures/kmap-minimal.yaml @@ -0,0 +1,9 @@ +builders: + - kmap: + username: user@user.com + password: password + url: http://foo.com/kmap-client/ + categories: Productivity + file-path: ${WORKSPACE}/path/to/file.extension + app-name: AppName + version: b${BUILD_NUMBER}_r${SVN_REVISION} diff --git a/tests/builders/fixtures/runscope-full.xml b/tests/builders/fixtures/runscope-full.xml new file mode 100644 index 00000000..0830fce1 --- /dev/null +++ b/tests/builders/fixtures/runscope-full.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <builders> + <com.runscope.jenkins.Runscope.RunscopeBuilder plugin="runscope"> + <triggerEndPoint>https://api.runscope.com/radar/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/trigger</triggerEndPoint> + <accessToken>123456</accessToken> + <timeout>123</timeout> + </com.runscope.jenkins.Runscope.RunscopeBuilder> + </builders> +</project> diff --git a/tests/builders/fixtures/runscope-full.yaml b/tests/builders/fixtures/runscope-full.yaml new file mode 100644 index 00000000..795c1517 --- /dev/null +++ b/tests/builders/fixtures/runscope-full.yaml @@ -0,0 +1,5 @@ +builders: + - runscope: + test-trigger-url: "https://api.runscope.com/radar/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/trigger" + access-token: "123456" + timeout: 123 diff --git a/tests/builders/fixtures/runscope.xml b/tests/builders/fixtures/runscope-minimal.xml index d14e49b1..05bc9122 100644 --- a/tests/builders/fixtures/runscope.xml +++ b/tests/builders/fixtures/runscope-minimal.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <project> <builders> - <com.runscope.jenkins.Runscope.RunscopeBuilder> + <com.runscope.jenkins.Runscope.RunscopeBuilder plugin="runscope"> <triggerEndPoint>https://api.runscope.com/radar/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/trigger</triggerEndPoint> <accessToken>123456</accessToken> <timeout>60</timeout> diff --git a/tests/builders/fixtures/runscope.yaml b/tests/builders/fixtures/runscope-minimal.yaml index 9871b181..47827c40 100644 --- a/tests/builders/fixtures/runscope.yaml +++ b/tests/builders/fixtures/runscope-minimal.yaml @@ -2,4 +2,3 @@ builders: - runscope: test-trigger-url: "https://api.runscope.com/radar/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/trigger" access-token: "123456" - timeout: 60 diff --git a/tests/builders/fixtures/xcode.xml b/tests/builders/fixtures/xcode.xml new file mode 100644 index 00000000..dbe78c9d --- /dev/null +++ b/tests/builders/fixtures/xcode.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <builders> + <au.com.rayh.XCodeBuilder> + <cleanBeforeBuild>false</cleanBeforeBuild> + <cleanTestReports>false</cleanTestReports> + <generateArchive>false</generateArchive> + <configuration>Release</configuration> + <configurationBuildDir/> + <target/> + <sdk/> + <symRoot/> + <xcodeProjectPath/> + <xcodeProjectFile/> + <xcodebuildArguments/> + <xcodeSchema/> + <xcodeWorkspaceFile/> + <embeddedProfileFile/> + <codeSigningIdentity/> + <allowFailingBuildResults>false</allowFailingBuildResults> + <provideApplicationVersion>false</provideApplicationVersion> + <cfBundleVersionValue/> + <cfBundleShortVersionStringValue/> + <buildIpa>false</buildIpa> + <ipaName/> + <ipaOutputDirectory/> + <keychainName/> + <keychainPath/> + <keychainPwd/> + <unlockKeychain>false</unlockKeychain> + </au.com.rayh.XCodeBuilder> + <au.com.rayh.DeveloperProfileLoader> + <id>849b07cd-ac61-4588-89c8-b6606ee84946</id> + </au.com.rayh.DeveloperProfileLoader> + <au.com.rayh.XCodeBuilder> + <cleanBeforeBuild>true</cleanBeforeBuild> + <cleanTestReports>true</cleanTestReports> + <generateArchive>false</generateArchive> + <configuration>Distribution</configuration> + <configurationBuildDir/> + <target>TARGET</target> + <sdk>iphonesimulator</sdk> + <symRoot/> + <xcodeProjectPath/> + <xcodeProjectFile/> + <xcodebuildArguments>test ONLY_ACTIVE_ARCH=NO -destination 'platform=iOS Simulator,name=iPhone 6' -derivedDataPath .</xcodebuildArguments> + <xcodeSchema>UASDKInternal</xcodeSchema> + <xcodeWorkspaceFile>UA</xcodeWorkspaceFile> + <embeddedProfileFile>PROFILE</embeddedProfileFile> + <codeSigningIdentity>iPhone Distribution: MapMyFitness Inc.</codeSigningIdentity> + <allowFailingBuildResults>true</allowFailingBuildResults> + <provideApplicationVersion>true</provideApplicationVersion> + <cfBundleVersionValue>TECHNICAL</cfBundleVersionValue> + <cfBundleShortVersionStringValue>MARKETING</cfBundleShortVersionStringValue> + <buildIpa>true</buildIpa> + <ipaName>${VERSION}</ipaName> + <ipaOutputDirectory>/output</ipaOutputDirectory> + <keychainName/> + <keychainPath>/Users/jenkins/Library/Keychains/jenkins-uasdk-ios-pre_review</keychainPath> + <keychainPwd>testpass</keychainPwd> + <unlockKeychain>true</unlockKeychain> + </au.com.rayh.XCodeBuilder> + </builders> +</project> diff --git a/tests/builders/fixtures/xcode.yaml b/tests/builders/fixtures/xcode.yaml new file mode 100644 index 00000000..4bdc1536 --- /dev/null +++ b/tests/builders/fixtures/xcode.yaml @@ -0,0 +1,22 @@ +builders: + - xcode + - xcode: + developer-profile: "849b07cd-ac61-4588-89c8-b6606ee84946" + clean-build: true + clean-test-reports: true + configuration: Distribution + target: TARGET + sdk: iphonesimulator + build-arguments: "test ONLY_ACTIVE_ARCH=NO -destination 'platform=iOS Simulator,name=iPhone 6' -derivedDataPath ." + schema: "UASDKInternal" + workspace: "UA" + profile: "PROFILE" + codesign-id: "iPhone Distribution: MapMyFitness Inc." + allow-failing: true + version-technical: "TECHNICAL" + version-marketing: "MARKETING" + ipa-version: "${VERSION}" + ipa-output: "/output" + keychain-path: "/Users/jenkins/Library/Keychains/jenkins-uasdk-ios-pre_review" + keychain-password: "testpass" + keychain-unlock: true diff --git a/tests/modules/test_helpers.py b/tests/modules/test_helpers.py index a59fa3e7..47c05875 100644 --- a/tests/modules/test_helpers.py +++ b/tests/modules/test_helpers.py @@ -70,7 +70,7 @@ class TestCaseTestHelpers(LoggingFixture, testtools.TestCase): required_mappings, fail_required=True) - # Test invalid user input + # Test invalid user input for list user_input_root = XML.Element('testUserInput') user_input_data = yaml.load("user-input-string: bye") valid_inputs = ['hello'] @@ -82,3 +82,29 @@ class TestCaseTestHelpers(LoggingFixture, testtools.TestCase): user_input_root, user_input_data, user_input_mappings) + + # Test invalid user input for dict + user_input_root = XML.Element('testUserInput') + user_input_data = yaml.load("user-input-string: later") + valid_inputs = {'hello': 'world'} + user_input_mappings = [('user-input-string', 'userInputString', + 'user-input', valid_inputs)] + + self.assertRaises(InvalidAttributeError, + convert_mapping_to_xml, + user_input_root, + user_input_data, + user_input_mappings) + + # Test invalid key for dict + user_input_root = XML.Element('testUserInput') + user_input_data = yaml.load("user-input-string: world") + valid_inputs = {'hello': 'world'} + user_input_mappings = [('user-input-string', 'userInputString', + 'user-input', valid_inputs)] + + self.assertRaises(InvalidAttributeError, + convert_mapping_to_xml, + user_input_root, + user_input_data, + user_input_mappings) diff --git a/tests/properties/fixtures/delivery-pipeline1.xml b/tests/properties/fixtures/delivery-pipeline-full.xml index c62e23f9..132764e3 100644 --- a/tests/properties/fixtures/delivery-pipeline1.xml +++ b/tests/properties/fixtures/delivery-pipeline-full.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <project> <properties> - <se.diabol.jenkins.pipeline.PipelineProperty> + <se.diabol.jenkins.pipeline.PipelineProperty plugin="delivery-pipeline-plugin"> <stageName>Stage</stageName> <taskName>Task</taskName> <descriptionTemplate>Task-Description</descriptionTemplate> diff --git a/tests/properties/fixtures/delivery-pipeline1.yaml b/tests/properties/fixtures/delivery-pipeline-full.yaml index c8013bcb..c8013bcb 100644 --- a/tests/properties/fixtures/delivery-pipeline1.yaml +++ b/tests/properties/fixtures/delivery-pipeline-full.yaml diff --git a/tests/properties/fixtures/delivery-pipeline2.xml b/tests/properties/fixtures/delivery-pipeline-minimal.xml index f34569ff..db61340d 100644 --- a/tests/properties/fixtures/delivery-pipeline2.xml +++ b/tests/properties/fixtures/delivery-pipeline-minimal.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <project> <properties> - <se.diabol.jenkins.pipeline.PipelineProperty> + <se.diabol.jenkins.pipeline.PipelineProperty plugin="delivery-pipeline-plugin"> <stageName/> <taskName/> <descriptionTemplate/> diff --git a/tests/properties/fixtures/delivery-pipeline2.yaml b/tests/properties/fixtures/delivery-pipeline-minimal.yaml index 78398605..78398605 100644 --- a/tests/properties/fixtures/delivery-pipeline2.yaml +++ b/tests/properties/fixtures/delivery-pipeline-minimal.yaml diff --git a/tests/publishers/fixtures/codecover-full.xml b/tests/publishers/fixtures/codecover-full.xml new file mode 100644 index 00000000..0f4920fc --- /dev/null +++ b/tests/publishers/fixtures/codecover-full.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <publishers> + <hudson.plugins.codecover.CodeCoverPublisher plugin="codecover"> + <includes>./path/report.html</includes> + <healthReports> + <minStatement>1</minStatement> + <maxStatement>100</maxStatement> + <minBranch>2</minBranch> + <maxBranch>90</maxBranch> + <minLoop>3</minLoop> + <maxLoop>80</maxLoop> + <minCondition>4</minCondition> + <maxCondition>70</maxCondition> + </healthReports> + </hudson.plugins.codecover.CodeCoverPublisher> + </publishers> +</project> diff --git a/tests/publishers/fixtures/codecover-full.yaml b/tests/publishers/fixtures/codecover-full.yaml new file mode 100644 index 00000000..5424428f --- /dev/null +++ b/tests/publishers/fixtures/codecover-full.yaml @@ -0,0 +1,11 @@ +publishers: + - codecover: + include: ./path/report.html + min-statement: 1 + max-statement: 100 + min-branch: 2 + max-branch: 90 + min-loop: 3 + max-loop: 80 + min-condition: 4 + max-condition: 70 diff --git a/tests/publishers/fixtures/codecover-minimal.xml b/tests/publishers/fixtures/codecover-minimal.xml new file mode 100644 index 00000000..01bbd962 --- /dev/null +++ b/tests/publishers/fixtures/codecover-minimal.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <publishers> + <hudson.plugins.codecover.CodeCoverPublisher plugin="codecover"> + <includes/> + <healthReports> + <minStatement>0</minStatement> + <maxStatement>90</maxStatement> + <minBranch>0</minBranch> + <maxBranch>80</maxBranch> + <minLoop>0</minLoop> + <maxLoop>50</maxLoop> + <minCondition>0</minCondition> + <maxCondition>50</maxCondition> + </healthReports> + </hudson.plugins.codecover.CodeCoverPublisher> + </publishers> +</project> diff --git a/tests/publishers/fixtures/codecover-minimal.yaml b/tests/publishers/fixtures/codecover-minimal.yaml new file mode 100644 index 00000000..83fc95e4 --- /dev/null +++ b/tests/publishers/fixtures/codecover-minimal.yaml @@ -0,0 +1,2 @@ +publishers: + - codecover diff --git a/tests/publishers/fixtures/growl-full.xml b/tests/publishers/fixtures/growl-full.xml new file mode 100644 index 00000000..38eca0ed --- /dev/null +++ b/tests/publishers/fixtures/growl-full.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <publishers> + <hudson.plugins.growl.GrowlPublisher plugin="growl"> + <IP>foo.ip.address</IP> + <onlyOnFailureOrRecovery>true</onlyOnFailureOrRecovery> + </hudson.plugins.growl.GrowlPublisher> + </publishers> +</project> diff --git a/tests/publishers/fixtures/growl-full.yaml b/tests/publishers/fixtures/growl-full.yaml new file mode 100644 index 00000000..72d60d7a --- /dev/null +++ b/tests/publishers/fixtures/growl-full.yaml @@ -0,0 +1,4 @@ +publishers: + - growl: + ip: foo.ip.address + notify-only-on-fail-or-recovery: true diff --git a/tests/publishers/fixtures/growl-minimal.xml b/tests/publishers/fixtures/growl-minimal.xml new file mode 100644 index 00000000..7010cbf4 --- /dev/null +++ b/tests/publishers/fixtures/growl-minimal.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <publishers> + <hudson.plugins.growl.GrowlPublisher plugin="growl"> + <IP>foo.ip.address</IP> + <onlyOnFailureOrRecovery>false</onlyOnFailureOrRecovery> + </hudson.plugins.growl.GrowlPublisher> + </publishers> +</project> diff --git a/tests/publishers/fixtures/growl-minimal.yaml b/tests/publishers/fixtures/growl-minimal.yaml new file mode 100644 index 00000000..2aafb81c --- /dev/null +++ b/tests/publishers/fixtures/growl-minimal.yaml @@ -0,0 +1,3 @@ +publishers: + - growl: + ip: foo.ip.address diff --git a/tests/publishers/fixtures/junit001.xml b/tests/publishers/fixtures/junit001.xml index fc1db95b..04a424d8 100644 --- a/tests/publishers/fixtures/junit001.xml +++ b/tests/publishers/fixtures/junit001.xml @@ -4,6 +4,7 @@ <hudson.tasks.junit.JUnitResultArchiver plugin="junit"> <testResults>nosetests.xml</testResults> <keepLongStdio>true</keepLongStdio> + <allowEmptyResults>false</allowEmptyResults> <healthScaleFactor>1.0</healthScaleFactor> <allowEmptyResults>false</allowEmptyResults> <testDataPublishers/> diff --git a/tests/publishers/fixtures/junit002.xml b/tests/publishers/fixtures/junit002.xml index cb168626..33153e75 100644 --- a/tests/publishers/fixtures/junit002.xml +++ b/tests/publishers/fixtures/junit002.xml @@ -4,6 +4,7 @@ <hudson.tasks.junit.JUnitResultArchiver plugin="junit"> <testResults>nosetests-example.xml</testResults> <keepLongStdio>false</keepLongStdio> + <allowEmptyResults>true</allowEmptyResults> <healthScaleFactor>2.0</healthScaleFactor> <allowEmptyResults>true</allowEmptyResults> <testDataPublishers> diff --git a/tests/publishers/fixtures/junit002.yaml b/tests/publishers/fixtures/junit002.yaml index 8f427586..3bd171f5 100644 --- a/tests/publishers/fixtures/junit002.yaml +++ b/tests/publishers/fixtures/junit002.yaml @@ -8,3 +8,4 @@ publishers: claim-build: true measurement-plots: true flaky-test-reports: true + allow-empty-results: true diff --git a/tests/publishers/fixtures/logstash-full.xml b/tests/publishers/fixtures/logstash-full.xml index f0e05749..4c8db3ab 100644 --- a/tests/publishers/fixtures/logstash-full.xml +++ b/tests/publishers/fixtures/logstash-full.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> <project> <publishers> - <jenkins.plugins.logstash.LogstashNotifier> + <jenkins.plugins.logstash.LogstashNotifier plugin="logstash"> <maxLines>2000</maxLines> - <failBuild>True</failBuild> + <failBuild>true</failBuild> </jenkins.plugins.logstash.LogstashNotifier> </publishers> </project> diff --git a/tests/publishers/fixtures/logstash-min.xml b/tests/publishers/fixtures/logstash-min.xml index 18f2a07b..45541487 100644 --- a/tests/publishers/fixtures/logstash-min.xml +++ b/tests/publishers/fixtures/logstash-min.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> <project> <publishers> - <jenkins.plugins.logstash.LogstashNotifier> + <jenkins.plugins.logstash.LogstashNotifier plugin="logstash"> <maxLines>1000</maxLines> - <failBuild>False</failBuild> + <failBuild>false</failBuild> </jenkins.plugins.logstash.LogstashNotifier> </publishers> </project> diff --git a/tests/triggers/fixtures/gitlab001.xml b/tests/triggers/fixtures/gitlab001.xml index d01b4c91..2b199809 100644 --- a/tests/triggers/fixtures/gitlab001.xml +++ b/tests/triggers/fixtures/gitlab001.xml @@ -2,16 +2,22 @@ <project> <triggers class="vector"> <com.dabsquared.gitlabjenkins.GitLabPushTrigger> + <triggerOpenMergeRequestOnPush>true</triggerOpenMergeRequestOnPush> + <branchFilterType>All</branchFilterType> <spec/> <triggerOnPush>true</triggerOnPush> <triggerOnMergeRequest>true</triggerOnMergeRequest> - <triggerOpenMergeRequestOnPush>true</triggerOpenMergeRequestOnPush> + <triggerOnNoteRequest>true</triggerOnNoteRequest> + <noteRegex>Jenkins please retry a build</noteRegex> <ciSkip>true</ciSkip> + <skipWorkInProgressMergeRequest>true</skipWorkInProgressMergeRequest> <setBuildDescription>true</setBuildDescription> <addNoteOnMergeRequest>true</addNoteOnMergeRequest> <addVoteOnMergeRequest>true</addVoteOnMergeRequest> + <acceptMergeRequestOnSuccess>false</acceptMergeRequestOnSuccess> <addCiMessage>true</addCiMessage> <allowAllBranches>true</allowAllBranches> + <targetBranchRegex/> <includeBranchesSpec>master, master2, local-test</includeBranchesSpec> <excludeBranchesSpec>broken-test, master-foo</excludeBranchesSpec> </com.dabsquared.gitlabjenkins.GitLabPushTrigger> diff --git a/tests/triggers/fixtures/gitlab002.xml b/tests/triggers/fixtures/gitlab002.xml index 6d9442f9..e82157ec 100644 --- a/tests/triggers/fixtures/gitlab002.xml +++ b/tests/triggers/fixtures/gitlab002.xml @@ -2,16 +2,22 @@ <project> <triggers class="vector"> <com.dabsquared.gitlabjenkins.GitLabPushTrigger> + <triggerOpenMergeRequestOnPush>true</triggerOpenMergeRequestOnPush> + <branchFilterType>All</branchFilterType> <spec/> <triggerOnPush>true</triggerOnPush> <triggerOnMergeRequest>true</triggerOnMergeRequest> - <triggerOpenMergeRequestOnPush>true</triggerOpenMergeRequestOnPush> + <triggerOnNoteRequest>true</triggerOnNoteRequest> + <noteRegex>Jenkins please retry a build</noteRegex> <ciSkip>true</ciSkip> + <skipWorkInProgressMergeRequest>true</skipWorkInProgressMergeRequest> <setBuildDescription>true</setBuildDescription> <addNoteOnMergeRequest>true</addNoteOnMergeRequest> <addVoteOnMergeRequest>true</addVoteOnMergeRequest> + <acceptMergeRequestOnSuccess>false</acceptMergeRequestOnSuccess> <addCiMessage>false</addCiMessage> <allowAllBranches>false</allowAllBranches> + <targetBranchRegex/> <includeBranchesSpec>master</includeBranchesSpec> <excludeBranchesSpec>feature</excludeBranchesSpec> </com.dabsquared.gitlabjenkins.GitLabPushTrigger> diff --git a/tests/triggers/fixtures/gitlab003.xml b/tests/triggers/fixtures/gitlab003.xml index f3ad460e..7e85278a 100644 --- a/tests/triggers/fixtures/gitlab003.xml +++ b/tests/triggers/fixtures/gitlab003.xml @@ -2,16 +2,22 @@ <project> <triggers class="vector"> <com.dabsquared.gitlabjenkins.GitLabPushTrigger> + <triggerOpenMergeRequestOnPush>true</triggerOpenMergeRequestOnPush> + <branchFilterType>All</branchFilterType> <spec/> <triggerOnPush>true</triggerOnPush> <triggerOnMergeRequest>true</triggerOnMergeRequest> - <triggerOpenMergeRequestOnPush>true</triggerOpenMergeRequestOnPush> + <triggerOnNoteRequest>true</triggerOnNoteRequest> + <noteRegex>Jenkins please retry a build</noteRegex> <ciSkip>true</ciSkip> + <skipWorkInProgressMergeRequest>true</skipWorkInProgressMergeRequest> <setBuildDescription>true</setBuildDescription> <addNoteOnMergeRequest>true</addNoteOnMergeRequest> <addVoteOnMergeRequest>true</addVoteOnMergeRequest> + <acceptMergeRequestOnSuccess>false</acceptMergeRequestOnSuccess> <addCiMessage>false</addCiMessage> <allowAllBranches>false</allowAllBranches> + <targetBranchRegex/> <includeBranchesSpec>master</includeBranchesSpec> <excludeBranchesSpec>baz, foo, fnord</excludeBranchesSpec> </com.dabsquared.gitlabjenkins.GitLabPushTrigger> diff --git a/tests/triggers/fixtures/gitlab004.plugins_info.yaml b/tests/triggers/fixtures/gitlab004.plugins_info.yaml new file mode 100644 index 00000000..56447ee9 --- /dev/null +++ b/tests/triggers/fixtures/gitlab004.plugins_info.yaml @@ -0,0 +1,3 @@ +- longName: 'GitLab Plugin' + shortName: 'gitlab-plugin' + version: "1.1.26" diff --git a/tests/triggers/fixtures/gitlab004.xml b/tests/triggers/fixtures/gitlab004.xml new file mode 100644 index 00000000..94d8f4fd --- /dev/null +++ b/tests/triggers/fixtures/gitlab004.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <triggers class="vector"> + <com.dabsquared.gitlabjenkins.GitLabPushTrigger> + <triggerOpenMergeRequestOnPush>both</triggerOpenMergeRequestOnPush> + <branchFilterType>All</branchFilterType> + <spec/> + <triggerOnPush>false</triggerOnPush> + <triggerOnMergeRequest>false</triggerOnMergeRequest> + <triggerOnNoteRequest>true</triggerOnNoteRequest> + <noteRegex>Jenkins please retry a build</noteRegex> + <ciSkip>false</ciSkip> + <skipWorkInProgressMergeRequest>true</skipWorkInProgressMergeRequest> + <setBuildDescription>false</setBuildDescription> + <addNoteOnMergeRequest>false</addNoteOnMergeRequest> + <addVoteOnMergeRequest>false</addVoteOnMergeRequest> + <acceptMergeRequestOnSuccess>false</acceptMergeRequestOnSuccess> + <addCiMessage>true</addCiMessage> + <allowAllBranches>true</allowAllBranches> + <targetBranchRegex/> + <includeBranchesSpec>master, master2, local-test</includeBranchesSpec> + <excludeBranchesSpec>broken-test, master-foo</excludeBranchesSpec> + </com.dabsquared.gitlabjenkins.GitLabPushTrigger> + </triggers> +</project> diff --git a/tests/triggers/fixtures/gitlab004.yaml b/tests/triggers/fixtures/gitlab004.yaml new file mode 100644 index 00000000..d4f21d13 --- /dev/null +++ b/tests/triggers/fixtures/gitlab004.yaml @@ -0,0 +1,18 @@ +triggers: + - gitlab: + trigger-push: false + trigger-merge-request: false + trigger-open-merge-request-push: both + ci-skip: false + set-build-description: false + add-note-merge-request: false + add-vote-merge-request: false + add-ci-message: true + allow-all-branches: true + include-branches: + - 'master' + - 'master2' + - 'local-test' + exclude-branches: + - 'broken-test' + - 'master-foo' diff --git a/tests/triggers/fixtures/gitlab005.plugins_info.yaml b/tests/triggers/fixtures/gitlab005.plugins_info.yaml new file mode 100644 index 00000000..56447ee9 --- /dev/null +++ b/tests/triggers/fixtures/gitlab005.plugins_info.yaml @@ -0,0 +1,3 @@ +- longName: 'GitLab Plugin' + shortName: 'gitlab-plugin' + version: "1.1.26" diff --git a/tests/triggers/fixtures/gitlab005.xml b/tests/triggers/fixtures/gitlab005.xml new file mode 100644 index 00000000..7870ff70 --- /dev/null +++ b/tests/triggers/fixtures/gitlab005.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <triggers class="vector"> + <com.dabsquared.gitlabjenkins.GitLabPushTrigger> + <triggerOpenMergeRequestOnPush>never</triggerOpenMergeRequestOnPush> + <branchFilterType>All</branchFilterType> + <spec/> + <triggerOnPush>true</triggerOnPush> + <triggerOnMergeRequest>true</triggerOnMergeRequest> + <triggerOnNoteRequest>true</triggerOnNoteRequest> + <noteRegex>Jenkins please retry a build</noteRegex> + <ciSkip>true</ciSkip> + <skipWorkInProgressMergeRequest>true</skipWorkInProgressMergeRequest> + <setBuildDescription>true</setBuildDescription> + <addNoteOnMergeRequest>true</addNoteOnMergeRequest> + <addVoteOnMergeRequest>true</addVoteOnMergeRequest> + <acceptMergeRequestOnSuccess>false</acceptMergeRequestOnSuccess> + <addCiMessage>false</addCiMessage> + <allowAllBranches>false</allowAllBranches> + <targetBranchRegex/> + <includeBranchesSpec/> + <excludeBranchesSpec/> + </com.dabsquared.gitlabjenkins.GitLabPushTrigger> + </triggers> +</project> diff --git a/tests/triggers/fixtures/gitlab005.yaml b/tests/triggers/fixtures/gitlab005.yaml new file mode 100644 index 00000000..eff43973 --- /dev/null +++ b/tests/triggers/fixtures/gitlab005.yaml @@ -0,0 +1,2 @@ +triggers: + - gitlab diff --git a/tests/triggers/fixtures/gitlab006.plugins_info.yaml b/tests/triggers/fixtures/gitlab006.plugins_info.yaml new file mode 100644 index 00000000..4ba0b897 --- /dev/null +++ b/tests/triggers/fixtures/gitlab006.plugins_info.yaml @@ -0,0 +1,3 @@ +- longName: 'GitLab Plugin' + shortName: 'gitlab-plugin' + version: "1.2.4" diff --git a/tests/triggers/fixtures/gitlab006.xml b/tests/triggers/fixtures/gitlab006.xml new file mode 100644 index 00000000..af5fdac2 --- /dev/null +++ b/tests/triggers/fixtures/gitlab006.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <triggers class="vector"> + <com.dabsquared.gitlabjenkins.GitLabPushTrigger> + <triggerOpenMergeRequestOnPush>both</triggerOpenMergeRequestOnPush> + <branchFilterType>RegexBasedFilter</branchFilterType> + <spec/> + <triggerOnPush>false</triggerOnPush> + <triggerOnMergeRequest>false</triggerOnMergeRequest> + <triggerOnNoteRequest>true</triggerOnNoteRequest> + <noteRegex>Retrigger</noteRegex> + <ciSkip>false</ciSkip> + <skipWorkInProgressMergeRequest>false</skipWorkInProgressMergeRequest> + <setBuildDescription>false</setBuildDescription> + <addNoteOnMergeRequest>false</addNoteOnMergeRequest> + <addVoteOnMergeRequest>false</addVoteOnMergeRequest> + <acceptMergeRequestOnSuccess>true</acceptMergeRequestOnSuccess> + <addCiMessage>true</addCiMessage> + <allowAllBranches>false</allowAllBranches> + <targetBranchRegex>(.*debug.*|.*release.*)</targetBranchRegex> + <includeBranchesSpec>include1, include2</includeBranchesSpec> + <excludeBranchesSpec>exclude1, exclude2</excludeBranchesSpec> + </com.dabsquared.gitlabjenkins.GitLabPushTrigger> + </triggers> +</project> diff --git a/tests/triggers/fixtures/gitlab006.yaml b/tests/triggers/fixtures/gitlab006.yaml new file mode 100644 index 00000000..bb84e73d --- /dev/null +++ b/tests/triggers/fixtures/gitlab006.yaml @@ -0,0 +1,22 @@ +triggers: + - gitlab: + trigger-push: false + trigger-merge-request: false + trigger-open-merge-request-push: both + trigger-note-request: false + note-regex: Retrigger + ci-skip: false + wip-skip: false + set-build-description: false + add-note-merge-request: false + add-vote-merge-request: false + accept-merge-request-on-success: true + add-ci-message: true + branch-filter-type: RegexBasedFilter + include-branches: + - include1 + - include2 + exclude-branches: + - exclude1 + - exclude2 + target-branch-regex: '(.*debug.*|.*release.*)' diff --git a/tests/wrappers/fixtures/delivery-pipeline1.xml b/tests/wrappers/fixtures/delivery-pipeline-full.xml index 5afab711..84fa9f22 100644 --- a/tests/wrappers/fixtures/delivery-pipeline1.xml +++ b/tests/wrappers/fixtures/delivery-pipeline-full.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <project> <buildWrappers> - <se.diabol.jenkins.pipeline.PipelineVersionContributor> + <se.diabol.jenkins.pipeline.PipelineVersionContributor plugin="delivery-pipeline-plugin"> <versionTemplate>1.0.0-${BUILD_NUMBER}</versionTemplate> <updateDisplayName>true</updateDisplayName> </se.diabol.jenkins.pipeline.PipelineVersionContributor> diff --git a/tests/wrappers/fixtures/delivery-pipeline1.yaml b/tests/wrappers/fixtures/delivery-pipeline-full.yaml index 1965def2..1965def2 100644 --- a/tests/wrappers/fixtures/delivery-pipeline1.yaml +++ b/tests/wrappers/fixtures/delivery-pipeline-full.yaml diff --git a/tests/wrappers/fixtures/delivery-pipeline2.xml b/tests/wrappers/fixtures/delivery-pipeline-minimal.xml index 8bc3c0df..5f545634 100644 --- a/tests/wrappers/fixtures/delivery-pipeline2.xml +++ b/tests/wrappers/fixtures/delivery-pipeline-minimal.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <project> <buildWrappers> - <se.diabol.jenkins.pipeline.PipelineVersionContributor> + <se.diabol.jenkins.pipeline.PipelineVersionContributor plugin="delivery-pipeline-plugin"> <versionTemplate/> <updateDisplayName>false</updateDisplayName> </se.diabol.jenkins.pipeline.PipelineVersionContributor> diff --git a/tests/wrappers/fixtures/delivery-pipeline2.yaml b/tests/wrappers/fixtures/delivery-pipeline-minimal.yaml index 324915a3..324915a3 100644 --- a/tests/wrappers/fixtures/delivery-pipeline2.yaml +++ b/tests/wrappers/fixtures/delivery-pipeline-minimal.yaml |