From 3cd778c05335568008def438f6a0e5cfe4186113 Mon Sep 17 00:00:00 2001 From: Tyler Camp Date: Wed, 18 Jan 2023 14:34:27 -0500 Subject: [PATCH] Change "analysis failed behavior" to have more of a global effect --- .../codedx/AnalysisResultConfiguration.java | 11 +--- .../plugins/codedx/BuildEffectBehavior.java | 6 +- .../plugins/codedx/CodeDxPublisher.java | 56 ++++++++++++++----- .../codedx/CodeDxPublisher/config.jelly | 11 ++-- src/main/webapp/help-breakIfFailed.html | 4 -- .../webapp/help-errorHandlingBehavior.html | 12 ++++ 6 files changed, 63 insertions(+), 37 deletions(-) delete mode 100644 src/main/webapp/help-breakIfFailed.html create mode 100644 src/main/webapp/help-errorHandlingBehavior.html diff --git a/src/main/java/org/jenkinsci/plugins/codedx/AnalysisResultConfiguration.java b/src/main/java/org/jenkinsci/plugins/codedx/AnalysisResultConfiguration.java index 3a3a87d..5eb5030 100644 --- a/src/main/java/org/jenkinsci/plugins/codedx/AnalysisResultConfiguration.java +++ b/src/main/java/org/jenkinsci/plugins/codedx/AnalysisResultConfiguration.java @@ -32,13 +32,11 @@ public class AnalysisResultConfiguration { private int numBuildsInGraph; private boolean breakForPolicy; - private BuildEffectBehavior analysisFailedBehavior; - @DataBoundConstructor public AnalysisResultConfiguration(String failureSeverity, String unstableSeverity, boolean failureOnlyNew, boolean unstableOnlyNew, int numBuildsInGraph, - boolean breakForPolicy, BuildEffectBehavior analysisFailedBehavior) { + boolean breakForPolicy) { this.failureSeverity = failureSeverity; this.unstableSeverity = unstableSeverity; @@ -46,7 +44,6 @@ public AnalysisResultConfiguration(String failureSeverity, this.unstableOnlyNew = unstableOnlyNew; this.numBuildsInGraph = numBuildsInGraph; this.breakForPolicy = breakForPolicy; - this.analysisFailedBehavior = analysisFailedBehavior; } public String getFailureSeverity() { return failureSeverity; @@ -78,12 +75,6 @@ public int getNumBuildsInGraph() { public void setNumBuildsInGraph(int numBuildsInGraph) { this.numBuildsInGraph = numBuildsInGraph; } - public BuildEffectBehavior getAnalysisFailedBehavior() { - return analysisFailedBehavior; - } - public void setAnalysisFailedBehavior(BuildEffectBehavior behavior) { - this.analysisFailedBehavior = behavior; - } public boolean getBreakForPolicy() { return breakForPolicy; } diff --git a/src/main/java/org/jenkinsci/plugins/codedx/BuildEffectBehavior.java b/src/main/java/org/jenkinsci/plugins/codedx/BuildEffectBehavior.java index bfaa0f6..6ab81a4 100644 --- a/src/main/java/org/jenkinsci/plugins/codedx/BuildEffectBehavior.java +++ b/src/main/java/org/jenkinsci/plugins/codedx/BuildEffectBehavior.java @@ -1,9 +1,9 @@ package org.jenkinsci.plugins.codedx; public enum BuildEffectBehavior { - MarkFailed("Mark Failed"), - MarkUnstable("Mark Unstable"), - None("Ignore"); + MarkFailed("Mark Build as Failed"), + MarkUnstable("Mark Build as Unstable"), + None("Ignore Errors"); private String label; BuildEffectBehavior(String label) { diff --git a/src/main/java/org/jenkinsci/plugins/codedx/CodeDxPublisher.java b/src/main/java/org/jenkinsci/plugins/codedx/CodeDxPublisher.java index 096be26..8a921eb 100644 --- a/src/main/java/org/jenkinsci/plugins/codedx/CodeDxPublisher.java +++ b/src/main/java/org/jenkinsci/plugins/codedx/CodeDxPublisher.java @@ -83,6 +83,8 @@ public class CodeDxPublisher extends Recorder implements SimpleBuildStep { private String targetBranchName, baseBranchName; + private BuildEffectBehavior errorHandlingBehavior; + private final static Logger logger = Logger.getLogger(CodeDxPublisher.class.getName()); /** @@ -109,6 +111,7 @@ public CodeDxPublisher( this.selfSignedCertificateFingerprint = null; this.targetBranchName = null; this.baseBranchName = null; + this.errorHandlingBehavior = BuildEffectBehavior.MarkFailed; setupClient(); } @@ -218,20 +221,31 @@ public void setBaseBranchName(String baseBranchName) { this.baseBranchName = null; } - private void handleAnalysisFailure(Run build, PrintStream buildOutput, String cause) { - switch (analysisResultConfiguration.getAnalysisFailedBehavior()) { + public BuildEffectBehavior getErrorHandlingBehavior() { + return errorHandlingBehavior; + } + + @DataBoundSetter + public void setErrorHandlingBehavior(BuildEffectBehavior behavior) { + errorHandlingBehavior = behavior; + } + + // returns true if we ignore the error, false if we want to exit prematurely + private Boolean handleAnalysisFailure(Run build, PrintStream buildOutput, String cause) { + buildOutput.println(cause); + switch (errorHandlingBehavior) { case MarkUnstable: - buildOutput.println(cause + ", marking build as Unstable"); + buildOutput.println("Marking build as Unstable"); build.setResult(Result.UNSTABLE); - break; + return false; case MarkFailed: - buildOutput.println(cause + ", marking build as Failure"); + buildOutput.println("Marking build as Failure"); build.setResult(Result.FAILURE); - break; + return false; - case None: - break; + default: + return true; } } @@ -271,7 +285,12 @@ public void perform( cdxVersion = repeatingClient.getCodeDxVersion(); buildOutput.println("Got Code Dx version: " + cdxVersion); } catch (CodeDxClientException e) { - throw new IOException("Failed to get Code Dx version; aborting build.", e); + if (!handleAnalysisFailure(build, buildOutput, "Failed to get Code Dx version")) { + return; + } else { + cdxVersion = CodeDxVersion.fromString("1.0.0"); + buildOutput.println("Continuing with placeholder Code Dx version " + cdxVersion); + } } ValueResolver valueResolver = new ValueResolver(build, workspace, listener, buildOutput); @@ -345,7 +364,9 @@ public void perform( String.format("Response Content: %s", e.getResponseContent()) + '\n' + Util.getStackTrace(e); - throw new AbortException(message); + buildOutput.println(message); + handleAnalysisFailure(build, buildOutput, "Failed to start analysis"); + return; // nothing else to do if we can't start the analysis, everything else relies on it } finally { // close streams after we're done sending them for(Map.Entry entry : toSend.entrySet()){ @@ -373,7 +394,11 @@ public void perform( repeatingClient.setAnalysisName(project, response.getAnalysisId(), expandedAnalysisName); buildOutput.println("Successfully updated analysis name."); } catch (CodeDxClientException e) { - throw new IOException("Got error from Code Dx API Client while trying to set the analysis name", e); + e.printStackTrace(buildOutput); + // this doesn't affect anything else in the plugin, only exit early if we're meant to fail + if (!handleAnalysisFailure(build, buildOutput, "Got error from Code Dx API Client while trying to set the analysis name")) { + return; + } } } } @@ -402,7 +427,9 @@ public void perform( } } while (Job.QUEUED.equals(status) || Job.RUNNING.equals(status)); } catch (CodeDxClientException e) { - throw new IOException("Fatal Error! There was a problem querying for the analysis status.", e); + e.printStackTrace(buildOutput); + handleAnalysisFailure(build, buildOutput, "There was an error querying for the analysis status"); + return; // nothing else to do if the analysis failed } if (Job.COMPLETED.equals(status)) { @@ -467,7 +494,8 @@ public void perform( throw new AbortException("Build result is non-success, terminating build"); } } catch (CodeDxClientException e) { - throw new IOException("Fatal Error! There was a problem retrieving analysis results.", e); + e.printStackTrace(buildOutput); + handleAnalysisFailure(build, buildOutput, "There was an error retrieving analysis results"); } } else { buildOutput.println("Analysis status: " + status); @@ -730,7 +758,7 @@ public ListBoxModel doFillProjectIdItems(@QueryParameter final String url, @Quer return listBox; } - public ListBoxModel doFillAnalysisFailedBehaviorItems() { + public ListBoxModel doFillErrorHandlingBehaviorItems() { ListBoxModel listBox = new ListBoxModel(); listBox.add(BuildEffectBehavior.None.getLabel(), BuildEffectBehavior.None.name()); listBox.add(BuildEffectBehavior.MarkUnstable.getLabel(), BuildEffectBehavior.MarkUnstable.name()); diff --git a/src/main/resources/org/jenkinsci/plugins/codedx/CodeDxPublisher/config.jelly b/src/main/resources/org/jenkinsci/plugins/codedx/CodeDxPublisher/config.jelly index 770d77b..47c03f0 100644 --- a/src/main/resources/org/jenkinsci/plugins/codedx/CodeDxPublisher/config.jelly +++ b/src/main/resources/org/jenkinsci/plugins/codedx/CodeDxPublisher/config.jelly @@ -47,6 +47,11 @@ + + + + + @@ -54,12 +59,6 @@ checked="${analysisResultConfiguration != null}" help="/plugin/codedx/help-analysisResultConfiguration.html"> - - - - - - diff --git a/src/main/webapp/help-breakIfFailed.html b/src/main/webapp/help-breakIfFailed.html deleted file mode 100644 index b5aec17..0000000 --- a/src/main/webapp/help-breakIfFailed.html +++ /dev/null @@ -1,4 +0,0 @@ -
-

Whether or not to fail the build if the Code Dx analysis fails.

-

Note: connection errors such as timeouts will cause the build to fail regardless of this setting.

-
\ No newline at end of file diff --git a/src/main/webapp/help-errorHandlingBehavior.html b/src/main/webapp/help-errorHandlingBehavior.html new file mode 100644 index 0000000..3ab99a9 --- /dev/null +++ b/src/main/webapp/help-errorHandlingBehavior.html @@ -0,0 +1,12 @@ +
+

+ Determines the action when a connection error occurs, or when the analysis fails. If + set to "Ignore Errors", the build will always succeed when an error occurs, regardless + of any "Build Failure Conditions" or "Build Unstable Conditions" set in the + "Wait for Analysis Results" section. +

+

+ (Does not affect behavior for internal plugin errors, eg configuration errors or unexpected exceptions - these + will still cause build errors.) +

+
\ No newline at end of file