aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pom.xml5
-rw-r--r--src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java64
-rw-r--r--src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketPullRequestsBuilder.java2
-rw-r--r--src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java7
-rw-r--r--src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly3
-rw-r--r--src/test/java/BitbucketBuildRepositoryTest.java12
6 files changed, 77 insertions, 16 deletions
diff --git a/pom.xml b/pom.xml
index 976d29c..fb23ec8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,6 +25,11 @@
<name>nishio_dens</name>
<email>nishio@densan-labs.net</email>
</developer>
+ <developer>
+ <id>damovsky</id>
+ <name>Martin Damovsky</name>
+ <email>martin.damovsky@gmail.com</email>
+ </developer>
</developers>
<!-- get every artifact through repo.jenkins-ci.org, which proxies all the artifacts that we need -->
diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java
index aedfb91..90de6b5 100644
--- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java
+++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java
@@ -7,20 +7,26 @@ import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredenti
import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials;
import hudson.Extension;
import hudson.model.*;
+import hudson.model.Queue;
import hudson.model.queue.QueueTaskFuture;
import hudson.plugins.git.RevisionParameterAction;
import hudson.triggers.Trigger;
import hudson.triggers.TriggerDescriptor;
import hudson.util.ListBoxModel;
+import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
+import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import static com.cloudbees.plugins.credentials.CredentialsMatchers.instanceOf;
@@ -43,11 +49,12 @@ public class BitbucketBuildTrigger extends Trigger<AbstractProject<?, ?>> {
private final String ciSkipPhrases;
private final boolean checkDestinationCommit;
private final boolean approveIfSuccess;
+ private final boolean cancelOutdatedJobs;
transient private BitbucketPullRequestsBuilder bitbucketPullRequestsBuilder;
@Extension
- public static final BitbucketBuildTriggerDescriptor descriptor = new BitbucketBuildTriggerDescriptor();
+ public static final BitbucketBuildTriggerDescriptor descriptor = new BitbucketBuildTriggerDescriptor();
@DataBoundConstructor
public BitbucketBuildTrigger(
@@ -64,7 +71,8 @@ public class BitbucketBuildTrigger extends Trigger<AbstractProject<?, ?>> {
String ciName,
String ciSkipPhrases,
boolean checkDestinationCommit,
- boolean approveIfSuccess
+ boolean approveIfSuccess,
+ boolean cancelOutdatedJobs
) throws ANTLRException {
super(cron);
this.projectPath = projectPath;
@@ -81,6 +89,7 @@ public class BitbucketBuildTrigger extends Trigger<AbstractProject<?, ?>> {
this.ciSkipPhrases = ciSkipPhrases;
this.checkDestinationCommit = checkDestinationCommit;
this.approveIfSuccess = approveIfSuccess;
+ this.cancelOutdatedJobs = cancelOutdatedJobs;
}
public String getProjectPath() {
@@ -114,7 +123,7 @@ public class BitbucketBuildTrigger extends Trigger<AbstractProject<?, ?>> {
public String getBranchesFilter() {
return branchesFilter;
}
-
+
public boolean getBranchesFilterBySCMIncludes() {
return branchesFilterBySCMIncludes;
}
@@ -139,6 +148,10 @@ public class BitbucketBuildTrigger extends Trigger<AbstractProject<?, ?>> {
return approveIfSuccess;
}
+ public boolean getCancelOutdatedJobs() {
+ return cancelOutdatedJobs;
+ }
+
@Override
public void start(AbstractProject<?, ?> project, boolean newInstance) {
try {
@@ -164,9 +177,54 @@ public class BitbucketBuildTrigger extends Trigger<AbstractProject<?, ?>> {
public QueueTaskFuture<?> startJob(BitbucketCause cause) {
Map<String, ParameterValue> values = this.getDefaultParameters();
+
+ if (getCancelOutdatedJobs()) {
+ cancelPreviousJobsInQueueThatMatch(cause);
+ abortRunningJobsThatMatch(cause);
+ }
+
return this.job.scheduleBuild2(0, cause, new ParametersAction(new ArrayList(values.values())), new RevisionParameterAction(cause.getSourceCommitHash()));
}
+ private void cancelPreviousJobsInQueueThatMatch(@Nonnull BitbucketCause bitbucketCause) {
+ logger.fine("Looking for queued jobs that match PR ID: " + bitbucketCause.getPullRequestId());
+ Queue queue = Jenkins.getInstance().getQueue();
+ for (Queue.Item item : queue.getItems()) {
+ if (hasCauseFromTheSamePullRequest(item.getCauses(), bitbucketCause)) {
+ logger.info("Canceling item in queue: " + item);
+ queue.cancel(item);
+ }
+ }
+ }
+
+ private void abortRunningJobsThatMatch(@Nonnull BitbucketCause bitbucketCause) {
+ logger.fine("Looking for running jobs that match PR ID: " + bitbucketCause.getPullRequestId());
+ for (Object o : job.getBuilds()) {
+ if (o instanceof Build) {
+ Build build = (Build) o;
+ if (build.isBuilding() && hasCauseFromTheSamePullRequest(build.getCauses(), bitbucketCause)) {
+ logger.info("Aborting build: " + build + " since PR is outdated");
+ build.getExecutor().interrupt(Result.ABORTED);
+ }
+ }
+ }
+ }
+
+ private boolean hasCauseFromTheSamePullRequest(@Nullable List<Cause> causes, @Nullable BitbucketCause pullRequestCause) {
+ if (causes != null && pullRequestCause != null) {
+ for (Cause cause : causes) {
+ if (cause instanceof BitbucketCause) {
+ BitbucketCause sc = (BitbucketCause) cause;
+ if (StringUtils.equals(sc.getPullRequestId(), pullRequestCause.getPullRequestId()) &&
+ StringUtils.equals(sc.getRepositoryName(), pullRequestCause.getRepositoryName())) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
private Map<String, ParameterValue> getDefaultParameters() {
Map<String, ParameterValue> values = new HashMap<String, ParameterValue>();
ParametersDefinitionProperty definitionProperty = this.job.getProperty(ParametersDefinitionProperty.class);
diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketPullRequestsBuilder.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketPullRequestsBuilder.java
index d337796..899edba 100644
--- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketPullRequestsBuilder.java
+++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketPullRequestsBuilder.java
@@ -69,10 +69,8 @@ public class BitbucketPullRequestsBuilder {
return new String(Hex.encodeHex(MD5.digest(this.project.getFullName().getBytes("UTF-8"))));
} catch (NoSuchAlgorithmException exc) {
logger.log(Level.WARNING, "Failed to produce hash", exc);
- exc.printStackTrace();
} catch (UnsupportedEncodingException exc) {
logger.log(Level.WARNING, "Failed to produce hash", exc);
- exc.printStackTrace();
}
return this.project.getFullName();
}
diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java
index 759c696..0c87478 100644
--- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java
+++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java
@@ -119,10 +119,8 @@ public class ApiClient {
return new String(Hex.encodeHex(SHA1.digest(computedKey.getBytes("UTF-8"))));
} catch(NoSuchAlgorithmException e) {
logger.log(Level.WARNING, "Failed to create hash provider", e);
- e.printStackTrace();
} catch (UnsupportedEncodingException e) {
logger.log(Level.WARNING, "Failed to create hash provider", e);
- e.printStackTrace();
}
}
return (computedKey.length() <= MAX_KEY_SIZE_BB_API) ? computedKey : computedKey.substring(0, MAX_KEY_SIZE_BB_API);
@@ -173,7 +171,6 @@ public class ApiClient {
new NameValuePair[]{}), Pullrequest.Participant.class);
} catch (IOException e) {
logger.log(Level.WARNING, "Invalid pull request approval response.", e);
- e.printStackTrace();
}
return null;
}
@@ -186,7 +183,6 @@ public class ApiClient {
return parse(post(v1("/pullrequests/" + pullRequestId + "/comments"), data), new TypeReference<Pullrequest.Comment>() {});
} catch(Exception e) {
logger.log(Level.WARNING, "Invalid pull request comment response.", e);
- e.printStackTrace();
}
return null;
}
@@ -203,7 +199,6 @@ public class ApiClient {
} while (url != null);
} catch (Exception e) {
logger.log(Level.WARNING, "invalid response.", e);
- e.printStackTrace();
}
return values;
}
@@ -255,10 +250,8 @@ public class ApiClient {
return req.getResponseBodyAsString();
} catch (HttpException e) {
logger.log(Level.WARNING, "Failed to send request.", e);
- e.printStackTrace();
} catch (IOException e) {
logger.log(Level.WARNING, "Failed to send request.", e);
- e.printStackTrace();
} finally {
req.releaseConnection();
}
diff --git a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly
index d4b23da..971954f 100644
--- a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly
+++ b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly
@@ -38,4 +38,7 @@
<f:entry title="Approve if build success?" field="approveIfSuccess">
<f:checkbox />
</f:entry>
+ <f:entry title="Cancel outdated jobs?" field="cancelOutdatedJobs">
+ <f:checkbox default="false"/>
+ </f:entry>
</j:jelly>
diff --git a/src/test/java/BitbucketBuildRepositoryTest.java b/src/test/java/BitbucketBuildRepositoryTest.java
index 953bd81..148e504 100644
--- a/src/test/java/BitbucketBuildRepositoryTest.java
+++ b/src/test/java/BitbucketBuildRepositoryTest.java
@@ -118,7 +118,8 @@ public class BitbucketBuildRepositoryTest {
"", true,
"", "", "",
true,
- true
+ true,
+ false
);
BitbucketPullRequestsBuilder builder = EasyMock.createMock(BitbucketPullRequestsBuilder.class);
@@ -148,7 +149,8 @@ public class BitbucketBuildRepositoryTest {
"", true,
"", "", "",
true,
- true
+ true,
+ false
);
BitbucketPullRequestsBuilder builder = EasyMock.createMock(BitbucketPullRequestsBuilder.class);
@@ -202,7 +204,8 @@ public class BitbucketBuildRepositoryTest {
"", true,
"jenkins", "Jenkins", "",
true,
- true
+ true,
+ false
);
BitbucketPullRequestsBuilder builder = EasyMock.createMock(BitbucketPullRequestsBuilder.class);
@@ -248,7 +251,8 @@ public class BitbucketBuildRepositoryTest {
"", true,
"jenkins-too-long-ci-key", "Jenkins", "",
true,
- true
+ true,
+ false
);
final MessageDigest MD5 = MessageDigest.getInstance("MD5");