aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md54
-rw-r--r--pom.xml5
-rw-r--r--src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketPullRequestsBuilder.java2
-rw-r--r--src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java53
-rw-r--r--src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java34
-rw-r--r--src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilter.html31
-rw-r--r--src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilterBySCMIncludes.html10
-rw-r--r--src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-ciSkipPhrases.html5
8 files changed, 125 insertions, 69 deletions
diff --git a/README.md b/README.md
index ec61a65..15e8030 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
Bitbucket Pull Request Builder Plugin
-================================
+=====================================
This Jenkins plugin builds pull requests from Bitbucket.org and will report the test results.
@@ -7,25 +7,23 @@ This Jenkins plugin builds pull requests from Bitbucket.org and will report the
Prerequisites
-================================
+-------------
- Jenkins 1.509.4 or higher.
- https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin
Creating a Job
-=================================
+-------------
- Create a new job
-- Select Git SCM
-- Add Repository URL as bellow
- - git@bitbucket.org:${repositoryOwner}/${repositoryName}.git
-- In Branch Specifier, type as bellow
- - */${sourceBranch}
+- Select and configure Git SCM
+ - Add Repository URL, `git@bitbucket.org:${repositoryOwner}/${repositoryName}.git`
+ - In Branch Specifier, type `*/${sourceBranch}`
- Under Build Triggers, check Bitbucket Pull Request Builder
- In Cron, enter crontab for this job.
- - ex: * * * * *
-- In Bitbucket BasicAuth Username, write your bitbucket username like jenkins@densan-labs.net
+ - e.g. `* * * * *` will check for new pull requests every minute
+- In Bitbucket BasicAuth Username, write your bitbucket username, like `jenkins@densan-labs.net`
- In Bitbucket BasicAuth Password, write your password
- In CI Identifier, enter an unique identifier among your Jenkins jobs related to the repo
- In CI Name, enter a human readable name for your Jenkins server
@@ -33,30 +31,46 @@ Creating a Job
- Write RepositoryName
- Save to preserve your changes
+
Merge the Pull Request's Source Branch into the Target Branch Before Building
-==============================================================================
-You may want Jenkins to attempt to merge your PR before doing the build -- this way it will find conflicts for you automatically.
+-----------------------------------------------------------------------------
+
+You may want Jenkins to attempt to merge your PR before building.
+This may help expose inconsistencies between the source branch and target branch.
+Note that if the merge cannot be completed, the build will fail immediately.
+
- Follow the steps above in "Creating a Job"
- In the "Source Code Management" > "Git" > "Additional Behaviors" section, click "Add" > "Merge Before Building"
-- In "Name of Repository" put "origin" (or, if not using default name, use your remote repository's name. Note: unlike in the main part of the Git Repository config, you cannot leave this item blank for "default".)
+- In "Name of Repository" put "origin" (or, if not using default name, use your remote repository's name. Note: unlike in the main part of the Git Repository config, you cannot leave this item blank for "default").
- In "Branch to merge to" put "${targetBranch}"
- Note that as long as you don't push these changes to your remote repository, the merge only happens in your local repository.
-
If you are merging into your target branch, you might want Jenkins to do a new build of the Pull Request when the target branch changes.
- There is a checkbox that says, "Rebuild if destination branch changes?" which enables this check.
-Rerun test builds
-====================
+Rerun a Build
+-------------
+
+If you want to rerun a pull request build, write a comment on your pull request reading “test this please”.
-If you want to rerun pull request test, write “test this please” comment to your pull request.
+Environment Variables Provided
+------------------------------
+- `sourceBranch`
+- `targetBranch`
+- `repositoryOwner`
+- `repositoryName`
+- `pullRequestId`
+- `destinationRepositoryOwner`
+- `destinationRepositoryName`
+- `pullRequestTitle`
+- `pullRequestAuthor`
Contributing to Bitbucket Pull Request Builder Plugin
-================================================
+-----------------------------------------------------
- Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
@@ -70,13 +84,13 @@ Contributing to Bitbucket Pull Request Builder Plugin
Copyright
-=============================
+---------
Copyright © 2014 S.nishio.
License
-=============================
+-------
- BSD License
- See COPYING file
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/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 c8dfeb2..0c87478 100644
--- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java
+++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/ApiClient.java
@@ -5,10 +5,14 @@ import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.DeleteMethod;
+import org.apache.commons.httpclient.params.HttpClientParams;
import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.type.TypeFactory;
+import org.codehaus.jackson.type.JavaType;
import org.codehaus.jackson.type.TypeReference;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
@@ -42,10 +46,16 @@ public class ApiClient {
public static final byte MAX_KEY_SIZE_BB_API = 40;
public static class HttpClientFactory {
- public static final HttpClientFactory INSTANCE = new HttpClientFactory();
+ public static final HttpClientFactory INSTANCE = new HttpClientFactory();
+ private static final int DEFAULT_TIMEOUT = 60000;
public HttpClient getInstanceHttpClient() {
HttpClient client = new HttpClient();
+
+ HttpClientParams params = client.getParams();
+ params.setConnectionManagerTimeout(DEFAULT_TIMEOUT);
+ params.setSoTimeout(DEFAULT_TIMEOUT);
+
if (Jenkins.getInstance() == null) return client;
ProxyConfiguration proxy = Jenkins.getInstance().proxy;
@@ -82,23 +92,11 @@ public class ApiClient {
}
public List<Pullrequest> getPullRequests() {
- try {
- return parse(get(v2("/pullrequests/")), Pullrequest.Response.class).getPullrequests();
- } catch(Exception e) {
- logger.log(Level.WARNING, "invalid pull request response.", e);
- e.printStackTrace();
- }
- return Collections.EMPTY_LIST;
+ return getAllValues(v2("/pullrequests/"), 50, Pullrequest.class);
}
public List<Pullrequest.Comment> getPullRequestComments(String commentOwnerName, String commentRepositoryName, String pullRequestId) {
- try {
- return parse(get(v1("/pullrequests/" + pullRequestId + "/comments")), new TypeReference<List<Pullrequest.Comment>>() {});
- } catch(Exception e) {
- logger.log(Level.WARNING, "invalid pull request response.", e);
- e.printStackTrace();
- }
- return Collections.EMPTY_LIST;
+ return getAllValues(v2("/pullrequests/" + pullRequestId + "/comments"), 100, Pullrequest.Comment.class);
}
public String getName() {
@@ -121,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);
@@ -175,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;
}
@@ -188,11 +183,26 @@ 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;
}
+ private <T> List<T> getAllValues(String rootUrl, int pageLen, Class<T> cls) {
+ List<T> values = new ArrayList<T>();
+ try {
+ String url = rootUrl + "?pagelen=" + pageLen;
+ do {
+ final JavaType type = TypeFactory.defaultInstance().constructParametricType(Pullrequest.Response.class, cls);
+ Pullrequest.Response<T> response = parse(get(url), type);
+ values.addAll(response.getValues());
+ url = response.getNext();
+ } while (url != null);
+ } catch (Exception e) {
+ logger.log(Level.WARNING, "invalid response.", e);
+ }
+ return values;
+ }
+
private HttpClient getHttpClient() {
return this.factory.getInstanceHttpClient();
}
@@ -240,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();
}
@@ -253,6 +261,9 @@ public class ApiClient {
private <R> R parse(String response, Class<R> cls) throws IOException {
return new ObjectMapper().readValue(response, cls);
}
+ private <R> R parse(String response, JavaType type) throws IOException {
+ return new ObjectMapper().readValue(response, type);
+ }
private <R> R parse(String response, TypeReference<R> ref) throws IOException {
return new ObjectMapper().readValue(response, ref);
}
diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java
index 140c213..25755a4 100644
--- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java
+++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java
@@ -2,6 +2,7 @@ package bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket;
import java.util.List;
import java.util.Comparator;
+import java.util.Map;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
@@ -31,11 +32,12 @@ public class Pullrequest {
private Author author;
@JsonIgnoreProperties(ignoreUnknown = true)
- public static class Response {
+ public static class Response<T> {
private int pageLength;
- private List<Pullrequest> pullrequests;
+ private List<T> values;
private int page;
private int size;
+ private String next;
@JsonProperty("pagelen")
public int getPageLength() {
@@ -45,13 +47,11 @@ public class Pullrequest {
public void setPageLength(int pageLength) {
this.pageLength = pageLength;
}
- @JsonProperty("values")
- public List<Pullrequest> getPullrequests() {
- return pullrequests;
+ public List<T> getValues() {
+ return values;
}
- @JsonProperty("values")
- public void setPullrequests(List<Pullrequest> pullrequests) {
- this.pullrequests = pullrequests;
+ public void setValues(List<T> values) {
+ this.values = values;
}
public int getPage() {
return page;
@@ -65,8 +65,15 @@ public class Pullrequest {
public void setSize(int size) {
this.size = size;
}
+ public String getNext() {
+ return next;
+ }
+ public void setNext(String next) {
+ this.next = next;
+ }
}
+
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Revision {
private Repository repository;
@@ -107,7 +114,7 @@ public class Pullrequest {
@JsonProperty("full_name")
public void setFullName(String fullName) {
// Also extract owner- and reponame
- if (name != null) {
+ if (fullName != null) {
this.ownerName = fullName.split("/")[0];
this.repositoryName = fullName.split("/")[1];
}
@@ -214,8 +221,13 @@ public class Pullrequest {
return content;
}
- public void setContent(String content) {
- this.content = content;
+ public void setContent(Object content) {
+ if (content instanceof String) {
+ this.content = (String)content;
+ } else if (content instanceof Map){
+ this.content = (String)((Map)content).get("raw");
+ }
+ return;
}
@JsonProperty("utc_last_updated")
public String getUpdatedOn() {
diff --git a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilter.html b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilter.html
index 88af799..30e5f5e 100644
--- a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilter.html
+++ b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilter.html
@@ -1,12 +1,19 @@
-Filter option in custom format. Default value is empty or "any".
-Available formats:
-* any pull requests applied for this project: "any", "*" or empty string.
-* filtered by destination branch: "my-branch" or more complex reg-ex filter "r:^master" (must be started with "r:" and case insensitive match).
-* filtered by source and destination branches: "s:source-branch d:dest-branch"
-* filtered by source and destination branches with regex: "s:r:^feature d:r:master$"
-* filtered by many destination/source branches: "s:one s:two s:three d:master d:r:master$"
-* filtered by many sources branches: "s:one s:two s:r:^three d:"
-When you using format with source branch filter "s" or destination filter "d", you must cpecify great than one source and destination filter, eg "s:1 s:2 s:... d:".
-Any sources and any destinations for pull request:
-* filter string: "*"
-* filter string: "s: d:"
+<div>
+ Filter option in custom format. Default value is empty or <tt>any</tt>.<br/>
+ Available formats:
+ <ul>
+ <li>any pull requests applied for this project: <tt>any</tt>, <tt>*</tt> or empty string</li>
+ <li>filtered by destination branch: <tt>my-branch</tt> or more complex reg-ex filter <tt>r:^master</tt> (must be started with <tt>r:</tt> and case insensitive match).</li>
+ <li>filtered by source and destination branches: <tt>s:source-branch d:dest-branch</tt></li>
+ <li>filtered by source and destination branches with regex: <tt>s:r:^feature d:r:master$</tt></li>
+ <li>filtered by many destination/source branches: <tt>s:one s:two s:three d:master d:r:master$</tt></li>
+ <li>filtered by many sources branches: <tt>s:one s:two s:r:^three d:</tt></li>
+ </ul>
+ <p/>
+ When you using format with source branch filter <tt>s</tt> or destination filter <tt>d</tt>, you must specify great than one source and destination filter, eg <tt>s:1 s:2 s:... d:</tt>.<br/>
+ Any sources and any destinations for pull request:
+ <ul>
+ <li>filter string: <tt>*</tt></li>
+ <li>filter string: <tt>s: d:</tt></li>
+ </ul>
+</div>
diff --git a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilterBySCMIncludes.html b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilterBySCMIncludes.html
index 3f24419..cc9d47c 100644
--- a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilterBySCMIncludes.html
+++ b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilterBySCMIncludes.html
@@ -1,3 +1,7 @@
-It is sugar-option for synchronize option "BranchesFilter" to Git SCM option "Branches to build" without manual editing.
-Check this option suppose than your "BranchesFilter" field has logick equal value with Git SCM "Branches to build" option (original value from "BranchesFilter" field will e ignored).
-If "Branches to build" option has values "*/master */feature-master */build-with-jenkins", then "BranchesFilter" field will have value "d:master d:feature-master d:build-with-jenkins".
+Uses the Git SCM option "Branches to build" option as the value for
+"BranchesFilter". If the "BranchesFilter" field itself has any content,
+it will be ignored.
+<br>
+If the "Branches to build" option has values
+"*/master */feature-master */build-with-jenkins", then "BranchesFilter"
+field will have value "d:master d:feature-master d:build-with-jenkins".
diff --git a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-ciSkipPhrases.html b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-ciSkipPhrases.html
new file mode 100644
index 0000000..f30f306
--- /dev/null
+++ b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-ciSkipPhrases.html
@@ -0,0 +1,5 @@
+A comma-separated list of strings to search the pull request title for.
+<br>
+e.g. If set to "trivial,[skiptest]", any PRs containing either "trivial" or
+"[skiptest]" (case-insensitive) will not be built.
+