diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java index c709cdb13..d4609cbe7 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java @@ -33,6 +33,13 @@ import java.util.logging.Logger; import java.util.regex.Pattern; +import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; +import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBranch; +import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketCommit; +import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest; +import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequestSource; +import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository; +import com.cloudbees.jenkins.plugins.sshcredentials.SSHUserPrivateKey; import com.cloudbees.plugins.credentials.CredentialsNameProvider; import org.apache.commons.lang.StringUtils; import org.kohsuke.stapler.AncestorInPath; @@ -40,11 +47,6 @@ import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; -import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; -import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBranch; -import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketCommit; -import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest; -import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository; import com.cloudbees.jenkins.plugins.sshcredentials.SSHUserPrivateKey; import com.cloudbees.plugins.credentials.common.StandardCredentials; import com.cloudbees.plugins.credentials.common.StandardListBoxModel; @@ -80,7 +82,7 @@ /** * SCM source implementation for Bitbucket. - * + *
* It provides a way to discover/retrieve branches and pull requests through the Bitbuclet REST API
* which is much faster than the plain Git SCM source implementation.
*/
@@ -289,21 +291,24 @@ private void retrievePullRequests(SCMHeadObserver observer, final TaskListener l
if (bitbucket.isPrivate()) {
List extends BitbucketPullRequest> pulls = bitbucket.getPullRequests();
for (final BitbucketPullRequest pull : pulls) {
+ BitbucketPullRequestSource source = pull.getSource();
+ BitbucketRepository repository = source.getRepository();
+ BitbucketBranch branch = source.getBranch();
listener.getLogger().println(
- "Checking PR from " + pull.getSource().getRepository().getFullName() + " and branch "
- + pull.getSource().getBranch().getName());
+ "Checking PR from " + repository.getFullName() + " and branch "
+ + branch.getName());
// Resolve full hash. See https://bitbucket.org/site/master/issues/11415/pull-request-api-should-return-full-commit
String hash = bitbucket.resolveSourceFullHash(pull);
if (hash != null) {
- observe(observer, listener,
- pull.getSource().getRepository().getOwnerName(),
- pull.getSource().getRepository().getRepositoryName(),
- pull.getSource().getBranch().getName(),
- hash,
- Integer.parseInt(pull.getId()));
+ if (shouldObserve(listener, repository.getOwnerName(),
+ repository.getRepositoryName(),
+ branch.getName(), hash)) {
+ PullrequestSCMHead prHead = new PullrequestSCMHead(pull);
+ observe(observer, prHead, hash);
+ }
} else {
- listener.getLogger().format("Can not resolve hash: [%s]%n", pull.getSource().getCommit().getHash());
+ listener.getLogger().format("Can not resolve hash: [%s]%n", source.getCommit().getHash());
}
if (!observer.isObserving()) {
return;
@@ -323,16 +328,18 @@ private void retrieveBranches(@NonNull final SCMHeadObserver observer, @NonNull
List extends BitbucketBranch> branches = bitbucket.getBranches();
for (BitbucketBranch branch : branches) {
listener.getLogger().println("Checking branch " + branch.getName() + " from " + fullName);
- observe(observer, listener, repoOwner, repository, branch.getName(),
- branch.getRawNode(), null);
+ if (shouldObserve(listener, repoOwner, repository, branch.getName(), branch.getRawNode())) {
+ SCMHeadWithOwnerAndRepo head = new SCMHeadWithOwnerAndRepo(repoOwner, repository, branch.getName());
+ observe(observer, head, branch.getRawNode());
+ }
}
}
- private void observe(SCMHeadObserver observer, final TaskListener listener,
- final String owner, final String repositoryName,
- final String branchName, final String hash, Integer prId) throws IOException {
+ private boolean shouldObserve(final TaskListener listener,
+ final String owner, final String repositoryName,
+ final String branchName, final String hash) throws IOException {
if (isExcluded(branchName)) {
- return;
+ return false;
}
final BitbucketApi bitbucket = getBitbucketConnector().create(owner, repositoryName, getScanCredentials());
SCMSourceCriteria branchCriteria = getCriteria();
@@ -362,13 +369,18 @@ public boolean exists(@NonNull String path) throws IOException {
};
if (branchCriteria.isHead(probe, listener)) {
listener.getLogger().println("Met criteria");
+ return true;
} else {
listener.getLogger().println("Does not meet criteria");
- return;
+ return false;
}
}
+ return true;
+ }
+
+ private synchronized void observe(SCMHeadObserver observer,
+ SCMHead head, final String hash) throws IOException {
SCMRevision revision;
- SCMHeadWithOwnerAndRepo head = new SCMHeadWithOwnerAndRepo(owner, repositoryName, branchName, prId);
if (getRepositoryType() == RepositoryType.MERCURIAL) {
revision = new MercurialRevision(head, hash);
} else {
@@ -450,12 +462,12 @@ private StandardCredentials getCheckoutCredentials() {
}
public String getRemoteName() {
- return "origin";
+ return "origin";
}
/**
* Returns true if the branchName isn't matched by includes or is matched by excludes.
- *
+ *
* @param branchName
* @return true if branchName is excluded or is not included
*/
@@ -465,10 +477,10 @@ private boolean isExcluded(String branchName) {
}
/**
- * Returns the pattern corresponding to the branches containing wildcards.
- *
- * @param branches space separated list of expressions.
- * For example "*" which would match all branches and branch* would match branch1, branch2, etc.
+ * Returns the pattern corresponding to the branches containing wildcards.
+ *
+ * @param branches space separated list of expressions.
+ * For example "*" which would match all branches and branch* would match branch1, branch2, etc.
* @return pattern corresponding to the branches containing wildcards (ready to be used by {@link Pattern})
*/
private String getPattern(String branches) {
@@ -548,7 +560,7 @@ public static FormValidation doCheckBitbucketServerUrl(@QueryParameter String bi
try {
new URL(bitbucketServerUrl);
} catch (MalformedURLException e) {
- return FormValidation.error("Invalid URL: " + e.getMessage());
+ return FormValidation.error("Invalid URL: " + e.getMessage());
}
return FormValidation.ok();
}
diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/PullRequestAction.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/PullRequestAction.java
new file mode 100644
index 000000000..585bd0e10
--- /dev/null
+++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/PullRequestAction.java
@@ -0,0 +1,27 @@
+package com.cloudbees.jenkins.plugins.bitbucket;
+
+import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest;
+import jenkins.scm.api.actions.ChangeRequestAction;
+
+final class PullRequestAction extends ChangeRequestAction {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String number;
+ private final String title;
+
+ PullRequestAction(BitbucketPullRequest pr) {
+ number = pr.getId();
+ title = pr.getTitle();
+ }
+
+ @Override
+ public String getId() {
+ return number;
+ }
+
+ @Override
+ public String getTitle() {
+ return title;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/PullrequestSCMHead.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/PullrequestSCMHead.java
new file mode 100644
index 000000000..bed3041b7
--- /dev/null
+++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/PullrequestSCMHead.java
@@ -0,0 +1,37 @@
+package com.cloudbees.jenkins.plugins.bitbucket;
+
+import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest;
+import edu.umd.cs.findbugs.annotations.NonNull;
+import hudson.model.Action;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PullrequestSCMHead extends SCMHeadWithOwnerAndRepo {
+
+ private static final long serialVersionUID = 1L;
+ private static final String PR_BRANCH_PREFIX = "PR-";
+
+ private final PullRequestAction metatdata;
+
+ public PullrequestSCMHead(BitbucketPullRequest pullRequest) {
+ super(pullRequest.getSource().getRepository().getOwnerName(),
+ pullRequest.getSource().getRepository().getRepositoryName(),
+ pullRequest.getSource().getBranch().getName());
+ this.metatdata = new PullRequestAction(pullRequest);
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return PR_BRANCH_PREFIX + metatdata.getId();
+ }
+
+ @NonNull
+ @Override
+ public List extends Action> getAllActions() {
+ List
*
- * This information is required in this plugin since {@link BitbucketSCMSource} is processing pull requests
- * and they are managed as separate repositories in Bitbucket without any reference to them in the destination
- * repository.
*/
public class SCMHeadWithOwnerAndRepo extends SCMHead {
@@ -45,19 +40,10 @@ public class SCMHeadWithOwnerAndRepo extends SCMHead {
private final String repoName;
- private final Integer pullRequestId;
-
- private static final String PR_BRANCH_PREFIX = "PR-";
-
- public SCMHeadWithOwnerAndRepo(String repoOwner, String repoName, String branchName, Integer pullRequestId) {
+ public SCMHeadWithOwnerAndRepo(String repoOwner, String repoName, String branchName) {
super(branchName);
this.repoOwner = repoOwner;
this.repoName = repoName;
- this.pullRequestId = pullRequestId;
- }
-
- public SCMHeadWithOwnerAndRepo(String repoOwner, String repoName, String branchName) {
- this(repoOwner, repoName, branchName, null);
}
public String getRepoOwner() {
@@ -69,24 +55,9 @@ public String getRepoName() {
}
/**
- * @return the original branch name without the "PR-owner-" part.
+ * @return the original branch name.
*/
public String getBranchName() {
return super.getName();
}
-
- /**
- * Returns the prettified branch name by adding "PR-[ID]" if the branch is coming from a PR.
- * Use {@link #getBranchName()} to get the real branch name.
- */
- @Override
- public String getName() {
- return pullRequestId != null ? PR_BRANCH_PREFIX + pullRequestId : getBranchName();
- }
-
- @CheckForNull
- public Integer getPullRequestId() {
- return pullRequestId;
- }
-
}
diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketPullRequest.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketPullRequest.java
index 17ef3ccae..31fde2efa 100644
--- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketPullRequest.java
+++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketPullRequest.java
@@ -39,4 +39,8 @@ public interface BitbucketPullRequest {
*/
String getId();
+ /**
+ * @return pull request Title as provided by Bitbucket. It will be used for the job name.
+ */
+ String getTitle();
}
\ No newline at end of file
diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/pullrequest/BitbucketPullRequestValue.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/pullrequest/BitbucketPullRequestValue.java
index 671eb918e..cac82fbcd 100644
--- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/pullrequest/BitbucketPullRequestValue.java
+++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/pullrequest/BitbucketPullRequestValue.java
@@ -32,6 +32,7 @@
public class BitbucketPullRequestValue implements BitbucketPullRequest {
private BitbucketPullRequestValueRepository source;
private String id;
+ private String title;
public BitbucketPullRequestSource getSource() {
return source;
@@ -49,4 +50,11 @@ public void setId(String id) {
this.id = id;
}
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
}
diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/pullrequest/BitbucketServerPullRequest.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/pullrequest/BitbucketServerPullRequest.java
index 89caa6144..0738c5fbd 100644
--- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/pullrequest/BitbucketServerPullRequest.java
+++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/pullrequest/BitbucketServerPullRequest.java
@@ -34,6 +34,8 @@ public class BitbucketServerPullRequest implements BitbucketPullRequest {
private String id;
+ private String title;
+
@JsonProperty("fromRef")
private BitbucketServerPullRequestSource source;
@@ -55,4 +57,12 @@ public void setId(String id) {
this.id = id;
}
+ @Override
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
}
diff --git a/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketClientMockUtils.java b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketClientMockUtils.java
index 78c202282..7677bd67c 100644
--- a/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketClientMockUtils.java
+++ b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketClientMockUtils.java
@@ -159,6 +159,7 @@ private static BitbucketPullRequestValue getPullRequest() {
pr.setSource(source);
pr.setId("23");
+ pr.setTitle("Title");
return pr;
}