Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-multibranch</artifactId>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>cloudbees-bitbucket-branch-source</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* @author <a href="mailto:nicolas.deloof@gmail.com">Nicolas De Loof</a>
*/
@Extension
public class BitbucketHookReceiver implements UnprotectedRootAction {
public class BitbucketHookReceiver extends BitbucketCrumbExclusion implements UnprotectedRootAction {

private final BitbucketPayloadProcessor payloadProcessor = new BitbucketPayloadProcessor();
public static final String BITBUCKET_HOOK_URL = "bitbucket-hook";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,19 @@
import org.eclipse.jgit.transport.URIish;
import com.google.common.base.Objects;
import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject;
import com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource;

public class BitbucketJobProbe {

private boolean isBranchPluginAvailable = false;

public BitbucketJobProbe() {
if (Jenkins.get().getPlugin("cloudbees-bitbucket-branch-source") != null) {

Check warning on line 43 in src/main/java/com/cloudbees/jenkins/plugins/BitbucketJobProbe.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 43 is only partially covered, one branch is missing
LOGGER.log(Level.FINEST, "Bitbucket branch source available");
isBranchPluginAvailable = true;
}
}

public void triggerMatchingJobs(String user, String url, String scm, String payload) {
triggerMatchingJobs(user, url, scm, payload, null);
}
Expand All @@ -56,7 +66,7 @@
bTrigger = (BitBucketTrigger) trigger;
LOGGER.log(Level.FINE, "Job [{0}] has BitBucketTrigger", job.getName());
break;
} else if ( trigger instanceof BitBucketMultibranchTrigger){
} else if (trigger instanceof BitBucketMultibranchTrigger) {
LOGGER.fine("Trigger is BitBucketMultibranchTrigger");
}
}
Expand Down Expand Up @@ -98,7 +108,7 @@
LOGGER.finest("scmSourceOwner [" + scmSourceOwner.getName() + "] is of type WorkflowMultiBranchProject");
WorkflowMultiBranchProject workflowMultiBranchProject = (WorkflowMultiBranchProject) scmSourceOwner;
AtomicReference<BitBucketMultibranchTrigger> bitBucketMultibranchTrigger = new AtomicReference<>(null);
if ( workflowMultiBranchProject.getTriggers().isEmpty()) {
if (workflowMultiBranchProject.getTriggers().isEmpty()) {
LOGGER.finest("No triggers found");
} else {
workflowMultiBranchProject.getTriggers().forEach(((triggerDescriptor, trigger) -> {
Expand All @@ -108,10 +118,10 @@
}
}));
}
if ( bitBucketMultibranchTrigger.get() == null){
if (bitBucketMultibranchTrigger.get() == null) {
scmSourceOwner.onSCMSourceUpdated(scmSource);
} else {
if (workflowMultiBranchProject.isBuildable()){
if (workflowMultiBranchProject.isBuildable()) {
bitBucketMultibranchTrigger.get().setPayload(payload);
BitBucketPushCause bitBucketPushCause = new BitBucketPushCause(user);
workflowMultiBranchProject.scheduleBuild2(0, new CauseAction(bitBucketPushCause));
Expand All @@ -125,19 +135,19 @@
} else if (scmSourceOwner instanceof WorkflowMultiBranchProject) {
LOGGER.finest("scmSourceOwner [" + scmSourceOwner.getName() + "] is of type WorkflowMultiBranchProject");
WorkflowMultiBranchProject workflowMultiBranchProject = (WorkflowMultiBranchProject) scmSourceOwner;
if ( workflowMultiBranchProject.getTriggers().isEmpty()){
if (workflowMultiBranchProject.getTriggers().isEmpty()) {
LOGGER.finest("No triggers found");
} else {
workflowMultiBranchProject.getTriggers().forEach(((triggerDescriptor, trigger) -> {
if ( trigger instanceof BitBucketMultibranchTrigger){
if (trigger instanceof BitBucketMultibranchTrigger) {
LOGGER.finest("Found BitBucketMultibranchTrigger type");
BitBucketMultibranchTrigger bitBucketMultibranchTrigger = (BitBucketMultibranchTrigger) trigger;
if ( bitBucketMultibranchTrigger.getOverrideUrl() == null || bitBucketMultibranchTrigger.getOverrideUrl().isEmpty()){
if (bitBucketMultibranchTrigger.getOverrideUrl() == null || bitBucketMultibranchTrigger.getOverrideUrl().isEmpty()) {
LOGGER.finest("Ignoring empty overrideUrl");
} else {
LOGGER.fine("Found override URL [" + bitBucketMultibranchTrigger.getOverrideUrl() + "]");
LOGGER.log(Level.FINE, "Trying to match {0} ", remote + "<-->" + bitBucketMultibranchTrigger.getOverrideUrl());
if ( bitBucketMultibranchTrigger.getOverrideUrl().equalsIgnoreCase(remote.toString())) {
if (bitBucketMultibranchTrigger.getOverrideUrl().equalsIgnoreCase(remote.toString())) {
LOGGER.info(String.format("Triggering BitBucket scmSourceOwner [%s] by overrideUrl [%s]",scmSourceOwner.getName(), bitBucketMultibranchTrigger.getOverrideUrl()));
scmSourceOwner.onSCMSourceUpdated(scmSource);
}
Expand Down Expand Up @@ -216,10 +226,21 @@
}

private boolean match(SCMSource scm, URIish url) {
if (scm instanceof GitSCMSource) {
LOGGER.log(Level.FINEST, "SCMSource is GitSCMSource");
String gitRemote = ((GitSCMSource) scm).getRemote();
if (scm instanceof GitSCMSource || (isBranchPluginAvailable && scm instanceof BitbucketSCMSource)) {
String gitRemote;
if (scm instanceof GitSCMSource) {
LOGGER.log(Level.FINEST, "SCMSource is GitSCMSource");
gitRemote = ((GitSCMSource) scm).getRemote();
} else if (isBranchPluginAvailable) {
LOGGER.log(Level.FINEST, "SCMSource is BitbucketSCMSource");
gitRemote = ((BitbucketSCMSource) scm).getServerUrl() + "/" +
((BitbucketSCMSource) scm).getRepoOwner() + "/" +
((BitbucketSCMSource) scm).getRepository();
Comment on lines +236 to +238

Choose a reason for hiding this comment

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

This URL structure looks specific to Bitbucket Cloud, incompatible with Server and Data Center.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@KalleOlaviNiemitalo this define a generic match. Why should be incompatible? The code just decouple a different type coming.

Choose a reason for hiding this comment

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

My mistake. In Bitbucket Server, the web UI uses URLs like https://bitbucket.example:8443/projects/DEMOPROJ/repos/demorepo/browse, which includes the "projects" and "repos" keywords. I worried that this pull request does not add those keywords and might then be incompatible. However, in Bitbucket Server, git clone uses URLs like ssh://git@bitbucket.example:7999/DEMOPROJ/demorepo.git or https://bitbucket.example:8443/scm/demoproj/demorepo.git; these do not include the "projects" and "repos" keywords. So this pull request seems compatible after all.

} else {
return false;
}
URIish urIish;
LOGGER.log(Level.FINEST, "SCMSource remote is " + gitRemote);

Check warning on line 243 in src/main/java/com/cloudbees/jenkins/plugins/BitbucketJobProbe.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 229-243 are not covered by tests
try {
urIish = new URIish(gitRemote);
} catch (URISyntaxException e) {
Expand Down
Loading