Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JENKINS-48737 Fixing lightweight pull request checkouts, also for files in subdirectories #174

Merged
merged 9 commits into from
Apr 7, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Copy link
Member

Choose a reason for hiding this comment

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

Testing out whether this is even possible

Copy link
Member

@jetersen jetersen Apr 6, 2019

Choose a reason for hiding this comment

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

Yup only possible when the PR is coming from the same repository.
Atlassian is the one to blame for having an issue open for six years and counting.

} 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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}

}