1
votes

I have a Jenkins Pipeline Library method called branchExists.groovy that checks if a branch exists in a remote (not local!) repository.

This is the code:

#!/usr/bin/env groovy

def call(String repoUrl, String branchName) {
    // Use git ls-remote to verify branch existence
    def sout = sh(returnStdout: true, script: "#!/bin/bash\ngit ls-remote --heads ${repoUrl} refs/heads/${branchName}").trim()
    return sout.size() != 0
}

So, as you can see, a Bash shell is started to run the command git ls-remote. To run a shell, the method must run inside the context of a node{} block in the Pipeline, even if I don't do anything else on that node.

Is there a way in Jenkins Pipeline parlance, to check remote branches without needing to run a shell command, and thereby not making it necessary to occupy a node{}?

EDIT: maybe it's good to know that the Git server is Atlassian Bitbucket Server, so maybe I could use the Bitbucket API? Or would that still require a node?


Why do I want to avoid occupying a node?

The reason why I am concerned about not occupying a node, is because of flyweight/lightweight vs heavyweight executors. See https://support.cloudbees.com/hc/en-us/articles/360012808951-Pipeline-Difference-between-flyweight-and-heavyweight-Executors

Flyweight executors are just threads, running inside of the Jenkins master’s JVM. Flyweight executors are unlimited and will be created automatically when needed, unlike heavyweight executors, which are limited based on their node’s configuration.

Every Pipeline script itself runs on the master using a flyweight executor (i.e. Java thread). Pipeline steps such as sh and bat will execute on a heavyweight executor when enclosed in a node block, so in a well-designed Pipeline where complicated logic happens only in those steps, the flyweight executor should be idling while steps run on remote agents for most of the build.

Flyweight executors won't block the build queue and won't be blocked by the build queue. If all heavyweight executors are saturated then my pipeline won't continue until an executor becomes available to run git ls-remote.

1
My understanding is that all the sh commands are ran on Master anyway, so in order to keep my resources to the minimum I would make a dedicated (container) slave for trivial commands. As alternative node('master') would force the whole execution on master - but this is not always a good idea. - Iftimie Tudor
It's not just about running on "master" (Jenkins please get rid of that racially charged word ASAP!), it's also that, as long as your code doesn't run on a node, it runs in a so-called "lightweight executor", which means that it isn't blocking other jobs in the build queue AND if all executors are taken by other jobs, the pipeline won't continue until an executor becomes available. - Amedee Van Gasse
Thank you for the explanation ! It seems that I cannot edit my comment to replace the old Jenkins terminology. :( - Iftimie Tudor
Don't worry, my comment between brackets wasn't aimed at you. :) - Amedee Van Gasse

1 Answers

0
votes

As far as I can find, the answer is no. I can't find anything in Jenkins itself that might provide the functionality.

Even if you were to try talking to the BitBucket API, you would still need a node to handle that communication.

The only way that I think you might be able to achieve the functionality you're looking for would be to write a custom Java or Groovy library that you could incorporate into your Jenkinsfile that would either talk to git natively through a library like JGit or talk to BitBucket natively like bitbucket-rest.