diff --git a/docs/USER_GUIDE.adoc b/docs/USER_GUIDE.adoc index 0ebb23a60..f48de1787 100644 --- a/docs/USER_GUIDE.adoc +++ b/docs/USER_GUIDE.adoc @@ -239,6 +239,18 @@ The STOPPED status prevents merge checks on Cloud, CANCELLED status should preve 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]. +[id=bitbucket-env-var] +== Environment Variables + +This plugin contribute to the enviroment with the following variables: + +- BITBUCKET_REPOSITORY: the repository name/slug +- BITBUCKET_OWNER: the repository owner name/slug, in Bitbucket Cloud is the equivalent of workspace name +- BITBUCKET_PROJECT_KEY: the project key in which the repository is contained +- BITBUCKET_SERVER_URL: the Bitbucket server URL + +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. + [id=bitbucket-misc-config] == Miscellaneous configuration diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketApiUtils.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketApiUtils.java index 5becb2713..ae12dbd04 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketApiUtils.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketApiUtils.java @@ -9,6 +9,7 @@ import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration; import com.cloudbees.plugins.credentials.CredentialsProvider; import com.cloudbees.plugins.credentials.common.StandardCredentials; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Util; import hudson.model.Item; import hudson.util.FormFillFailure; @@ -29,6 +30,10 @@ public static boolean isCloud(BitbucketApi client) { return client instanceof BitbucketCloudApiClient; } + public static boolean isCloud(@NonNull String serverURL) { + return StringUtils.startsWith(serverURL, BitbucketCloudEndpoint.SERVER_URL); + } + public static ListBoxModel getFromBitbucket(SCMSourceOwner context, String serverUrl, String credentialsId, diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketGitSCMBuilder.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketGitSCMBuilder.java index f91abd5b4..f35cbd744 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketGitSCMBuilder.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketGitSCMBuilder.java @@ -28,7 +28,6 @@ import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepositoryProtocol; import com.cloudbees.jenkins.plugins.bitbucket.endpoints.AbstractBitbucketEndpoint; -import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketCloudEndpoint; import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration; import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketServerEndpoint; import com.cloudbees.jenkins.plugins.sshcredentials.SSHUserPrivateKey; @@ -107,11 +106,11 @@ public BitbucketGitSCMBuilder(@NonNull BitbucketSCMSource scmSource, @NonNull SC endpoint = new BitbucketServerEndpoint(null, serverURL, false, null); } - String repositoryUrl = endpoint.getRepositoryUrl(scmSource.getRepoOwner(), scmSource.getRepository()); - if (endpoint instanceof BitbucketCloudEndpoint) { - withBrowser(new BitbucketWeb(repositoryUrl)); + String repositoryURL = endpoint.getRepositoryUrl(scmSource.getRepoOwner(), scmSource.getRepository()); + if (BitbucketApiUtils.isCloud(endpoint.getServerUrl())) { + withBrowser(new BitbucketWeb(repositoryURL)); } else { - withBrowser(new BitbucketServer(repositoryUrl)); + withBrowser(new BitbucketServer(repositoryURL)); } // Test for protocol 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 4b6a2ada0..7f7cf0cf9 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java @@ -32,6 +32,7 @@ import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketHref; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketMirroredRepository; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketMirroredRepositoryDescriptor; +import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketProject; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRequestException; @@ -44,6 +45,8 @@ import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration; import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketServerEndpoint; import com.cloudbees.jenkins.plugins.bitbucket.hooks.HasPullRequests; +import com.cloudbees.jenkins.plugins.bitbucket.impl.extension.BitbucketEnvVarExtension; +import com.cloudbees.jenkins.plugins.bitbucket.impl.util.URLUtils; import com.cloudbees.jenkins.plugins.bitbucket.server.BitbucketServerWebhookImplementation; import com.cloudbees.jenkins.plugins.bitbucket.server.client.BitbucketServerAPIClient; import com.cloudbees.jenkins.plugins.bitbucket.server.client.repository.BitbucketServerRepository; @@ -75,8 +78,6 @@ import hudson.util.ListBoxModel; import java.io.IOException; import java.io.ObjectStreamException; -import java.net.MalformedURLException; -import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -128,6 +129,7 @@ import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.accmod.restrictions.ProtectedExternally; import org.kohsuke.stapler.AncestorInPath; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; @@ -385,6 +387,7 @@ public List getTraits() { return Collections.unmodifiableList(traits); } + @Override @DataBoundSetter public void setTraits(@CheckForNull List traits) { this.traits = new ArrayList<>(Util.fixNull(traits)); @@ -690,7 +693,7 @@ class Skip extends IOException { boolean fork = !fullName.equalsIgnoreCase(pull.getSource().getRepository().getFullName()); String pullRepoOwner = pull.getSource().getRepository().getOwnerName(); String pullRepository = pull.getSource().getRepository().getRepositoryName(); - final BitbucketApi pullBitbucket = fork && originBitbucket instanceof BitbucketCloudApiClient + final BitbucketApi pullBitbucket = fork && BitbucketApiUtils.isCloud(originBitbucket) ? BitbucketApiFactory.newInstance( getServerUrl(), authenticator(), @@ -999,7 +1002,7 @@ private BitbucketCommit findPRDestinationCommit(BitbucketPullRequest pr, TaskLis } @Override - public SCM build(SCMHead head, SCMRevision revision) { + public SCM build(@NonNull SCMHead head, @CheckForNull SCMRevision revision) { initCloneLinks(); String scmCredentialsId = credentialsId; @@ -1027,26 +1030,38 @@ public SCM build(SCMHead head, SCMRevision revision) { scmExtension = new GitClientAuthenticatorExtension(null); } + String projectKey = getProjectKey(); + return new BitbucketGitSCMBuilder(this, head, revision, scmCredentialsId) .withExtension(scmExtension) + .withExtension(new BitbucketEnvVarExtension(getRepoOwner(), getRepository(), projectKey, getServerUrl())) .withCloneLinks(primaryCloneLinks, mirrorCloneLinks) .withTraits(traits) .build(); } + @CheckForNull + @Restricted(ProtectedExternally.class) + protected String getProjectKey() { + String projectKey = null; + try { + BitbucketProject project = buildBitbucketClient().getRepository().getProject(); + if (project != null) { + projectKey = project.getKey(); + } + } catch (IOException | InterruptedException e) { + LOGGER.severe("Failure getting the project key of repository " + getRepository() + " : " + e.getMessage()); + } + return projectKey; + } + private void setPrimaryCloneLinks(List links) { links.forEach(link -> { if (StringUtils.startsWithIgnoreCase(link.getName(), "http")) { - try { - URL linkURL = new URL(link.getHref()); - // Remove the username from URL because it will be set into the GIT_URL variable - // credentials used to clone or for push/pull could be different than this will cause a failure - // Restore the behaviour before mirror link feature. - URL cleanURL = new URL(linkURL.getProtocol(), linkURL.getHost(), linkURL.getPort(), linkURL.getFile()); - link.setHref(cleanURL.toExternalForm()); - } catch (MalformedURLException e) { - // do nothing, URL can not be parsed, leave as is - } + // Remove the username from URL because it will be set into the GIT_URL variable + // credentials used to clone or for push/pull could be different than this will cause a failure + // Restore the behaviour before mirror link feature. + link.setHref(URLUtils.removeAuthority(link.getHref())); } }); primaryCloneLinks = links; @@ -1112,13 +1127,15 @@ protected List retrieveActions(@CheckForNull SCMSourceEvent event, result.add(new BitbucketDefaultBranch(repoOwner, repository, defaultBranch)); } UriTemplate template; - if (BitbucketCloudEndpoint.SERVER_URL.equals(getServerUrl())) { + if (BitbucketApiUtils.isCloud(getServerUrl())) { template = UriTemplate.fromTemplate(getServerUrl() + CLOUD_REPO_TEMPLATE); } else { template = UriTemplate.fromTemplate(getServerUrl() + SERVER_REPO_TEMPLATE); } - template.set("owner", repoOwner).set("repo", repository); - String url = template.expand(); + String url = template + .set("owner", repoOwner) + .set("repo", repository) + .expand(); result.add(new BitbucketLink("icon-bitbucket-repo", url)); result.add(new ObjectMetadataAction(r.getRepositoryName(), null, url)); return result; diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/FallbackToOtherRepositoryGitSCMExtension.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/FallbackToOtherRepositoryGitSCMExtension.java index 85e824e96..0cdffe11e 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/FallbackToOtherRepositoryGitSCMExtension.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/FallbackToOtherRepositoryGitSCMExtension.java @@ -8,7 +8,6 @@ import hudson.plugins.git.extensions.GitSCMExtension; import java.net.URISyntaxException; import java.util.List; -import java.util.stream.Collectors; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.URIish; import org.jenkinsci.plugins.gitclient.FetchCommand; @@ -18,6 +17,7 @@ * If specified commit hashes are not found in repository then fetch * specified branches from remote. */ +//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 public class FallbackToOtherRepositoryGitSCMExtension extends GitSCMExtension { private final String cloneLink; @@ -49,7 +49,7 @@ public Revision decorateRevisionToBuild( String branch = branchWithHash.getBranch(); return new RefSpec("+refs/heads/" + branch + ":refs/remotes/" + remoteName + "/" + branch); }) - .collect(Collectors.toList()); + .toList(); if (!refSpecs.isEmpty()) { FetchCommand fetchCommand = git.fetch_(); diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/GitClientAuthenticatorExtension.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/GitClientAuthenticatorExtension.java index 441c773fe..f1957f3b1 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/GitClientAuthenticatorExtension.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/GitClientAuthenticatorExtension.java @@ -6,8 +6,10 @@ import hudson.plugins.git.extensions.GitSCMExtension; import org.jenkinsci.plugins.gitclient.GitClient; +// 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 public class GitClientAuthenticatorExtension extends GitSCMExtension { + // TODO remove this because it is serialized in config.xml with username and secret (password or token could change/expiry specially with OAuth2) private final StandardUsernameCredentials credentials; public GitClientAuthenticatorExtension(StandardUsernameCredentials credentials) { diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClient.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClient.java index 6dad8ec8c..110aad888 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClient.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClient.java @@ -24,7 +24,6 @@ */ package com.cloudbees.jenkins.plugins.bitbucket.client; -import com.cloudbees.jenkins.plugins.bitbucket.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBuildStatus; @@ -50,6 +49,7 @@ import com.cloudbees.jenkins.plugins.bitbucket.client.repository.UserRoleInRepository; import com.cloudbees.jenkins.plugins.bitbucket.credentials.BitbucketUsernamePasswordAuthenticator; import com.cloudbees.jenkins.plugins.bitbucket.filesystem.BitbucketSCMFile; +import com.cloudbees.jenkins.plugins.bitbucket.impl.util.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.internal.api.AbstractBitbucketApi; import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; import com.damnhandy.uri.template.UriTemplate; diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudWebhookPayload.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudWebhookPayload.java index f9cc9a284..158c55687 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudWebhookPayload.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudWebhookPayload.java @@ -23,11 +23,11 @@ */ package com.cloudbees.jenkins.plugins.bitbucket.client; -import com.cloudbees.jenkins.plugins.bitbucket.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequestEvent; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPushEvent; import com.cloudbees.jenkins.plugins.bitbucket.client.events.BitbucketCloudPullRequestEvent; import com.cloudbees.jenkins.plugins.bitbucket.client.events.BitbucketCloudPushEvent; +import com.cloudbees.jenkins.plugins.bitbucket.impl.util.JsonParser; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; import java.io.IOException; diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/credentials/BitbucketOAuthAuthenticator.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/credentials/BitbucketOAuthAuthenticator.java index 79dfcab04..5bcc95b95 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/credentials/BitbucketOAuthAuthenticator.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/credentials/BitbucketOAuthAuthenticator.java @@ -85,8 +85,7 @@ public void configureRequest(HttpRequest request) { @Override public StandardUsernameCredentials getCredentialsForSCM() { try { - return new UsernamePasswordCredentialsImpl( - CredentialsScope.GLOBAL, getId(), null, "x-token-auth", getToken().getAccessToken()); + return new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, getId(), null, "x-token-auth", getToken().getAccessToken()); } catch (FormException e) { throw new RuntimeException(e); } diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/NativeServerPullRequestHookProcessor.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/NativeServerPullRequestHookProcessor.java index 11f6b1ceb..c118590ec 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/NativeServerPullRequestHookProcessor.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/NativeServerPullRequestHookProcessor.java @@ -25,11 +25,11 @@ import com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource; import com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSourceContext; -import com.cloudbees.jenkins.plugins.bitbucket.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.PullRequestSCMHead; import com.cloudbees.jenkins.plugins.bitbucket.PullRequestSCMRevision; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository; +import com.cloudbees.jenkins.plugins.bitbucket.impl.util.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.server.client.repository.BitbucketServerRepository; import com.cloudbees.jenkins.plugins.bitbucket.server.events.NativeServerPullRequestEvent; import com.google.common.base.Ascii; diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/NativeServerPushHookProcessor.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/NativeServerPushHookProcessor.java index 0c4cf27de..87c9478b8 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/NativeServerPushHookProcessor.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/NativeServerPushHookProcessor.java @@ -27,10 +27,10 @@ import com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSourceContext; import com.cloudbees.jenkins.plugins.bitbucket.BitbucketTagSCMHead; import com.cloudbees.jenkins.plugins.bitbucket.BranchSCMHead; -import com.cloudbees.jenkins.plugins.bitbucket.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.PullRequestSCMHead; import com.cloudbees.jenkins.plugins.bitbucket.PullRequestSCMRevision; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest; +import com.cloudbees.jenkins.plugins.bitbucket.impl.util.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.server.client.BitbucketServerAPIClient; import com.cloudbees.jenkins.plugins.bitbucket.server.client.pullrequest.BitbucketServerPullRequest; import com.cloudbees.jenkins.plugins.bitbucket.server.client.repository.BitbucketServerRepository; diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/extension/BitbucketEnvVarExtension.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/extension/BitbucketEnvVarExtension.java new file mode 100644 index 000000000..d77f18f73 --- /dev/null +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/extension/BitbucketEnvVarExtension.java @@ -0,0 +1,39 @@ +package com.cloudbees.jenkins.plugins.bitbucket.impl.extension; + +import com.cloudbees.jenkins.plugins.bitbucket.impl.util.URLUtils; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import hudson.plugins.git.GitSCM; +import hudson.plugins.git.extensions.GitSCMExtension; +import java.util.Map; + +public class BitbucketEnvVarExtension extends GitSCMExtension { + + private final String owner; + private final String repository; + private final String projectKey; + private final String serverURL; + + public BitbucketEnvVarExtension(@Nullable String owner, @NonNull String repository, @Nullable String projectKey, @NonNull String serverURL) { + this.owner = owner; + this.repository = repository; + this.projectKey = projectKey; + this.serverURL = URLUtils.removeAuthority(serverURL); + } + + /** + * Contribute additional environment variables about the target branch. + * Since source branch could be from a forked repository, for which the + * credentials in use are not allowed to do nothing, is discarded. + * + * @param scm GitSCM used as reference + * @param env environment variables to be added + */ + @Override + public void populateEnvironmentVariables(GitSCM scm, Map env) { + env.put("BITBUCKET_REPOSITORY", repository); + env.put("BITBUCKET_OWNER", owner); + env.put("BITBUCKET_PROJECT_KEY", projectKey); + env.put("BITBUCKET_SERVER_URL", serverURL); + } +} diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/JsonParser.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/util/JsonParser.java similarity index 97% rename from src/main/java/com/cloudbees/jenkins/plugins/bitbucket/JsonParser.java rename to src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/util/JsonParser.java index 947d16cef..12133ea3f 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/JsonParser.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/util/JsonParser.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.cloudbees.jenkins.plugins.bitbucket; +package com.cloudbees.jenkins.plugins.bitbucket.impl.util; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/util/URLUtils.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/util/URLUtils.java new file mode 100644 index 000000000..ff2cbbbfb --- /dev/null +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/impl/util/URLUtils.java @@ -0,0 +1,26 @@ +package com.cloudbees.jenkins.plugins.bitbucket.impl.util; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import java.net.MalformedURLException; +import java.net.URL; + +public final class URLUtils { + + private URLUtils() { + } + + @Nullable + public static String removeAuthority(@CheckForNull String url) { + if (url != null) { + try { + URL linkURL = new URL(url); + URL cleanURL = new URL(linkURL.getProtocol(), linkURL.getHost(), linkURL.getPort(), linkURL.getFile()); + return cleanURL.toExternalForm(); + } catch (MalformedURLException e) { + // do nothing, URL can not be parsed, leave as is + } + } + return url; + } +} 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 6f6f13b79..9d3992fab 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 @@ -23,7 +23,6 @@ */ package com.cloudbees.jenkins.plugins.bitbucket.server.client; -import com.cloudbees.jenkins.plugins.bitbucket.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketAuthenticator; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBuildStatus; @@ -42,6 +41,7 @@ import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration; import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketServerEndpoint; import com.cloudbees.jenkins.plugins.bitbucket.filesystem.BitbucketSCMFile; +import com.cloudbees.jenkins.plugins.bitbucket.impl.util.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.internal.api.AbstractBitbucketApi; import com.cloudbees.jenkins.plugins.bitbucket.server.BitbucketServerVersion; import com.cloudbees.jenkins.plugins.bitbucket.server.BitbucketServerWebhookImplementation; diff --git a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerWebhookPayload.java b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerWebhookPayload.java index f80231d1d..a8ee68b51 100644 --- a/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerWebhookPayload.java +++ b/src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerWebhookPayload.java @@ -23,9 +23,9 @@ */ package com.cloudbees.jenkins.plugins.bitbucket.server.client; -import com.cloudbees.jenkins.plugins.bitbucket.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequestEvent; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPushEvent; +import com.cloudbees.jenkins.plugins.bitbucket.impl.util.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.server.events.BitbucketServerPullRequestEvent; import com.cloudbees.jenkins.plugins.bitbucket.server.events.BitbucketServerPushEvent; import edu.umd.cs.findbugs.annotations.CheckForNull; diff --git a/src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/Messages.properties b/src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/Messages.properties index 8759e3860..7ce13a0c2 100644 --- a/src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/Messages.properties +++ b/src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/Messages.properties @@ -1,3 +1,26 @@ +# +# The MIT License +# +# Copyright (c) 2016, CloudBees, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + BitbucketLink.DisplayName=Bitbucket BitbucketSCMNavigator.UncategorizedSCMSourceCategory.DisplayName=Repositories BitbucketSCMSource.UncategorizedSCMHeadCategory.DisplayName=Branches diff --git a/src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/impl/extension/BitbucketEnvVarExtension/buildEnv.groovy b/src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/impl/extension/BitbucketEnvVarExtension/buildEnv.groovy new file mode 100644 index 000000000..f9f16b43b --- /dev/null +++ b/src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/impl/extension/BitbucketEnvVarExtension/buildEnv.groovy @@ -0,0 +1,10 @@ +package com.cloudbees.jenkins.plugins.bitbucket.impl.extension.BitbucketEnvVarExtension + +def l = namespace(lib.JenkinsTagLib) + +// Base on javadoc in EnvironmentContributor Jenkins provides other extension points (such as SCM) to contribute environment variables to builds, and for those plugins, Jenkins also looks for /buildEnv.groovy and aggregates them. +['BITBUCKET_REPOSITORY', 'BITBUCKET_OWNER', 'BITBUCKET_PROJECT_KEY', 'BITBUCKET_SERVER_URL'].each {name -> + l.buildEnvVar(name: name) { + raw(_("${name}.blurb")) + } +} \ No newline at end of file diff --git a/src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/impl/extension/BitbucketEnvVarExtension/buildEnv.properties b/src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/impl/extension/BitbucketEnvVarExtension/buildEnv.properties new file mode 100644 index 000000000..8e6a8e5bc --- /dev/null +++ b/src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/impl/extension/BitbucketEnvVarExtension/buildEnv.properties @@ -0,0 +1,27 @@ +# +# The MIT License +# +# Copyright (c) 2024, Nikolas Falco +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +BITBUCKET_REPOSITORY.blurb=For a multibranch project, this will be set to the repository name/slug +BITBUCKET_OWNER.blurb=For a multibranch project, this will be set to the repository owner name/slug, in Bitbucket Cloud is the equivalent of workspace name +BITBUCKET_PROJECT_KEY.blurb=For a multibranch project, this will be set to the project key in which the repository is contained +BITBUCKET_SERVER_URL.blurb=For a multibranch project, this will be set to the Bitbucket server URL diff --git a/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClientTest.java b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClientTest.java index 58adb0b6d..ab4b756b8 100644 --- a/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClientTest.java +++ b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudApiClientTest.java @@ -23,7 +23,6 @@ */ package com.cloudbees.jenkins.plugins.bitbucket.client; -import com.cloudbees.jenkins.plugins.bitbucket.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBuildStatus; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBuildStatus.Status; @@ -31,6 +30,7 @@ import com.cloudbees.jenkins.plugins.bitbucket.client.BitbucketIntegrationClientFactory.IRequestAudit; import com.cloudbees.jenkins.plugins.bitbucket.client.repository.BitbucketCloudRepository; import com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketCloudEndpoint; +import com.cloudbees.jenkins.plugins.bitbucket.impl.util.JsonParser; import hudson.ProxyConfiguration; import io.jenkins.cli.shaded.org.apache.commons.lang.RandomStringUtils; import java.io.IOException; diff --git a/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/server/events/BitbucketServerPullRequestEventTest.java b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/server/events/BitbucketServerPullRequestEventTest.java index 6e9aed129..2bc687e7f 100644 --- a/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/server/events/BitbucketServerPullRequestEventTest.java +++ b/src/test/java/com/cloudbees/jenkins/plugins/bitbucket/server/events/BitbucketServerPullRequestEventTest.java @@ -23,8 +23,8 @@ */ package com.cloudbees.jenkins.plugins.bitbucket.server.events; -import com.cloudbees.jenkins.plugins.bitbucket.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequestEvent; +import com.cloudbees.jenkins.plugins.bitbucket.impl.util.JsonParser; import com.cloudbees.jenkins.plugins.bitbucket.server.client.BitbucketServerWebhookPayload; import com.cloudbees.jenkins.plugins.bitbucket.server.client.pullrequest.BitbucketServerPullRequest; import java.io.IOException;