From 910b3589b1560971d952edba10f449b09a7e7fc9 Mon Sep 17 00:00:00 2001 From: Ulli Hafner Date: Tue, 20 Aug 2024 14:09:04 +0200 Subject: [PATCH] [JENKINS-72973] Add an option to skip the SCM delta calculation. --- .../analysis/core/steps/IssuesRecorder.java | 21 +++++++++-- .../core/steps/PublishIssuesStep.java | 20 +++++++++-- .../analysis/core/steps/RecordIssuesStep.java | 16 +++++++++ .../help-skipDeltaCalculation.html | 8 +++++ .../help-skipDeltaCalculation.html | 8 +++++ .../help-skipDeltaCalculation.html | 8 +++++ .../resources/issues/publish-parameters.jelly | 19 +++++----- .../issues/publish-parameters.properties | 5 +-- .../warnings/steps/GitForensicsITest.java | 36 +++++++++++++++++++ 9 files changed, 127 insertions(+), 14 deletions(-) create mode 100644 plugin/src/main/resources/io/jenkins/plugins/analysis/core/steps/IssuesRecorder/help-skipDeltaCalculation.html create mode 100644 plugin/src/main/resources/io/jenkins/plugins/analysis/core/steps/PublishIssuesStep/help-skipDeltaCalculation.html create mode 100644 plugin/src/main/resources/io/jenkins/plugins/analysis/core/steps/RecordIssuesStep/help-skipDeltaCalculation.html diff --git a/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/IssuesRecorder.java b/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/IssuesRecorder.java index 88504c8e86..8bc2c62fb2 100644 --- a/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/IssuesRecorder.java +++ b/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/IssuesRecorder.java @@ -59,6 +59,7 @@ import io.jenkins.plugins.analysis.core.util.TrendChartType; import io.jenkins.plugins.analysis.core.util.WarningsQualityGate; import io.jenkins.plugins.checks.steps.ChecksInfo; +import io.jenkins.plugins.forensics.delta.DeltaCalculator.NullDeltaCalculator; import io.jenkins.plugins.forensics.delta.DeltaCalculatorFactory; import io.jenkins.plugins.prism.SourceCodeDirectory; import io.jenkins.plugins.prism.SourceCodeRetention; @@ -119,6 +120,7 @@ public class IssuesRecorder extends Recorder { private transient boolean publishAllIssues; // @deprecated: use checksAnnotationScope instead private boolean skipPostProcessing; // @since 10.6.0: by default, post-processing will be enabled + private boolean skipDeltaCalculation; // @since 11.5.0: by default, delta computation is enabled @CheckForNull private ChecksInfo checksInfo; @@ -463,6 +465,20 @@ public void setSkipPostProcessing(final boolean skipPostProcessing) { this.skipPostProcessing = skipPostProcessing; } + /** + * Returns whether the SCM delta calculation for the new issue detection should be disabled. + * + * @return {@code true} if the SCM delta calculation for the new issue detection should be disabled. + */ + public boolean isSkipDeltaCalculation() { + return skipDeltaCalculation; + } + + @DataBoundSetter + public void setSkipDeltaCalculation(final boolean skipDeltaCalculation) { + this.skipDeltaCalculation = skipDeltaCalculation; + } + /** * Determines whether to fail the step on errors during the step of recording issues. * @@ -733,8 +749,9 @@ AnalysisResult publishResult(final Run run, final FilePath workspace, fina logHandler.logInfoMessages(report.getInfoMessages()); logHandler.logErrorMessages(report.getErrorMessages()); - var deltaCalculator = DeltaCalculatorFactory - .findDeltaCalculator(scm, run, workspace, listener, new FilteredLog()); + var deltaCalculator = isSkipDeltaCalculation() + ? new NullDeltaCalculator() + : DeltaCalculatorFactory.findDeltaCalculator(scm, run, workspace, listener, new FilteredLog()); IssuesPublisher publisher = new IssuesPublisher(run, annotatedReport, deltaCalculator, new HealthDescriptor(healthy, unhealthy, minimumSeverity), qualityGates, diff --git a/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/PublishIssuesStep.java b/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/PublishIssuesStep.java index 765911b5a7..6168a1122c 100644 --- a/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/PublishIssuesStep.java +++ b/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/PublishIssuesStep.java @@ -59,6 +59,7 @@ public class PublishIssuesStep extends Step implements Serializable { private boolean ignoreQualityGate = false; // by default, a successful quality gate is mandatory private boolean failOnError = false; // by default, it should not fail on error + private boolean skipDeltaCalculation; // @since 11.5.0: by default, delta computation is enabled private boolean skipPublishingChecks; // by default, warnings should be published to SCM platforms private ChecksAnnotationScope checksAnnotationScope = ChecksAnnotationScope.NEW; // @since 11.0.0 @@ -169,6 +170,20 @@ public boolean getFailOnError() { return failOnError; } + /** + * Returns whether the SCM delta calculation for the new issue detection should be disabled. + * + * @return {@code true} if the SCM delta calculation for the new issue detection should be disabled. + */ + public boolean isSkipDeltaCalculation() { + return skipDeltaCalculation; + } + + @DataBoundSetter + public void setSkipDeltaCalculation(final boolean skipDeltaCalculation) { + this.skipDeltaCalculation = skipDeltaCalculation; + } + /** * Returns whether publishing checks should be skipped. * @@ -414,8 +429,9 @@ protected ResultAction run() throws IOException, InterruptedException, IllegalSt report.addAll(step.reports); var workspace = getContext().get(FilePath.class); - var deltaCalculator = workspace == null ? new DeltaCalculator.NullDeltaCalculator() : DeltaCalculatorFactory - .findDeltaCalculator(step.scm, getRun(), workspace, getTaskListener(), new FilteredLog()); + var deltaCalculator = workspace == null || step.isSkipDeltaCalculation() + ? new DeltaCalculator.NullDeltaCalculator() + : DeltaCalculatorFactory.findDeltaCalculator(step.scm, getRun(), workspace, getTaskListener(), new FilteredLog()); IssuesPublisher publisher = new IssuesPublisher(getRun(), report, deltaCalculator, new HealthDescriptor(step.getHealthy(), step.getUnhealthy(), diff --git a/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/RecordIssuesStep.java b/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/RecordIssuesStep.java index 2c569196e1..a7cb8a45a7 100644 --- a/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/RecordIssuesStep.java +++ b/plugin/src/main/java/io/jenkins/plugins/analysis/core/steps/RecordIssuesStep.java @@ -86,6 +86,7 @@ public class RecordIssuesStep extends Step implements Serializable { private boolean isBlameDisabled; private boolean skipPostProcessing; // @since 10.6.0: by default, post-processing will be enabled + private boolean skipDeltaCalculation; // @since 11.5.0: by default, delta computation is enabled private boolean skipPublishingChecks; // by default, checks will be published private ChecksAnnotationScope checksAnnotationScope = ChecksAnnotationScope.NEW; // @since 11.0.0 @@ -403,6 +404,20 @@ public void setSkipPostProcessing(final boolean skipPostProcessing) { this.skipPostProcessing = skipPostProcessing; } + /** + * Returns whether the SCM delta calculation for the new issue detection should be disabled. + * + * @return {@code true} if the SCM delta calculation for the new issue detection should be disabled. + */ + public boolean isSkipDeltaCalculation() { + return skipDeltaCalculation; + } + + @DataBoundSetter + public void setSkipDeltaCalculation(final boolean skipDeltaCalculation) { + this.skipDeltaCalculation = skipDeltaCalculation; + } + /** * Returns whether publishing checks should be skipped. * @@ -614,6 +629,7 @@ protected List run() throws IOException, InterruptedException { recorder.setAggregatingResults(step.getAggregatingResults()); recorder.setBlameDisabled(step.isSkipBlames()); recorder.setSkipPostProcessing(step.isSkipPostProcessing()); + recorder.setSkipDeltaCalculation(step.isSkipDeltaCalculation()); recorder.setScm(step.getScm()); recorder.setSkipPublishingChecks(step.isSkipPublishingChecks()); recorder.setChecksAnnotationScope(step.getChecksAnnotationScope()); diff --git a/plugin/src/main/resources/io/jenkins/plugins/analysis/core/steps/IssuesRecorder/help-skipDeltaCalculation.html b/plugin/src/main/resources/io/jenkins/plugins/analysis/core/steps/IssuesRecorder/help-skipDeltaCalculation.html new file mode 100644 index 0000000000..1e21258929 --- /dev/null +++ b/plugin/src/main/resources/io/jenkins/plugins/analysis/core/steps/IssuesRecorder/help-skipDeltaCalculation.html @@ -0,0 +1,8 @@ +
+ If this option is unchecked, then the plugin analyzes the code changes between the current build and + the reference build. Currently, this feature is only available for Git and requires the + git-forensics plugin + to be installed. Based on this delta report, issues are then classified + as new or outstanding. Only issues that are part of the obtained diff will be marked as new. + If this operation slows down your build, you can use this option to deactivate this feature. +
diff --git a/plugin/src/main/resources/io/jenkins/plugins/analysis/core/steps/PublishIssuesStep/help-skipDeltaCalculation.html b/plugin/src/main/resources/io/jenkins/plugins/analysis/core/steps/PublishIssuesStep/help-skipDeltaCalculation.html new file mode 100644 index 0000000000..1e21258929 --- /dev/null +++ b/plugin/src/main/resources/io/jenkins/plugins/analysis/core/steps/PublishIssuesStep/help-skipDeltaCalculation.html @@ -0,0 +1,8 @@ +
+ If this option is unchecked, then the plugin analyzes the code changes between the current build and + the reference build. Currently, this feature is only available for Git and requires the + git-forensics plugin + to be installed. Based on this delta report, issues are then classified + as new or outstanding. Only issues that are part of the obtained diff will be marked as new. + If this operation slows down your build, you can use this option to deactivate this feature. +
diff --git a/plugin/src/main/resources/io/jenkins/plugins/analysis/core/steps/RecordIssuesStep/help-skipDeltaCalculation.html b/plugin/src/main/resources/io/jenkins/plugins/analysis/core/steps/RecordIssuesStep/help-skipDeltaCalculation.html new file mode 100644 index 0000000000..1e21258929 --- /dev/null +++ b/plugin/src/main/resources/io/jenkins/plugins/analysis/core/steps/RecordIssuesStep/help-skipDeltaCalculation.html @@ -0,0 +1,8 @@ +
+ If this option is unchecked, then the plugin analyzes the code changes between the current build and + the reference build. Currently, this feature is only available for Git and requires the + git-forensics plugin + to be installed. Based on this delta report, issues are then classified + as new or outstanding. Only issues that are part of the obtained diff will be marked as new. + If this operation slows down your build, you can use this option to deactivate this feature. +
diff --git a/plugin/src/main/resources/issues/publish-parameters.jelly b/plugin/src/main/resources/issues/publish-parameters.jelly index fe7d6c1d2d..37785f5145 100644 --- a/plugin/src/main/resources/issues/publish-parameters.jelly +++ b/plugin/src/main/resources/issues/publish-parameters.jelly @@ -7,19 +7,22 @@ - - + + - + - - - - - + + + + + + + + diff --git a/plugin/src/main/resources/issues/publish-parameters.properties b/plugin/src/main/resources/issues/publish-parameters.properties index 6ad92b6d48..9b3a9f0de8 100644 --- a/plugin/src/main/resources/issues/publish-parameters.properties +++ b/plugin/src/main/resources/issues/publish-parameters.properties @@ -1,5 +1,5 @@ description.reference=One important feature of the Warnings Plugin is the classification of issues as \ - new, outstanding and fixed. In order to compute this classification, the plugin requires a reference build (baseline). \ + new, outstanding and fixed. To compute this classification, the plugin requires a reference build (baseline). \ New, fixed, and outstanding issues are then computed by comparing the issues in the current build and in the baseline. title.ignoreQualityGate=Ignore the results of the quality gates when determining the reference build title.failOnError=Fail the build if errors have been reported during the execution @@ -14,12 +14,13 @@ qualityGates.description=You can define an arbitrary number of quality gates tha title.trendChartType=Trend Chart Type and Position title.skipPublishingChecks=Skip publishing of checks to SCM provider platforms +title.skipDeltaCalculation=Skip SCM delta calculation to identify new issues title.checksAnnotationScope=Select the scope of source code annotations threshold.100.percent=100% threshold.0.percent=0% description.health.limit=Configure the 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. -title.health.severities=Health Report Severities +title.health.severities=Health Report Severities description.healthy=Report health as 100% when the number of issues is less than this value. description.unhealthy=Report health as 0% when the number of issues is greater than this value. diff --git a/plugin/src/test/java/io/jenkins/plugins/analysis/warnings/steps/GitForensicsITest.java b/plugin/src/test/java/io/jenkins/plugins/analysis/warnings/steps/GitForensicsITest.java index b8bc27a1cd..4bbcba1429 100644 --- a/plugin/src/test/java/io/jenkins/plugins/analysis/warnings/steps/GitForensicsITest.java +++ b/plugin/src/test/java/io/jenkins/plugins/analysis/warnings/steps/GitForensicsITest.java @@ -65,6 +65,42 @@ private String createScanForIssuesStep(final String sourceDirectories) { + PUBLISH_ISSUES_STEP; } + @Test + void shouldSkipDeltaCalculation() { + WorkflowJob job = createPipelineWithWorkspaceFilesWithSuffix(); + + createFileInWorkspace(job, "java-issues.txt", + createJavaWarning(MODIFIED_FILE, 111) + + createJavaWarning(SCM_RESOLVER, AFFECTED_LINE)); + + var step = "recordIssues skipDeltaCalculation: true, " + + "sourceDirectories: [[path: 'forensics-api']], tool: java(pattern:'**/*issues.txt', reportEncoding:'UTF-8')"; + job.setDefinition(asStage(checkout(OLD_COMMIT), step)); + + buildSuccessfully(job); // reference build + + createFileInWorkspace(job, "java-issues.txt", + createJavaWarning(MODIFIED_FILE, 111) // outstanding and modified + + createJavaWarning(MODIFIED_FILE, 112) // new and modified + + createJavaWarning(MODIFIED_FILE, 113) // new and modified + + createJavaWarning(SCM_RESOLVER, AFFECTED_LINE) // outstanding (not modified) + + createJavaWarning(MODIFIED_FILE, 2)); // new (not modified) + + job.setDefinition(asStage(CHECKOUT_FORENSICS_API, "discoverReferenceBuild()", step)); + + AnalysisResult result = scheduleSuccessfulBuild(job); + assertThat(getConsoleLog(result)).contains( + "Detect all issues that are part of modified code", + "No relevant modified code found", + "Created analysis result for 5 issues (found 3 new issues, fixed 0 issues)"); + assertThat(getConsoleLog(result)).doesNotContain( + "-> Using commit 'a6d0ef0' as latest commit for build", + "-> Using commit '3097ea1' as latest commit for build", + "-> Invoking Git delta calculator for determining the changes between commits 'a6d0ef0' and '3097ea1'", + "-> Start scanning for differences between commits...", + "Issues in modified code"); + } + /** * Checks out an existing Git repository and starts a pipeline with the record step. Verifies that the Git forensics * plugin is correctly invoked.