Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,20 @@
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;
import org.kohsuke.stapler.DataBoundConstructor;
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;
Expand Down Expand Up @@ -80,7 +82,7 @@

/**
* SCM source implementation for Bitbucket.
*
* <p>
* 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.
*/
Expand Down Expand Up @@ -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;
Expand All @@ -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();
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
*/
Expand All @@ -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) {
Expand Down Expand Up @@ -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();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before messing around with these classes, it might be wise to take into account JENKINS-36283, which would probably involve changing the representation of heads and/or revisions. At least it did in the case of the analogous jenkinsci/github-branch-source-plugin#60.


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<Action> actions = new ArrayList<>(super.getAllActions());
actions.add(metatdata);
return actions;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,14 @@
*/
package com.cloudbees.jenkins.plugins.bitbucket;

import edu.umd.cs.findbugs.annotations.CheckForNull;
import jenkins.scm.api.SCMHead;

/**
* {@link SCMHead} extended with additional information:
* <ul>
* <li>{@link #repoOwner}: the repository owner</li>
* <li>{@link #repoName}: the repository name</li>
* <li>{@link #pullRequestId}: the pull request ID (if it is representing a PR, null otherwise)</li>
* </ul>
* 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 {

Expand All @@ -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() {
Expand All @@ -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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
public class BitbucketPullRequestValue implements BitbucketPullRequest {
private BitbucketPullRequestValueRepository source;
private String id;
private String title;

public BitbucketPullRequestSource getSource() {
return source;
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public class BitbucketServerPullRequest implements BitbucketPullRequest {

private String id;

private String title;

@JsonProperty("fromRef")
private BitbucketServerPullRequestSource source;

Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ private static BitbucketPullRequestValue getPullRequest() {
pr.setSource(source);

pr.setId("23");
pr.setTitle("Title");
return pr;
}

Expand Down