Skip to content

Commit d3bc076

Browse files
committed
[JENKINS-53535] Make Bitbucket Server, Owner and repository environment variables for Bitbucket Team/Project based jobs (#949)
Add as environment variables some bitbucket useful informations like: - repository name (slug); - owner name (slug); - project key; - the server URL.
1 parent 9bd998b commit d3bc076

21 files changed

+192
-35
lines changed

docs/USER_GUIDE.adoc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,18 @@ The STOPPED status prevents merge checks on Cloud, CANCELLED status should preve
239239
If this does not meet you need you can disable any notification to Bitbucket using the https://github.com/jenkinsci/skip-notifications-trait-plugin/[skip-notifications-trait-plugin] and provide notification about the build status yourself. This can be achieved via a curl shell command or by using build steps provided by the https://github.com/jenkinsci/bitbucket-build-status-notifier-plugin[bitbucket-build-status-notifier-plugin].
240240

241241

242+
[id=bitbucket-env-var]
243+
== Environment Variables
244+
245+
This plugin contribute to the enviroment with the following variables:
246+
247+
- BITBUCKET_REPOSITORY: the repository name/slug
248+
- BITBUCKET_OWNER: the repository owner name/slug, in Bitbucket Cloud is the equivalent of workspace name
249+
- BITBUCKET_PROJECT_KEY: the project key in which the repository is contained
250+
- BITBUCKET_SERVER_URL: the Bitbucket server URL
251+
252+
These variables were added to allow users to easily integrate calls to Bitbucket's REST APIs into their own pipelines to implement own business logics.
253+
242254
[id=bitbucket-misc-config]
243255
== Miscellaneous configuration
244256

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketGitSCMBuilder.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository;
2929
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepositoryProtocol;
3030
import com.cloudbees.jenkins.plugins.bitbucket.endpoints.AbstractBitbucketEndpoint;
31-
import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketCloudEndpoint;
3231
import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration;
3332
import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketServerEndpoint;
33+
import com.cloudbees.jenkins.plugins.bitbucket.impl.util.BitbucketApiUtils;
3434
import com.cloudbees.jenkins.plugins.bitbucket.impl.util.BitbucketCredentials;
3535
import com.cloudbees.jenkins.plugins.sshcredentials.SSHUserPrivateKey;
3636
import com.cloudbees.plugins.credentials.Credentials;
@@ -108,11 +108,11 @@ public BitbucketGitSCMBuilder(@NonNull BitbucketSCMSource scmSource, @NonNull SC
108108
endpoint = new BitbucketServerEndpoint(null, serverURL, false, null);
109109
}
110110

111-
String repositoryUrl = endpoint.getRepositoryUrl(scmSource.getRepoOwner(), scmSource.getRepository());
112-
if (endpoint instanceof BitbucketCloudEndpoint) {
113-
withBrowser(new BitbucketWeb(repositoryUrl));
111+
String repositoryURL = endpoint.getRepositoryUrl(scmSource.getRepoOwner(), scmSource.getRepository());
112+
if (BitbucketApiUtils.isCloud(endpoint.getServerUrl())) {
113+
withBrowser(new BitbucketWeb(repositoryURL));
114114
} else {
115-
withBrowser(new BitbucketServer(repositoryUrl));
115+
withBrowser(new BitbucketServer(repositoryURL));
116116
}
117117

118118
// Test for protocol

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketHref;
3232
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketMirroredRepository;
3333
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketMirroredRepositoryDescriptor;
34+
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketProject;
3435
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest;
3536
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository;
3637
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRequestException;
@@ -42,9 +43,11 @@
4243
import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration;
4344
import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketServerEndpoint;
4445
import com.cloudbees.jenkins.plugins.bitbucket.hooks.HasPullRequests;
46+
import com.cloudbees.jenkins.plugins.bitbucket.impl.util.BitbucketApiUtils;
4547
import com.cloudbees.jenkins.plugins.bitbucket.impl.util.BitbucketApiUtils.BitbucketSupplier;
4648
import com.cloudbees.jenkins.plugins.bitbucket.impl.util.BitbucketCredentials;
4749
import com.cloudbees.jenkins.plugins.bitbucket.impl.util.MirrorListSupplier;
50+
import com.cloudbees.jenkins.plugins.bitbucket.impl.util.URLUtils;
4851
import com.cloudbees.jenkins.plugins.bitbucket.server.BitbucketServerWebhookImplementation;
4952
import com.cloudbees.jenkins.plugins.bitbucket.server.client.BitbucketServerAPIClient;
5053
import com.cloudbees.jenkins.plugins.bitbucket.server.client.repository.BitbucketServerRepository;
@@ -75,8 +78,6 @@
7578
import hudson.util.ListBoxModel;
7679
import java.io.IOException;
7780
import java.io.ObjectStreamException;
78-
import java.net.MalformedURLException;
79-
import java.net.URL;
8081
import java.util.ArrayList;
8182
import java.util.Arrays;
8283
import java.util.Collection;
@@ -128,6 +129,7 @@
128129
import org.jenkinsci.Symbol;
129130
import org.kohsuke.accmod.Restricted;
130131
import org.kohsuke.accmod.restrictions.NoExternalUse;
132+
import org.kohsuke.accmod.restrictions.ProtectedExternally;
131133
import org.kohsuke.stapler.AncestorInPath;
132134
import org.kohsuke.stapler.DataBoundConstructor;
133135
import org.kohsuke.stapler.DataBoundSetter;
@@ -385,6 +387,7 @@ public List<SCMSourceTrait> getTraits() {
385387
return Collections.unmodifiableList(traits);
386388
}
387389

390+
@Override
388391
@DataBoundSetter
389392
public void setTraits(@CheckForNull List<SCMSourceTrait> traits) {
390393
this.traits = new ArrayList<>(Util.fixNull(traits));
@@ -690,7 +693,7 @@ class Skip extends IOException {
690693
boolean fork = !fullName.equalsIgnoreCase(pull.getSource().getRepository().getFullName());
691694
String pullRepoOwner = pull.getSource().getRepository().getOwnerName();
692695
String pullRepository = pull.getSource().getRepository().getRepositoryName();
693-
final BitbucketApi pullBitbucket = fork && originBitbucket instanceof BitbucketCloudApiClient
696+
final BitbucketApi pullBitbucket = fork && BitbucketApiUtils.isCloud(originBitbucket)
694697
? BitbucketApiFactory.newInstance(
695698
getServerUrl(),
696699
authenticator(),
@@ -999,7 +1002,7 @@ private BitbucketCommit findPRDestinationCommit(BitbucketPullRequest pr, TaskLis
9991002
}
10001003

10011004
@Override
1002-
public SCM build(SCMHead head, SCMRevision revision) {
1005+
public SCM build(@NonNull SCMHead head, @CheckForNull SCMRevision revision) {
10031006
initCloneLinks();
10041007

10051008
boolean sshAuth = traits.stream()
@@ -1013,19 +1016,28 @@ public SCM build(SCMHead head, SCMRevision revision) {
10131016
.build();
10141017
}
10151018

1019+
@CheckForNull
1020+
@Restricted(ProtectedExternally.class)
1021+
protected String getProjectKey() {
1022+
String projectKey = null;
1023+
try {
1024+
BitbucketProject project = buildBitbucketClient().getRepository().getProject();
1025+
if (project != null) {
1026+
projectKey = project.getKey();
1027+
}
1028+
} catch (IOException | InterruptedException e) {
1029+
LOGGER.severe("Failure getting the project key of repository " + getRepository() + " : " + e.getMessage());
1030+
}
1031+
return projectKey;
1032+
}
1033+
10161034
private void setPrimaryCloneLinks(List<BitbucketHref> links) {
10171035
links.forEach(link -> {
10181036
if (StringUtils.startsWithIgnoreCase(link.getName(), "http")) {
1019-
try {
1020-
URL linkURL = new URL(link.getHref());
1021-
// Remove the username from URL because it will be set into the GIT_URL variable
1022-
// credentials used to clone or for push/pull could be different than this will cause a failure
1023-
// Restore the behaviour before mirror link feature.
1024-
URL cleanURL = new URL(linkURL.getProtocol(), linkURL.getHost(), linkURL.getPort(), linkURL.getFile());
1025-
link.setHref(cleanURL.toExternalForm());
1026-
} catch (MalformedURLException e) {
1027-
// do nothing, URL can not be parsed, leave as is
1028-
}
1037+
// Remove the username from URL because it will be set into the GIT_URL variable
1038+
// credentials used to clone or for push/pull could be different than this will cause a failure
1039+
// Restore the behaviour before mirror link feature.
1040+
link.setHref(URLUtils.removeAuthority(link.getHref()));
10291041
}
10301042
});
10311043
primaryCloneLinks = links;
@@ -1091,13 +1103,15 @@ protected List<Action> retrieveActions(@CheckForNull SCMSourceEvent event,
10911103
result.add(new BitbucketDefaultBranch(repoOwner, repository, defaultBranch));
10921104
}
10931105
UriTemplate template;
1094-
if (BitbucketCloudEndpoint.SERVER_URL.equals(getServerUrl())) {
1106+
if (BitbucketApiUtils.isCloud(getServerUrl())) {
10951107
template = UriTemplate.fromTemplate(getServerUrl() + CLOUD_REPO_TEMPLATE);
10961108
} else {
10971109
template = UriTemplate.fromTemplate(getServerUrl() + SERVER_REPO_TEMPLATE);
10981110
}
1099-
template.set("owner", repoOwner).set("repo", repository);
1100-
String url = template.expand();
1111+
String url = template
1112+
.set("owner", repoOwner)
1113+
.set("repo", repository)
1114+
.expand();
11011115
result.add(new BitbucketLink("icon-bitbucket-repo", url));
11021116
result.add(new ObjectMetadataAction(r.getRepositoryName(), null, url));
11031117
return result;

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/FallbackToOtherRepositoryGitSCMExtension.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import hudson.plugins.git.extensions.GitSCMExtension;
99
import java.net.URISyntaxException;
1010
import java.util.List;
11-
import java.util.stream.Collectors;
1211
import org.eclipse.jgit.transport.RefSpec;
1312
import org.eclipse.jgit.transport.URIish;
1413
import org.jenkinsci.plugins.gitclient.FetchCommand;
@@ -18,6 +17,7 @@
1817
* If specified commit hashes are not found in repository then fetch
1918
* specified branches from remote.
2019
*/
20+
//TODO be attention serialized in config.xml of the job as extension child of hudson.plugins.git.GitSCM. Provide a xml alias when move to package com.cloudbees.jenkins.plugins.bitbucket.impl.extension
2121
public class FallbackToOtherRepositoryGitSCMExtension extends GitSCMExtension {
2222

2323
private final String cloneLink;
@@ -49,7 +49,7 @@ public Revision decorateRevisionToBuild(
4949
String branch = branchWithHash.getBranch();
5050
return new RefSpec("+refs/heads/" + branch + ":refs/remotes/" + remoteName + "/" + branch);
5151
})
52-
.collect(Collectors.toList());
52+
.toList();
5353

5454
if (!refSpecs.isEmpty()) {
5555
FetchCommand fetchCommand = git.fetch_();

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/GitClientAuthenticatorExtension.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
import hudson.plugins.git.extensions.GitSCMExtension;
77
import org.jenkinsci.plugins.gitclient.GitClient;
88

9+
// TODO be attention serialized in config.xml of the job as extension child of hudson.plugins.git.GitSCM. Provide a xml alias when move to package com.cloudbees.jenkins.plugins.bitbucket.impl.extension
910
public class GitClientAuthenticatorExtension extends GitSCMExtension {
1011

12+
// TODO remove this because it is serialized in config.xml with username and secret (password or token could change/expiry specially with OAuth2)
1113
private final StandardUsernameCredentials credentials;
1214

1315
public GitClientAuthenticatorExtension(StandardUsernameCredentials credentials) {

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
*/
2525
package com.cloudbees.jenkins.plugins.bitbucket.client;
2626

27-
import com.cloudbees.jenkins.plugins.bitbucket.JsonParser;
2827
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi;
2928
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator;
3029
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBuildStatus;
@@ -51,6 +50,7 @@
5150
import com.cloudbees.jenkins.plugins.bitbucket.filesystem.BitbucketSCMFile;
5251
import com.cloudbees.jenkins.plugins.bitbucket.impl.client.AbstractBitbucketApi;
5352
import com.cloudbees.jenkins.plugins.bitbucket.impl.credentials.BitbucketUsernamePasswordAuthenticator;
53+
import com.cloudbees.jenkins.plugins.bitbucket.impl.util.JsonParser;
5454
import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
5555
import com.damnhandy.uri.template.UriTemplate;
5656
import com.damnhandy.uri.template.impl.Operator;

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudWebhookPayload.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@
2323
*/
2424
package com.cloudbees.jenkins.plugins.bitbucket.client;
2525

26-
import com.cloudbees.jenkins.plugins.bitbucket.JsonParser;
2726
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequestEvent;
2827
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPushEvent;
2928
import com.cloudbees.jenkins.plugins.bitbucket.client.events.BitbucketCloudPullRequestEvent;
3029
import com.cloudbees.jenkins.plugins.bitbucket.client.events.BitbucketCloudPushEvent;
30+
import com.cloudbees.jenkins.plugins.bitbucket.impl.util.JsonParser;
3131
import edu.umd.cs.findbugs.annotations.CheckForNull;
3232
import edu.umd.cs.findbugs.annotations.NonNull;
3333
import java.io.IOException;

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/NativeServerPullRequestHookProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@
2525

2626
import com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource;
2727
import com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSourceContext;
28-
import com.cloudbees.jenkins.plugins.bitbucket.JsonParser;
2928
import com.cloudbees.jenkins.plugins.bitbucket.PullRequestSCMHead;
3029
import com.cloudbees.jenkins.plugins.bitbucket.PullRequestSCMRevision;
3130
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest;
3231
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository;
32+
import com.cloudbees.jenkins.plugins.bitbucket.impl.util.JsonParser;
3333
import com.cloudbees.jenkins.plugins.bitbucket.server.client.repository.BitbucketServerRepository;
3434
import com.cloudbees.jenkins.plugins.bitbucket.server.events.NativeServerPullRequestEvent;
3535
import com.google.common.base.Ascii;

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/NativeServerPushHookProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@
2727
import com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSourceContext;
2828
import com.cloudbees.jenkins.plugins.bitbucket.BitbucketTagSCMHead;
2929
import com.cloudbees.jenkins.plugins.bitbucket.BranchSCMHead;
30-
import com.cloudbees.jenkins.plugins.bitbucket.JsonParser;
3130
import com.cloudbees.jenkins.plugins.bitbucket.PullRequestSCMHead;
3231
import com.cloudbees.jenkins.plugins.bitbucket.PullRequestSCMRevision;
3332
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest;
33+
import com.cloudbees.jenkins.plugins.bitbucket.impl.util.JsonParser;
3434
import com.cloudbees.jenkins.plugins.bitbucket.server.client.BitbucketServerAPIClient;
3535
import com.cloudbees.jenkins.plugins.bitbucket.server.client.pullrequest.BitbucketServerPullRequest;
3636
import com.cloudbees.jenkins.plugins.bitbucket.server.client.repository.BitbucketServerRepository;

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/credentials/BitbucketOAuthAuthenticator.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,7 @@ public void configureRequest(HttpRequest request) {
8585
@Override
8686
public StandardUsernameCredentials getCredentialsForSCM() {
8787
try {
88-
return new UsernamePasswordCredentialsImpl(
89-
CredentialsScope.GLOBAL, getId(), null, "x-token-auth", getToken().getAccessToken());
88+
return new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, getId(), null, "x-token-auth", getToken().getAccessToken());
9089
} catch (FormException e) {
9190
throw new RuntimeException(e);
9291
}

0 commit comments

Comments
 (0)