From b1fa0c9a2ec195306312218c1a4277200f3876d3 Mon Sep 17 00:00:00 2001 From: s78258819-svg Date: Fri, 29 Aug 2025 06:26:48 -0400 Subject: [PATCH 1/9] Added functionality for Multibranch Scan Functionality added to trigger a Jenkins Multibranch scan when a branch is added or deleted in bitbucket. --- .../BitBucketPPRJobProbe.java | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/BitBucketPPRJobProbe.java b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/BitBucketPPRJobProbe.java index 7c65edde..e7e794ba 100644 --- a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/BitBucketPPRJobProbe.java +++ b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/BitBucketPPRJobProbe.java @@ -21,11 +21,6 @@ package io.jenkins.plugins.bitbucketpushandpullrequest; -import static io.jenkins.plugins.bitbucketpushandpullrequest.common.BitBucketPPRConst.PULL_REQUEST_MERGED; -import static io.jenkins.plugins.bitbucketpushandpullrequest.common.BitBucketPPRConst.PULL_REQUEST_SERVER_MERGED; -import static io.jenkins.plugins.bitbucketpushandpullrequest.common.BitBucketPPRConst.REPOSITORY_CLOUD_PUSH; -import static io.jenkins.plugins.bitbucketpushandpullrequest.common.BitBucketPPRConst.REPOSITORY_SERVER_PUSH; - import hudson.model.Job; import hudson.plugins.git.GitSCM; import hudson.plugins.git.GitStatus; @@ -53,6 +48,9 @@ import jenkins.model.ParameterizedJobMixIn; import jenkins.triggers.SCMTriggerItem; import org.eclipse.jgit.transport.URIish; +import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject; + +import static io.jenkins.plugins.bitbucketpushandpullrequest.common.BitBucketPPRConst.*; /** * @@ -152,6 +150,8 @@ private void triggerScm(@Nonnull Job job, List remotes, jobTrigger.scmTriggerItem.ifPresent(it -> it.getSCMs().forEach(scm -> { + triggerMultibranchScan(job, bitbucketAction); + // @todo add comments to explain what is this check for if (job.getParent() instanceof MultiBranchProject && mPJobShouldNotBeTriggered(job, bitbucketEvent, bitbucketAction)) { @@ -244,4 +244,36 @@ private boolean matchGitScm(SCM scm, URIish remote) { .anyMatch((repo) -> repo.getURIs().stream().anyMatch((repoUrl) -> GitStatus.looselyMatches(repoUrl, remote))); } + private void triggerMultibranchScan(@Nonnull Job job, + BitBucketPPRAction bitbucketAction) { + + String getLatestCommit = bitbucketAction.getLatestCommit(); + String getLatestFromCommit = bitbucketAction.getLatestFromCommit(); + String pipelineName = job.getParent().getFullName(); + String getPayldChgType = bitbucketAction.getPayloadChangeType(); + + logger.log(Level.INFO, + "Pipeline Name : {0}, To Hash : {1}, From Hash : {2}, Payload Change Type : {3}", + new String[] {pipelineName, getLatestCommit, getLatestFromCommit, getPayldChgType}); + + if ((getLatestFromCommit.equals(EMPTY_HASH) && PAYLOAD_CHANGE_TYPE_ADD.equals(getPayldChgType)) || + (getLatestCommit.equals(EMPTY_HASH) && PAYLOAD_CHANGE_TYPE_DELETE.equals(getPayldChgType))) { + + Jenkins jenkins = Jenkins.get(); + + WorkflowMultiBranchProject mbp = (WorkflowMultiBranchProject) jenkins.getItemByFullName(pipelineName); + + if (mbp != null) { + mbp.scheduleBuild2(0); + + logger.log(Level.INFO, + "Triggered branch indexing for: {0}", + new String[] { pipelineName }); + } else { + logger.log(Level.WARNING, + "Multibranch job not found: {0}", + new String[] { pipelineName }); + } + } + } } From 830ec3f8b602c9cfbebe5d5dc86dcbfa4a95ffc3 Mon Sep 17 00:00:00 2001 From: s78258819-svg Date: Fri, 29 Aug 2025 06:30:34 -0400 Subject: [PATCH 2/9] Added functions for data capture Added a function to capture both the from Hash and change type items that are inside of the payload received from Bitbucket --- .../action/BitBucketPPRAction.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRAction.java b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRAction.java index eb65e6dc..31beb8ad 100644 --- a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRAction.java +++ b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRAction.java @@ -141,4 +141,8 @@ default String getLatestCommitFromRef() { default String getLatestCommitToRef() { return null; } + + default String getLatestFromCommit() { return null; } + + default String getPayloadChangeType() { return null; } } From 631004c363df1b7f710263c56cc8c1a74afc1261 Mon Sep 17 00:00:00 2001 From: s78258819-svg Date: Fri, 29 Aug 2025 06:33:42 -0400 Subject: [PATCH 3/9] Added full functions for payload data Functions added get the from hash and change type items from the Bitbucket payload --- .../BitBucketPPRServerRepositoryAction.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRServerRepositoryAction.java b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRServerRepositoryAction.java index fcc1e323..c7fc5eb1 100644 --- a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRServerRepositoryAction.java +++ b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRServerRepositoryAction.java @@ -186,4 +186,24 @@ public List getCommitLinks() throws MalformedURLException { private String getBaseUrl() { return baseUrl.getProtocol() + "://" + baseUrl.getHost() + ":" + baseUrl.getPort(); } + + @Override + public String getLatestFromCommit() { + for (BitBucketPPRServerChange change : payload.getServerChanges()) { + if(change.getRefId() != null) { + return change.getFromHash(); + } + } + return null; + } + + @Override + public String getPayloadChangeType() { + for (BitBucketPPRServerChange change : payload.getServerChanges()) { + if(change.getRefId() != null) { + return change.getType(); + } + } + return null; + } } From f81501bc7f9e32e52af0a35a6e44ed76019131a0 Mon Sep 17 00:00:00 2001 From: s78258819-svg Date: Fri, 29 Aug 2025 06:36:49 -0400 Subject: [PATCH 4/9] Added constant variables Added constant variables for the change type values along with the value of an empty hash. These are used to determine when a branch is being added or deleted. --- .../bitbucketpushandpullrequest/common/BitBucketPPRConst.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/common/BitBucketPPRConst.java b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/common/BitBucketPPRConst.java index ada053b8..e0e35e09 100644 --- a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/common/BitBucketPPRConst.java +++ b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/common/BitBucketPPRConst.java @@ -61,6 +61,10 @@ public final class BitBucketPPRConst { public static final String APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded"; + public static final String PAYLOAD_CHANGE_TYPE_ADD = "ADD"; + public static final String PAYLOAD_CHANGE_TYPE_DELETE = "DELETE"; + public static final String EMPTY_HASH = "0000000000000000000000000000000000000000"; + private BitBucketPPRConst() { throw new AssertionError(); } From fe10aac28c1d0072910388d61b839a1f9716dffc Mon Sep 17 00:00:00 2001 From: s78258819-svg Date: Fri, 29 Aug 2025 06:44:06 -0400 Subject: [PATCH 5/9] Update repository URL Updating the plugin repository to have the correct URL for a successful Maven Build --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 16cbfcd4..01175073 100644 --- a/pom.xml +++ b/pom.xml @@ -212,13 +212,13 @@ repo.jenkins-ci.org - https://repo.jenkins.io/public/ + https://repo.jenkins-ci.org/public/ repo.jenkins-ci.org - https://repo.jenkins.io/public/ + https://repo.jenkins-ci.org/public/ From 22760a000d2729242b676312d4e69ce17a690d78 Mon Sep 17 00:00:00 2001 From: s78258819-svg Date: Fri, 5 Sep 2025 07:13:58 -0400 Subject: [PATCH 6/9] Update Logic for Multibranch Pipeline Scan Trigger Previously when triggering the scan it was done so for all pipelines. New logic ensures that it only occurs for the repo captured from the payload if it matches the branch source specified in the multibranch pipeline --- .../BitBucketPPRJobProbe.java | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/BitBucketPPRJobProbe.java b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/BitBucketPPRJobProbe.java index e7e794ba..f0c66eaf 100644 --- a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/BitBucketPPRJobProbe.java +++ b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/BitBucketPPRJobProbe.java @@ -49,6 +49,8 @@ import jenkins.triggers.SCMTriggerItem; import org.eclipse.jgit.transport.URIish; import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject; +import jenkins.branch.BranchSource; +import jenkins.scm.api.SCMSource; import static io.jenkins.plugins.bitbucketpushandpullrequest.common.BitBucketPPRConst.*; @@ -252,23 +254,44 @@ private void triggerMultibranchScan(@Nonnull Job job, String pipelineName = job.getParent().getFullName(); String getPayldChgType = bitbucketAction.getPayloadChangeType(); - logger.log(Level.INFO, - "Pipeline Name : {0}, To Hash : {1}, From Hash : {2}, Payload Change Type : {3}", - new String[] {pipelineName, getLatestCommit, getLatestFromCommit, getPayldChgType}); - if ((getLatestFromCommit.equals(EMPTY_HASH) && PAYLOAD_CHANGE_TYPE_ADD.equals(getPayldChgType)) || (getLatestCommit.equals(EMPTY_HASH) && PAYLOAD_CHANGE_TYPE_DELETE.equals(getPayldChgType))) { Jenkins jenkins = Jenkins.get(); - WorkflowMultiBranchProject mbp = (WorkflowMultiBranchProject) jenkins.getItemByFullName(pipelineName); + WorkflowMultiBranchProject mbp = jenkins.getInstance().getItemByFullName(pipelineName, WorkflowMultiBranchProject.class); if (mbp != null) { - mbp.scheduleBuild2(0); + for (BranchSource bs : mbp.getSourcesList()) { + SCMSource src = bs.getSource(); + String getOPT1CloneUrl = bitbucketAction.getOPT1CloneUrl(); + String getOPT2CloneUrl = bitbucketAction.getOPT2CloneUrl(); + + logger.log(Level.FINEST, + "Source Type: {0}", + new String[] { src.getDescriptor().getDisplayName() }); + + if (src instanceof jenkins.plugins.git.GitSCMSource) { + jenkins.plugins.git.GitSCMSource git = (jenkins.plugins.git.GitSCMSource) src; + String gitRemote = git.getRemote(); + + logger.log(Level.FINEST, + "Branch Source URL: {0}", + new String[] { gitRemote }); + + if (gitRemote.equals(getOPT1CloneUrl) || gitRemote.equals(getOPT2CloneUrl)) { + logger.log(Level.FINEST, + "Branch Source URL: {0}, getOPT1CloneUrl: {1}, getOPT2CloneUrl: {2}", + new String[] { gitRemote, getOPT1CloneUrl, getOPT2CloneUrl }); + + mbp.scheduleBuild2(0); - logger.log(Level.INFO, + logger.log(Level.INFO, "Triggered branch indexing for: {0}", new String[] { pipelineName }); + } + } + } } else { logger.log(Level.WARNING, "Multibranch job not found: {0}", From d841e5683ae09386160377b7a3eceaac3d5ed929 Mon Sep 17 00:00:00 2001 From: s78258819-svg Date: Fri, 5 Sep 2025 07:17:16 -0400 Subject: [PATCH 7/9] Adding functions to pull clone links from payload Functiions have been added to pull http and ssh clone links from bitbucket payload --- .../action/BitBucketPPRAction.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRAction.java b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRAction.java index 31beb8ad..d98a1c2d 100644 --- a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRAction.java +++ b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRAction.java @@ -145,4 +145,8 @@ default String getLatestCommitToRef() { default String getLatestFromCommit() { return null; } default String getPayloadChangeType() { return null; } + + default String getOPT1CloneUrl() { return null; } + + default String getOPT2CloneUrl() { return null; } } From 8bf993adf49102814c4a74ec5b4b3bb9163d27a0 Mon Sep 17 00:00:00 2001 From: s78258819-svg Date: Fri, 5 Sep 2025 07:20:51 -0400 Subject: [PATCH 8/9] Added functions for capturing clone links Added Functions to pull the SSH and HTTP clone links from the Bitbucket payload --- .../action/BitBucketPPRServerRepositoryAction.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRServerRepositoryAction.java b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRServerRepositoryAction.java index c7fc5eb1..0c17cbac 100644 --- a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRServerRepositoryAction.java +++ b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/action/BitBucketPPRServerRepositoryAction.java @@ -206,4 +206,14 @@ public String getPayloadChangeType() { } return null; } + + @Override + public String getOPT1CloneUrl() { + return payload.getServerRepository().getLinks().getCloneProperty().get(0).getHref(); + } + + @Override + public String getOPT2CloneUrl() { + return payload.getServerRepository().getLinks().getCloneProperty().get(1).getHref(); + } } From 7495fed659393de94dd9ae6321d9e33975e462dd Mon Sep 17 00:00:00 2001 From: s78258819-svg Date: Wed, 1 Oct 2025 07:34:31 -0400 Subject: [PATCH 9/9] Update BitBucketPPRJobProbe.java Ran into null pointer issue causing issues with other triggers. Updates made to resolve null pointer occurrence. --- .../BitBucketPPRJobProbe.java | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/BitBucketPPRJobProbe.java b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/BitBucketPPRJobProbe.java index f0c66eaf..f000c7f7 100644 --- a/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/BitBucketPPRJobProbe.java +++ b/src/main/java/io/jenkins/plugins/bitbucketpushandpullrequest/BitBucketPPRJobProbe.java @@ -254,49 +254,51 @@ private void triggerMultibranchScan(@Nonnull Job job, String pipelineName = job.getParent().getFullName(); String getPayldChgType = bitbucketAction.getPayloadChangeType(); - if ((getLatestFromCommit.equals(EMPTY_HASH) && PAYLOAD_CHANGE_TYPE_ADD.equals(getPayldChgType)) || - (getLatestCommit.equals(EMPTY_HASH) && PAYLOAD_CHANGE_TYPE_DELETE.equals(getPayldChgType))) { + if ((getLatestCommit != null) && (getLatestFromCommit != null) && (pipelineName != null) && (getPayldChgType != null)) { + if ((getLatestFromCommit.equals(EMPTY_HASH) && PAYLOAD_CHANGE_TYPE_ADD.equals(getPayldChgType)) || + (getLatestCommit.equals(EMPTY_HASH) && PAYLOAD_CHANGE_TYPE_DELETE.equals(getPayldChgType))) { - Jenkins jenkins = Jenkins.get(); + Jenkins jenkins = Jenkins.get(); - WorkflowMultiBranchProject mbp = jenkins.getInstance().getItemByFullName(pipelineName, WorkflowMultiBranchProject.class); + WorkflowMultiBranchProject mbp = jenkins.getInstance().getItemByFullName(pipelineName, WorkflowMultiBranchProject.class); - if (mbp != null) { - for (BranchSource bs : mbp.getSourcesList()) { - SCMSource src = bs.getSource(); - String getOPT1CloneUrl = bitbucketAction.getOPT1CloneUrl(); - String getOPT2CloneUrl = bitbucketAction.getOPT2CloneUrl(); + if (mbp != null) { + for (BranchSource bs : mbp.getSourcesList()) { + SCMSource src = bs.getSource(); + String getOPT1CloneUrl = bitbucketAction.getOPT1CloneUrl(); + String getOPT2CloneUrl = bitbucketAction.getOPT2CloneUrl(); - logger.log(Level.FINEST, + logger.log(Level.FINEST, "Source Type: {0}", new String[] { src.getDescriptor().getDisplayName() }); - if (src instanceof jenkins.plugins.git.GitSCMSource) { - jenkins.plugins.git.GitSCMSource git = (jenkins.plugins.git.GitSCMSource) src; - String gitRemote = git.getRemote(); + if (src instanceof jenkins.plugins.git.GitSCMSource) { + jenkins.plugins.git.GitSCMSource git = (jenkins.plugins.git.GitSCMSource) src; + String gitRemote = git.getRemote(); - logger.log(Level.FINEST, + logger.log(Level.FINEST, "Branch Source URL: {0}", new String[] { gitRemote }); - if (gitRemote.equals(getOPT1CloneUrl) || gitRemote.equals(getOPT2CloneUrl)) { - logger.log(Level.FINEST, + if (gitRemote.equals(getOPT1CloneUrl) || gitRemote.equals(getOPT2CloneUrl)) { + logger.log(Level.FINEST, "Branch Source URL: {0}, getOPT1CloneUrl: {1}, getOPT2CloneUrl: {2}", new String[] { gitRemote, getOPT1CloneUrl, getOPT2CloneUrl }); - mbp.scheduleBuild2(0); + mbp.scheduleBuild2(0); - logger.log(Level.INFO, + logger.log(Level.INFO, "Triggered branch indexing for: {0}", new String[] { pipelineName }); + } } } - } - } else { - logger.log(Level.WARNING, + } else { + logger.log(Level.WARNING, "Multibranch job not found: {0}", new String[] { pipelineName }); - } + } + } } } }