Update: Thanks to Torben Kerr for adding instructions for setting up these properties at the multibranch build level rather then for each Jenkinsfile. You can check out his “fix” here.
As the Jenkins pipeline functionality continues to rapidly evolve – the project documentation (or lack thereof), has been a consistent pain point as a user. Invariably, the documentation is either out of date or completely missing. I expect the docs to improve as the project matures, but for now, the cake is a lie. I ran into this roadblock recently, looking for a way to limit the number of concurrent builds that happen in Jenkins, using the pipeline. In all of my anguish, I hope this post will help others in avoiding the tediousness of finding the seemingly simple functionality of limiting concurrent builds, as well as give some insight into strategies for figuring out how to find undocumented features in Jenkins.
While this feature is fairly obvious for old-style Jenkins jobs, a simple check box in the job configuration – finding the same functionality for pipelines is seemingly non existent. Through extensive Googling and Stack Overflowing, I discovered this feature was recently added to the Multibranch plugin. Specifically, I found an issue in the (awful) issue tracker used by Jenkins, which in turn led me to uncover some code in a semi recent PR that basically allows concurrency to be turned on or off. Of course when I tried to use the code from the PR it didn’t work right away. So I had to go deeper.
Eventually, I stumbled across a SO post that discusses how to use the properties functionality of pipelines. Equipped with this new piece of information, I finally had enough substance to start playing around with the code. To make the creation of pipelines easier, Jenkins also recently added a snippet generator, which allows users to build out sample snippets quickly.
To use the snippet generator, either drill into an existing pipeline style job using a similar URL as below:
https://jenkins.example.com/job/<jobname>/pipeline-syntax/
Or create a new job, and click on the “Pipeline Syntax” link after it has been created to test out different snippets.
Inside the snippet generator there are a number of “steps” to choose from. From the information I had already gathered, I just selected the properties step to create the basic skeleton of what I wanted and was able to use the disableConcurrentBuilds() function I found earlier. Below is a snippet of what the code in your Jenkinsfile might actually look like:
node { // This oneliner is what limits concurrent builds properties([disableConcurrentBuilds()]) // Do stuff ... }
Yep. That’s it. Just make sure to put the properties() function at the beginning of the node block, otherwise concurrency won’t be adjusted right away and could lead to problems. Another thing to note; the step to disable concurrency could just as easily be moved into workflow libraries and applied at the global level and applied at the beginning of all jobs if you wanted to limit concurrency for all pipeline builds, since the code is just Groovy. Finally, the code will disable concurrent builds on a per branch basis. Essentially, if you push many different branches it will still build all of them, it will just limit each branch to one build at a time and will queue up jobs for any commits that get pushed after the initial job has been created. I know that is a mouthful. Let me know in the comments if this explanation needs any clarification.
While I love open source software, sometimes project’s move so fast that certain areas of it get neglected. I am thankful for things like Github, because I was able use it to piece together all the other information I found to come up with a solution. But, I would argue having good documentation not only saves folks like me the time and energy of the crazy searches, it also makes it much easier for potentially new users to look at, and understand what is going on. I will be 100% honest and say that Jenkins pipelines are not for the faint of heart, and I’m sure there are many others who will agree with this sentiment. I know it is easier said than done, but anything right now would be an improvement in my opinion.