diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java index a69bf0ab3..e9d3df97f 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/filesystem/BitbucketSCMFileSystem.java @@ -32,6 +32,7 @@ import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApiFactory; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator; +import com.cloudbees.jenkins.plugins.bitbucket.client.BitbucketCloudApiClient; import com.cloudbees.plugins.credentials.CredentialsMatchers; import com.cloudbees.plugins.credentials.CredentialsProvider; import com.cloudbees.plugins.credentials.common.StandardCredentials; @@ -139,17 +140,36 @@ public SCMFileSystem build(@NonNull SCMSource source, @NonNull SCMHead head, @Ch BitbucketAuthenticator authenticator = AuthenticationTokens.convert(BitbucketAuthenticator.authenticationContext(serverUrl), credentials); BitbucketApi apiClient = BitbucketApiFactory.newInstance(serverUrl, authenticator, owner, repository); - String ref; + String ref = null; + if (head instanceof BranchSCMHead) { ref = head.getName(); } else if (head instanceof PullRequestSCMHead) { + // working on a pull request - can be either "HEAD" or "MERGE" PullRequestSCMHead pr = (PullRequestSCMHead) head; - if (!(pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.MERGE) && pr.getRepository() != null) { - return new BitbucketSCMFileSystem(apiClient, pr.getOriginName(), rev); + if (pr.getRepository() == null) { // check access to repository (might be forked) + return null; + } + + if (apiClient instanceof BitbucketCloudApiClient) { + // support lightweight checkout for branches with same owner and repository + if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.HEAD && + pr.getRepoOwner().equals(src.getRepoOwner()) && + pr.getRepository().equals(src.getRepository())) { + ref = pr.getOriginName(); + } else { + // Bitbucket cloud does not support refs for pull requests + // Makes lightweight checkout for forks and merge strategy improbable + // TODO waiting for cloud support: https://bitbucket.org/site/master/issues/5814/refify-pull-requests-by-making-them-a-ref + return null; + } + } else if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.HEAD) { + ref = "pull-requests/" + pr.getId() + "/from"; + } else if (pr.getCheckoutStrategy() == ChangeRequestCheckoutStrategy.MERGE) { + ref = "pull-requests/" + pr.getId() + "/merge"; } - return null; // TODO support merge revisions somehow } else if (head instanceof BitbucketTagSCMHead) { - ref = "tags/" + head.getName(); + ref = "tags/" + head.getName(); } else { return null; } diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java index bc4299f93..d05a838d2 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java @@ -147,7 +147,7 @@ public BitbucketCommit call() throws Exception { private static final String API_PULL_REQUESTS_PATH = API_REPOSITORY_PATH + "/pull-requests{?start,limit,at,direction,state}"; private static final String API_PULL_REQUEST_PATH = API_REPOSITORY_PATH + "/pull-requests/{id}"; private static final String API_PULL_REQUEST_MERGE_PATH = API_REPOSITORY_PATH + "/pull-requests/{id}/merge"; - private static final String API_BROWSE_PATH = API_REPOSITORY_PATH + "/browse{/path*}{?at}"; + static final String API_BROWSE_PATH = API_REPOSITORY_PATH + "/browse/{+path}{?at}"; private static final String API_COMMITS_PATH = API_REPOSITORY_PATH + "/commits{/hash}"; private static final String API_PROJECT_PATH = API_BASE_PATH + "/projects/{owner}"; private static final String API_COMMIT_COMMENT_PATH = API_REPOSITORY_PATH + "/commits{/hash}/comments"; diff --git a/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClientTest.java b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClientTest.java new file mode 100644 index 000000000..979e42ef5 --- /dev/null +++ b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClientTest.java @@ -0,0 +1,34 @@ +package com.cloudbees.jenkins.plugins.bitbucket.server.client; + +import com.damnhandy.uri.template.UriTemplate; +import org.junit.Assert; +import org.junit.Test; + +import static com.cloudbees.jenkins.plugins.bitbucket.server.client.BitbucketServerAPIClient.API_BROWSE_PATH; + +public class BitbucketServerAPIClientTest { + + @Test + public void repoBrowsePathFolder() { + String expand = UriTemplate + .fromTemplate(API_BROWSE_PATH) + .set("owner", "test") + .set("repo", "test") + .set("path", "folder/Jenkinsfile") + .set("at", "fix/test") + .expand(); + Assert.assertEquals("/rest/api/1.0/projects/test/repos/test/browse/folder/Jenkinsfile?at=fix%2Ftest", expand); + } + + @Test + public void repoBrowsePathFile() { + String expand = UriTemplate + .fromTemplate(API_BROWSE_PATH) + .set("owner", "test") + .set("repo", "test") + .set("path", "Jenkinsfile") + .expand(); + Assert.assertEquals("/rest/api/1.0/projects/test/repos/test/browse/Jenkinsfile", expand); + } + +}