Skip to content

Commit

Permalink
Jenkins-65698 - feat - added BITBUCKET_PAYLOAD to multi-branch
Browse files Browse the repository at this point in the history
  • Loading branch information
tzachs committed Aug 11, 2024
1 parent ba19db8 commit 9b733c4
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 2 deletions.
13 changes: 13 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,19 @@
<artifactId>workflow-multibranch</artifactId>
</dependency>

<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>git</artifactId>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>scm-api</artifactId>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class BitBucketMultibranchTrigger extends Trigger<WorkflowMultiBranchProj
private static final Logger LOGGER = Logger.getLogger(BitBucketMultibranchTrigger.class.getName());

private String overrideUrl;
private String payload;

@DataBoundConstructor
public BitBucketMultibranchTrigger() { }
Expand All @@ -34,6 +35,14 @@ public void setOverrideUrl(String overrideUrl){
this.overrideUrl = overrideUrl;
}

public void setPayload(String payload) {
this.payload = payload;
}

public String getPayload() {
return payload;
}

@Extension
public static class MultibranchDescriptor extends TriggerDescriptor {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.cloudbees.jenkins.plugins;

import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.EnvVars;
import hudson.Extension;
import hudson.model.*;
import jenkins.branch.MultiBranchProject;

import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Logger;

@Extension
public class BitbucketEnvironmentContributor extends EnvironmentContributor {
private static final Logger LOGGER = Logger.getLogger(BitbucketEnvironmentContributor.class.getName());

@Override
public void buildEnvironmentFor(@NonNull Run r, @NonNull EnvVars envs, @NonNull TaskListener listener) throws IOException, InterruptedException {
super.buildEnvironmentFor(r, envs, listener);
}

@SuppressWarnings("rawtypes")
@Override
public void buildEnvironmentFor(@NonNull Job j, @NonNull EnvVars envs, @NonNull TaskListener listener) throws IOException, InterruptedException {
super.buildEnvironmentFor(j, envs, listener);
ItemGroup parent = j.getParent();
AtomicReference<BitBucketMultibranchTrigger> bitBucketMultibranchTrigger = new AtomicReference<>(null);
if ( parent instanceof MultiBranchProject){
((MultiBranchProject<?, ?>) parent).getTriggers().forEach((triggerDescriptor, trigger) -> {
if ( trigger instanceof BitBucketMultibranchTrigger){
bitBucketMultibranchTrigger.set((BitBucketMultibranchTrigger) trigger);
}
});
}

if ( bitBucketMultibranchTrigger.get() != null){
if ( bitBucketMultibranchTrigger.get().getPayload() == null){
LOGGER.finest("BITBUCKET_PAYLOAD is null, ignoring");
} else {
envs.put("BITBUCKET_PAYLOAD", bitBucketMultibranchTrigger.get().getPayload());
}
}
}
}
32 changes: 30 additions & 2 deletions src/main/java/com/cloudbees/jenkins/plugins/BitbucketJobProbe.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.cloudbees.jenkins.plugins;

import hudson.model.CauseAction;
import hudson.model.Job;
import hudson.plugins.git.GitSCM;
import hudson.plugins.git.GitStatus;
Expand All @@ -12,6 +13,7 @@
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down Expand Up @@ -92,8 +94,34 @@ public void triggerMatchingJobs(String user, String url, String scm, String payl
for (SCMSource scmSource : scmSources) {
LOGGER.log(Level.FINER, "Considering candidate scmSource {0}", scmSource);
if (match(scmSource, remote)) {
LOGGER.log(Level.FINER, "Triggering BitBucket scmSourceOwner [{0}]", scmSourceOwner);
scmSourceOwner.onSCMSourceUpdated(scmSource);
if (scmSourceOwner instanceof WorkflowMultiBranchProject) {
LOGGER.finest("scmSourceOwner [" + scmSourceOwner.getName() + "] is of type WorkflowMultiBranchProject");
WorkflowMultiBranchProject workflowMultiBranchProject = (WorkflowMultiBranchProject) scmSourceOwner;
AtomicReference<BitBucketMultibranchTrigger> bitBucketMultibranchTrigger = new AtomicReference<>(null);
if ( workflowMultiBranchProject.getTriggers().isEmpty()) {
LOGGER.finest("No triggers found");
} else {
workflowMultiBranchProject.getTriggers().forEach(((triggerDescriptor, trigger) -> {
if (trigger instanceof BitBucketMultibranchTrigger) {
LOGGER.finest("Found BitBucketMultibranchTrigger type");
bitBucketMultibranchTrigger.set((BitBucketMultibranchTrigger) trigger);
}
}));
}
if ( bitBucketMultibranchTrigger.get() == null){
scmSourceOwner.onSCMSourceUpdated(scmSource);
} else {
if (workflowMultiBranchProject.isBuildable()){
bitBucketMultibranchTrigger.get().setPayload(payload);
BitBucketPushCause bitBucketPushCause = new BitBucketPushCause(user);
workflowMultiBranchProject.scheduleBuild2(0, new CauseAction(bitBucketPushCause));
} else {
LOGGER.finest("workflowMultiBranchProject is not builtable");
}
}
} else {
scmSourceOwner.onSCMSourceUpdated(scmSource);
}
} else if (scmSourceOwner instanceof WorkflowMultiBranchProject) {
LOGGER.finest("scmSourceOwner [" + scmSourceOwner.getName() + "] is of type WorkflowMultiBranchProject");
WorkflowMultiBranchProject workflowMultiBranchProject = (WorkflowMultiBranchProject) scmSourceOwner;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.cloudbees.jenkins.plugins;

import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.EnvVars;
import hudson.console.AnnotatedLargeText;
import hudson.model.*;
import jenkins.branch.BranchSource;
import jenkins.branch.MultiBranchProject;
import jenkins.plugins.git.GitSCMSource;
import jenkins.plugins.git.GitSampleRepoRule;
import jenkins.plugins.git.traits.BranchDiscoveryTrait;
import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.jvnet.hudson.test.JenkinsRule;
import org.junit.Rule;
import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

import static org.junit.Assert.*;


@SuppressWarnings({"rawtypes", "ResultOfMethodCallIgnored"})
public class BitbucketMultibranchTest {

@Rule
public JenkinsRule jenkinsRule = new JenkinsRule();

@Rule
public GitSampleRepoRule sampleRepo = new GitSampleRepoRule();


@Test
public void testWorkflowMultiBranchProject() throws Exception{
BitbucketEnvironmentContributor instance =
jenkinsRule.jenkins.getExtensionList(EnvironmentContributor.class).get(BitbucketEnvironmentContributor.class);
assertNotNull(instance);


// Initialize a Git repository
sampleRepo.init();
sampleRepo.write("Jenkinsfile", "pipeline { agent any; triggers { bitbucketPush } stages { stage('Build') { steps { echo 'Building...' } } } }");
sampleRepo.git("add", "Jenkinsfile");
sampleRepo.git("commit", "--message=Initial commit");

// Create a new WorkflowMultiBranchProject
WorkflowMultiBranchProject workflowMultiBranchProject = jenkinsRule.jenkins.createProject(WorkflowMultiBranchProject.class, "my-project");

// Add a GitSCMSource to the project
GitSCMSource gitSource = new GitSCMSource(sampleRepo.toString());
gitSource.getTraits().add(new BranchDiscoveryTrait());

workflowMultiBranchProject.getSourcesList().add(new BranchSource(gitSource));

// Schedule and find a branch project
WorkflowJob job = scheduleAndFindBranchProject(workflowMultiBranchProject);


// Get the last build and perform assertions
WorkflowRun build = job.getLastBuild();
assertNotNull(build);
assertEquals(1, build.getNumber());
jenkinsRule.assertBuildStatusSuccess(build);
jenkinsRule.assertLogContains("Branch indexing", build);
}

private static class Bla extends CauseAction implements EnvironmentContributingAction {

@Override
public void buildEnvironment(@NonNull Run<?, ?> run, @NonNull EnvVars env) {
EnvironmentContributingAction.super.buildEnvironment(run, env);
env.put("BITBUCKET_PAYLOAD", "checking_payload");
}
}

private WorkflowJob scheduleAndFindBranchProject(WorkflowMultiBranchProject workflowMultiBranchProject) throws Exception {

// Schedule indexing and wait for completion
Queue.Item queueItem = workflowMultiBranchProject.scheduleBuild2(0,
new CauseAction(new BitBucketPushCause("tzachs")), new Bla());

Queue.Executable executable = Objects.requireNonNull(queueItem).getFuture().get();
if ( executable instanceof MultiBranchProject.BranchIndexing){
MultiBranchProject.BranchIndexing branchIndexing = (MultiBranchProject.BranchIndexing) executable;
String multiBranchLog = getLog(branchIndexing.getLogText());
jenkinsRule.assertStringContains(multiBranchLog, "Starting branch indexing");
jenkinsRule.assertStringContains(multiBranchLog, "Started by BitBucket push by tzachs");
}
jenkinsRule.waitUntilNoActivity();

return workflowMultiBranchProject.getItem("master");

}

private String getLog(AnnotatedLargeText logText) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();

logText.writeLogTo(0, baos);

return baos.toString(StandardCharsets.UTF_8);
}
}

0 comments on commit 9b733c4

Please sign in to comment.