From 6fb41818d63ca0067171f8c01fcdbed196335b44 Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Tue, 5 Nov 2013 17:17:31 -0500 Subject: [PATCH] =?UTF-8?q?[FIXED=20JENKINS-16376]=20Never=20wait=20for=20?= =?UTF-8?q?previous=20builds=20to=20complete=20just=20to=20get=20a=20more?= =?UTF-8?q?=20precise=20status.=20If=20and=20when=20we=20need=20to=20know?= =?UTF-8?q?=20the=20status=20of=20a=20previous=20build=20but=20it=20is=20s?= =?UTF-8?q?till=20running,=20simply=20print=20a=20warning=20to=20the=20(cu?= =?UTF-8?q?rrent=20build=E2=80=99s)=20log=20and=20proceed=20as=20if=20the?= =?UTF-8?q?=20previous=20build=20did=20not=20exist.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../emailext/ExtendedEmailPublisher.java | 26 ++++++++++-- .../content/AbstractChangesSinceContent.java | 10 ++--- .../plugins/content/BuildStatusContent.java | 12 +++--- .../content/ChangesSinceLastBuildContent.java | 23 ++++++----- ...hangesSinceLastSuccessfulBuildContent.java | 12 +++--- .../ChangesSinceLastUnstableBuildContent.java | 12 +++--- .../plugins/trigger/BuildingTrigger.java | 3 +- .../plugins/trigger/FixedTrigger.java | 3 +- .../trigger/FixedUnhealthyTrigger.java | 9 ++-- .../plugins/trigger/ImprovementTrigger.java | 8 ++-- .../plugins/trigger/NthFailureTrigger.java | 3 +- .../plugins/trigger/RegressionTrigger.java | 8 ++-- .../plugins/trigger/StatusChangedTrigger.java | 3 +- .../plugins/trigger/StillFailingTrigger.java | 3 +- .../plugins/trigger/StillUnstableTrigger.java | 3 +- .../plugins/emailext/Messages.properties | 1 + .../emailext/ExtendedEmailPublisherTest.java | 41 ++++++++++++++++++- 17 files changed, 127 insertions(+), 53 deletions(-) diff --git a/src/main/java/hudson/plugins/emailext/ExtendedEmailPublisher.java b/src/main/java/hudson/plugins/emailext/ExtendedEmailPublisher.java index 6e410a9c6..982603b72 100755 --- a/src/main/java/hudson/plugins/emailext/ExtendedEmailPublisher.java +++ b/src/main/java/hudson/plugins/emailext/ExtendedEmailPublisher.java @@ -30,7 +30,7 @@ import hudson.FilePath; import hudson.model.Action; import hudson.model.Item; -import hudson.security.Permission; +import hudson.model.TaskListener; import org.apache.commons.lang.StringUtils; import org.codehaus.groovy.control.CompilerConfiguration; @@ -61,6 +61,8 @@ import java.util.StringTokenizer; import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; import javax.mail.Address; import javax.mail.Message; @@ -572,7 +574,7 @@ private MimeMessage createMail(EmailType type, AbstractBuild build, BuildL msg.setReplyTo(replyToAddresses.toArray(new InternetAddress[replyToAddresses.size()])); } - AbstractBuild pb = build.getPreviousBuild(); + AbstractBuild pb = getPreviousBuild(build, listener); if (pb != null) { // Send mails as replies until next successful build MailMessageIdAction b = pb.getAction(MailMessageIdAction.class); @@ -764,7 +766,25 @@ public boolean needsToRunAfterFinalized() { } public BuildStepMonitor getRequiredMonitorService() { - return BuildStepMonitor.BUILD; + return BuildStepMonitor.NONE; + } + + /** + * Looks for a previous build, so long as that is in fact completed. + * Necessary since {@link #getRequiredMonitorService} does not wait for the previous build, + * so in the case of parallel-capable jobs, we need to behave sensibly when a later build actually finishes before an earlier one. + * @param build a build for which we may be sending mail + * @param listener a listener to which we may print warnings in case the actual previous build is still in progress + * @return the previous build, or null if that build is missing, or is still in progress + */ + public static @CheckForNull AbstractBuild getPreviousBuild(@Nonnull AbstractBuild build, TaskListener listener) { + AbstractBuild previousBuild = build.getPreviousBuild(); + if (previousBuild != null && previousBuild.isBuilding()) { + listener.getLogger().println(Messages.ExtendedEmailPublisher__is_still_in_progress_ignoring_for_purpo(previousBuild.getDisplayName())); + return null; + } else { + return previousBuild; + } } @Override diff --git a/src/main/java/hudson/plugins/emailext/plugins/content/AbstractChangesSinceContent.java b/src/main/java/hudson/plugins/emailext/plugins/content/AbstractChangesSinceContent.java index 62fefecef..fce58b562 100644 --- a/src/main/java/hudson/plugins/emailext/plugins/content/AbstractChangesSinceContent.java +++ b/src/main/java/hudson/plugins/emailext/plugins/content/AbstractChangesSinceContent.java @@ -27,6 +27,7 @@ import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.model.TaskListener; +import hudson.plugins.emailext.ExtendedEmailPublisher; import hudson.plugins.emailext.Util; import java.io.IOException; @@ -56,7 +57,7 @@ abstract public class AbstractChangesSinceContent public String evaluate(AbstractBuild build, TaskListener listener, String macroName) throws MacroEvaluationException, IOException, InterruptedException { // No previous build so bail - if (build.getPreviousBuild() == null) { + if (ExtendedEmailPublisher.getPreviousBuild(build, listener) == null) { return ""; } @@ -69,9 +70,9 @@ public String evaluate(AbstractBuild build, TaskListener listener, String final AbstractBuild endBuild; if (reverse) { startBuild = build; - endBuild = getFirstIncludedBuild(build); + endBuild = getFirstIncludedBuild(build, listener); } else { - startBuild = getFirstIncludedBuild(build); + startBuild = getFirstIncludedBuild(build, listener); endBuild = build; } AbstractBuild currentBuild = null; @@ -129,6 +130,5 @@ public boolean hasNestedContent() { public abstract String getShortHelpDescription(); - public abstract

, B extends AbstractBuild> AbstractBuild getFirstIncludedBuild( - AbstractBuild build); + public abstract AbstractBuild getFirstIncludedBuild(AbstractBuild build, TaskListener listener); } diff --git a/src/main/java/hudson/plugins/emailext/plugins/content/BuildStatusContent.java b/src/main/java/hudson/plugins/emailext/plugins/content/BuildStatusContent.java index 5d38c0b4b..313039c04 100644 --- a/src/main/java/hudson/plugins/emailext/plugins/content/BuildStatusContent.java +++ b/src/main/java/hudson/plugins/emailext/plugins/content/BuildStatusContent.java @@ -2,8 +2,8 @@ import hudson.model.AbstractBuild; import hudson.model.Result; -import hudson.model.Run; import hudson.model.TaskListener; +import hudson.plugins.emailext.ExtendedEmailPublisher; import hudson.plugins.emailext.plugins.EmailToken; import java.io.IOException; @@ -33,14 +33,14 @@ public String evaluate(AbstractBuild build, TaskListener listener, String Result buildResult = build.getResult(); if (buildResult == Result.FAILURE) { - Run prevBuild = build.getPreviousBuild(); + AbstractBuild prevBuild = ExtendedEmailPublisher.getPreviousBuild(build, listener); if (prevBuild != null && (prevBuild.getResult() == Result.FAILURE)) { return "Still Failing"; } else { return "Failure"; } } else if (buildResult == Result.UNSTABLE) { - Run prevBuild = build.getPreviousBuild(); + AbstractBuild prevBuild = ExtendedEmailPublisher.getPreviousBuild(build, listener); if (prevBuild != null) { if (prevBuild.getResult() == Result.UNSTABLE) { return "Still Unstable"; @@ -52,7 +52,7 @@ public String evaluate(AbstractBuild build, TaskListener listener, String //iterate through previous builds //(fail_or_aborted)* and then an unstable : return still unstable //(fail_or_aborted)* and then successful : return unstable - Run previous = prevBuild.getPreviousBuild(); + AbstractBuild previous = ExtendedEmailPublisher.getPreviousBuild(prevBuild, listener); while (previous != null) { if (previous.getResult() == Result.SUCCESS) { return "Unstable"; @@ -60,7 +60,7 @@ public String evaluate(AbstractBuild build, TaskListener listener, String if (previous.getResult() == Result.UNSTABLE) { return "Still unstable"; } - previous = previous.getPreviousBuild(); + previous = ExtendedEmailPublisher.getPreviousBuild(previous, listener); } return "Unstable"; } @@ -68,7 +68,7 @@ public String evaluate(AbstractBuild build, TaskListener listener, String return "Unstable"; } } else if (buildResult == Result.SUCCESS) { - Run prevBuild = build.getPreviousBuild(); + AbstractBuild prevBuild = ExtendedEmailPublisher.getPreviousBuild(build, listener); if (prevBuild != null && (prevBuild.getResult() == Result.UNSTABLE || prevBuild.getResult() == Result.FAILURE)) { return "Fixed"; } else { diff --git a/src/main/java/hudson/plugins/emailext/plugins/content/ChangesSinceLastBuildContent.java b/src/main/java/hudson/plugins/emailext/plugins/content/ChangesSinceLastBuildContent.java index a61487618..0f9f1983b 100644 --- a/src/main/java/hudson/plugins/emailext/plugins/content/ChangesSinceLastBuildContent.java +++ b/src/main/java/hudson/plugins/emailext/plugins/content/ChangesSinceLastBuildContent.java @@ -4,6 +4,7 @@ import hudson.model.AbstractBuild.DependencyChange; import hudson.model.AbstractProject; import hudson.model.TaskListener; +import hudson.plugins.emailext.ExtendedEmailPublisher; import hudson.plugins.emailext.Util; import hudson.plugins.emailext.plugins.EmailToken; import hudson.scm.ChangeLogSet; @@ -12,7 +13,6 @@ import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException; import java.io.IOException; -import java.lang.reflect.Method; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Collection; @@ -72,18 +72,21 @@ public String evaluate(AbstractBuild build, TaskListener listener, String Util.printf(buf, format, new ChangesSincePrintfSpec(entry, pathFormat, dateFormatter)); } - if (showDependencies && build.getPreviousBuild() != null) - for (Entry e : build - .getDependencyChanges(build.getPreviousBuild()).entrySet()) { - buf.append("\n=======================\n"); - buf.append("\nChanges in ").append(e.getKey().getName()) - .append(":\n"); - for (AbstractBuild b : e.getValue().getBuilds()) { - for (ChangeLogSet.Entry entry : b.getChangeSet()) { - Util.printf(buf, format, new ChangesSincePrintfSpec(entry, pathFormat, dateFormatter)); + if (showDependencies) { + AbstractBuild previousBuild = ExtendedEmailPublisher.getPreviousBuild(build, listener); + if (previousBuild != null) { + for (Entry e : build.getDependencyChanges(previousBuild).entrySet()) { + buf.append("\n=======================\n"); + buf.append("\nChanges in ").append(e.getKey().getName()) + .append(":\n"); + for (AbstractBuild b : e.getValue().getBuilds()) { + for (ChangeLogSet.Entry entry : b.getChangeSet()) { + Util.printf(buf, format, new ChangesSincePrintfSpec(entry, pathFormat, dateFormatter)); + } } } } + } return buf.toString(); } diff --git a/src/main/java/hudson/plugins/emailext/plugins/content/ChangesSinceLastSuccessfulBuildContent.java b/src/main/java/hudson/plugins/emailext/plugins/content/ChangesSinceLastSuccessfulBuildContent.java index 1e2308280..b34aaa433 100644 --- a/src/main/java/hudson/plugins/emailext/plugins/content/ChangesSinceLastSuccessfulBuildContent.java +++ b/src/main/java/hudson/plugins/emailext/plugins/content/ChangesSinceLastSuccessfulBuildContent.java @@ -1,8 +1,9 @@ package hudson.plugins.emailext.plugins.content; import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; import hudson.model.Result; +import hudson.model.TaskListener; +import hudson.plugins.emailext.ExtendedEmailPublisher; import hudson.plugins.emailext.plugins.EmailToken; @EmailToken @@ -28,14 +29,13 @@ public String getShortHelpDescription() { } @Override - public

, B extends AbstractBuild> AbstractBuild getFirstIncludedBuild( - AbstractBuild build) { - AbstractBuild firstIncludedBuild = build; + public AbstractBuild getFirstIncludedBuild(AbstractBuild build, TaskListener listener) { + AbstractBuild firstIncludedBuild = build; - B prev = firstIncludedBuild.getPreviousBuild(); + AbstractBuild prev = ExtendedEmailPublisher.getPreviousBuild(firstIncludedBuild, listener); while (prev != null && prev.getResult() != Result.SUCCESS) { firstIncludedBuild = prev; - prev = firstIncludedBuild.getPreviousBuild(); + prev = ExtendedEmailPublisher.getPreviousBuild(firstIncludedBuild, listener); } return firstIncludedBuild; diff --git a/src/main/java/hudson/plugins/emailext/plugins/content/ChangesSinceLastUnstableBuildContent.java b/src/main/java/hudson/plugins/emailext/plugins/content/ChangesSinceLastUnstableBuildContent.java index 56103d599..cef3691d4 100644 --- a/src/main/java/hudson/plugins/emailext/plugins/content/ChangesSinceLastUnstableBuildContent.java +++ b/src/main/java/hudson/plugins/emailext/plugins/content/ChangesSinceLastUnstableBuildContent.java @@ -1,8 +1,9 @@ package hudson.plugins.emailext.plugins.content; import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; import hudson.model.Result; +import hudson.model.TaskListener; +import hudson.plugins.emailext.ExtendedEmailPublisher; import hudson.plugins.emailext.plugins.EmailToken; @EmailToken @@ -28,14 +29,13 @@ public String getShortHelpDescription() { } @Override - public

, B extends AbstractBuild> AbstractBuild getFirstIncludedBuild( - AbstractBuild build) { - AbstractBuild firstIncludedBuild = build; + public AbstractBuild getFirstIncludedBuild(AbstractBuild build, TaskListener listener) { + AbstractBuild firstIncludedBuild = build; - B prev = firstIncludedBuild.getPreviousBuild(); + AbstractBuild prev = ExtendedEmailPublisher.getPreviousBuild(firstIncludedBuild, listener); while (prev != null && prev.getResult().isWorseThan(Result.UNSTABLE)) { firstIncludedBuild = prev; - prev = firstIncludedBuild.getPreviousBuild(); + prev = ExtendedEmailPublisher.getPreviousBuild(firstIncludedBuild, listener); } return firstIncludedBuild; diff --git a/src/main/java/hudson/plugins/emailext/plugins/trigger/BuildingTrigger.java b/src/main/java/hudson/plugins/emailext/plugins/trigger/BuildingTrigger.java index 2aed70d53..2be61c3f3 100644 --- a/src/main/java/hudson/plugins/emailext/plugins/trigger/BuildingTrigger.java +++ b/src/main/java/hudson/plugins/emailext/plugins/trigger/BuildingTrigger.java @@ -4,6 +4,7 @@ import hudson.model.AbstractBuild; import hudson.model.Result; import hudson.model.TaskListener; +import hudson.plugins.emailext.ExtendedEmailPublisher; import hudson.plugins.emailext.plugins.EmailTrigger; import hudson.plugins.emailext.plugins.EmailTriggerDescriptor; import org.kohsuke.stapler.DataBoundConstructor; @@ -24,7 +25,7 @@ public boolean trigger(AbstractBuild build, TaskListener listener) { Result buildResult = build.getResult(); if (buildResult == Result.UNSTABLE) { - AbstractBuild prevBuild = build.getPreviousBuild(); + AbstractBuild prevBuild = ExtendedEmailPublisher.getPreviousBuild(build, listener); if (prevBuild != null && (prevBuild.getResult() == Result.FAILURE)) { return true; } diff --git a/src/main/java/hudson/plugins/emailext/plugins/trigger/FixedTrigger.java b/src/main/java/hudson/plugins/emailext/plugins/trigger/FixedTrigger.java index c75b5dab2..3f990d6f2 100644 --- a/src/main/java/hudson/plugins/emailext/plugins/trigger/FixedTrigger.java +++ b/src/main/java/hudson/plugins/emailext/plugins/trigger/FixedTrigger.java @@ -4,6 +4,7 @@ import hudson.model.AbstractBuild; import hudson.model.Result; import hudson.model.TaskListener; +import hudson.plugins.emailext.ExtendedEmailPublisher; import hudson.plugins.emailext.plugins.EmailTrigger; import hudson.plugins.emailext.plugins.EmailTriggerDescriptor; @@ -26,7 +27,7 @@ public boolean trigger(AbstractBuild build, TaskListener listener) { Result buildResult = build.getResult(); if (buildResult == Result.SUCCESS) { - AbstractBuild prevBuild = build.getPreviousBuild(); + AbstractBuild prevBuild = ExtendedEmailPublisher.getPreviousBuild(build, listener); if (prevBuild != null && (prevBuild.getResult() == Result.UNSTABLE || prevBuild.getResult() == Result.FAILURE)) { return true; } diff --git a/src/main/java/hudson/plugins/emailext/plugins/trigger/FixedUnhealthyTrigger.java b/src/main/java/hudson/plugins/emailext/plugins/trigger/FixedUnhealthyTrigger.java index 2f13c3512..701d28083 100644 --- a/src/main/java/hudson/plugins/emailext/plugins/trigger/FixedUnhealthyTrigger.java +++ b/src/main/java/hudson/plugins/emailext/plugins/trigger/FixedUnhealthyTrigger.java @@ -4,6 +4,7 @@ import hudson.model.AbstractBuild; import hudson.model.Result; import hudson.model.TaskListener; +import hudson.plugins.emailext.ExtendedEmailPublisher; import hudson.plugins.emailext.plugins.EmailTrigger; import hudson.plugins.emailext.plugins.EmailTriggerDescriptor; @@ -25,7 +26,7 @@ public boolean trigger(AbstractBuild build, TaskListener listener) { Result buildResult = build.getResult(); if (buildResult == Result.SUCCESS) { - AbstractBuild prevBuild = getPreviousBuild(build); + AbstractBuild prevBuild = getPreviousBuild(build, listener); if (prevBuild != null && (prevBuild.getResult() == Result.UNSTABLE || prevBuild.getResult() == Result.FAILURE)) { return true; } @@ -37,13 +38,13 @@ public boolean trigger(AbstractBuild build, TaskListener listener) { /** * Find most recent previous build matching certain criteria. */ - private AbstractBuild getPreviousBuild(AbstractBuild build) { + private AbstractBuild getPreviousBuild(AbstractBuild build, TaskListener listener) { - AbstractBuild prevBuild = build.getPreviousBuild(); + AbstractBuild prevBuild = ExtendedEmailPublisher.getPreviousBuild(build, listener); // Skip ABORTED builds if (prevBuild != null && (prevBuild.getResult() == Result.ABORTED)) { - return getPreviousBuild(prevBuild); + return getPreviousBuild(prevBuild, listener); } return prevBuild; diff --git a/src/main/java/hudson/plugins/emailext/plugins/trigger/ImprovementTrigger.java b/src/main/java/hudson/plugins/emailext/plugins/trigger/ImprovementTrigger.java index 0500ca1b7..fd2f47570 100644 --- a/src/main/java/hudson/plugins/emailext/plugins/trigger/ImprovementTrigger.java +++ b/src/main/java/hudson/plugins/emailext/plugins/trigger/ImprovementTrigger.java @@ -3,6 +3,7 @@ import hudson.Extension; import hudson.model.AbstractBuild; import hudson.model.TaskListener; +import hudson.plugins.emailext.ExtendedEmailPublisher; import hudson.plugins.emailext.plugins.EmailTrigger; import hudson.plugins.emailext.plugins.EmailTriggerDescriptor; @@ -20,11 +21,12 @@ public ImprovementTrigger(boolean sendToList, boolean sendToDevs, boolean sendTo @Override public boolean trigger(AbstractBuild build, TaskListener listener) { + AbstractBuild previousBuild = ExtendedEmailPublisher.getPreviousBuild(build, listener); - if (build.getPreviousBuild() == null) + if (previousBuild == null) return false; if (build.getTestResultAction() == null) return false; - if (build.getPreviousBuild().getTestResultAction() == null) + if (previousBuild.getTestResultAction() == null) return false; int numCurrFailures = getNumFailures(build); @@ -33,7 +35,7 @@ public boolean trigger(AbstractBuild build, TaskListener listener) { // builds that aggregate downstream test results before those test // results are available... return build.getTestResultAction().getTotalCount() > 0 - && numCurrFailures < getNumFailures(build.getPreviousBuild()) + && numCurrFailures < getNumFailures(previousBuild) && numCurrFailures > 0; } diff --git a/src/main/java/hudson/plugins/emailext/plugins/trigger/NthFailureTrigger.java b/src/main/java/hudson/plugins/emailext/plugins/trigger/NthFailureTrigger.java index 713e225fa..b5bfbd7d2 100644 --- a/src/main/java/hudson/plugins/emailext/plugins/trigger/NthFailureTrigger.java +++ b/src/main/java/hudson/plugins/emailext/plugins/trigger/NthFailureTrigger.java @@ -3,6 +3,7 @@ import hudson.model.AbstractBuild; import hudson.model.Result; import hudson.model.TaskListener; +import hudson.plugins.emailext.ExtendedEmailPublisher; import hudson.plugins.emailext.plugins.EmailTrigger; import hudson.plugins.emailext.plugins.EmailTriggerDescriptor; @@ -35,7 +36,7 @@ public boolean trigger(AbstractBuild build, TaskListener listener) { return false; } - build = build.getPreviousBuild(); + build = ExtendedEmailPublisher.getPreviousBuild(build, listener); } // Check the the preceding build was a success. diff --git a/src/main/java/hudson/plugins/emailext/plugins/trigger/RegressionTrigger.java b/src/main/java/hudson/plugins/emailext/plugins/trigger/RegressionTrigger.java index 41b9e270e..b6c920fc7 100644 --- a/src/main/java/hudson/plugins/emailext/plugins/trigger/RegressionTrigger.java +++ b/src/main/java/hudson/plugins/emailext/plugins/trigger/RegressionTrigger.java @@ -4,6 +4,7 @@ import hudson.model.Result; import hudson.model.AbstractBuild; import hudson.model.TaskListener; +import hudson.plugins.emailext.ExtendedEmailPublisher; import hudson.plugins.emailext.plugins.EmailTrigger; import hudson.plugins.emailext.plugins.EmailTriggerDescriptor; @@ -22,14 +23,15 @@ public RegressionTrigger(boolean sendToList, boolean sendToDevs, boolean sendToR @Override public boolean trigger(AbstractBuild build, TaskListener listener) { - if (build.getPreviousBuild() == null) + AbstractBuild previousBuild = ExtendedEmailPublisher.getPreviousBuild(build, listener); + if (previousBuild == null) return build.getResult() == Result.FAILURE; if (build.getTestResultAction() == null) return false; - if (build.getPreviousBuild().getTestResultAction() == null) + if (previousBuild.getTestResultAction() == null) return build.getTestResultAction().getFailCount() > 0; return build.getTestResultAction().getFailCount() > - build.getPreviousBuild().getTestResultAction().getFailCount(); + previousBuild.getTestResultAction().getFailCount(); } @Extension diff --git a/src/main/java/hudson/plugins/emailext/plugins/trigger/StatusChangedTrigger.java b/src/main/java/hudson/plugins/emailext/plugins/trigger/StatusChangedTrigger.java index 761899619..40e995df8 100644 --- a/src/main/java/hudson/plugins/emailext/plugins/trigger/StatusChangedTrigger.java +++ b/src/main/java/hudson/plugins/emailext/plugins/trigger/StatusChangedTrigger.java @@ -4,6 +4,7 @@ import hudson.model.Result; import hudson.model.TaskListener; import hudson.model.AbstractBuild; +import hudson.plugins.emailext.ExtendedEmailPublisher; import hudson.plugins.emailext.plugins.EmailTriggerDescriptor; import hudson.plugins.emailext.plugins.EmailTrigger; @@ -25,7 +26,7 @@ public boolean trigger(AbstractBuild build, TaskListener listener) { final Result buildResult = build.getResult(); if (buildResult != null) { - final AbstractBuild prevBuild = build.getPreviousBuild(); + final AbstractBuild prevBuild = ExtendedEmailPublisher.getPreviousBuild(build, listener); if (prevBuild == null) { // Notify at the first status defined diff --git a/src/main/java/hudson/plugins/emailext/plugins/trigger/StillFailingTrigger.java b/src/main/java/hudson/plugins/emailext/plugins/trigger/StillFailingTrigger.java index b757f58e1..8d24f8df2 100644 --- a/src/main/java/hudson/plugins/emailext/plugins/trigger/StillFailingTrigger.java +++ b/src/main/java/hudson/plugins/emailext/plugins/trigger/StillFailingTrigger.java @@ -4,6 +4,7 @@ import hudson.model.AbstractBuild; import hudson.model.Result; import hudson.model.TaskListener; +import hudson.plugins.emailext.ExtendedEmailPublisher; import hudson.plugins.emailext.plugins.EmailTrigger; import hudson.plugins.emailext.plugins.EmailTriggerDescriptor; @@ -24,7 +25,7 @@ public boolean trigger(AbstractBuild build, TaskListener listener) { Result buildResult = build.getResult(); if (buildResult == Result.FAILURE) { - AbstractBuild prevBuild = build.getPreviousBuild(); + AbstractBuild prevBuild = ExtendedEmailPublisher.getPreviousBuild(build, listener); if (prevBuild != null && (prevBuild.getResult() == Result.FAILURE)) { return true; } diff --git a/src/main/java/hudson/plugins/emailext/plugins/trigger/StillUnstableTrigger.java b/src/main/java/hudson/plugins/emailext/plugins/trigger/StillUnstableTrigger.java index 7d6041459..219cf54af 100644 --- a/src/main/java/hudson/plugins/emailext/plugins/trigger/StillUnstableTrigger.java +++ b/src/main/java/hudson/plugins/emailext/plugins/trigger/StillUnstableTrigger.java @@ -4,6 +4,7 @@ import hudson.model.AbstractBuild; import hudson.model.Result; import hudson.model.TaskListener; +import hudson.plugins.emailext.ExtendedEmailPublisher; import hudson.plugins.emailext.plugins.EmailTrigger; import hudson.plugins.emailext.plugins.EmailTriggerDescriptor; @@ -25,7 +26,7 @@ public boolean trigger(AbstractBuild build, TaskListener listener) { Result buildResult = build.getResult(); if (buildResult == Result.UNSTABLE) { - AbstractBuild prevBuild = build.getPreviousBuild(); + AbstractBuild prevBuild = ExtendedEmailPublisher.getPreviousBuild(build, listener); if (prevBuild != null && (prevBuild.getResult() == Result.UNSTABLE)) { return true; } diff --git a/src/main/resources/hudson/plugins/emailext/Messages.properties b/src/main/resources/hudson/plugins/emailext/Messages.properties index 764398d86..64d284a20 100644 --- a/src/main/resources/hudson/plugins/emailext/Messages.properties +++ b/src/main/resources/hudson/plugins/emailext/Messages.properties @@ -1,3 +1,4 @@ +ExtendedEmailPublisher._is_still_in_progress_ignoring_for_purpo={0} is still in progress; ignoring for purposes of comparison ExtendedEmailPublisherDescriptor.DisplayName=Editable Email Notification ExtendedEmailPublisherDescriptor.AdminAddress=address not configured yet diff --git a/src/test/java/hudson/plugins/emailext/ExtendedEmailPublisherTest.java b/src/test/java/hudson/plugins/emailext/ExtendedEmailPublisherTest.java index 0e92fcd6d..d9b0bc362 100755 --- a/src/test/java/hudson/plugins/emailext/ExtendedEmailPublisherTest.java +++ b/src/test/java/hudson/plugins/emailext/ExtendedEmailPublisherTest.java @@ -2,14 +2,17 @@ import com.gargoylesoftware.htmlunit.html.HtmlPage; import com.gargoylesoftware.htmlunit.html.HtmlTextInput; +import hudson.Launcher; +import hudson.model.AbstractBuild; +import hudson.model.BuildListener; import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertThat; import static org.junit.matchers.JUnitMatchers.containsString; import static org.junit.matchers.JUnitMatchers.hasItems; import static org.junit.matchers.JUnitMatchers.hasItem; import hudson.model.FreeStyleBuild; import hudson.model.Result; import hudson.model.Cause.UserCause; +import hudson.model.Descriptor; import hudson.model.FreeStyleProject; import hudson.model.User; import hudson.plugins.emailext.plugins.EmailTrigger; @@ -20,13 +23,17 @@ import hudson.plugins.emailext.plugins.trigger.FixedUnhealthyTrigger; import hudson.plugins.emailext.plugins.trigger.NotBuiltTrigger; import hudson.plugins.emailext.plugins.trigger.PreBuildTrigger; +import hudson.plugins.emailext.plugins.trigger.RegressionTrigger; import hudson.plugins.emailext.plugins.trigger.StillFailingTrigger; import hudson.plugins.emailext.plugins.trigger.SuccessTrigger; +import hudson.tasks.Builder; import hudson.tasks.Mailer; +import java.io.IOException; import java.lang.reflect.Field; import java.util.List; import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; import javax.mail.Address; import javax.mail.Message; @@ -46,6 +53,7 @@ import static org.junit.Assert.*; import org.jvnet.hudson.test.Bug; import org.jvnet.hudson.test.JenkinsRule.WebClient; +import org.jvnet.hudson.test.SleepBuilder; public class ExtendedEmailPublisherTest { @@ -773,6 +781,37 @@ public void testConfiguredStateNoTriggers() HtmlTextInput recipientList = page.getElementByName("project_recipient_list"); assertEquals(recipientList.getText(), "mickey@disney.com"); } + + @Bug(16376) + @Test public void concurrentBuilds() throws Exception { + publisher.configuredTriggers.add(new RegressionTrigger(false, false, false, false, "", "", "", "", "", 0, "")); + project.setConcurrentBuild(true); + project.getBuildersList().add(new SleepOnceBuilder()); + FreeStyleBuild build1 = project.scheduleBuild2(0).waitForStart(); + assertEquals(1, build1.number); + FreeStyleBuild build2 = j.assertBuildStatusSuccess(project.scheduleBuild2(0).get(9999, TimeUnit.MILLISECONDS)); + assertEquals(2, build2.number); + assertTrue(build1.isBuilding()); + assertFalse(build2.isBuilding()); + j.assertLogContains(Messages.ExtendedEmailPublisher__is_still_in_progress_ignoring_for_purpo(build1.getDisplayName()), build2); + } + /** + * Similar to {@link SleepBuilder} but only on the first build. + * (Removing the builder between builds is tricky since you would have to wait for the first one to actually start it.) + */ + private static final class SleepOnceBuilder extends Builder { + @Override public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { + if (build.number == 1) { + Thread.sleep(99999); + } + return true; + } + public static final class DescriptorImpl extends Descriptor { + @Override public String getDisplayName() { + return "Sleep once"; + } + } + } private void addEmailType(EmailTrigger trigger) { trigger.setEmail(new EmailType() {