diff --git a/src/main/java/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher.java b/src/main/java/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher.java index 4b7f385..b3849e1 100644 --- a/src/main/java/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher.java +++ b/src/main/java/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher.java @@ -63,6 +63,7 @@ public class DependencyCheckPublisher extends AbstractThresholdPublisher impleme private String pattern; private boolean stopBuild = false; + private boolean skipNoReportFiles = false; @DataBoundConstructor public DependencyCheckPublisher() { @@ -96,6 +97,15 @@ public boolean isStopBuild() { return stopBuild; } + public boolean isSkipNoReportFiles() { + return skipNoReportFiles; + } + + @DataBoundSetter + public void setSkipNoReportFiles(boolean skipNoReportFiles) { + this.skipNoReportFiles = skipNoReportFiles; + } + /** * This method is called whenever the build step is executed. * @@ -133,13 +143,23 @@ public Result process(@NonNull final Run build, } Result result = Result.SUCCESS; + final FindingsAggregator findingsAggregator = new FindingsAggregator(build.getNumber()); + final FilePath[] odcReportFiles = filePath.list(pattern); if (ArrayUtils.isEmpty(odcReportFiles)) { logger.println(Messages.Publisher_NoArtifactsFound()); + // build action with empty result or the trend graph will be interrupted and disappear + final ResultAction projectAction = new ResultAction(build, + findingsAggregator.getAggregatedFindings(), + findingsAggregator.getSeverityDistribution()); + build.addAction(projectAction); + + if (skipNoReportFiles) { + return result; + } return Result.UNSTABLE; } - final FindingsAggregator findingsAggregator = new FindingsAggregator(build.getNumber()); for (FilePath odcReportFile : odcReportFiles) { try { logger.println(Messages.Publisher_ParsingFile() + " " + odcReportFile.getRemote()); diff --git a/src/main/java/org/jenkinsci/plugins/DependencyCheck/pipeline/DependencyCheckStep.java b/src/main/java/org/jenkinsci/plugins/DependencyCheck/pipeline/DependencyCheckStep.java index cb7a619..86d11e9 100644 --- a/src/main/java/org/jenkinsci/plugins/DependencyCheck/pipeline/DependencyCheckStep.java +++ b/src/main/java/org/jenkinsci/plugins/DependencyCheck/pipeline/DependencyCheckStep.java @@ -40,6 +40,7 @@ public class DependencyCheckStep extends Step implements Serializable { private String pattern; private boolean stopBuild = false; + private boolean skipNoReportFiles = false; private Integer unstableTotalCritical; private Integer unstableTotalHigh; private Integer unstableTotalMedium; @@ -92,6 +93,15 @@ public boolean isStopBuild() { return stopBuild; } + public boolean isSkipNoReportFiles() { + return skipNoReportFiles; + } + + @DataBoundSetter + public void setSkipNoReportFiles(boolean skipNoReportFiles) { + this.skipNoReportFiles = skipNoReportFiles; + } + @Override public StepExecution start(StepContext context) throws Exception { return new DependencyCheckStepExecutor(this, context); diff --git a/src/main/java/org/jenkinsci/plugins/DependencyCheck/pipeline/DependencyCheckStepExecutor.java b/src/main/java/org/jenkinsci/plugins/DependencyCheck/pipeline/DependencyCheckStepExecutor.java index 532ea7c..5b204f7 100644 --- a/src/main/java/org/jenkinsci/plugins/DependencyCheck/pipeline/DependencyCheckStepExecutor.java +++ b/src/main/java/org/jenkinsci/plugins/DependencyCheck/pipeline/DependencyCheckStepExecutor.java @@ -53,6 +53,7 @@ protected Void run() throws Exception { DependencyCheckPublisher publisher = new DependencyCheckPublisher(); publisher.setPattern(step.getPattern()); publisher.setStopBuild(step.isStopBuild()); + publisher.setSkipNoReportFiles(step.isSkipNoReportFiles()); publisher.setTotalThresholdAnalysisExploitable(step.isTotalThresholdAnalysisExploitable()); publisher.setFailedTotalCritical(step.getFailedTotalCritical()); diff --git a/src/main/resources/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher/config.jelly b/src/main/resources/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher/config.jelly index 552840a..caf8f7d 100755 --- a/src/main/resources/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher/config.jelly +++ b/src/main/resources/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher/config.jelly @@ -24,6 +24,10 @@ limitations under the License. + + + + diff --git a/src/main/resources/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher/config.properties b/src/main/resources/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher/config.properties index 358be30..232d58e 100755 --- a/src/main/resources/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher/config.properties +++ b/src/main/resources/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher/config.properties @@ -14,4 +14,5 @@ # limitations under the License. pattern.title=XML Report Pattern -stopBuild.title=Stop build when a failed threshold is violated \ No newline at end of file +stopBuild.title=Stop build when a failed threshold is violated +skipNoReportFiles.title=Skip threshold validation if there are no report files \ No newline at end of file diff --git a/src/main/resources/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher/help-skipNoReportFiles.html b/src/main/resources/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher/help-skipNoReportFiles.html new file mode 100644 index 0000000..89ad9d4 --- /dev/null +++ b/src/main/resources/org/jenkinsci/plugins/DependencyCheck/DependencyCheckPublisher/help-skipNoReportFiles.html @@ -0,0 +1,3 @@ +
+ If enabled and no report file was found, the build result remains unchanged +
\ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/DependencyCheck/pipeline/DependencyCheckStepTest.java b/src/test/java/org/jenkinsci/plugins/DependencyCheck/pipeline/DependencyCheckStepTest.java index 86c212b..86753f0 100644 --- a/src/test/java/org/jenkinsci/plugins/DependencyCheck/pipeline/DependencyCheckStepTest.java +++ b/src/test/java/org/jenkinsci/plugins/DependencyCheck/pipeline/DependencyCheckStepTest.java @@ -21,7 +21,7 @@ import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; -import org.junit.Rule; +import org.junit.ClassRule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; @@ -30,8 +30,8 @@ public class DependencyCheckStepTest { - @Rule - public JenkinsRule jenkinsRule = new JenkinsRule(); + @ClassRule + public static JenkinsRule jenkinsRule = new JenkinsRule(); private WorkflowJob getBaseJob(String jobName) throws Exception { WorkflowJob job = jenkinsRule.jenkins.createProject(WorkflowJob.class, jobName); @@ -91,7 +91,7 @@ public void unstable_on_total_high() throws Exception { @Test public void stop_build_on_failed_threshold() throws Exception { - WorkflowJob job = getBaseJob("dependencyCheckPublisherWorkflowStepSetLimits"); + WorkflowJob job = getBaseJob("dependencyCheckPublisherWorkflowStepStopBuild"); job.setDefinition(new CpsFlowDefinition("" + "node {\n" + " dependencyCheckPublisher(pattern: '**/dependency-check-report.xml', failedTotalHigh: 0, stopBuild:true)\n" @@ -104,4 +104,22 @@ public void stop_build_on_failed_threshold() throws Exception { assertThat(result.getSeverityDistribution().getHigh()).isPositive(); } + @Test + public void skip_threshold_if_no_report_files_has_been_found() throws Exception { + WorkflowJob job = getBaseJob("dependencyCheckPublisherWorkflowStepSkipNoReportFile"); + job.setDefinition( + new CpsFlowDefinition("" + "node {\n" + " dependencyCheckPublisher(pattern: '**/definetlynothere.xml', skipNoReportFiles:false)\n" + + " echo('Hello World')\n" + "}\n", true)); + + WorkflowRun run = job.scheduleBuild2(0).get(); + jenkinsRule.assertBuildStatus(Result.UNSTABLE, run); + + job = getBaseJob("dependencyCheckPublisherWorkflowStepIgnoreMissing2"); + job.setDefinition( + new CpsFlowDefinition("" + "node {\n" + " dependencyCheckPublisher(pattern: '**/definetlynothere.xml', skipNoReportFiles:true)\n" + + " echo('Hello World')\n" + "}\n", true)); + + run = job.scheduleBuild2(0).get(); + jenkinsRule.assertBuildStatus(Result.SUCCESS, run); + } } \ No newline at end of file