diff --git a/core/src/main/java/hudson/maven/MavenBuild.java b/core/src/main/java/hudson/maven/MavenBuild.java index 86dedaadfd3fe9e99f0a892f3959da1dd4d06549..672ed2a1ffb458ed36a756a22eaa0341905a085b 100644 --- a/core/src/main/java/hudson/maven/MavenBuild.java +++ b/core/src/main/java/hudson/maven/MavenBuild.java @@ -3,6 +3,7 @@ package hudson.maven; import hudson.FilePath; import hudson.Util; import hudson.maven.agent.*; +import hudson.maven.reporters.SurefireArchiver; import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.model.BuildListener; @@ -125,8 +126,18 @@ public class MavenBuild extends AbstractBuild { hudson.maven.agent.PluginManagerInterceptor.setListener(pmi); LifecycleExecutorInterceptor.setListener(pmi); + markAsSuccess = false; + int r = Main.launch(goals.toArray(new String[goals.size()])); - return r==0 ? Result.SUCCESS : Result.FAILURE; + + if(r==0) return Result.SUCCESS; + + if(markAsSuccess) { + listener.getLogger().println("Maven failed with error."); + return Result.SUCCESS; + } + + return Result.FAILURE; } catch (NoSuchMethodException e) { throw new IOException2(e); } catch (IllegalAccessException e) { @@ -407,4 +418,24 @@ public class MavenBuild extends AbstractBuild { } private static final ProcessCache mavenProcessCache = new ProcessCache(MAX_PROCESS_CACHE); + + /** + * Used by selected {@link MavenReporter}s to notify the maven build agent + * that even though Maven is going to fail, we should report the build as + * success. + * + *

+ * This rather ugly hook is necessary to mark builds as unstable, since + * maven considers a test failure to be a build failure, which will otherwise + * mark the build as FAILED. + * + *

+ * It's OK for this field to be static, because the JVM where this is actually + * used is in the Maven JVM, so only one build is going on for the whole JVM. + * + *

+ * Even though this field is public, please consider this field reserved + * for {@link SurefireArchiver}. Subject to change without notice. + */ + public static boolean markAsSuccess; } diff --git a/core/src/main/java/hudson/maven/reporters/SurefireArchiver.java b/core/src/main/java/hudson/maven/reporters/SurefireArchiver.java index 2f85b5f7d66e2bb28eeb1be0afe6347d8e38d8bd..ad99bd54c4cbae8c184ab0ecf89da86d47526bb7 100644 --- a/core/src/main/java/hudson/maven/reporters/SurefireArchiver.java +++ b/core/src/main/java/hudson/maven/reporters/SurefireArchiver.java @@ -13,6 +13,7 @@ import hudson.model.Result; import hudson.tasks.junit.TestResult; import hudson.tasks.junit.TestResultAction; import hudson.tasks.test.TestResultProjectAction; +import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; @@ -64,16 +65,22 @@ public class SurefireArchiver extends MavenReporter { final TestResult tr = new TestResult(started.getTime() - 1000/*error margin*/, ds); - build.execute(new BuildCallable() { - public Void call(MavenBuild build) throws IOException, InterruptedException { + int failCount = build.execute(new BuildCallable() { + public Integer call(MavenBuild build) throws IOException, InterruptedException { TestResultAction action = new TestResultAction(build, tr, listener); build.getActions().add(action); if(tr.getFailCount()>0) build.setResult(Result.UNSTABLE); build.registerAsProjectAction(SurefireArchiver.this); - return null; + return tr.getFailCount(); } }); + + // if surefire plugin is going to kill maven because of a test failure, + // intercept that (or otherwise build will be marked as failure) + if(failCount>0 && error instanceof MojoFailureException) { + MavenBuild.markAsSuccess = true; + } } return true;