diff --git a/jenkins_jobs/modules/publishers.py b/jenkins_jobs/modules/publishers.py index 0e4001768..35b512368 100644 --- a/jenkins_jobs/modules/publishers.py +++ b/jenkins_jobs/modules/publishers.py @@ -3603,6 +3603,139 @@ def valgrind(parser, xml_parent, data): data.get('publish-if-failed', False)).lower() +def build_trends_publisher(plugin_name, xml_element, data): + """Helper to create various trend publishers. + """ + + def append_thresholds(element, data, only_totals): + """Appends the status thresholds. + """ + + for status in ['unstable', 'failed']: + status_data = data.get(status, {}) + + limits = [ + ('total-all', 'TotalAll'), + ('total-high', 'TotalHigh'), + ('total-normal', 'TotalNormal'), + ('total-low', 'TotalLow')] + + if only_totals is False: + limits.extend([ + ('new-all', 'NewAll'), + ('new-high', 'NewHigh'), + ('new-normal', 'NewNormal'), + ('new-low', 'NewLow')]) + + for key, tag_suffix in limits: + tag_name = status + tag_suffix + XML.SubElement(element, tag_name).text = str( + status_data.get(key, '')) + + # Tuples containing: setting name, tag name, default value + settings = [ + ('healthy', 'healthy', ''), + ('unhealthy', 'unHealthy', ''), + ('health-threshold', 'thresholdLimit', 'low'), + ('plugin-name', 'pluginName', plugin_name), + ('default-encoding', 'defaultEncoding', ''), + ('can-run-on-failed', 'canRunOnFailed', False), + ('use-stable-build-as-reference', 'useStableBuildAsReference', False), + ('use-delta-values', 'useDeltaValues', False), + ('thresholds', 'thresholds', {}), + ('should-detect-modules', 'shouldDetectModules', False), + ('dont-compute-new', 'dontComputeNew', True), + ('do-not-resolve-relative-paths', 'doNotResolveRelativePaths', False), + ('pattern', 'pattern', '')] + + thresholds = ['low', 'normal', 'high'] + + for key, tag_name, default in settings: + xml_config = XML.SubElement(xml_element, tag_name) + config_value = data.get(key, default) + + if key == 'thresholds': + append_thresholds( + xml_config, + config_value, + data.get('dont-compute-new', True)) + elif key == 'health-threshold' and config_value not in thresholds: + raise JenkinsJobsException("health-threshold must be one of %s" % + ", ".join(thresholds)) + else: + if isinstance(default, bool): + xml_config.text = str(config_value).lower() + else: + xml_config.text = str(config_value) + + +def pmd(parser, xml_parent, data): + """yaml: pmd + Publish trend reports with PMD. + Requires the Jenkins `PMD Plugin. + <https://wiki.jenkins-ci.org/display/JENKINS/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-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 + + Full example: + + .. literalinclude:: /../../tests/publishers/fixtures/pmd002.yaml + + """ + + xml_element = XML.SubElement(xml_parent, 'hudson.plugins.pmd.PmdPublisher') + + build_trends_publisher('[PMD] ', xml_element, data) + + class Publishers(jenkins_jobs.modules.base.Base): sequence = 70 diff --git a/setup.cfg b/setup.cfg index 1330c426a..3bb19fbb1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -143,8 +143,9 @@ jenkins_jobs.publishers = performance=jenkins_jobs.modules.publishers:performance pipeline=jenkins_jobs.modules.publishers:pipeline plot=jenkins_jobs.modules.publishers:plot - postbuildscript=jenkins_jobs.modules.publishers:postbuildscript + pmd=jenkins_jobs.modules.publishers:pmd post-tasks=jenkins_jobs.modules.publishers:post_tasks + postbuildscript=jenkins_jobs.modules.publishers:postbuildscript robot=jenkins_jobs.modules.publishers:robot ruby-metrics=jenkins_jobs.modules.publishers:ruby_metrics scp=jenkins_jobs.modules.publishers:scp diff --git a/tests/publishers/fixtures/pmd001.xml b/tests/publishers/fixtures/pmd001.xml new file mode 100644 index 000000000..8d046aa6d --- /dev/null +++ b/tests/publishers/fixtures/pmd001.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <publishers> + <hudson.plugins.pmd.PmdPublisher> + <healthy>0</healthy> + <unHealthy>100</unHealthy> + <thresholdLimit>high</thresholdLimit> + <pluginName>[PMD] </pluginName> + <defaultEncoding/> + <canRunOnFailed>false</canRunOnFailed> + <useStableBuildAsReference>false</useStableBuildAsReference> + <useDeltaValues>false</useDeltaValues> + <thresholds> + <unstableTotalAll/> + <unstableTotalHigh>10</unstableTotalHigh> + <unstableTotalNormal/> + <unstableTotalLow/> + <failedTotalAll/> + <failedTotalHigh>1</failedTotalHigh> + <failedTotalNormal/> + <failedTotalLow/> + </thresholds> + <shouldDetectModules>false</shouldDetectModules> + <dontComputeNew>true</dontComputeNew> + <doNotResolveRelativePaths>false</doNotResolveRelativePaths> + <pattern>**/pmd-result.xml</pattern> + </hudson.plugins.pmd.PmdPublisher> + </publishers> +</project> diff --git a/tests/publishers/fixtures/pmd001.yaml b/tests/publishers/fixtures/pmd001.yaml new file mode 100644 index 000000000..8aba6c5c5 --- /dev/null +++ b/tests/publishers/fixtures/pmd001.yaml @@ -0,0 +1,11 @@ +publishers: + - pmd: + pattern: '**/pmd-result.xml' + healthy: 0 + unhealthy: 100 + health-threshold: 'high' + thresholds: + unstable: + total-high: 10 + failed: + total-high: 1 diff --git a/tests/publishers/fixtures/pmd002.xml b/tests/publishers/fixtures/pmd002.xml new file mode 100644 index 000000000..044911a50 --- /dev/null +++ b/tests/publishers/fixtures/pmd002.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <publishers> + <hudson.plugins.pmd.PmdPublisher> + <healthy>0</healthy> + <unHealthy>100</unHealthy> + <thresholdLimit>high</thresholdLimit> + <pluginName>[PMD] </pluginName> + <defaultEncoding>utf-8</defaultEncoding> + <canRunOnFailed>true</canRunOnFailed> + <useStableBuildAsReference>false</useStableBuildAsReference> + <useDeltaValues>false</useDeltaValues> + <thresholds> + <unstableTotalAll>90</unstableTotalAll> + <unstableTotalHigh>80</unstableTotalHigh> + <unstableTotalNormal>70</unstableTotalNormal> + <unstableTotalLow>60</unstableTotalLow> + <failedTotalAll>90</failedTotalAll> + <failedTotalHigh>80</failedTotalHigh> + <failedTotalNormal>70</failedTotalNormal> + <failedTotalLow>60</failedTotalLow> + </thresholds> + <shouldDetectModules>true</shouldDetectModules> + <dontComputeNew>true</dontComputeNew> + <doNotResolveRelativePaths>false</doNotResolveRelativePaths> + <pattern>**/pmd-result.xml</pattern> + </hudson.plugins.pmd.PmdPublisher> + </publishers> +</project> diff --git a/tests/publishers/fixtures/pmd002.yaml b/tests/publishers/fixtures/pmd002.yaml new file mode 100644 index 000000000..183015531 --- /dev/null +++ b/tests/publishers/fixtures/pmd002.yaml @@ -0,0 +1,20 @@ +publishers: + - pmd: + pattern: '**/pmd-result.xml' + can-run-on-failed: true + should-detect-modules: true + healthy: 0 + unhealthy: 100 + health-threshold: 'high' + thresholds: + unstable: + total-all: 90 + total-high: 80 + total-normal: 70 + total-low: 60 + failed: + total-all: 90 + total-high: 80 + total-normal: 70 + total-low: 60 + default-encoding: 'utf-8' diff --git a/tests/publishers/fixtures/pmd003.xml b/tests/publishers/fixtures/pmd003.xml new file mode 100644 index 000000000..9f0320dcb --- /dev/null +++ b/tests/publishers/fixtures/pmd003.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <publishers> + <hudson.plugins.pmd.PmdPublisher> + <healthy/> + <unHealthy/> + <thresholdLimit>low</thresholdLimit> + <pluginName>[PMD] </pluginName> + <defaultEncoding/> + <canRunOnFailed>false</canRunOnFailed> + <useStableBuildAsReference>false</useStableBuildAsReference> + <useDeltaValues>false</useDeltaValues> + <thresholds> + <unstableTotalAll/> + <unstableTotalHigh/> + <unstableTotalNormal/> + <unstableTotalLow/> + <failedTotalAll/> + <failedTotalHigh/> + <failedTotalNormal/> + <failedTotalLow/> + </thresholds> + <shouldDetectModules>false</shouldDetectModules> + <dontComputeNew>true</dontComputeNew> + <doNotResolveRelativePaths>false</doNotResolveRelativePaths> + <pattern/> + </hudson.plugins.pmd.PmdPublisher> + </publishers> +</project> diff --git a/tests/publishers/fixtures/pmd003.yaml b/tests/publishers/fixtures/pmd003.yaml new file mode 100644 index 000000000..4ece24be6 --- /dev/null +++ b/tests/publishers/fixtures/pmd003.yaml @@ -0,0 +1,2 @@ +publishers: + - pmd diff --git a/tests/publishers/fixtures/pmd004.xml b/tests/publishers/fixtures/pmd004.xml new file mode 100644 index 000000000..cfacbd4d7 --- /dev/null +++ b/tests/publishers/fixtures/pmd004.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<project> + <publishers> + <hudson.plugins.pmd.PmdPublisher> + <healthy>0</healthy> + <unHealthy>100</unHealthy> + <thresholdLimit>high</thresholdLimit> + <pluginName>[PMD] </pluginName> + <defaultEncoding>utf-8</defaultEncoding> + <canRunOnFailed>true</canRunOnFailed> + <useStableBuildAsReference>true</useStableBuildAsReference> + <useDeltaValues>true</useDeltaValues> + <thresholds> + <unstableTotalAll>90</unstableTotalAll> + <unstableTotalHigh>80</unstableTotalHigh> + <unstableTotalNormal>70</unstableTotalNormal> + <unstableTotalLow>60</unstableTotalLow> + <unstableNewAll>50</unstableNewAll> + <unstableNewHigh>40</unstableNewHigh> + <unstableNewNormal>30</unstableNewNormal> + <unstableNewLow>20</unstableNewLow> + <failedTotalAll>91</failedTotalAll> + <failedTotalHigh>81</failedTotalHigh> + <failedTotalNormal>71</failedTotalNormal> + <failedTotalLow>61</failedTotalLow> + <failedNewAll>51</failedNewAll> + <failedNewHigh>41</failedNewHigh> + <failedNewNormal>31</failedNewNormal> + <failedNewLow>21</failedNewLow> + </thresholds> + <shouldDetectModules>true</shouldDetectModules> + <dontComputeNew>false</dontComputeNew> + <doNotResolveRelativePaths>true</doNotResolveRelativePaths> + <pattern>**/pmd-result.xml</pattern> + </hudson.plugins.pmd.PmdPublisher> + </publishers> +</project> diff --git a/tests/publishers/fixtures/pmd004.yml b/tests/publishers/fixtures/pmd004.yml new file mode 100644 index 000000000..1f418ff10 --- /dev/null +++ b/tests/publishers/fixtures/pmd004.yml @@ -0,0 +1,32 @@ +publishers: + - pmd: + pattern: '**/pmd-result.xml' + can-run-on-failed: true + should-detect-modules: true + healthy: 0 + unhealthy: 100 + health-threshold: 'high' + thresholds: + unstable: + total-all: 90 + total-high: 80 + total-normal: 70 + total-low: 60 + new-all: 50 + new-high: 40 + new-normal: 30 + new-low: 20 + failed: + total-all: 91 + total-high: 81 + total-normal: 71 + total-low: 61 + new-all: 51 + new-high: 41 + new-normal: 31 + new-low: 21 + default-encoding: 'utf-8' + do-not-resolve-relative-paths: true + dont-compute-new: false + use-stable-build-as-reference: true + use-delta-values: true