├── .gitignore ├── src ├── main │ ├── resources │ │ ├── com │ │ │ └── cloudbees │ │ │ │ └── jenkins │ │ │ │ └── plugins │ │ │ │ └── bitbucket │ │ │ │ ├── BitbucketSCMNavigator │ │ │ │ ├── help-credentialsId.html │ │ │ │ ├── help-checkoutCredentialsId.html │ │ │ │ ├── help-pattern.html │ │ │ │ ├── help-sshPort.html │ │ │ │ ├── help-bitbucketServerUrl.html │ │ │ │ ├── help-repoOwner.html │ │ │ │ ├── help-autoRegisterHooks.jelly │ │ │ │ └── config.jelly │ │ │ │ ├── AbstractBranchJobFilter │ │ │ │ └── config.jelly │ │ │ │ ├── BitbucketSCMSource │ │ │ │ ├── help-sshPort.html │ │ │ │ ├── help-bitbucketServerUrl.html │ │ │ │ ├── help-repoOwner.jelly │ │ │ │ ├── help-checkoutCredentialsId.jelly │ │ │ │ ├── help-credentialsId.jelly │ │ │ │ ├── help.html │ │ │ │ ├── help-autoRegisterHook.jelly │ │ │ │ └── config-detail.jelly │ │ │ │ ├── CustomNameJobColumn │ │ │ │ ├── columnHeader.jelly │ │ │ │ └── config.jelly │ │ │ │ └── Messages.properties │ │ └── index.jelly │ ├── webapp │ │ └── images │ │ │ └── 48x48 │ │ │ └── bitbucket-scmnavigator.png │ └── java │ │ └── com │ │ └── cloudbees │ │ └── jenkins │ │ └── plugins │ │ └── bitbucket │ │ ├── api │ │ ├── BitbucketPushEvent.java │ │ ├── BitbucketException.java │ │ ├── BitbucketTeam.java │ │ ├── BitbucketRepositoryOwner.java │ │ ├── BitbucketBranch.java │ │ ├── BitbucketPullRequestEvent.java │ │ ├── BitbucketCommit.java │ │ ├── BitbucketPullRequestSource.java │ │ ├── BitbucketRequestException.java │ │ ├── BitbucketPullRequest.java │ │ ├── BitbucketWebHook.java │ │ ├── BitbucketRepository.java │ │ ├── BitbucketBuildStatus.java │ │ └── BitbucketApi.java │ │ ├── hooks │ │ ├── BitbucketType.java │ │ ├── PushHookProcessor.java │ │ ├── PullRequestHookProcessor.java │ │ ├── HookEventType.java │ │ ├── HookProcessor.java │ │ ├── BitbucketSCMSourcePushHookReceiver.java │ │ └── WebhookAutoRegisterListener.java │ │ ├── BranchJobFilter.java │ │ ├── PullRequestJobFilter.java │ │ ├── AbstractBranchJobFilter.java │ │ ├── PullRequestAction.java │ │ ├── client │ │ ├── repository │ │ │ ├── BitbucketRepositoryHooks.java │ │ │ ├── PaginatedBitbucketRepository.java │ │ │ ├── BitbucketCloudTeam.java │ │ │ ├── BitbucketCloudRepositoryOwner.java │ │ │ ├── UserRoleInRepository.java │ │ │ ├── BitbucketRepositoryHook.java │ │ │ └── BitbucketCloudRepository.java │ │ ├── pullrequest │ │ │ ├── BitbucketPullRequests.java │ │ │ ├── BitbucketPullRequestValueRepository.java │ │ │ └── BitbucketPullRequestValue.java │ │ ├── events │ │ │ ├── BitbucketCloudPushEvent.java │ │ │ └── BitbucketCloudPullRequestEvent.java │ │ ├── branch │ │ │ ├── BitbucketCloudBranch.java │ │ │ └── BitbucketCloudCommit.java │ │ └── BitbucketCloudWebhookPayload.java │ │ ├── server │ │ ├── events │ │ │ ├── BitbucketServerPushEvent.java │ │ │ └── BitbucketServerPullRequestEvent.java │ │ └── client │ │ │ ├── repository │ │ │ ├── BitbucketServerProject.java │ │ │ ├── BitbucketServerRepositoryOwner.java │ │ │ ├── BitbucketServerRepositories.java │ │ │ └── BitbucketServerRepository.java │ │ │ ├── branch │ │ │ ├── BitbucketServerBranch.java │ │ │ ├── BitbucketServerBranches.java │ │ │ └── BitbucketServerCommit.java │ │ │ ├── pullrequest │ │ │ ├── BitbucketServerPullRequests.java │ │ │ ├── BitbucketServerPullRequest.java │ │ │ └── BitbucketServerPullRequestSource.java │ │ │ └── BitbucketServerWebhookPayload.java │ │ ├── RepositoryType.java │ │ ├── BitbucketChangesetCommentNotifier.java │ │ ├── CustomNameJobColumn.java │ │ ├── HttpsRepositoryUriResolver.java │ │ ├── BitbucketNotifier.java │ │ ├── RepositoryUriResolver.java │ │ ├── SshRepositoryUriResolver.java │ │ ├── SCMHeadWithOwnerAndRepo.java │ │ └── BitbucketApiConnector.java └── test │ └── java │ └── com │ └── cloudbees │ └── jenkins │ └── plugins │ └── bitbucket │ ├── UriResolverTest.java │ ├── SCMNavigatorIntegrationTest.java │ ├── WebhooksAutoregisterTest.java │ ├── SCMNavigatorTest.java │ ├── BranchScanningTest.java │ └── BitbucketClientMockUtils.java └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | .classpath 3 | .settings 4 | target 5 | work 6 | 7 | # INTELLIJ 8 | .idea 9 | *.iml 10 | *.iws 11 | *.ipr -------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMNavigator/help-credentialsId.html: -------------------------------------------------------------------------------- 1 |
2 |

Credentials used to scan branches and check out sources

3 |
-------------------------------------------------------------------------------- /src/main/webapp/images/48x48/bitbucket-scmnavigator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/batterseapower/bitbucket-branch-source-plugin/master/src/main/webapp/images/48x48/bitbucket-scmnavigator.png -------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMNavigator/help-checkoutCredentialsId.html: -------------------------------------------------------------------------------- 1 |
2 |

Credentials used to check out sources during a build.

3 |
-------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMNavigator/help-pattern.html: -------------------------------------------------------------------------------- 1 |
2 |

Regular expression to specify what repositories one wants to include

3 |
-------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/AbstractBranchJobFilter/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource/help-sshPort.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | Left blank to use Bitbucket Cloud. 4 | SSH Port as configured in Bitbucket Server settings. 5 |

6 |
-------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/CustomNameJobColumn/columnHeader.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | ${it.message} 4 | -------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMNavigator/help-sshPort.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | Left blank to use Bitbucket Cloud. 4 | SSH Port as configured in Bitbucket Server settings. 5 |

6 |
-------------------------------------------------------------------------------- /src/main/resources/index.jelly: -------------------------------------------------------------------------------- 1 | 2 |
3 | Allows to use Bitbucket Cloud as a source for multi-branch projects. It also 4 | provides the required connectors for Bitbucket Cloud Team Folder (also known as 5 | repositories auto-discovering). 6 |
7 | -------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMNavigator/help-bitbucketServerUrl.html: -------------------------------------------------------------------------------- 1 |
2 |

Left blank to use Bitbucket Cloud. 3 | Set your Bitbucket Server base URL to use your own server instance. The URL must contain the full URL including 4 | a base path (if exists).

5 |
-------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource/help-bitbucketServerUrl.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | Left blank to use Bitbucket Cloud. 4 | Set your Bitbucket Server base URL to use your own server instance. The URL must contain the full URL including 5 | a base path (if exists). 6 |

7 |
-------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource/help-repoOwner.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | Repository owner. It will be used to build the repository URL: http://bitbucket.org/[owner]/repository 6 |
7 |
8 |
-------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource/help-checkoutCredentialsId.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | Credentials used to clone the repository. They can be Username and Password credentials or SSH credentials 6 |
7 |
8 |
-------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/CustomNameJobColumn/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/Messages.properties: -------------------------------------------------------------------------------- 1 | BitbucketSCMNavigator.DisplayName=Bitbucket Team/Project 2 | BitbucketSCMNavigator.Description=Scans a Bitbucket Cloud Team (or Bitbucket Server Project) for all repositories matching some defined markers. 3 | ListViewColumn.Repository=Repository 4 | ListViewColumn.Branch=Branch 5 | ListViewColumn.PullRequest=Pull Request -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketPushEvent.java: -------------------------------------------------------------------------------- 1 | package com.cloudbees.jenkins.plugins.bitbucket.api; 2 | 3 | /** 4 | * Represents a push event coming from Bitbucket (webhooks). 5 | */ 6 | public interface BitbucketPushEvent { 7 | /** 8 | * @return the destination repository that the push points to. 9 | */ 10 | BitbucketRepository getRepository(); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource/help-credentialsId.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | Credentials used to access Bitbucket REST API to retrieve branches and pull requests information. 6 | They must be Username and Password credentials. 7 |
8 |
9 |
-------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMNavigator/help-repoOwner.html: -------------------------------------------------------------------------------- 1 |
2 |

Specify the name of the Bitbucket Team or Bitbucket User Account.

3 |

4 | It could be a Bitbucket Project also, if using Bitbucket Server. 5 | In this case (Bitbucket Server): 6 |

10 |

11 |
-------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource/help.html: -------------------------------------------------------------------------------- 1 |
2 | SCM Source implementation which provides a connector to import branches and pull requests 3 | from Bitbucket. 4 | 5 | It will retrieve all branches and pull requests available at indexing time. Username and password 6 | credentials are needed to access Bitbucket API (Scan Credentials field), and both SSH and username/password 7 | can be used for git checkout (see advanced options by clicking in the Advanced button below). 8 | 9 | If only "Scan Credentials" are provided they will be used for the scan process and git checkout. 10 |
11 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/BitbucketType.java: -------------------------------------------------------------------------------- 1 | package com.cloudbees.jenkins.plugins.bitbucket.hooks; 2 | 3 | import edu.umd.cs.findbugs.annotations.CheckForNull; 4 | 5 | public enum BitbucketType { 6 | 7 | CLOUD("cloud"), 8 | 9 | SERVER("server"); 10 | 11 | private String key; 12 | 13 | BitbucketType(String key) { 14 | this.key = key; 15 | } 16 | 17 | public String getKey() { 18 | return key; 19 | } 20 | 21 | @CheckForNull 22 | public static BitbucketType fromString(String key) { 23 | for (BitbucketType value : BitbucketType.values()) { 24 | if (value.getKey().equals(key)) { 25 | return value; 26 | } 27 | } 28 | return null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BranchJobFilter.java: -------------------------------------------------------------------------------- 1 | package com.cloudbees.jenkins.plugins.bitbucket; 2 | 3 | import org.kohsuke.stapler.DataBoundConstructor; 4 | 5 | import hudson.Extension; 6 | import hudson.model.Descriptor; 7 | import hudson.views.ViewJobFilter; 8 | import jenkins.scm.api.SCMHead; 9 | 10 | public class BranchJobFilter extends AbstractBranchJobFilter { 11 | @DataBoundConstructor 12 | public BranchJobFilter() {} 13 | 14 | @Override 15 | protected boolean shouldShow(SCMHead head) { 16 | return head instanceof SCMHeadWithOwnerAndRepo && ((SCMHeadWithOwnerAndRepo) head).getPullRequestId() == null; 17 | } 18 | 19 | @Extension 20 | public static class DescriptorImpl extends Descriptor { 21 | @Override 22 | public String getDisplayName() { 23 | return "Bitbucket Branch Jobs Only"; 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/PullRequestJobFilter.java: -------------------------------------------------------------------------------- 1 | package com.cloudbees.jenkins.plugins.bitbucket; 2 | 3 | import org.kohsuke.stapler.DataBoundConstructor; 4 | 5 | import hudson.Extension; 6 | import hudson.model.Descriptor; 7 | import hudson.views.ViewJobFilter; 8 | import jenkins.scm.api.SCMHead; 9 | 10 | public class PullRequestJobFilter extends AbstractBranchJobFilter { 11 | @DataBoundConstructor 12 | public PullRequestJobFilter() {} 13 | 14 | @Override 15 | protected boolean shouldShow(SCMHead head) { 16 | return head instanceof SCMHeadWithOwnerAndRepo && ((SCMHeadWithOwnerAndRepo) head).getPullRequestId() != null; 17 | } 18 | 19 | @Extension 20 | public static class DescriptorImpl extends Descriptor { 21 | @Override 22 | public String getDisplayName() { 23 | return "Bitbucket Pull Request Jobs Only"; 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource/help-autoRegisterHook.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |

6 | Activate this option to auto-register a hook on the specified Bitbucket repository. This hook will notify Jenkins 7 | about new commits on branches and pull requests, so new builds will be triggered automatically on related jobs. 8 |

9 |

10 | Otherwise the hook can be created manually using the following information: 11 |

    12 |
  • URL: [JENKINS_ROOT_URL]/bitbucket-scmsource-hook/notify
  • 13 |
  • Check "Push", "Pull Request Created" and "Pull Request Updated" in the triggers section.
  • 14 |
15 | NOTE: [JENKINS_ROOT_URL] must be exactly the same that is configured in Jenkins main configuration. 16 |

17 |
18 |
19 |
-------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMNavigator/help-autoRegisterHooks.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |

6 | Activate this option to auto-register a hook on all discovered Bitbucket Cloud repositories. This hook will notify Jenkins 7 | about new commits on branches and pull requests, so new builds will be triggered automatically on related jobs. 8 |

9 |

10 | Otherwise the hook can be created manually using the following information: 11 |

    12 |
  • URL: ${app.rootUrl != null ? app.rootUrl : "[JENKINS_ROOT_URL]/"}bitbucket-scmsource-hook/notify
  • 13 |
  • Check "Push", "Pull Request Created" and "Pull Request Updated" in the triggers section.
  • 14 |
15 | NOTE: this Jenkins instance must accesible somehow from internet (concretely reachable from Bitbucket Cloud). 16 |

17 |
18 |
19 |
-------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMNavigator/config.jelly: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/AbstractBranchJobFilter.java: -------------------------------------------------------------------------------- 1 | package com.cloudbees.jenkins.plugins.bitbucket; 2 | 3 | import java.util.List; 4 | 5 | import com.cloudbees.jenkins.plugins.bitbucket.CustomComputedFolderItemListener.Sniffer; 6 | import com.cloudbees.jenkins.plugins.bitbucket.CustomComputedFolderItemListener.Sniffer.BranchMatch; 7 | 8 | import hudson.model.TopLevelItem; 9 | import hudson.model.View; 10 | import hudson.views.ViewJobFilter; 11 | import jenkins.scm.api.SCMHead; 12 | 13 | abstract class AbstractBranchJobFilter extends ViewJobFilter { 14 | public AbstractBranchJobFilter() {} 15 | 16 | @Override 17 | public List filter(List added, List all, View filteringView) { 18 | for (TopLevelItem i : all) { 19 | if (added.contains(i)) continue; // already in there 20 | 21 | BranchMatch b = Sniffer.matchBranch(i); 22 | if (b!=null) { 23 | SCMHead head = b.getScmBranch().getHead(); 24 | if (shouldShow(head)) { 25 | added.add(i); 26 | } 27 | } 28 | } 29 | return added; 30 | } 31 | 32 | protected abstract boolean shouldShow(SCMHead head); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/main/resources/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource/config-detail.jelly: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/PullRequestAction.java: -------------------------------------------------------------------------------- 1 | package com.cloudbees.jenkins.plugins.bitbucket; 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | 6 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest; 7 | 8 | import edu.umd.cs.findbugs.annotations.NonNull; 9 | import jenkins.scm.api.actions.ChangeRequestAction; 10 | 11 | public class PullRequestAction extends ChangeRequestAction { 12 | private final String number; 13 | private URL url; 14 | private final String title; 15 | private final String userLogin; 16 | 17 | public PullRequestAction(BitbucketPullRequest pr) { 18 | number = pr.getId(); 19 | try { 20 | url = new URL(pr.getLink()); 21 | } catch (MalformedURLException e) { 22 | url = null; 23 | } 24 | title = pr.getTitle(); 25 | userLogin = pr.getAuthorLogin(); 26 | } 27 | 28 | @Override 29 | @NonNull 30 | public String getId() { 31 | return number; 32 | } 33 | 34 | @Override 35 | public URL getURL() { 36 | return url; 37 | } 38 | 39 | @Override 40 | public String getTitle() { 41 | return title; 42 | } 43 | 44 | @Override 45 | public String getAuthor() { 46 | return userLogin; 47 | } 48 | 49 | private static final long serialVersionUID = 1L; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.api; 25 | 26 | public class BitbucketException extends RuntimeException { 27 | 28 | public BitbucketException(String message, Throwable cause) { 29 | super(message, cause); 30 | } 31 | 32 | public BitbucketException(String message) { 33 | super(message); 34 | } 35 | 36 | private static final long serialVersionUID = 1L; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketTeam.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.api; 25 | 26 | /** 27 | * Represents a Bitbucket team (or a Project when working with Bitbucket Server). 28 | */ 29 | public interface BitbucketTeam { 30 | 31 | /** 32 | * @return team or project name 33 | */ 34 | String getName(); 35 | 36 | /** 37 | * @return team or project display name. 38 | */ 39 | String getDisplayName(); 40 | 41 | } -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketRepositoryOwner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.api; 25 | 26 | /** 27 | * A repository owner. 28 | * It could be a user, a team or a project. 29 | */ 30 | public interface BitbucketRepositoryOwner { 31 | 32 | /** 33 | * @return the owner name 34 | */ 35 | String getUsername(); 36 | 37 | /** 38 | * @return the owner's display name (not used for references) 39 | */ 40 | String getDisplayName(); 41 | 42 | } -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketBranch.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.api; 25 | 26 | /** 27 | * Bitbucket Branch. 28 | * 29 | * It's used to represent branches to be built and source branches for pull requests. 30 | */ 31 | public interface BitbucketBranch { 32 | 33 | /** 34 | * @return the head commit node of this branch 35 | */ 36 | String getRawNode(); 37 | 38 | /** 39 | * @return the branch name 40 | */ 41 | String getName(); 42 | 43 | } -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketPullRequestEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.api; 25 | 26 | /** 27 | * Represents a pull request event coming from Bitbucket (webhooks). 28 | */ 29 | public interface BitbucketPullRequestEvent { 30 | 31 | /** 32 | * @return the pull request that originates this event. 33 | */ 34 | BitbucketPullRequest getPullRequest(); 35 | 36 | /** 37 | * @return the destination repository that {@link #getPullRequest()} points to. 38 | */ 39 | BitbucketRepository getRepository(); 40 | 41 | } -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketCommit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.api; 25 | 26 | /** 27 | * Bitbucket commit. 28 | */ 29 | public interface BitbucketCommit { 30 | 31 | /** 32 | * @return commit message 33 | */ 34 | String getMessage(); 35 | 36 | /** 37 | * @return the commit date in ISO format 38 | */ 39 | String getDate(); 40 | 41 | /** 42 | * @return the commit hash (complete, not reduced) 43 | */ 44 | String getHash(); 45 | 46 | /** 47 | * @return commit time in milliseconds (Java timestamp) 48 | */ 49 | long getDateMillis(); 50 | 51 | } -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketPullRequestSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.api; 25 | 26 | /** 27 | * Represents a pull request source, which is a repository, a branch in that repository and the head commit. 28 | */ 29 | public interface BitbucketPullRequestSource { 30 | 31 | /** 32 | * @return source repository 33 | */ 34 | BitbucketRepository getRepository(); 35 | 36 | /** 37 | * @return source branch to be merged in the pull request 38 | */ 39 | BitbucketBranch getBranch(); 40 | 41 | /** 42 | * @return the branch head commit 43 | */ 44 | BitbucketCommit getCommit(); 45 | 46 | } -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketRequestException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.api; 25 | 26 | public class BitbucketRequestException extends RuntimeException { 27 | 28 | private int httpCode; 29 | 30 | public BitbucketRequestException(int httpCode, String message) { 31 | super(message); 32 | this.httpCode = httpCode; 33 | } 34 | 35 | public BitbucketRequestException(int httpCode, String message, Throwable t) { 36 | super(message, t); 37 | this.httpCode = httpCode; 38 | } 39 | 40 | public int getHttpCode() { 41 | return httpCode; 42 | } 43 | 44 | private static final long serialVersionUID = 1L; 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketPullRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.api; 25 | 26 | import edu.umd.cs.findbugs.annotations.NonNull; 27 | 28 | /** 29 | * Represents a pull request in Bitbucket. 30 | * Only the source repository is necessary, the destination repo is inferred. 31 | */ 32 | public interface BitbucketPullRequest { 33 | 34 | /** 35 | * @return the source repository of this pull request 36 | */ 37 | BitbucketPullRequestSource getSource(); 38 | 39 | /** 40 | * @return pull request ID as provided by Bitbucket. It can be used for notifications. 41 | */ 42 | @NonNull 43 | String getId(); 44 | 45 | String getTitle(); 46 | 47 | String getLink(); 48 | 49 | String getAuthorLogin(); 50 | 51 | } -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/repository/BitbucketRepositoryHooks.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client.repository; 25 | 26 | import java.util.List; 27 | 28 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 29 | 30 | @JsonIgnoreProperties(ignoreUnknown = true) 31 | public class BitbucketRepositoryHooks { 32 | 33 | private String next; 34 | 35 | private List values; 36 | 37 | public String getNext() { 38 | return next; 39 | } 40 | 41 | public void setNext(String next) { 42 | this.next = next; 43 | } 44 | 45 | public List getValues() { 46 | return values; 47 | } 48 | 49 | public void setValues(List values) { 50 | this.values = values; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/pullrequest/BitbucketPullRequests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client.pullrequest; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 27 | 28 | import java.util.List; 29 | 30 | @JsonIgnoreProperties(ignoreUnknown = true) 31 | public class BitbucketPullRequests { 32 | 33 | private List values; 34 | 35 | private String next; 36 | 37 | public List getValues() { 38 | return values; 39 | } 40 | 41 | public void setValues(List prValues) { 42 | this.values = prValues; 43 | } 44 | 45 | public String getNext() { 46 | return next; 47 | } 48 | 49 | public void setNext(String next) { 50 | this.next = next; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/repository/PaginatedBitbucketRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client.repository; 25 | 26 | import java.util.List; 27 | 28 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 29 | 30 | @JsonIgnoreProperties(ignoreUnknown = true) 31 | public class PaginatedBitbucketRepository { 32 | 33 | private String next; 34 | 35 | private List values; 36 | 37 | public List getValues() { 38 | return values; 39 | } 40 | 41 | public void setValues(List values) { 42 | this.values = values; 43 | } 44 | 45 | public String getNext() { 46 | return next; 47 | } 48 | 49 | public void setNext(String next) { 50 | this.next = next; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/events/BitbucketCloudPushEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client.events; 25 | 26 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPushEvent; 27 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository; 28 | import com.cloudbees.jenkins.plugins.bitbucket.client.repository.BitbucketCloudRepository; 29 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 30 | 31 | @JsonIgnoreProperties(ignoreUnknown = true) 32 | public class BitbucketCloudPushEvent implements BitbucketPushEvent { 33 | 34 | private BitbucketCloudRepository repository; 35 | 36 | public BitbucketRepository getRepository() { 37 | return repository; 38 | } 39 | 40 | public void setRepository(BitbucketCloudRepository repository) { 41 | this.repository = repository; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/events/BitbucketServerPushEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.server.events; 25 | 26 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPushEvent; 27 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository; 28 | import com.cloudbees.jenkins.plugins.bitbucket.server.client.repository.BitbucketServerRepository; 29 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 30 | 31 | @JsonIgnoreProperties(ignoreUnknown = true) 32 | public class BitbucketServerPushEvent implements BitbucketPushEvent{ 33 | 34 | private BitbucketServerRepository repository; 35 | 36 | public BitbucketRepository getRepository() { 37 | return repository; 38 | } 39 | 40 | public void setRepository(BitbucketServerRepository repository) { 41 | this.repository = repository; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketWebHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.api; 25 | 26 | import java.util.List; 27 | 28 | /** 29 | * Represents a webhook in Bitbucket. 30 | */ 31 | public interface BitbucketWebHook { 32 | 33 | /** 34 | * @return webhook description text 35 | */ 36 | String getDescription(); 37 | 38 | /** 39 | * @return webhook URL (not required at creation time) 40 | */ 41 | String getUrl(); 42 | 43 | /** 44 | * @return tru if the webhook is active (not required at creation time) 45 | */ 46 | boolean isActive(); 47 | 48 | /** 49 | * @return the list of events this webhook is notifying 50 | */ 51 | List getEvents(); 52 | 53 | /** 54 | * @return Bitbucket internal ID for this webhook (not required at creation time) 55 | */ 56 | String getUuid(); 57 | 58 | } -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/RepositoryType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket; 25 | 26 | import edu.umd.cs.findbugs.annotations.CheckForNull; 27 | import edu.umd.cs.findbugs.annotations.NonNull; 28 | 29 | public enum RepositoryType { 30 | 31 | /** 32 | * Git repository. 33 | */ 34 | GIT("git"), 35 | 36 | /** 37 | * Mercurial repository. 38 | */ 39 | MERCURIAL("hg"); 40 | 41 | private String type; 42 | 43 | RepositoryType(@NonNull String type) { 44 | this.type = type; 45 | } 46 | 47 | public String getType() { 48 | return type; 49 | } 50 | 51 | @CheckForNull 52 | public static RepositoryType fromString(String type) { 53 | if (GIT.type.equals(type)) { 54 | return GIT; 55 | } else if (MERCURIAL.type.equals(type)) { 56 | return MERCURIAL; 57 | } else { 58 | return null; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/repository/BitbucketCloudTeam.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client.repository; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 27 | import org.codehaus.jackson.annotate.JsonProperty; 28 | 29 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketTeam; 30 | 31 | @JsonIgnoreProperties(ignoreUnknown = true) 32 | public class BitbucketCloudTeam implements BitbucketTeam { 33 | 34 | @JsonProperty("username") 35 | private String name; 36 | 37 | @JsonProperty("display_name") 38 | private String displayName; 39 | 40 | @Override 41 | public String getName() { 42 | return name; 43 | } 44 | 45 | public void setName(String name) { 46 | this.name = name; 47 | } 48 | 49 | @Override 50 | public String getDisplayName() { 51 | return displayName; 52 | } 53 | 54 | public void setDisplayName(String displayName) { 55 | this.displayName = displayName; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/repository/BitbucketServerProject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.server.client.repository; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 27 | import org.codehaus.jackson.annotate.JsonProperty; 28 | 29 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketTeam; 30 | 31 | @JsonIgnoreProperties(ignoreUnknown = true) 32 | public class BitbucketServerProject implements BitbucketTeam { 33 | 34 | @JsonProperty("key") 35 | private String name; 36 | 37 | @JsonProperty("name") 38 | private String displayName; 39 | 40 | @Override 41 | public String getName() { 42 | return name; 43 | } 44 | 45 | @Override 46 | public String getDisplayName() { 47 | return displayName; 48 | } 49 | 50 | public void setName(String name) { 51 | this.name = name; 52 | } 53 | 54 | public void setDisplayName(String displayName) { 55 | this.displayName = displayName; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketChangesetCommentNotifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket; 25 | 26 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; 27 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBuildStatus; 28 | 29 | import edu.umd.cs.findbugs.annotations.NonNull; 30 | 31 | /** 32 | * Bitbucket notifier implementation that sends notifications as commit comments. 33 | */ 34 | public class BitbucketChangesetCommentNotifier extends BitbucketNotifier { 35 | 36 | private BitbucketApi bitbucket; 37 | 38 | public BitbucketChangesetCommentNotifier(@NonNull BitbucketApi bitbucket) { 39 | this.bitbucket = bitbucket; 40 | } 41 | 42 | @Override 43 | public void notify(String repoOwner, String repoName, String hash, String content) { 44 | bitbucket.postCommitComment(hash, content); 45 | } 46 | 47 | @Override 48 | public void buildStatus(BitbucketBuildStatus status) { 49 | bitbucket.postBuildStatus(status); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.api; 25 | 26 | /** 27 | * Represents a Bitbucket repository. 28 | */ 29 | public interface BitbucketRepository { 30 | 31 | /** 32 | * @return the scm type (git ot hg) 33 | */ 34 | String getScm(); 35 | 36 | /** 37 | * @return full repositoty name, which is owner/name (where owner could be a user, a team or a project) 38 | */ 39 | String getFullName(); 40 | 41 | /** 42 | * @return repository owner (could be a user, a team or a project) 43 | */ 44 | BitbucketRepositoryOwner getOwner(); 45 | 46 | /** 47 | * @return {@link #getOwner()}'s name 48 | */ 49 | String getOwnerName(); 50 | 51 | /** 52 | * @return the repository name (as extracted from {@link #getFullName()}) 53 | */ 54 | String getRepositoryName(); 55 | 56 | /** 57 | * @return return true if the repository is a private one (false otherwise). 58 | */ 59 | boolean isPrivate(); 60 | 61 | } -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/repository/BitbucketServerRepositoryOwner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.server.client.repository; 25 | 26 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepositoryOwner; 27 | 28 | public class BitbucketServerRepositoryOwner implements BitbucketRepositoryOwner { 29 | 30 | private String username; 31 | 32 | private String displayName; 33 | 34 | public BitbucketServerRepositoryOwner(String username, String displayName) { 35 | this.username = username; 36 | this.displayName = displayName; 37 | } 38 | 39 | @Override 40 | public String getUsername() { 41 | return username; 42 | } 43 | 44 | @Override 45 | public String getDisplayName() { 46 | return displayName; 47 | } 48 | 49 | public void setUsername(String username) { 50 | this.username = username; 51 | } 52 | 53 | public void setDisplayName(String displayName) { 54 | this.displayName = displayName; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/repository/BitbucketCloudRepositoryOwner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client.repository; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 27 | import org.codehaus.jackson.annotate.JsonProperty; 28 | 29 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepositoryOwner; 30 | 31 | @JsonIgnoreProperties(ignoreUnknown = true) 32 | public class BitbucketCloudRepositoryOwner implements BitbucketRepositoryOwner { 33 | 34 | private String username; 35 | 36 | @JsonProperty("display_name") 37 | private String displayName; 38 | 39 | @Override 40 | public String getUsername() { 41 | return username; 42 | } 43 | 44 | @Override 45 | public String getDisplayName() { 46 | return displayName; 47 | } 48 | 49 | public void setUsername(String username) { 50 | this.username = username; 51 | } 52 | 53 | public void setDisplayName(String displayName) { 54 | this.displayName = displayName; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/CustomNameJobColumn.java: -------------------------------------------------------------------------------- 1 | package com.cloudbees.jenkins.plugins.bitbucket; 2 | 3 | import java.util.logging.Level; 4 | import java.util.logging.Logger; 5 | 6 | import org.jvnet.localizer.Localizable; 7 | import org.jvnet.localizer.ResourceBundleHolder; 8 | import org.kohsuke.stapler.DataBoundConstructor; 9 | 10 | import hudson.Extension; 11 | import hudson.views.JobColumn; 12 | import hudson.views.ListViewColumnDescriptor; 13 | import jenkins.model.Jenkins; 14 | import jenkins.util.NonLocalizable; 15 | 16 | public class CustomNameJobColumn extends JobColumn { 17 | 18 | /** 19 | * Resource bundle name. 20 | */ 21 | private final String bundle; 22 | private final String key; 23 | 24 | private transient Localizable loc; 25 | 26 | @DataBoundConstructor 27 | public CustomNameJobColumn(String bundle, String key) { 28 | this.bundle = bundle; 29 | this.key = key; 30 | readResolve(); 31 | } 32 | 33 | public CustomNameJobColumn(Class bundle, Localizable loc) { 34 | this.bundle = bundle.getName(); 35 | this.key = loc.getKey(); 36 | this.loc = loc; 37 | } 38 | 39 | public String getBundle() { 40 | return bundle; 41 | } 42 | 43 | public String getKey() { 44 | return loc.getKey(); 45 | } 46 | 47 | public String getMessage() { 48 | return loc.toString(); 49 | } 50 | 51 | private Object readResolve() { 52 | try { 53 | loc = new Localizable( 54 | ResourceBundleHolder.get(Jenkins.getActiveInstance().pluginManager.uberClassLoader.loadClass(bundle)), 55 | key); 56 | } catch (ClassNotFoundException e) { 57 | LOGGER.log(Level.WARNING, "No such bundle: " + bundle); 58 | loc = new NonLocalizable(bundle + ':' + key); 59 | } 60 | return this; 61 | } 62 | 63 | @Extension 64 | public static class DescriptorImpl extends ListViewColumnDescriptor { 65 | @Override 66 | public String getDisplayName() { 67 | return "Repositories"; 68 | } 69 | 70 | @Override 71 | public boolean shownByDefault() { 72 | return false; 73 | } 74 | } 75 | 76 | private static final Logger LOGGER = Logger.getLogger(CustomNameJobColumn.class.getName()); 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/repository/UserRoleInRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client.repository; 25 | 26 | /** 27 | * User role in repository: 28 | *
    29 | *
  • owner: returns all repositories owned by the current user.
  • 30 | *
  • admin: returns repositories to which the user has explicit administrator access.
  • 31 | *
  • contributor: returns repositories to which the user has explicit write access.
  • 32 | *
  • member: returns repositories to which the user has explicit read access.
  • 33 | *
34 | * 35 | * See API docs for more information. 36 | */ 37 | public enum UserRoleInRepository { 38 | 39 | OWNER("owner"), 40 | ADMIN("admin"), 41 | CONTRIBUTOR("contributor"), 42 | MEMBER("member"); 43 | 44 | private String id; 45 | 46 | private UserRoleInRepository(String id) { 47 | this.id = id; 48 | } 49 | 50 | public String getId() { 51 | return id; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/branch/BitbucketServerBranch.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.server.client.branch; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 27 | 28 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBranch; 29 | 30 | @JsonIgnoreProperties(ignoreUnknown = true) 31 | public class BitbucketServerBranch implements BitbucketBranch { 32 | 33 | private String displayId; 34 | 35 | private String latestCommit; 36 | 37 | public BitbucketServerBranch() { 38 | } 39 | 40 | public BitbucketServerBranch(String name, String headHash) { 41 | this.displayId = name; 42 | this.latestCommit = headHash; 43 | } 44 | 45 | @Override 46 | public String getRawNode() { 47 | return latestCommit; 48 | } 49 | 50 | @Override 51 | public String getName() { 52 | return displayId; 53 | } 54 | 55 | public void setDisplayId(String displayId) { 56 | this.displayId = displayId; 57 | } 58 | 59 | public void setLatestCommit(String latestCommit) { 60 | this.latestCommit = latestCommit; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/HttpsRepositoryUriResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket; 25 | 26 | import java.net.MalformedURLException; 27 | 28 | public class HttpsRepositoryUriResolver extends RepositoryUriResolver { 29 | 30 | public HttpsRepositoryUriResolver(String baseUrl) throws MalformedURLException { 31 | super(baseUrl); 32 | } 33 | 34 | @Override 35 | public String getRepositoryUri(String owner, String repository, RepositoryType type) { 36 | String uri = null; 37 | if (type == RepositoryType.MERCURIAL) { 38 | if (isServer()) { 39 | throw new IllegalStateException("Mercurial is not supported by Bitbucket Server (https://jira.atlassian.com/browse/BSERV-2469)"); 40 | } 41 | uri = "/" + owner + "/" + repository; 42 | } else { 43 | // Defaults to git 44 | uri = "/" + owner + "/" + repository + ".git"; 45 | } 46 | if (isServer()) { 47 | uri = getUrlAsString() + "/scm" + uri; 48 | } else { 49 | uri = getUrlAsString() + uri; 50 | } 51 | return uri; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/branch/BitbucketCloudBranch.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client.branch; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 27 | import org.codehaus.jackson.annotate.JsonProperty; 28 | 29 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBranch; 30 | 31 | @JsonIgnoreProperties(ignoreUnknown = true) 32 | public class BitbucketCloudBranch implements BitbucketBranch { 33 | 34 | @JsonProperty("raw_node") 35 | private String rawNode; 36 | 37 | private String name; 38 | 39 | // Needed for compatibility with different Bitbucket API JSON messages 40 | private String branch; 41 | 42 | public String getBranch() { 43 | return branch; 44 | } 45 | 46 | public void setBranch(String branch) { 47 | this.branch = branch; 48 | } 49 | 50 | @Override 51 | 52 | public String getRawNode() { 53 | return rawNode; 54 | } 55 | 56 | @Override 57 | public String getName() { 58 | return name != null ? name : branch; 59 | } 60 | 61 | public void setRawNode(String rawNode) { 62 | this.rawNode = rawNode; 63 | } 64 | 65 | public void setName(String name) { 66 | this.name = name; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/events/BitbucketServerPullRequestEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.server.events; 25 | 26 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequestEvent; 27 | import com.cloudbees.jenkins.plugins.bitbucket.server.client.pullrequest.BitbucketServerPullRequest; 28 | import com.cloudbees.jenkins.plugins.bitbucket.server.client.repository.BitbucketServerRepository; 29 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 30 | import org.codehaus.jackson.annotate.JsonProperty; 31 | 32 | @JsonIgnoreProperties(ignoreUnknown = true) 33 | public class BitbucketServerPullRequestEvent implements BitbucketPullRequestEvent { 34 | 35 | @JsonProperty("pullrequest") 36 | private BitbucketServerPullRequest pullRequest; 37 | 38 | private BitbucketServerRepository repository; 39 | 40 | @Override 41 | public BitbucketServerPullRequest getPullRequest() { 42 | return pullRequest; 43 | } 44 | 45 | public void setPullRequest(BitbucketServerPullRequest pullRequest) { 46 | this.pullRequest = pullRequest; 47 | } 48 | 49 | @Override 50 | public BitbucketServerRepository getRepository() { 51 | return repository; 52 | } 53 | 54 | public void setRepository(BitbucketServerRepository repository) { 55 | this.repository = repository; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketNotifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket; 25 | 26 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBuildStatus; 27 | 28 | import edu.umd.cs.findbugs.annotations.CheckForNull; 29 | 30 | /** 31 | * Abstract Bitbucket commit notifier implementation. 32 | */ 33 | public abstract class BitbucketNotifier { 34 | 35 | /** 36 | * Notify bitbucket about a new build status on a concrete commit. 37 | * 38 | * @param repoOwner repository owner name (username) 39 | * @param repoName repository name 40 | * @param hash commit hash 41 | * @param content notification content 42 | */ 43 | public abstract void notify(@CheckForNull String repoOwner, @CheckForNull String repoName, String hash, String content); 44 | 45 | /** 46 | * Notify bitbucket through the build status API. 47 | * 48 | * @param status the status object to serialize 49 | */ 50 | public abstract void buildStatus(BitbucketBuildStatus status); 51 | 52 | /** 53 | * Convenience method that calls {@link #notify(String, String, String, String)} without owner 54 | * and repository name. 55 | * 56 | * @param hash commit hash 57 | * @param content notification content 58 | */ 59 | public void notify(String hash, String content) { 60 | notify(null, null, hash, content); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/branch/BitbucketServerBranches.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.server.client.branch; 25 | 26 | import java.util.List; 27 | 28 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 29 | import org.codehaus.jackson.annotate.JsonProperty; 30 | 31 | @JsonIgnoreProperties(ignoreUnknown = true) 32 | public class BitbucketServerBranches { 33 | 34 | private List values; 35 | 36 | private Integer size; 37 | 38 | @JsonProperty("isLastPage") 39 | private Boolean lastPage; 40 | 41 | private Integer nextPageStart; 42 | 43 | public List getValues() { 44 | return values; 45 | } 46 | 47 | public void setValues(List values) { 48 | this.values = values; 49 | } 50 | 51 | public Integer getSize() { 52 | return size; 53 | } 54 | 55 | public void setSize(Integer size) { 56 | this.size = size; 57 | } 58 | 59 | public Boolean isLastPage() { 60 | return lastPage; 61 | } 62 | 63 | public void setLastPage(Boolean lastPage) { 64 | this.lastPage = lastPage; 65 | } 66 | 67 | public Integer getNextPageStart() { 68 | return nextPageStart; 69 | } 70 | 71 | public void setNextPageStart(Integer nextPageStart) { 72 | this.nextPageStart = nextPageStart; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/repository/BitbucketServerRepositories.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.server.client.repository; 25 | 26 | import java.util.List; 27 | 28 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 29 | import org.codehaus.jackson.annotate.JsonProperty; 30 | 31 | @JsonIgnoreProperties(ignoreUnknown = true) 32 | public class BitbucketServerRepositories { 33 | 34 | private List values; 35 | 36 | private Integer size; 37 | 38 | @JsonProperty("isLastPage") 39 | private Boolean lastPage; 40 | 41 | private Integer nextPageStart; 42 | 43 | public List getValues() { 44 | return values; 45 | } 46 | 47 | public void setValues(List values) { 48 | this.values = values; 49 | } 50 | 51 | public Integer getSize() { 52 | return size; 53 | } 54 | 55 | public void setSize(Integer size) { 56 | this.size = size; 57 | } 58 | 59 | public Boolean isLastPage() { 60 | return lastPage; 61 | } 62 | 63 | public void setLastPage(Boolean lastPage) { 64 | this.lastPage = lastPage; 65 | } 66 | 67 | public Integer getNextPageStart() { 68 | return nextPageStart; 69 | } 70 | 71 | public void setNextPageStart(Integer nextPageStart) { 72 | this.nextPageStart = nextPageStart; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/pullrequest/BitbucketServerPullRequests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.server.client.pullrequest; 25 | 26 | import java.util.List; 27 | 28 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 29 | import org.codehaus.jackson.annotate.JsonProperty; 30 | 31 | @JsonIgnoreProperties(ignoreUnknown = true) 32 | public class BitbucketServerPullRequests { 33 | 34 | private List values; 35 | 36 | private Integer size; 37 | 38 | @JsonProperty("isLastPage") 39 | private Boolean lastPage; 40 | 41 | private Integer nextPageStart; 42 | 43 | public List getValues() { 44 | return values; 45 | } 46 | 47 | public void setValues(List prValues) { 48 | this.values = prValues; 49 | } 50 | 51 | public Integer getSize() { 52 | return size; 53 | } 54 | 55 | public void setSize(Integer size) { 56 | this.size = size; 57 | } 58 | 59 | public boolean isLastPage() { 60 | return lastPage; 61 | } 62 | 63 | public void setLastPage(Boolean lastPage) { 64 | this.lastPage = lastPage; 65 | } 66 | 67 | public Integer getNextPageStart() { 68 | return nextPageStart; 69 | } 70 | 71 | public void setNextPageStart(Integer nextPageStart) { 72 | this.nextPageStart = nextPageStart; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/PushHookProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.hooks; 25 | 26 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPushEvent; 27 | import com.cloudbees.jenkins.plugins.bitbucket.client.BitbucketCloudWebhookPayload; 28 | import com.cloudbees.jenkins.plugins.bitbucket.server.client.BitbucketServerWebhookPayload; 29 | 30 | import java.util.logging.Logger; 31 | 32 | public class PushHookProcessor extends HookProcessor { 33 | 34 | private static final Logger LOGGER = Logger.getLogger(PushHookProcessor.class.getName()); 35 | 36 | @Override 37 | public void process(String payload, BitbucketType instanceType) { 38 | if (payload != null) { 39 | BitbucketPushEvent push; 40 | if (instanceType == BitbucketType.SERVER) { 41 | push = BitbucketServerWebhookPayload.pushEventFromPayload(payload); 42 | } else { 43 | push = BitbucketCloudWebhookPayload.pushEventFromPayload(payload); 44 | } 45 | if (push != null) { 46 | String owner = push.getRepository().getOwnerName(); 47 | String repository = push.getRepository().getRepositoryName(); 48 | 49 | LOGGER.info(String.format("Received hook from Bitbucket. Processing push event on %s/%s", owner, repository)); 50 | scmSourceReIndex(owner, repository); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/events/BitbucketCloudPullRequestEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client.events; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 27 | import org.codehaus.jackson.annotate.JsonProperty; 28 | 29 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest; 30 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequestEvent; 31 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository; 32 | import com.cloudbees.jenkins.plugins.bitbucket.client.pullrequest.BitbucketPullRequestValue; 33 | import com.cloudbees.jenkins.plugins.bitbucket.client.repository.BitbucketCloudRepository; 34 | 35 | @JsonIgnoreProperties(ignoreUnknown = true) 36 | public class BitbucketCloudPullRequestEvent implements BitbucketPullRequestEvent { 37 | 38 | @JsonProperty("pullrequest") 39 | private BitbucketPullRequestValue pullRequest; 40 | 41 | private BitbucketCloudRepository repository; 42 | 43 | @Override 44 | public BitbucketPullRequest getPullRequest() { 45 | return pullRequest; 46 | } 47 | 48 | public void setPullRequest(BitbucketPullRequestValue pullRequest) { 49 | this.pullRequest = pullRequest; 50 | } 51 | 52 | @Override 53 | public BitbucketRepository getRepository() { 54 | return repository; 55 | } 56 | 57 | public void setRepository(BitbucketCloudRepository repository) { 58 | this.repository = repository; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/branch/BitbucketCloudCommit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client.branch; 25 | 26 | import java.text.ParseException; 27 | import java.text.SimpleDateFormat; 28 | import java.util.TimeZone; 29 | 30 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 31 | 32 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketCommit; 33 | 34 | @JsonIgnoreProperties(ignoreUnknown = true) 35 | public class BitbucketCloudCommit implements BitbucketCommit { 36 | 37 | private String message; 38 | 39 | private String date; 40 | 41 | private String hash; 42 | 43 | @Override 44 | public String getMessage() { 45 | return message; 46 | } 47 | 48 | @Override 49 | public String getDate() { 50 | return date; 51 | } 52 | 53 | @Override 54 | public String getHash() { 55 | return hash; 56 | } 57 | 58 | public void setMessage(String message) { 59 | this.message = message; 60 | } 61 | 62 | public void setDate(String date) { 63 | this.date = date; 64 | } 65 | 66 | public void setHash(String hash) { 67 | this.hash = hash; 68 | } 69 | 70 | @Override 71 | public long getDateMillis() { 72 | // 2013-10-21T07:21:51+00:00 73 | final SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); 74 | dateParser.setTimeZone(TimeZone.getTimeZone("GMT")); 75 | try { 76 | return dateParser.parse(date).getTime(); 77 | } catch (ParseException e) { 78 | return 0; 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/repository/BitbucketRepositoryHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client.repository; 25 | 26 | import java.util.List; 27 | 28 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 29 | 30 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketWebHook; 31 | 32 | @JsonIgnoreProperties(ignoreUnknown = true) 33 | public class BitbucketRepositoryHook implements BitbucketWebHook { 34 | 35 | private String uuid; 36 | 37 | private String description; 38 | 39 | private String url; 40 | 41 | private boolean active; 42 | 43 | private List events; 44 | 45 | @Override 46 | public String getDescription() { 47 | return description; 48 | } 49 | 50 | public void setDescription(String description) { 51 | this.description = description; 52 | } 53 | 54 | @Override 55 | public String getUrl() { 56 | return url; 57 | } 58 | 59 | public void setUrl(String url) { 60 | this.url = url; 61 | } 62 | 63 | @Override 64 | public boolean isActive() { 65 | return active; 66 | } 67 | 68 | public void setActive(boolean active) { 69 | this.active = active; 70 | } 71 | 72 | @Override 73 | public List getEvents() { 74 | return events; 75 | } 76 | 77 | public void setEvents(List events) { 78 | this.events = events; 79 | } 80 | 81 | @Override 82 | public String getUuid() { 83 | return uuid; 84 | } 85 | 86 | public void setUuid(String uuid) { 87 | this.uuid = uuid; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/RepositoryUriResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket; 25 | 26 | import java.net.MalformedURLException; 27 | import java.net.URL; 28 | 29 | import org.apache.commons.lang.StringUtils; 30 | 31 | import edu.umd.cs.findbugs.annotations.CheckForNull; 32 | 33 | public abstract class RepositoryUriResolver { 34 | 35 | private boolean server = false; 36 | private URL url; 37 | 38 | public RepositoryUriResolver(String baseUrl) throws MalformedURLException { 39 | if (baseUrl != null) { 40 | this.url = new URL(baseUrl); 41 | } 42 | if (!StringUtils.isBlank(baseUrl)) { 43 | server = true; 44 | } 45 | } 46 | 47 | public abstract String getRepositoryUri(String owner, String repository, RepositoryType type); 48 | 49 | public String getUrlAsString() { 50 | return url == null ? "https://bitbucket.org" : url.toExternalForm(); 51 | } 52 | 53 | @CheckForNull 54 | public URL getUrl() { 55 | return url; 56 | } 57 | 58 | /** 59 | * @return the authority part of the {@link #url} (which is host:port) 60 | */ 61 | public String getAuthority() { 62 | if (isServer()) { 63 | return url.getAuthority(); 64 | } 65 | return "bitbucket.org"; 66 | } 67 | 68 | /** 69 | * @return the host part of the {@link #url} 70 | */ 71 | public String getHost() { 72 | if (isServer()) { 73 | return url.getHost(); 74 | } 75 | return "bitbucket.org"; 76 | } 77 | 78 | protected boolean isServer() { 79 | return server; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/pullrequest/BitbucketServerPullRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.server.client.pullrequest; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 27 | import org.codehaus.jackson.annotate.JsonProperty; 28 | 29 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest; 30 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequestSource; 31 | 32 | @JsonIgnoreProperties(ignoreUnknown = true) 33 | public class BitbucketServerPullRequest implements BitbucketPullRequest { 34 | 35 | private String id; 36 | 37 | @JsonProperty("fromRef") 38 | private BitbucketServerPullRequestSource source; 39 | 40 | private String title; 41 | 42 | private String link; 43 | 44 | private String authorLogin; 45 | 46 | @Override 47 | public BitbucketPullRequestSource getSource() { 48 | return source; 49 | } 50 | 51 | public void setSource(BitbucketServerPullRequestSource source) { 52 | this.source = source; 53 | } 54 | 55 | @Override 56 | public String getId() { 57 | return id; 58 | } 59 | 60 | public void setId(String id) { 61 | this.id = id; 62 | } 63 | 64 | @Override 65 | public String getTitle() { 66 | return this.title; 67 | } 68 | 69 | // TODO: unmapped, need proper JsonProperty in the field 70 | @Override 71 | public String getLink() { 72 | return link; 73 | } 74 | 75 | // TODO: unmapped, need proper JsonProperty in the field 76 | @Override 77 | public String getAuthorLogin() { 78 | return authorLogin; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/PullRequestHookProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.hooks; 25 | 26 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequestEvent; 27 | import com.cloudbees.jenkins.plugins.bitbucket.client.BitbucketCloudWebhookPayload; 28 | import com.cloudbees.jenkins.plugins.bitbucket.server.client.BitbucketServerWebhookPayload; 29 | 30 | import java.util.logging.Logger; 31 | 32 | public class PullRequestHookProcessor extends HookProcessor { 33 | 34 | private static final Logger LOGGER = Logger.getLogger(PullRequestHookProcessor.class.getName()); 35 | 36 | @Override 37 | public void process(String payload, BitbucketType instanceType) { 38 | if (payload != null) { 39 | BitbucketPullRequestEvent pull; 40 | if (instanceType == BitbucketType.SERVER) { 41 | pull = BitbucketServerWebhookPayload.pullRequestEventFromPayload(payload); 42 | } else { 43 | pull = BitbucketCloudWebhookPayload.pullRequestEventFromPayload(payload); 44 | } 45 | 46 | if (pull != null) { 47 | String owner = pull.getRepository().getOwnerName(); 48 | String repository = pull.getRepository().getRepositoryName(); 49 | 50 | LOGGER.info(String.format("Received hook from Bitbucket. Processing pull request to %s/%s from %s/%s", 51 | owner, repository, pull.getPullRequest().getSource().getRepository().getOwnerName(), pull.getPullRequest().getSource().getRepository().getRepositoryName())); 52 | scmSourceReIndex(owner, repository); 53 | } 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/SshRepositoryUriResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket; 25 | 26 | import java.net.MalformedURLException; 27 | import java.net.URL; 28 | 29 | public class SshRepositoryUriResolver extends RepositoryUriResolver { 30 | 31 | /** 32 | * Bitbucket server uses a different port for SSH clones. 33 | * -1 for Bitbucket cloud. 34 | */ 35 | private int sshPort; 36 | 37 | public SshRepositoryUriResolver(String baseUrl, int sshPort) throws MalformedURLException { 38 | super(baseUrl); 39 | if (sshPort > 0) { 40 | this.sshPort = sshPort; 41 | } else { 42 | URL url = getUrl(); 43 | if (url != null) { 44 | if (url.getPort() > 0){ 45 | this.sshPort = url.getPort(); 46 | } else { 47 | this.sshPort = url.getDefaultPort(); 48 | } 49 | } 50 | } 51 | } 52 | 53 | @Override 54 | public String getRepositoryUri(String owner, String repository, RepositoryType type) { 55 | if (type == RepositoryType.MERCURIAL) { 56 | if (isServer()) { 57 | throw new IllegalStateException("Mercurial is not supported by Bitbucket Server (https://jira.atlassian.com/browse/BSERV-2469)"); 58 | } 59 | return "ssh://hg@" + getAuthority() + "/" + owner + "/" + repository; 60 | } else { 61 | // Defaults to git 62 | if (isServer()) { 63 | return "ssh://git@" + getHost() + ":" + sshPort + "/" + owner + "/" + repository + ".git"; 64 | } else { 65 | return "git@" + getHost() + ":" + owner + "/" + repository + ".git"; 66 | } 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/branch/BitbucketServerCommit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.server.client.branch; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 27 | import org.codehaus.jackson.annotate.JsonProperty; 28 | 29 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketCommit; 30 | 31 | @JsonIgnoreProperties(ignoreUnknown = true) 32 | public class BitbucketServerCommit implements BitbucketCommit { 33 | 34 | private String message; 35 | 36 | private String date; 37 | 38 | private String hash; 39 | 40 | @JsonProperty("authorTimestamp") 41 | private long dateMillis; 42 | 43 | public BitbucketServerCommit() { 44 | } 45 | 46 | public BitbucketServerCommit(String message, String date, String hash, long dateMillis) { 47 | this.message = message; 48 | this.date = date; 49 | this.hash = hash; 50 | this.dateMillis = dateMillis; 51 | } 52 | 53 | public BitbucketServerCommit(String hash) { 54 | this.hash = hash; 55 | } 56 | 57 | @Override 58 | public String getMessage() { 59 | return message; 60 | } 61 | 62 | @Override 63 | public String getDate() { 64 | return date; 65 | } 66 | 67 | @Override 68 | public String getHash() { 69 | return hash; 70 | } 71 | 72 | @Override 73 | public long getDateMillis() { 74 | return dateMillis; 75 | } 76 | 77 | public void setMessage(String message) { 78 | this.message = message; 79 | } 80 | 81 | public void setDate(String date) { 82 | this.date = date; 83 | } 84 | 85 | public void setHash(String hash) { 86 | this.hash = hash; 87 | } 88 | 89 | public void setDateMillis(long dateMillis) { 90 | this.dateMillis = dateMillis; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/BitbucketCloudWebhookPayload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client; 25 | 26 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequestEvent; 27 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPushEvent; 28 | import com.cloudbees.jenkins.plugins.bitbucket.client.events.BitbucketCloudPullRequestEvent; 29 | import com.cloudbees.jenkins.plugins.bitbucket.client.events.BitbucketCloudPushEvent; 30 | import edu.umd.cs.findbugs.annotations.CheckForNull; 31 | import edu.umd.cs.findbugs.annotations.NonNull; 32 | import org.codehaus.jackson.map.ObjectMapper; 33 | 34 | import java.io.IOException; 35 | import java.util.logging.Level; 36 | import java.util.logging.Logger; 37 | 38 | public class BitbucketCloudWebhookPayload { 39 | 40 | private static final Logger LOGGER = Logger.getLogger(BitbucketCloudWebhookPayload.class.getName()); 41 | 42 | @CheckForNull 43 | public static BitbucketPushEvent pushEventFromPayload(@NonNull String payload) { 44 | try { 45 | return parse(payload, BitbucketCloudPushEvent.class); 46 | } catch (IOException e) { 47 | LOGGER.log(Level.SEVERE, "Can not read hook payload", e); 48 | } 49 | return null; 50 | } 51 | 52 | @CheckForNull 53 | public static BitbucketPullRequestEvent pullRequestEventFromPayload(@NonNull String payload) { 54 | try { 55 | return parse(payload, BitbucketCloudPullRequestEvent.class); 56 | } catch (IOException e) { 57 | LOGGER.log(Level.SEVERE, "Can not read hook payload", e); 58 | } 59 | return null; 60 | } 61 | 62 | private static T parse(String response, Class clazz) throws IOException { 63 | ObjectMapper mapper = new ObjectMapper(); 64 | return mapper.readValue(response, clazz); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerWebhookPayload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.server.client; 25 | 26 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequestEvent; 27 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPushEvent; 28 | import com.cloudbees.jenkins.plugins.bitbucket.server.events.BitbucketServerPullRequestEvent; 29 | import com.cloudbees.jenkins.plugins.bitbucket.server.events.BitbucketServerPushEvent; 30 | import edu.umd.cs.findbugs.annotations.CheckForNull; 31 | import edu.umd.cs.findbugs.annotations.NonNull; 32 | import org.codehaus.jackson.map.ObjectMapper; 33 | 34 | import java.io.IOException; 35 | import java.util.logging.Level; 36 | import java.util.logging.Logger; 37 | 38 | public class BitbucketServerWebhookPayload { 39 | 40 | private static final Logger LOGGER = Logger.getLogger(BitbucketServerWebhookPayload.class.getName()); 41 | 42 | @CheckForNull 43 | public static BitbucketPushEvent pushEventFromPayload(@NonNull String payload) { 44 | try { 45 | return parse(payload, BitbucketServerPushEvent.class); 46 | } catch (IOException e) { 47 | LOGGER.log(Level.SEVERE, "Can not read hook payload", e); 48 | } 49 | return null; 50 | } 51 | 52 | @CheckForNull 53 | public static BitbucketPullRequestEvent pullRequestEventFromPayload(@NonNull String payload) { 54 | try { 55 | return parse(payload, BitbucketServerPullRequestEvent.class); 56 | } catch (IOException e) { 57 | LOGGER.log(Level.SEVERE, "Can not read hook payload", e); 58 | } 59 | return null; 60 | } 61 | 62 | private static T parse(String response, Class clazz) throws IOException { 63 | ObjectMapper mapper = new ObjectMapper(); 64 | return mapper.readValue(response, clazz); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/pullrequest/BitbucketServerPullRequestSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.server.client.pullrequest; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 27 | import org.codehaus.jackson.annotate.JsonProperty; 28 | 29 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBranch; 30 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketCommit; 31 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequestSource; 32 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository; 33 | import com.cloudbees.jenkins.plugins.bitbucket.server.client.branch.BitbucketServerBranch; 34 | import com.cloudbees.jenkins.plugins.bitbucket.server.client.branch.BitbucketServerCommit; 35 | import com.cloudbees.jenkins.plugins.bitbucket.server.client.repository.BitbucketServerRepository; 36 | 37 | @JsonIgnoreProperties(ignoreUnknown = true) 38 | public class BitbucketServerPullRequestSource implements BitbucketPullRequestSource { 39 | 40 | @JsonProperty("latestCommit") 41 | private String commitHash; 42 | 43 | @JsonProperty("displayId") 44 | private String branchName; 45 | 46 | private BitbucketServerRepository repository; 47 | 48 | @Override 49 | public BitbucketRepository getRepository() { 50 | return repository; 51 | } 52 | 53 | @Override 54 | public BitbucketBranch getBranch() { 55 | return new BitbucketServerBranch(branchName, commitHash); 56 | } 57 | 58 | @Override 59 | public BitbucketCommit getCommit() { 60 | return new BitbucketServerCommit(commitHash); 61 | } 62 | 63 | public void setCommitHash(String commitHash) { 64 | this.commitHash = commitHash; 65 | } 66 | 67 | public void setBranchName(String branchName) { 68 | this.branchName = branchName; 69 | } 70 | 71 | public void setRepository(BitbucketServerRepository repository) { 72 | this.repository = repository; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/pullrequest/BitbucketPullRequestValueRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client.pullrequest; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 27 | import org.codehaus.jackson.annotate.JsonProperty; 28 | 29 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketBranch; 30 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketCommit; 31 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequestSource; 32 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository; 33 | import com.cloudbees.jenkins.plugins.bitbucket.client.branch.BitbucketCloudBranch; 34 | import com.cloudbees.jenkins.plugins.bitbucket.client.branch.BitbucketCloudCommit; 35 | import com.cloudbees.jenkins.plugins.bitbucket.client.repository.BitbucketCloudRepository; 36 | 37 | @JsonIgnoreProperties(ignoreUnknown = true) 38 | public class BitbucketPullRequestValueRepository implements BitbucketPullRequestSource { 39 | private BitbucketCloudRepository repository; 40 | private BitbucketCloudBranch branch; 41 | private BitbucketCloudCommit commit; 42 | 43 | @Override 44 | @JsonProperty("repository") 45 | public BitbucketRepository getRepository() { 46 | return repository; 47 | } 48 | 49 | @JsonProperty("repository") 50 | public void setRepository(BitbucketCloudRepository repository) { 51 | this.repository = repository; 52 | } 53 | 54 | @Override 55 | @JsonProperty("branch") 56 | public BitbucketBranch getBranch() { 57 | return branch; 58 | } 59 | 60 | @JsonProperty("branch") 61 | public void setBranch(BitbucketCloudBranch branch) { 62 | this.branch = branch; 63 | } 64 | 65 | @Override 66 | @JsonProperty("commit") 67 | public BitbucketCommit getCommit() { 68 | return commit; 69 | } 70 | 71 | @JsonProperty("commit") 72 | public void setCommit(BitbucketCloudCommit commit) { 73 | this.commit = commit; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/HookEventType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.hooks; 25 | 26 | import edu.umd.cs.findbugs.annotations.CheckForNull; 27 | import edu.umd.cs.findbugs.annotations.NonNull; 28 | 29 | /** 30 | * Bitbucket hooks types managed by this plugin. 31 | */ 32 | public enum HookEventType { 33 | 34 | /** 35 | * See EventPayloads-Push 36 | */ 37 | PUSH("repo:push", PushHookProcessor.class), 38 | 39 | /** 40 | * See EventPayloads-Created 41 | */ 42 | PULL_REQUEST_CREATED("pullrequest:created", PullRequestHookProcessor.class), 43 | 44 | /** 45 | * See EventPayloads-Updated 46 | */ 47 | PULL_REQUEST_UPDATED("pullrequest:updated", PullRequestHookProcessor.class); 48 | 49 | private String key; 50 | private Class clazz; 51 | 52 |

HookEventType(@NonNull String key, Class

clazz) { 53 | this.key = key; 54 | this.clazz = clazz; 55 | } 56 | 57 | @CheckForNull 58 | public static HookEventType fromString(String key) { 59 | for (HookEventType value : HookEventType.values()) { 60 | if (value.getKey().equals(key)) { 61 | return value; 62 | } 63 | } 64 | return null; 65 | } 66 | 67 | public HookProcessor getProcessor() { 68 | try { 69 | return (HookProcessor) clazz.newInstance(); 70 | } catch (InstantiationException e) { 71 | throw new AssertionError("Can not instantiate hook payload processor: " + e.getMessage()); 72 | } catch (IllegalAccessException e) { 73 | throw new AssertionError("Can not instantiate hook payload processor: " + e.getMessage()); 74 | } 75 | } 76 | 77 | public String getKey() { 78 | return key; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/repository/BitbucketCloudRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client.repository; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 27 | import org.codehaus.jackson.annotate.JsonProperty; 28 | 29 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository; 30 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepositoryOwner; 31 | 32 | @JsonIgnoreProperties(ignoreUnknown = true) 33 | public class BitbucketCloudRepository implements BitbucketRepository { 34 | 35 | private String scm; 36 | 37 | @JsonProperty("full_name") 38 | private String fullName; 39 | 40 | private BitbucketCloudRepositoryOwner owner; 41 | 42 | @JsonProperty("updated_on") 43 | private String updatedOn; 44 | 45 | // JSON mapping added in setter because the field can not be called "private" 46 | private Boolean priv; 47 | 48 | @Override 49 | public String getScm() { 50 | return scm; 51 | } 52 | 53 | @Override 54 | public String getFullName() { 55 | return fullName; 56 | } 57 | 58 | @Override 59 | public BitbucketRepositoryOwner getOwner() { 60 | return owner; 61 | } 62 | 63 | public void setScm(String scm) { 64 | this.scm = scm; 65 | } 66 | 67 | public void setFullName(String fullName) { 68 | this.fullName = fullName; 69 | } 70 | 71 | public void setOwner(BitbucketCloudRepositoryOwner owner) { 72 | this.owner = owner; 73 | } 74 | 75 | public void setUpdatedOn(String updatedOn) { 76 | this.updatedOn = updatedOn; 77 | } 78 | 79 | @Override 80 | public String getOwnerName() { 81 | if (this.fullName != null) { 82 | return this.fullName.split("/")[0]; 83 | } 84 | return null; 85 | } 86 | 87 | @Override 88 | public String getRepositoryName() { 89 | if (this.fullName != null) { 90 | return this.fullName.split("/")[1]; 91 | } 92 | return null; 93 | } 94 | 95 | @Override 96 | public boolean isPrivate() { 97 | return priv; 98 | } 99 | 100 | @JsonProperty("is_private") 101 | public void setPrivate(Boolean priv) { 102 | this.priv = priv; 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/repository/BitbucketServerRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.server.client.repository; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 27 | import org.codehaus.jackson.annotate.JsonProperty; 28 | 29 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepository; 30 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepositoryOwner; 31 | 32 | @JsonIgnoreProperties(ignoreUnknown = true) 33 | public class BitbucketServerRepository implements BitbucketRepository { 34 | 35 | @JsonProperty("scmId") 36 | private String scm; 37 | 38 | private Project project; 39 | 40 | @JsonProperty("slug") 41 | private String repositoryName; 42 | 43 | // JSON mapping added in setter because the field can not be called "public" 44 | private Boolean publc; 45 | 46 | @Override 47 | public String getScm() { 48 | return scm; 49 | } 50 | 51 | @Override 52 | public String getFullName() { 53 | return project.getKey() + "/" + repositoryName; 54 | } 55 | 56 | @Override 57 | public BitbucketRepositoryOwner getOwner() { 58 | return new BitbucketServerRepositoryOwner(project.getKey(), project.getName()); 59 | } 60 | 61 | @Override 62 | public String getOwnerName() { 63 | return project.getKey(); 64 | } 65 | 66 | @Override 67 | public String getRepositoryName() { 68 | return repositoryName; 69 | } 70 | 71 | public void setProject(Project p) { 72 | this.project = p; 73 | } 74 | 75 | @Override 76 | public boolean isPrivate() { 77 | return !publc; 78 | } 79 | 80 | @JsonProperty("public") 81 | public void setPublic(Boolean publc) { 82 | this.publc = publc; 83 | } 84 | 85 | @JsonIgnoreProperties(ignoreUnknown = true) 86 | public static class Project { 87 | 88 | @JsonProperty 89 | private String key; 90 | 91 | @JsonProperty 92 | private String name; 93 | 94 | public String getKey() { 95 | return key; 96 | } 97 | 98 | public void setKey(String key) { 99 | this.key = key; 100 | } 101 | 102 | public String getName() { 103 | return name; 104 | } 105 | 106 | public void setName(String name) { 107 | this.name = name; 108 | } 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/client/pullrequest/BitbucketPullRequestValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.client.pullrequest; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 27 | 28 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest; 29 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequestSource; 30 | 31 | @JsonIgnoreProperties(ignoreUnknown = true) 32 | public class BitbucketPullRequestValue implements BitbucketPullRequest { 33 | private BitbucketPullRequestValueRepository source; 34 | private String id; 35 | private String title; 36 | 37 | private Links links; 38 | 39 | private Author author; 40 | 41 | public BitbucketPullRequestSource getSource() { 42 | return source; 43 | } 44 | 45 | public void setSource(BitbucketPullRequestValueRepository source) { 46 | this.source = source; 47 | } 48 | 49 | public String getId() { 50 | return id; 51 | } 52 | 53 | public void setId(String id) { 54 | this.id = id; 55 | } 56 | 57 | @Override 58 | public String getTitle() { 59 | return title; 60 | } 61 | 62 | @Override 63 | public String getLink() { 64 | return links.html.href; 65 | } 66 | 67 | @Override 68 | public String getAuthorLogin() { 69 | return author.username; 70 | } 71 | 72 | public void setTitle(String title) { 73 | this.title = title; 74 | } 75 | 76 | public void setLinks(Links link) { 77 | this.links = link; 78 | } 79 | 80 | public void setAuthor(Author author) { 81 | this.author = author; 82 | } 83 | 84 | @JsonIgnoreProperties(ignoreUnknown = true) 85 | public static class Links { 86 | private Html html; 87 | public Links() {} 88 | // for tests 89 | public Links(String link) { 90 | html = new Html(); 91 | html.href = link; 92 | } 93 | public void setHtml(Html html) { 94 | this.html = html; 95 | } 96 | 97 | @JsonIgnoreProperties(ignoreUnknown = true) 98 | private static class Html { 99 | public String href; 100 | public Html() {} 101 | } 102 | } 103 | 104 | @JsonIgnoreProperties(ignoreUnknown = true) 105 | public static class Author { 106 | private String username; 107 | public Author() {} 108 | public Author(String username) { 109 | this.username = username; 110 | } 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/test/java/com/cloudbees/jenkins/plugins/bitbucket/UriResolverTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket; 25 | 26 | import org.junit.Test; 27 | import static org.junit.Assert.*; 28 | 29 | import java.net.MalformedURLException; 30 | 31 | public class UriResolverTest { 32 | 33 | @Test 34 | public void httpUriResolver() throws MalformedURLException { 35 | HttpsRepositoryUriResolver r = new HttpsRepositoryUriResolver(null); 36 | assertEquals("https://bitbucket.org/user1/repo1.git", r.getRepositoryUri("user1", "repo1", RepositoryType.GIT)); 37 | assertEquals("https://bitbucket.org/user1/repo1", r.getRepositoryUri("user1", "repo1", RepositoryType.MERCURIAL)); 38 | r = new HttpsRepositoryUriResolver("http://localhost:1234"); 39 | assertEquals("http://localhost:1234/scm/user2/repo2.git", r.getRepositoryUri("user2", "repo2", RepositoryType.GIT)); 40 | r = new HttpsRepositoryUriResolver("http://192.168.1.100:1234"); 41 | assertEquals("http://192.168.1.100:1234/scm/user2/repo2.git", r.getRepositoryUri("user2", "repo2", RepositoryType.GIT)); 42 | } 43 | 44 | @Test 45 | public void sshUriResolver() throws MalformedURLException { 46 | SshRepositoryUriResolver r = new SshRepositoryUriResolver(null, -1); 47 | assertEquals("git@bitbucket.org:user1/repo1.git", r.getRepositoryUri("user1", "repo1", RepositoryType.GIT)); 48 | assertEquals("ssh://hg@bitbucket.org/user1/repo1", r.getRepositoryUri("user1", "repo1", RepositoryType.MERCURIAL)); 49 | r = new SshRepositoryUriResolver("http://localhost:1234", 7999); 50 | assertEquals("ssh://git@localhost:7999/user2/repo2.git", r.getRepositoryUri("user2", "repo2", RepositoryType.GIT)); 51 | r = new SshRepositoryUriResolver("http://myserver", 7999); 52 | assertEquals("ssh://git@myserver:7999/user2/repo2.git", r.getRepositoryUri("user2", "repo2", RepositoryType.GIT)); 53 | } 54 | 55 | @Test(expected = IllegalStateException.class) 56 | public void httpUriResolverIllegalStates() throws MalformedURLException { 57 | HttpsRepositoryUriResolver r = new HttpsRepositoryUriResolver("http://localhost:1234"); 58 | // Mercurial is not supported by Bitbucket Server 59 | r.getRepositoryUri("user1", "repo1", RepositoryType.MERCURIAL); 60 | } 61 | 62 | @Test(expected = IllegalStateException.class) 63 | public void sshUriResolverIllegalStates() throws MalformedURLException { 64 | SshRepositoryUriResolver r = new SshRepositoryUriResolver("http://localhost:1234", 7999); 65 | // Mercurial is not supported by Bitbucket Server 66 | r.getRepositoryUri("user1", "repo1", RepositoryType.MERCURIAL); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketBuildStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.api; 25 | 26 | import org.codehaus.jackson.annotate.JsonIgnore; 27 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; 28 | import org.kohsuke.accmod.Restricted; 29 | import org.kohsuke.accmod.restrictions.DoNotUse; 30 | 31 | @JsonIgnoreProperties(ignoreUnknown = true) 32 | public class BitbucketBuildStatus { 33 | 34 | /** 35 | * The commit hash to set the status on 36 | */ 37 | @JsonIgnore 38 | private String hash; 39 | 40 | /** 41 | * Text shown in the UI 42 | */ 43 | private String description; 44 | 45 | /** 46 | * One of: INPROGRESS|SUCCESSFUL|FAILED 47 | */ 48 | private String state; 49 | 50 | /** 51 | * The URL to liunk from the status details 52 | */ 53 | private String url; 54 | 55 | /** 56 | * Usually the job name in Jenkins 57 | */ 58 | private String key; 59 | 60 | /** 61 | * A short name, usuallt #job-name, #build-number (will be shown as link 62 | * text in BB UI) 63 | */ 64 | private String name; 65 | 66 | // Used for marshalling/unmarshalling 67 | @Restricted(DoNotUse.class) 68 | public BitbucketBuildStatus() {} 69 | 70 | public BitbucketBuildStatus(String hash, String description, String state, String url, String key, String name) { 71 | this.hash = hash; 72 | this.description = description; 73 | this.state = state; 74 | this.url = url; 75 | this.key = key; 76 | this.name = name; 77 | } 78 | 79 | public String getHash() { 80 | return hash; 81 | } 82 | 83 | public void setHash(String hash) { 84 | this.hash = hash; 85 | } 86 | 87 | public String getDescription() { 88 | return description; 89 | } 90 | 91 | public void setDescription(String description) { 92 | this.description = description; 93 | } 94 | 95 | public String getState() { 96 | return state; 97 | } 98 | 99 | public void setState(String state) { 100 | this.state = state; 101 | } 102 | 103 | public String getUrl() { 104 | return url; 105 | } 106 | 107 | public void setUrl(String url) { 108 | this.url = url; 109 | } 110 | 111 | public String getKey() { 112 | return key; 113 | } 114 | 115 | public void setKey(String key) { 116 | this.key = key; 117 | } 118 | 119 | public String getName() { 120 | return name; 121 | } 122 | 123 | public void setName(String name) { 124 | this.name = name; 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/SCMHeadWithOwnerAndRepo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket; 25 | 26 | import java.util.LinkedList; 27 | import java.util.List; 28 | 29 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketPullRequest; 30 | 31 | import edu.umd.cs.findbugs.annotations.CheckForNull; 32 | import hudson.model.Action; 33 | import jenkins.scm.api.SCMHead; 34 | 35 | /** 36 | * {@link SCMHead} extended with additional information: 37 | *

    38 | *
  • {@link #repoOwner}: the repository owner
  • 39 | *
  • {@link #repoName}: the repository name
  • 40 | *
  • {@link #metadata}: metadata related to Pull Requests - null if this object is not representing a PR
  • 41 | *
42 | * This information is required in this plugin since {@link BitbucketSCMSource} is processing pull requests 43 | * and they are managed as separate repositories in Bitbucket without any reference to them in the destination 44 | * repository. 45 | */ 46 | public class SCMHeadWithOwnerAndRepo extends SCMHead { 47 | 48 | private static final long serialVersionUID = 1L; 49 | 50 | private final String repoOwner; 51 | 52 | private final String repoName; 53 | 54 | private PullRequestAction metadata = null; 55 | 56 | private static final String PR_BRANCH_PREFIX = "PR-"; 57 | 58 | public SCMHeadWithOwnerAndRepo(String repoOwner, String repoName, String branchName, BitbucketPullRequest pr) { 59 | super(branchName); 60 | this.repoOwner = repoOwner; 61 | this.repoName = repoName; 62 | if (pr != null) { 63 | this.metadata = new PullRequestAction(pr); 64 | } 65 | } 66 | 67 | public SCMHeadWithOwnerAndRepo(String repoOwner, String repoName, String branchName) { 68 | this(repoOwner, repoName, branchName, null); 69 | } 70 | 71 | public String getRepoOwner() { 72 | return repoOwner; 73 | } 74 | 75 | public String getRepoName() { 76 | return repoName; 77 | } 78 | 79 | /** 80 | * @return the original branch name without the "PR-owner-" part. 81 | */ 82 | public String getBranchName() { 83 | return super.getName(); 84 | } 85 | 86 | /** 87 | * Returns the prettified branch name by adding "PR-[ID]" if the branch is coming from a PR. 88 | * Use {@link #getBranchName()} to get the real branch name. 89 | */ 90 | @Override 91 | public String getName() { 92 | return metadata != null ? PR_BRANCH_PREFIX + metadata.getId() : getBranchName(); 93 | } 94 | 95 | @CheckForNull 96 | public Integer getPullRequestId() { 97 | if (metadata != null) { 98 | return Integer.parseInt(metadata.getId()); 99 | } else { 100 | return null; 101 | } 102 | } 103 | 104 | @Override 105 | public List getAllActions() { 106 | List actions = new LinkedList(super.getAllActions()); 107 | if (metadata != null) { 108 | actions.add(metadata); 109 | } 110 | return actions; 111 | } 112 | } -------------------------------------------------------------------------------- /src/test/java/com/cloudbees/jenkins/plugins/bitbucket/SCMNavigatorIntegrationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket; 25 | 26 | import java.util.Map; 27 | 28 | import static org.junit.Assert.*; 29 | 30 | import org.junit.Rule; 31 | import org.junit.Test; 32 | import org.jvnet.hudson.test.JenkinsRule; 33 | import org.jvnet.hudson.test.TestExtension; 34 | import org.kohsuke.stapler.DataBoundConstructor; 35 | 36 | import hudson.model.ItemGroup; 37 | import jenkins.branch.MultiBranchProject; 38 | import jenkins.branch.MultiBranchProjectFactory; 39 | import jenkins.branch.MultiBranchProjectFactoryDescriptor; 40 | import jenkins.branch.OrganizationFolder; 41 | import jenkins.scm.api.SCMSource; 42 | import jenkins.scm.api.SCMSourceCriteria; 43 | 44 | public class SCMNavigatorIntegrationTest { 45 | 46 | @Rule 47 | public JenkinsRule j = new JenkinsRule(); 48 | 49 | @Test 50 | public void teamDiscoveringTest() throws Exception { 51 | OrganizationFolder teamFolder = j.jenkins.createProject(OrganizationFolder.class, "test"); 52 | BitbucketSCMNavigator navigator = new BitbucketSCMNavigator("myteam", null, null); 53 | navigator.setPattern("test-repos"); 54 | navigator.setBitbucketConnector(SCMNavigatorTest.getConnectorMock(RepositoryType.GIT, true)); 55 | teamFolder.getNavigators().add(navigator); 56 | teamFolder.scheduleBuild2(0).getFuture().get(); 57 | teamFolder.getComputation().writeWholeLogTo(System.out); 58 | // One repository must be discovered 59 | assertEquals(1, teamFolder.getItems().size()); 60 | MultiBranchProject project = teamFolder.getItems().iterator().next(); 61 | project.scheduleBuild2(0).getFuture().get(); 62 | project.getComputation().writeWholeLogTo(System.out); 63 | // Two items (1 branch matching criteria + 1 pull request) 64 | assertEquals(2, project.getItems().size()); 65 | } 66 | 67 | public static class MultiBranchProjectFactoryImpl extends MultiBranchProjectFactory.BySCMSourceCriteria { 68 | 69 | @DataBoundConstructor 70 | public MultiBranchProjectFactoryImpl() {} 71 | 72 | @Override 73 | protected SCMSourceCriteria getSCMSourceCriteria(SCMSource source) { 74 | return BranchScanningIntegrationTest.MultiBranchProjectImpl.CRITERIA; 75 | } 76 | 77 | @Override 78 | protected MultiBranchProject doCreateProject(ItemGroup parent, String name, Map attributes) { 79 | return new BranchScanningIntegrationTest.MultiBranchProjectImpl(parent, name); 80 | } 81 | 82 | @TestExtension 83 | public static class DescriptorImpl extends MultiBranchProjectFactoryDescriptor { 84 | 85 | @Override 86 | public MultiBranchProjectFactory newInstance() { 87 | return new MultiBranchProjectFactoryImpl(); 88 | } 89 | 90 | @Override 91 | public String getDisplayName() { 92 | return "Test multibranch factory"; 93 | } 94 | 95 | } 96 | 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/test/java/com/cloudbees/jenkins/plugins/bitbucket/WebhooksAutoregisterTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket; 25 | 26 | import java.io.File; 27 | import java.io.IOException; 28 | import java.util.logging.LogRecord; 29 | import java.util.logging.Logger; 30 | import java.util.logging.SimpleFormatter; 31 | 32 | import org.junit.Assert; 33 | import org.junit.Rule; 34 | import org.junit.Test; 35 | import org.jvnet.hudson.test.JenkinsRule; 36 | import org.xml.sax.SAXException; 37 | 38 | import com.cloudbees.jenkins.plugins.bitbucket.BranchScanningIntegrationTest.MultiBranchProjectImpl; 39 | import com.cloudbees.jenkins.plugins.bitbucket.hooks.WebhookAutoRegisterListener; 40 | import com.gargoylesoftware.htmlunit.html.HtmlForm; 41 | 42 | import hudson.util.RingBufferLogHandler; 43 | import jenkins.branch.BranchSource; 44 | import jenkins.branch.DefaultBranchPropertyStrategy; 45 | import jenkins.model.JenkinsLocationConfiguration; 46 | 47 | public class WebhooksAutoregisterTest { 48 | 49 | @Rule 50 | public JenkinsRule j = new JenkinsRule(); 51 | 52 | @Test 53 | public void registerHookTest() throws Exception { 54 | RingBufferLogHandler log = createJULTestHandler(); 55 | 56 | MultiBranchProjectImpl p = j.jenkins.createProject(MultiBranchProjectImpl.class, "test"); 57 | BitbucketSCMSource source = BranchScanningIntegrationTest.getTestSCMSource(RepositoryType.GIT, true); 58 | source.setAutoRegisterHook(true); 59 | p.getSourcesList().add(new BranchSource(source, new DefaultBranchPropertyStrategy(null))); 60 | p.scheduleBuild2(0); 61 | waitForLogFileMessage("Can not register hook. Jenkins root URL is not valid", log); 62 | 63 | setRootUrl(); 64 | p.save(); // force item listener to run onUpdated 65 | 66 | waitForLogFileMessage("Registering hook for amuniz/test-repos", log); 67 | 68 | } 69 | 70 | private void setRootUrl() throws IOException, SAXException, Exception { 71 | JenkinsLocationConfiguration.get().setUrl(j.getURL().toString().replace("localhost", "127.0.0.1")); 72 | } 73 | 74 | private void waitForLogFileMessage(String string, RingBufferLogHandler logs) throws IOException, InterruptedException { 75 | File rootDir = j.jenkins.getRootDir(); 76 | synchronized (rootDir) { 77 | int limit = 0; 78 | while (limit < 5) { 79 | rootDir.wait(1000); 80 | for (LogRecord r : logs.getView()) { 81 | if (r.getMessage().contains(string)) { 82 | return; 83 | } 84 | } 85 | limit++; 86 | } 87 | } 88 | Assert.assertTrue("Expected log not found: " + string, false); 89 | } 90 | 91 | private RingBufferLogHandler createJULTestHandler() throws SecurityException, IOException { 92 | RingBufferLogHandler handler = new RingBufferLogHandler(); 93 | SimpleFormatter formatter = new SimpleFormatter(); 94 | handler.setFormatter(formatter); 95 | Logger logger = Logger.getLogger(WebhookAutoRegisterListener.class.getName()); 96 | logger.addHandler(handler); 97 | return handler; 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/HookProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.hooks; 25 | 26 | import com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource; 27 | import hudson.security.ACL; 28 | import jenkins.scm.api.SCMSource; 29 | import jenkins.scm.api.SCMSourceOwner; 30 | import jenkins.scm.api.SCMSourceOwners; 31 | 32 | import java.util.List; 33 | import java.util.logging.Level; 34 | import java.util.logging.Logger; 35 | 36 | /** 37 | * Abstract hook processor. 38 | * 39 | * Add new hook processors by extending this class and implement {@link #process(String, BitbucketType)}, extract owner and repository 40 | * name from the hook payload and then call {@link #scmSourceReIndex(String, String)} to launch a branch/PR reindexing 41 | * on the mathing SCMSource. 42 | * 43 | * TODO: Improvement - We could schedule a build only in the affected job instead of running a full reindex (since we 44 | * have the branch contianing the commit in the hook payload). A full reindex would be forced only when the incoming 45 | * hook is resolved to a non-existent job (new branches or new PRs). 46 | */ 47 | public abstract class HookProcessor { 48 | 49 | private static final Logger LOGGER = Logger.getLogger(HookProcessor.class.getName()); 50 | 51 | /** 52 | * See Event Payloads for more 53 | * information about the payload parameter format. 54 | * 55 | * @param payload the hook payload 56 | * @param instanceType the Bitbucket type that called the hook 57 | */ 58 | public abstract void process(String payload, BitbucketType instanceType); 59 | 60 | /** 61 | * To be called by implementations once the owner and the repository have been extracted from the payload. 62 | * 63 | * @param owner the repository owner as configured in the SCMSource 64 | * @param repository the repository name as configured in the SCMSource 65 | */ 66 | protected void scmSourceReIndex(final String owner, final String repository) { 67 | ACL.impersonate(ACL.SYSTEM, new Runnable() { 68 | @Override 69 | public void run() { 70 | boolean reindexed = false; 71 | for (SCMSourceOwner scmOwner : SCMSourceOwners.all()) { 72 | List sources = scmOwner.getSCMSources(); 73 | for (SCMSource source : sources) { 74 | // Search for the correct SCM source 75 | if (source instanceof BitbucketSCMSource && ((BitbucketSCMSource) source).getRepoOwner().equalsIgnoreCase(owner) 76 | && ((BitbucketSCMSource) source).getRepository().equals(repository)) { 77 | LOGGER.log(Level.INFO, "Multibranch project found, reindexing " + scmOwner.getName()); 78 | scmOwner.onSCMSourceUpdated(source); 79 | reindexed = true; 80 | } 81 | } 82 | } 83 | if (!reindexed) { 84 | LOGGER.log(Level.INFO, "No multibranch project matching for reindex on {0}/{1}", new Object[] {owner, repository}); 85 | } 86 | } 87 | }); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/BitbucketSCMSourcePushHookReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.hooks; 25 | 26 | import java.io.IOException; 27 | import java.util.logging.Level; 28 | import java.util.logging.Logger; 29 | 30 | import hudson.security.csrf.CrumbExclusion; 31 | 32 | import javax.servlet.FilterChain; 33 | import javax.servlet.ServletException; 34 | import javax.servlet.http.HttpServletRequest; 35 | import javax.servlet.http.HttpServletResponse; 36 | 37 | import org.apache.commons.io.IOUtils; 38 | import org.kohsuke.stapler.HttpResponse; 39 | import org.kohsuke.stapler.StaplerRequest; 40 | 41 | import hudson.Extension; 42 | import hudson.model.UnprotectedRootAction; 43 | import hudson.util.HttpResponses; 44 | import org.apache.commons.io.IOUtils; 45 | import org.kohsuke.stapler.HttpResponse; 46 | import org.kohsuke.stapler.StaplerRequest; 47 | 48 | import javax.servlet.http.HttpServletResponse; 49 | import java.io.IOException; 50 | import java.util.logging.Logger; 51 | 52 | /** 53 | * Process Bitbucket push and pull requests creations/updates hooks. 54 | */ 55 | @Extension 56 | public class BitbucketSCMSourcePushHookReceiver extends CrumbExclusion implements UnprotectedRootAction { 57 | 58 | private static final Logger LOGGER = Logger.getLogger(BitbucketSCMSourcePushHookReceiver.class.getName()); 59 | 60 | private static final String PATH = "bitbucket-scmsource-hook"; 61 | 62 | public static final String FULL_PATH = PATH + "/notify"; 63 | 64 | @Override 65 | public boolean process(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) 66 | throws IOException, ServletException { 67 | String pathInfo = req.getPathInfo(); 68 | if (pathInfo != null && pathInfo.startsWith("/"+FULL_PATH)) { 69 | chain.doFilter(req, resp); 70 | return true; 71 | } 72 | return false; 73 | } 74 | 75 | @Override 76 | public String getUrlName() { 77 | return PATH; 78 | } 79 | 80 | /** 81 | * Receives Bitbucket push notifications. 82 | * 83 | * @param req Stapler request. It contains the payload in the body content 84 | * and a header param "X-Event-Key" pointing to the event type. 85 | * @return the HTTP response object 86 | * @throws IOException if there is any issue reading the HTTP content paylod. 87 | */ 88 | public HttpResponse doNotify(StaplerRequest req) throws IOException { 89 | String body = IOUtils.toString(req.getInputStream()); 90 | String eventKey = req.getHeader("X-Event-Key"); 91 | if (eventKey == null) { 92 | return HttpResponses.error(HttpServletResponse.SC_BAD_REQUEST, "X-Event-Key HTTP header not found"); 93 | } 94 | HookEventType type = HookEventType.fromString(eventKey); 95 | if (type == null) { 96 | LOGGER.info("Received unknown Bitbucket hook: " + eventKey + ". Skipping."); 97 | return HttpResponses.error(HttpServletResponse.SC_BAD_REQUEST, "X-Event-Key HTTP header invalid: " + eventKey); 98 | } 99 | 100 | String bitbucketKey = req.getHeader("X-Bitbucket-Type"); 101 | BitbucketType instanceType = null; 102 | if (bitbucketKey != null) { 103 | instanceType = BitbucketType.fromString(bitbucketKey); 104 | } 105 | if(instanceType == null){ 106 | LOGGER.log(Level.FINE, "X-Bitbucket-Type header not found. Bitbucket Cloud webhook incoming."); 107 | instanceType = BitbucketType.CLOUD; 108 | } 109 | 110 | type.getProcessor().process(body, instanceType); 111 | return HttpResponses.ok(); 112 | } 113 | 114 | @Override 115 | public String getIconFileName() { 116 | return null; 117 | } 118 | 119 | @Override 120 | public String getDisplayName() { 121 | return null; 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 4.0.0 27 | 28 | 29 | org.jenkins-ci.plugins 30 | plugin 31 | 2.5 32 | 33 | 34 | cloudbees-bitbucket-branch-source 35 | 1.9-SNAPSHOT 36 | hpi 37 | 38 | Bitbucket Branch Source Plugin 39 | https://wiki.jenkins-ci.org/display/JENKINS/Bitbucket+Branch+Source+Plugin 40 | Discover and build Bitbucket Cloud and Bitbucket Server pull requests and branches and send status notifications with the build result. 41 | 42 | 43 | MIT License 44 | http://opensource.org/licenses/MIT 45 | 46 | 47 | 48 | 49 | 1.642.3 50 | 51 | 52 | 53 | scm:git:git://github.com/jenkinsci/bitbucket-branch-source-plugin.git 54 | scm:git:git@github.com:jenkinsci/bitbucket-branch-source-plugin.git 55 | https://github.com/jenkinsci/bitbucket-branch-source-plugin 56 | HEAD 57 | 58 | 59 | 60 | 61 | org.jenkins-ci.plugins 62 | scm-api 63 | 1.2 64 | 65 | 66 | org.jenkins-ci.plugins 67 | branch-api 68 | 1.10.2 69 | 70 | 71 | org.jenkins-ci.plugins 72 | git 73 | 2.3.5 74 | 75 | 76 | org.apache.httpcomponents 77 | httpclient 78 | 79 | 80 | 81 | 82 | org.jenkins-ci.plugins 83 | mercurial 84 | 1.54 85 | 86 | 87 | org.codehaus.jackson 88 | jackson-jaxrs 89 | 1.9.13 90 | 91 | 92 | org.jenkins-ci.plugins 93 | display-url-api 94 | 0.2 95 | 96 | 97 | org.jenkins-ci.plugins.workflow 98 | workflow-multibranch 99 | 1.11 100 | test 101 | 102 | 103 | org.mockito 104 | mockito-core 105 | 1.10.19 106 | test 107 | 108 | 109 | org.hamcrest 110 | hamcrest-core 111 | 1.3 112 | test 113 | 114 | 115 | 116 | 117 | 118 | repo.jenkins-ci.org 119 | http://repo.jenkins-ci.org/public/ 120 | 121 | 122 | 123 | 124 | repo.jenkins-ci.org 125 | http://repo.jenkins-ci.org/public/ 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketApiConnector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket; 25 | 26 | import java.util.List; 27 | 28 | import javax.annotation.CheckForNull; 29 | 30 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; 31 | import com.cloudbees.jenkins.plugins.bitbucket.client.BitbucketCloudApiClient; 32 | import com.cloudbees.jenkins.plugins.bitbucket.server.client.BitbucketServerAPIClient; 33 | import com.cloudbees.plugins.credentials.CredentialsMatcher; 34 | import com.cloudbees.plugins.credentials.CredentialsMatchers; 35 | import com.cloudbees.plugins.credentials.CredentialsProvider; 36 | import com.cloudbees.plugins.credentials.common.StandardCredentials; 37 | import com.cloudbees.plugins.credentials.common.StandardListBoxModel; 38 | import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials; 39 | import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; 40 | import com.cloudbees.plugins.credentials.domains.DomainRequirement; 41 | import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; 42 | 43 | import hudson.Util; 44 | import hudson.security.ACL; 45 | import hudson.util.ListBoxModel; 46 | import jenkins.scm.api.SCMSourceOwner; 47 | 48 | public class BitbucketApiConnector { 49 | 50 | private String serverUrl; 51 | 52 | public BitbucketApiConnector() { 53 | } 54 | 55 | public BitbucketApiConnector(String serverUrl) { 56 | this.serverUrl = serverUrl; 57 | } 58 | 59 | public BitbucketApi create(String owner, String repository, StandardUsernamePasswordCredentials creds) { 60 | if (serverUrl == null) { 61 | return new BitbucketCloudApiClient(owner, repository, creds); 62 | } else { 63 | return new BitbucketServerAPIClient(serverUrl, owner, repository, creds, false); 64 | } 65 | } 66 | 67 | public BitbucketApi create(String owner, StandardUsernamePasswordCredentials creds) { 68 | if (serverUrl == null) { 69 | return new BitbucketCloudApiClient(owner, creds); 70 | } else { 71 | return new BitbucketServerAPIClient(serverUrl, owner, creds, false); 72 | } 73 | } 74 | 75 | @CheckForNull 76 | public T lookupCredentials(@CheckForNull SCMSourceOwner context, @CheckForNull String id, Class type) { 77 | if (Util.fixEmpty(id) == null) { 78 | return null; 79 | } else { 80 | if (id != null) { 81 | return CredentialsMatchers.firstOrNull( 82 | CredentialsProvider.lookupCredentials(type, context, ACL.SYSTEM, 83 | bitbucketDomainRequirements()), 84 | CredentialsMatchers.allOf( 85 | CredentialsMatchers.withId(id), 86 | CredentialsMatchers.anyOf(CredentialsMatchers.instanceOf(type)))); 87 | } 88 | return null; 89 | } 90 | } 91 | 92 | public ListBoxModel fillCheckoutCredentials(StandardListBoxModel result, SCMSourceOwner context) { 93 | result.withMatching(bitbucketCheckoutCredentialsMatcher(), CredentialsProvider.lookupCredentials( 94 | StandardCredentials.class, context, ACL.SYSTEM, bitbucketDomainRequirements())); 95 | return result; 96 | } 97 | 98 | public ListBoxModel fillCredentials(StandardListBoxModel result, SCMSourceOwner context) { 99 | result.withMatching(bitbucketCredentialsMatcher(), CredentialsProvider.lookupCredentials( 100 | StandardUsernameCredentials.class, context, ACL.SYSTEM, bitbucketDomainRequirements())); 101 | return result; 102 | } 103 | 104 | /* package */ static CredentialsMatcher bitbucketCredentialsMatcher() { 105 | return CredentialsMatchers.anyOf(CredentialsMatchers.instanceOf(StandardUsernamePasswordCredentials.class)); 106 | } 107 | 108 | /* package */ static CredentialsMatcher bitbucketCheckoutCredentialsMatcher() { 109 | return CredentialsMatchers.anyOf(CredentialsMatchers.instanceOf(StandardCredentials.class)); 110 | } 111 | 112 | /* package */ List bitbucketDomainRequirements() { 113 | if (serverUrl == null) { 114 | return URIRequirementBuilder.fromUri("https://bitbucket.org").build(); 115 | } else { 116 | return URIRequirementBuilder.fromUri(serverUrl).build(); 117 | } 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/api/BitbucketApi.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.api; 25 | 26 | import java.util.List; 27 | 28 | import com.cloudbees.jenkins.plugins.bitbucket.client.repository.UserRoleInRepository; 29 | 30 | import edu.umd.cs.findbugs.annotations.CheckForNull; 31 | 32 | /** 33 | * Provides access to a specific repository. 34 | * One API object needs to be created for each repository you want to work with. 35 | */ 36 | public interface BitbucketApi { 37 | 38 | /** 39 | * @return the repository owner name. 40 | */ 41 | String getOwner(); 42 | 43 | /** 44 | * @return the repository name. 45 | */ 46 | String getRepositoryName(); 47 | 48 | /** 49 | * @return the list of pull requests in the repository. 50 | */ 51 | List getPullRequests(); 52 | 53 | /** 54 | * @param id the pull request ID 55 | * @return the pull request or null if the PR does not exist 56 | */ 57 | @CheckForNull 58 | BitbucketPullRequest getPullRequestById(Integer id); 59 | 60 | /** 61 | * @return the repository specified by {@link #getOwner()}/{@link #getRepositoryName()} 62 | * (or null if repositoryName is not set) 63 | */ 64 | @CheckForNull 65 | BitbucketRepository getRepository(); 66 | 67 | /** 68 | * Post a comment to a given commit hash. 69 | * 70 | * @param hash commit hash 71 | * @param comment string to post as comment 72 | */ 73 | void postCommitComment(String hash, String comment); 74 | 75 | /** 76 | * Checks if the given path exists in the repository at the specified branch. 77 | * 78 | * @param branch the branch name 79 | * @param path the path to check for 80 | * @return true if the path exists 81 | */ 82 | boolean checkPathExists(String branch, String path); 83 | 84 | /** 85 | * @return the list of branches in the repository. 86 | */ 87 | List getBranches(); 88 | 89 | /** 90 | * Resolve the commit object given its hash. 91 | * 92 | * @param hash the hash to resolve 93 | * @return the commit object or null if the hash does not exist 94 | */ 95 | @CheckForNull 96 | BitbucketCommit resolveCommit(String hash); 97 | 98 | /** 99 | * Resolve the head commit hash of the pull request source repository branch. 100 | * 101 | * @param pull the pull request to resolve the source hash from 102 | * @return the source head hash 103 | */ 104 | String resolveSourceFullHash(BitbucketPullRequest pull); 105 | 106 | /** 107 | * Register a webhook on the repository. 108 | * 109 | * @param hook the webhook object 110 | */ 111 | void registerCommitWebHook(BitbucketWebHook hook); 112 | 113 | /** 114 | * Remove the webhook (ID field required) from the repository. 115 | * 116 | * @param hook the webhook object 117 | */ 118 | void removeCommitWebHook(BitbucketWebHook hook); 119 | 120 | /** 121 | * @return the list of webhooks registered in the repository. 122 | */ 123 | List getWebHooks(); 124 | 125 | /** 126 | * @return the team profile of the current owner, or null if {@link #getOwner()} is not a team ID. 127 | */ 128 | @CheckForNull 129 | BitbucketTeam getTeam(); 130 | 131 | /** 132 | * Returns the repositories where the user has the given role. 133 | * 134 | * @param role Filter repositories by the owner having this role in. 135 | * See {@link UserRoleInRepository} for more information. 136 | * Use role = null if the repoOwner is a team ID. 137 | * @return the repositories list (it can be empty) 138 | */ 139 | List getRepositories(UserRoleInRepository role); 140 | 141 | /** 142 | * Returns all the repositories for the current owner (even if it's a regular user or a team). 143 | * 144 | * @return all repositories for the current {@link #getOwner()} 145 | */ 146 | List getRepositories(); 147 | 148 | /** 149 | * Set the build status for the given commit hash. 150 | * 151 | * @param status the status object to be serialized 152 | */ 153 | void postBuildStatus(BitbucketBuildStatus status); 154 | 155 | /** 156 | * @return true if the repository ({@link #getOwner()}/{@link #getRepositoryName()}) is private, false otherwise 157 | * (if it's public or does not exists). 158 | */ 159 | boolean isPrivate(); 160 | 161 | } -------------------------------------------------------------------------------- /src/test/java/com/cloudbees/jenkins/plugins/bitbucket/SCMNavigatorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket; 25 | 26 | import static org.junit.Assert.*; 27 | import static org.mockito.Matchers.any; 28 | import static org.mockito.Matchers.anyString; 29 | import static org.mockito.Mockito.mock; 30 | import static org.mockito.Mockito.when; 31 | 32 | import java.io.IOException; 33 | import java.util.ArrayList; 34 | import java.util.List; 35 | 36 | import org.junit.Test; 37 | 38 | import com.cloudbees.jenkins.plugins.bitbucket.client.BitbucketCloudApiClient; 39 | import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; 40 | 41 | import hudson.model.TaskListener; 42 | import jenkins.scm.api.SCMSource; 43 | import jenkins.scm.api.SCMSourceObserver; 44 | import jenkins.scm.api.SCMSourceOwner; 45 | import jenkins.scm.api.SCMSourceObserver.ProjectObserver; 46 | 47 | public class SCMNavigatorTest { 48 | 49 | @Test 50 | public void teamRepositoriesDiscovering() throws IOException, InterruptedException { 51 | BitbucketSCMNavigator navigator = new BitbucketSCMNavigator("myteam", null, null); 52 | navigator.setPattern("repo(.*)"); 53 | navigator.setBitbucketConnector(getConnectorMock(RepositoryType.GIT, true)); 54 | SCMSourceObserverImpl observer = new SCMSourceObserverImpl(BitbucketClientMockUtils.getTaskListenerMock()); 55 | navigator.visitSources(observer); 56 | 57 | assertEquals("myteam", navigator.getRepoOwner()); 58 | assertEquals("repo(.*)", navigator.getPattern()); 59 | 60 | List observed = observer.getObserved(); 61 | // Only 2 repositores match the pattern 62 | assertTrue("There must be 2 repositories in the team, but was " + observed.size(), observed.size() == 2); 63 | assertEquals("repo1", observed.get(0)); 64 | assertEquals("repo2", observed.get(1)); 65 | 66 | List observers = observer.getProjectObservers(); 67 | for (ProjectObserver obs : observers) { 68 | List sources = ((SCMSourceObserverImpl.ProjectObserverImpl) obs).getSources(); 69 | // It should contain only one source 70 | assertTrue("Only one source must be created per observed repository", sources.size() == 1); 71 | SCMSource scmSource = sources.get(0); 72 | assertTrue("BitbucketSCMSource instances must be added", scmSource instanceof BitbucketSCMSource); 73 | // Check correct repoOwner (team name in this case) was set 74 | assertEquals(((BitbucketSCMSource) scmSource).getRepoOwner(), "myteam"); 75 | } 76 | } 77 | 78 | private class SCMSourceObserverImpl extends SCMSourceObserver { 79 | 80 | List observed = new ArrayList(); 81 | List projectObservers = new ArrayList(); 82 | TaskListener listener; 83 | 84 | public SCMSourceObserverImpl(TaskListener listener) { 85 | this.listener = listener; 86 | } 87 | 88 | @Override 89 | public SCMSourceOwner getContext() { 90 | return null; 91 | } 92 | 93 | @Override 94 | public TaskListener getListener() { 95 | return listener; 96 | } 97 | 98 | @Override 99 | public ProjectObserver observe(String projectName) throws IllegalArgumentException { 100 | observed.add(projectName); 101 | ProjectObserverImpl obs = new ProjectObserverImpl(); 102 | projectObservers.add(obs); 103 | return obs; 104 | } 105 | 106 | @Override 107 | public void addAttribute(String key, Object value) throws IllegalArgumentException, ClassCastException { 108 | } 109 | 110 | public List getObserved() { 111 | return observed; 112 | } 113 | 114 | public List getProjectObservers() { 115 | return projectObservers; 116 | } 117 | 118 | public class ProjectObserverImpl extends ProjectObserver { 119 | 120 | private List sources = new ArrayList(); 121 | 122 | @Override 123 | public void addSource(SCMSource source) { 124 | sources.add(source); 125 | } 126 | 127 | @Override 128 | public void addAttribute(String key, Object value) throws IllegalArgumentException, ClassCastException { 129 | } 130 | 131 | @Override 132 | public void complete() throws IllegalStateException, InterruptedException { 133 | } 134 | 135 | public List getSources() { 136 | return sources; 137 | } 138 | } 139 | } 140 | 141 | public static BitbucketApiConnector getConnectorMock(RepositoryType type, boolean includePullRequests) { 142 | BitbucketApiConnector mockConnector = mock(BitbucketApiConnector.class); 143 | BitbucketCloudApiClient mockedApi = BitbucketClientMockUtils.getAPIClientMock(type, includePullRequests); 144 | when(mockConnector.create(anyString(), any(StandardUsernamePasswordCredentials.class))).thenReturn(mockedApi); 145 | when(mockConnector.create(anyString(), anyString(), any(StandardUsernamePasswordCredentials.class))).thenReturn(mockedApi); 146 | return mockConnector; 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /src/test/java/com/cloudbees/jenkins/plugins/bitbucket/BranchScanningTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket; 25 | 26 | import static org.junit.Assert.*; 27 | import static org.mockito.Matchers.*; 28 | import static org.mockito.Mockito.*; 29 | import hudson.model.TaskListener; 30 | import hudson.plugins.git.GitSCM; 31 | import hudson.plugins.git.UserRemoteConfig; 32 | import hudson.plugins.mercurial.MercurialSCM; 33 | import hudson.scm.SCM; 34 | 35 | import java.io.IOException; 36 | import java.util.ArrayList; 37 | import java.util.List; 38 | 39 | import jenkins.plugins.git.AbstractGitSCMSource.SCMRevisionImpl; 40 | import jenkins.scm.api.SCMHead; 41 | import jenkins.scm.api.SCMHeadObserver; 42 | import jenkins.scm.api.SCMRevision; 43 | import jenkins.scm.api.SCMSourceCriteria; 44 | import jenkins.scm.api.SCMSourceOwner; 45 | import jenkins.scm.api.SCMSource; 46 | 47 | import org.junit.Test; 48 | 49 | import com.cloudbees.jenkins.plugins.bitbucket.client.BitbucketCloudApiClient; 50 | import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials; 51 | 52 | import edu.umd.cs.findbugs.annotations.NonNull; 53 | 54 | public class BranchScanningTest { 55 | 56 | private static final String repoOwner = "amuniz"; 57 | private static final String repoName = "test"; 58 | private static final String branchName = "branch1"; 59 | 60 | @Test 61 | public void uriResolverTest() { 62 | BitbucketSCMSource source = getBitbucketSCMSourceMock(RepositoryType.GIT); 63 | String remote = source.getRemote("amuniz", "test"); 64 | 65 | // When there is no checkout credentials set, https must be resolved 66 | assertEquals("https://bitbucket.org/amuniz/test.git", remote); 67 | 68 | source = getBitbucketSCMSourceMock(RepositoryType.MERCURIAL); 69 | remote = source.getRemote("amuniz", "test"); 70 | 71 | // Resolve URL for Mercurial repositories 72 | assertEquals("https://bitbucket.org/amuniz/test", remote); 73 | } 74 | 75 | @Test 76 | public void remoteConfigsTest() { 77 | BitbucketSCMSource source = getBitbucketSCMSourceMock(RepositoryType.GIT); 78 | List remoteConfigs = source.getGitRemoteConfigs(new SCMHeadWithOwnerAndRepo("amuniz", "test-repos", "branch1")); 79 | assertEquals(1, remoteConfigs.size()); 80 | assertEquals("+refs/heads/branch1", remoteConfigs.get(0).getRefspec()); 81 | } 82 | 83 | @Test 84 | public void retrieveTest() throws IOException, InterruptedException { 85 | BitbucketSCMSource source = getBitbucketSCMSourceMock(RepositoryType.GIT); 86 | 87 | SCMHeadWithOwnerAndRepo head = new SCMHeadWithOwnerAndRepo(repoOwner, repoName, branchName); 88 | SCMRevision rev = source.retrieve(head, BitbucketClientMockUtils.getTaskListenerMock()); 89 | 90 | // Last revision on branch1 must be returned 91 | assertEquals("52fc8e220d77ec400f7fc96a91d2fd0bb1bc553a", ((SCMRevisionImpl) rev).getHash()); 92 | 93 | } 94 | 95 | @Test 96 | public void scanTest() throws IOException, InterruptedException { 97 | BitbucketSCMSource source = getBitbucketSCMSourceMock(RepositoryType.GIT); 98 | SCMHeadObserverImpl observer = new SCMHeadObserverImpl(); 99 | source.retrieve(observer, BitbucketClientMockUtils.getTaskListenerMock()); 100 | 101 | // Only branch1 must be observed 102 | assertEquals(1, observer.getBranches().size()); 103 | assertEquals("branch1", observer.getBranches().get(0)); 104 | } 105 | 106 | @Test 107 | public void scanTestPullRequests() throws IOException, InterruptedException { 108 | BitbucketSCMSource source = getBitbucketSCMSourceMock(RepositoryType.GIT, true); 109 | SCMHeadObserverImpl observer = new SCMHeadObserverImpl(); 110 | source.retrieve(observer, BitbucketClientMockUtils.getTaskListenerMock()); 111 | 112 | // Only branch1 and my-feature-branch PR must be observed 113 | assertEquals(2, observer.getBranches().size()); 114 | assertEquals("branch1", observer.getBranches().get(0)); 115 | assertEquals("PR-23", observer.getBranches().get(1)); 116 | } 117 | 118 | @Test 119 | public void gitSCMTest() { 120 | SCM scm = scmBuild(RepositoryType.GIT); 121 | assertTrue("SCM must be an instance of GitSCM", scm instanceof GitSCM); 122 | } 123 | 124 | @Test 125 | public void mercurialSCMTest() { 126 | SCM scm = scmBuild(RepositoryType.MERCURIAL); 127 | assertTrue("SCM must be an instance of MercurialSCM", scm instanceof MercurialSCM); 128 | } 129 | 130 | private SCM scmBuild(RepositoryType type) { 131 | BitbucketSCMSource source = getBitbucketSCMSourceMock(type); 132 | return source.build(new SCMHeadWithOwnerAndRepo("amuniz", "test-repos", "branch1")); 133 | } 134 | 135 | private BitbucketSCMSource getBitbucketSCMSourceMock(RepositoryType type, boolean includePullRequests) { 136 | BitbucketSCMSource source = new BitbucketSCMSource(null, "amuniz", "test-repos"); 137 | source.setOwner(getSCMSourceOwnerMock()); 138 | BitbucketApiConnector mockFactory = mock(BitbucketApiConnector.class); 139 | BitbucketCloudApiClient mockedApi = BitbucketClientMockUtils.getAPIClientMock(type, includePullRequests); 140 | when(mockFactory.create(anyString(), anyString(), any(StandardUsernamePasswordCredentials.class))).thenReturn(mockedApi); 141 | source.setBitbucketConnector(mockFactory); 142 | return source; 143 | } 144 | 145 | private BitbucketSCMSource getBitbucketSCMSourceMock(RepositoryType type) { 146 | return getBitbucketSCMSourceMock(type, false); 147 | } 148 | 149 | private SCMSourceOwner getSCMSourceOwnerMock() { 150 | SCMSourceOwner mocked = mock(SCMSourceOwner.class); 151 | when(mocked.getSCMSourceCriteria(any(SCMSource.class))).thenReturn(new SCMSourceCriteria() { 152 | 153 | @Override 154 | public boolean isHead(Probe probe, TaskListener listener) throws IOException { 155 | return probe.exists("markerfile.txt"); 156 | } 157 | 158 | }); 159 | return mocked; 160 | } 161 | 162 | public final class SCMHeadObserverImpl extends SCMHeadObserver { 163 | 164 | public List branches = new ArrayList(); 165 | 166 | public void observe(@NonNull SCMHead head, @NonNull SCMRevision revision) { 167 | branches.add(head.getName()); 168 | } 169 | 170 | public List getBranches() { 171 | return branches; 172 | } 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /src/test/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketClientMockUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket; 25 | 26 | import static org.mockito.Matchers.any; 27 | import static org.mockito.Mockito.mock; 28 | import static org.mockito.Mockito.when; 29 | 30 | import java.util.ArrayList; 31 | import java.util.Arrays; 32 | import java.util.Collections; 33 | import java.util.List; 34 | 35 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; 36 | import com.cloudbees.jenkins.plugins.bitbucket.client.BitbucketCloudApiClient; 37 | import com.cloudbees.jenkins.plugins.bitbucket.client.branch.BitbucketCloudBranch; 38 | import com.cloudbees.jenkins.plugins.bitbucket.client.branch.BitbucketCloudCommit; 39 | import com.cloudbees.jenkins.plugins.bitbucket.client.pullrequest.BitbucketPullRequestValue; 40 | import com.cloudbees.jenkins.plugins.bitbucket.client.pullrequest.BitbucketPullRequestValue.Author; 41 | import com.cloudbees.jenkins.plugins.bitbucket.client.pullrequest.BitbucketPullRequestValueRepository; 42 | import com.cloudbees.jenkins.plugins.bitbucket.client.repository.BitbucketCloudRepository; 43 | import com.cloudbees.jenkins.plugins.bitbucket.client.repository.BitbucketRepositoryHook; 44 | import com.cloudbees.jenkins.plugins.bitbucket.client.repository.BitbucketCloudTeam; 45 | import com.cloudbees.jenkins.plugins.bitbucket.hooks.BitbucketSCMSourcePushHookReceiver; 46 | 47 | import hudson.model.TaskListener; 48 | import jenkins.model.Jenkins; 49 | 50 | public class BitbucketClientMockUtils { 51 | 52 | public static BitbucketCloudApiClient getAPIClientMock(RepositoryType type, boolean includePullRequests, 53 | boolean includeWebHooks) { 54 | BitbucketCloudApiClient bitbucket = mock(BitbucketCloudApiClient.class); 55 | // mock branch list 56 | List branches = new ArrayList(); 57 | branches.add(getBranch("branch1", "52fc8e220d77ec400f7fc96a91d2fd0bb1bc553a")); 58 | branches.add(getBranch("branch2", "707c59ce8292c927dddb6807fcf9c3c5e7c9b00f")); 59 | // add branches 60 | when(bitbucket.getBranches()).thenReturn(branches); 61 | if (RepositoryType.MERCURIAL == type) { 62 | withMockMercurialRepos(bitbucket); 63 | } else { 64 | withMockGitRepos(bitbucket); 65 | } 66 | 67 | if (includePullRequests) { 68 | when(bitbucket.getPullRequests()).thenReturn(Arrays.asList(getPullRequest())); 69 | when(bitbucket.checkPathExists("my-feature-branch", "markerfile.txt")).thenReturn(true); 70 | when(bitbucket.resolveSourceFullHash(any(BitbucketPullRequestValue.class))) 71 | .thenReturn("e851558f77c098d21af6bb8cc54a423f7cf12147"); 72 | } 73 | 74 | // mock file exists 75 | when(bitbucket.checkPathExists("branch1", "markerfile.txt")).thenReturn(true); 76 | when(bitbucket.checkPathExists("branch2", "markerfile.txt")).thenReturn(false); 77 | 78 | // Team discovering mocks 79 | when(bitbucket.getTeam()).thenReturn(getTeam()); 80 | when(bitbucket.getRepositories()).thenReturn(getRepositories()); 81 | 82 | // Auto-registering hooks 83 | if (includeWebHooks) { 84 | when(bitbucket.getWebHooks()).thenReturn(Collections.EMPTY_LIST) 85 | // Second call 86 | .thenReturn(getWebHooks()); 87 | } 88 | when(bitbucket.isPrivate()).thenReturn(true); 89 | 90 | return bitbucket; 91 | } 92 | 93 | public static BitbucketCloudApiClient getAPIClientMock(RepositoryType type, boolean includePullRequests) { 94 | return getAPIClientMock(type, includePullRequests, false); 95 | } 96 | 97 | private static List getWebHooks() { 98 | BitbucketRepositoryHook hook = new BitbucketRepositoryHook(); 99 | hook.setUrl(Jenkins.getActiveInstance().getRootUrl() + BitbucketSCMSourcePushHookReceiver.FULL_PATH); 100 | return Arrays.asList(hook); 101 | } 102 | 103 | private static List getRepositories() { 104 | BitbucketCloudRepository r1 = new BitbucketCloudRepository(); 105 | r1.setFullName("myteam/repo1"); 106 | BitbucketCloudRepository r2 = new BitbucketCloudRepository(); 107 | r2.setFullName("myteam/repo2"); 108 | BitbucketCloudRepository r3 = new BitbucketCloudRepository(); 109 | // test mock hack to avoid a lot of harness code 110 | r3.setFullName("amuniz/test-repos"); 111 | return Arrays.asList(r1, r2, r3); 112 | } 113 | 114 | private static BitbucketCloudTeam getTeam() { 115 | BitbucketCloudTeam t = new BitbucketCloudTeam(); 116 | t.setName("myteam"); 117 | t.setDisplayName("This is my team"); 118 | return t; 119 | } 120 | 121 | private static void withMockGitRepos(BitbucketApi bitbucket) { 122 | BitbucketCloudRepository repo = new BitbucketCloudRepository(); 123 | repo.setScm("git"); 124 | repo.setFullName("amuniz/test-repos"); 125 | repo.setPrivate(true); 126 | when(bitbucket.getRepository()).thenReturn(repo); 127 | } 128 | 129 | private static void withMockMercurialRepos(BitbucketApi bitbucket) { 130 | BitbucketCloudRepository repo = new BitbucketCloudRepository(); 131 | repo.setScm("hg"); 132 | repo.setFullName("amuniz/test-repos"); 133 | repo.setPrivate(true); 134 | when(bitbucket.getRepository()).thenReturn(repo); 135 | } 136 | 137 | private static BitbucketCloudBranch getBranch(String name, String hash) { 138 | BitbucketCloudBranch b = new BitbucketCloudBranch(); 139 | b.setName(name); 140 | b.setRawNode(hash); 141 | return b; 142 | } 143 | 144 | private static BitbucketPullRequestValue getPullRequest() { 145 | BitbucketPullRequestValue pr = new BitbucketPullRequestValue(); 146 | BitbucketPullRequestValueRepository source = new BitbucketPullRequestValueRepository(); 147 | 148 | BitbucketCloudBranch branch = new BitbucketCloudBranch(); 149 | branch.setName("my-feature-branch"); 150 | source.setBranch(branch); 151 | 152 | BitbucketCloudCommit commit = new BitbucketCloudCommit(); 153 | commit.setHash("e851558f77c098d21af6bb8cc54a423f7cf12147"); 154 | source.setCommit(commit); 155 | 156 | BitbucketCloudRepository repository = new BitbucketCloudRepository(); 157 | repository.setFullName("otheruser/test-repos"); 158 | source.setRepository(repository); 159 | 160 | pr.setSource(source); 161 | 162 | pr.setId("23"); 163 | pr.setAuthor(new BitbucketPullRequestValue.Author("amuniz")); 164 | pr.setLinks(new BitbucketPullRequestValue.Links("https://bitbucket.org/amuniz/test-repos/pull-requests/23")); 165 | return pr; 166 | } 167 | 168 | public static TaskListener getTaskListenerMock() { 169 | TaskListener mockTaskListener = mock(TaskListener.class); 170 | when(mockTaskListener.getLogger()).thenReturn(System.out); 171 | return mockTaskListener; 172 | } 173 | 174 | } 175 | -------------------------------------------------------------------------------- /src/main/java/com/cloudbees/jenkins/plugins/bitbucket/hooks/WebhookAutoRegisterListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2016, CloudBees, Inc. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package com.cloudbees.jenkins.plugins.bitbucket.hooks; 25 | 26 | import java.util.ArrayList; 27 | import java.util.Arrays; 28 | import java.util.List; 29 | import java.util.concurrent.ExecutorService; 30 | import java.util.concurrent.Executors; 31 | import java.util.logging.Level; 32 | import java.util.logging.Logger; 33 | 34 | import com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource; 35 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketApi; 36 | import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketWebHook; 37 | import com.cloudbees.jenkins.plugins.bitbucket.client.repository.BitbucketRepositoryHook; 38 | 39 | import hudson.Extension; 40 | import hudson.model.Item; 41 | import hudson.model.listeners.ItemListener; 42 | import hudson.triggers.SafeTimerTask; 43 | import hudson.util.DaemonThreadFactory; 44 | import hudson.util.NamingThreadFactory; 45 | import jenkins.model.Jenkins; 46 | import jenkins.scm.api.SCMSource; 47 | import jenkins.scm.api.SCMSourceOwner; 48 | import jenkins.scm.api.SCMSourceOwners; 49 | 50 | /** 51 | * {@link SCMSourceOwner} item listener that traverse the list of {@link SCMSource} and register 52 | * a webhook for every {@link BitbucketSCMSource} found. 53 | */ 54 | @Extension 55 | public class WebhookAutoRegisterListener extends ItemListener { 56 | 57 | private static final Logger LOGGER = Logger.getLogger(WebhookAutoRegisterListener.class.getName()); 58 | 59 | private static ExecutorService executorService; 60 | 61 | @Override 62 | public void onCreated(Item item) { 63 | if (!isApplicable(item)) { 64 | return; 65 | } 66 | registerHooksAsync((SCMSourceOwner) item); 67 | } 68 | 69 | @Override 70 | public void onDeleted(Item item) { 71 | if (!isApplicable(item)) { 72 | return; 73 | } 74 | removeHooksAsync((SCMSourceOwner) item); 75 | } 76 | 77 | @Override 78 | public void onUpdated(Item item) { 79 | if (!isApplicable(item)) { 80 | return; 81 | } 82 | registerHooksAsync((SCMSourceOwner) item); 83 | } 84 | 85 | private boolean isApplicable(Item item) { 86 | return item instanceof SCMSourceOwner; 87 | } 88 | 89 | private void registerHooksAsync(final SCMSourceOwner owner) { 90 | getExecutorService().submit(new SafeTimerTask() { 91 | @Override 92 | public void doRun() { 93 | registerHooks(owner); 94 | } 95 | }); 96 | } 97 | 98 | private void removeHooksAsync(final SCMSourceOwner owner) { 99 | getExecutorService().submit(new SafeTimerTask() { 100 | @Override 101 | public void doRun() { 102 | removeHooks(owner); 103 | } 104 | }); 105 | } 106 | 107 | // synchronized just to avoid duplicated webhooks in case SCMSourceOwner is updated repeteadly and quickly 108 | private synchronized void registerHooks(SCMSourceOwner owner) { 109 | List sources = getBitucketSCMSources(owner); 110 | for (BitbucketSCMSource source : sources) { 111 | if (source.isAutoRegisterHook()) { 112 | BitbucketApi bitbucket = source.buildBitbucketClient(); 113 | List existent = bitbucket.getWebHooks(); 114 | boolean exists = false; 115 | for (BitbucketWebHook hook : existent) { 116 | // Check if there is a hook pointing to us already 117 | if (hook.getUrl().equals(Jenkins.getActiveInstance().getRootUrl() + BitbucketSCMSourcePushHookReceiver.FULL_PATH)) { 118 | exists = true; 119 | break; 120 | } 121 | } 122 | if (!exists) { 123 | String rootUrl = Jenkins.getActiveInstance().getRootUrl(); 124 | if (rootUrl != null && !rootUrl.startsWith("http://localhost")) { 125 | LOGGER.info(String.format("Registering hook for %s/%s", source.getRepoOwner(), source.getRepository())); 126 | bitbucket.registerCommitWebHook(getHook()); 127 | } else { 128 | LOGGER.warning(String.format("Can not register hook. Jenkins root URL is not valid: %s", rootUrl)); 129 | } 130 | } 131 | } 132 | } 133 | } 134 | 135 | private void removeHooks(SCMSourceOwner owner) { 136 | List sources = getBitucketSCMSources(owner); 137 | for (BitbucketSCMSource source : sources) { 138 | if (source.isAutoRegisterHook()) { 139 | BitbucketApi bitbucket = source.buildBitbucketClient(); 140 | List existent = bitbucket.getWebHooks(); 141 | BitbucketWebHook hook = null; 142 | for (BitbucketWebHook h : existent) { 143 | // Check if there is a hook pointing to us 144 | if (h.getUrl().equals(Jenkins.getActiveInstance().getRootUrl() + BitbucketSCMSourcePushHookReceiver.FULL_PATH)) { 145 | hook = h; 146 | break; 147 | } 148 | } 149 | if (hook != null && !isUsedSomewhereElse(owner, source.getRepoOwner(), source.getRepository())) { 150 | LOGGER.info(String.format("Removing hook for %s/%s", source.getRepoOwner(), source.getRepository())); 151 | bitbucket.removeCommitWebHook(hook); 152 | } else { 153 | LOGGER.log(Level.FINE, String.format("NOT removing hook for %s/%s because does not exists or its used in other project", 154 | source.getRepoOwner(), source.getRepository())); 155 | } 156 | } 157 | } 158 | } 159 | 160 | private boolean isUsedSomewhereElse(SCMSourceOwner owner, String repoOwner, String repoName) { 161 | Iterable all = SCMSourceOwners.all(); 162 | for (SCMSourceOwner other : all) { 163 | if (owner != other) { 164 | for(SCMSource otherSource : other.getSCMSources()) { 165 | if (otherSource instanceof BitbucketSCMSource 166 | && ((BitbucketSCMSource) otherSource).getRepoOwner().equals(repoOwner) 167 | && ((BitbucketSCMSource) otherSource).getRepository().equals(repoName)) { 168 | return true; 169 | } 170 | } 171 | } 172 | } 173 | return false; 174 | } 175 | 176 | private List getBitucketSCMSources(SCMSourceOwner owner) { 177 | List sources = new ArrayList(); 178 | for (SCMSource source : owner.getSCMSources()) { 179 | if (source instanceof BitbucketSCMSource) { 180 | sources.add((BitbucketSCMSource) source); 181 | } 182 | } 183 | return sources; 184 | } 185 | 186 | private BitbucketWebHook getHook() { 187 | // TODO: generalize this for BB server 188 | BitbucketRepositoryHook hooks = new BitbucketRepositoryHook(); 189 | hooks.setActive(true); 190 | hooks.setDescription("Jenkins hooks"); 191 | hooks.setUrl(Jenkins.getActiveInstance().getRootUrl() + BitbucketSCMSourcePushHookReceiver.FULL_PATH); 192 | hooks.setEvents(Arrays.asList(HookEventType.PUSH.getKey(), 193 | HookEventType.PULL_REQUEST_CREATED.getKey(), HookEventType.PULL_REQUEST_UPDATED.getKey())); 194 | return hooks; 195 | } 196 | 197 | /** 198 | * We need a single thread executor to run webhooks operations in background but in order. 199 | * Registrations and removals need to be done in the same order than they were called by the item listener. 200 | */ 201 | private static synchronized ExecutorService getExecutorService() { 202 | if (executorService == null) { 203 | executorService = Executors.newSingleThreadExecutor(new NamingThreadFactory(new DaemonThreadFactory(), WebhookAutoRegisterListener.class.getName())); 204 | } 205 | return executorService; 206 | } 207 | 208 | } 209 | --------------------------------------------------------------------------------