8

Does Jenkins provide any functionality to achieve the following pipeline described below?

pipeline
{
    agent any
    options
    {
        when {
            branch 'master'
        }
        disableConcurrentBuilds()
    }
    stages { ... }
}

I have two states for repositories which this single pipeline must manage:

  1. Build for commits to merge-requests branches (pre-merge), allow builds to be run concurrently
  2. Build the master branch on merge of merge-requests (post-merge), do not allow builds to be run concurrently.
Sean Pianka
  • 2,157
  • 2
  • 27
  • 43

2 Answers2

3

You can use the Lockable Resources Plugin to guarantee that the problematic steps do not run in parallel when on the master branch.

Something like:

stage('on master') {
    when {
        branch 'master'
    }
    steps {
        lock(label: 'choose_a_label') {
            // your steps
        }
    }
}


stage('not on master') {
    when {
        not {
            branch 'master'
        }
    }
    steps {
        // your steps
    }
}
Chadi
  • 737
  • 1
  • 6
  • 21
  • 1
    Unlike `disableConcurrentBuilds()`, this approach will consume a node "seat" while it waits. I would only use it as a last resort. – Glenn Lane Jun 14 '23 at 18:53
2

@Chadi's answer is certainly correct and the Lockable Resources Plugin seems the only easy workaround as for now. The Jenkins documentation(Example 22. beforeOptions) shows an example that is very similar to what you want to do. Here another possible solution (not tested):

pipeline {
    agent none
    stages {
        stage('build') {
            stages {
                stage('on master') {
                    when {
                        beforeOptions true
                        branch 'master'
                    }
                    options {
                        lock label: 'master_build'
                    }
                    steps {
                        ...
                    }
                }
                stage('not on master') {
                    when {
                        not {
                            branch 'master'
                        }
                    }
                    steps {
                        ...
                    }
                }
            }
        }
    }
}

I have used nested stages to group them in the same stage but it is not mandatory, of course. The benefit I see are:

  • Locking now belongs to the stage options and the steps declaration contains steps and nothing else
  • The whole stage is locked and you do not risk to put some statements outside of the lock block
  • Personally, too many indentation levels reduce the readability, so if I can get rid of even one of them I am more than happy to do it.

The disadvantage is that you have to add a couple of lines and the beforeOptions, necessary to evaluate the when condition before options.

Marco Luzzara
  • 5,540
  • 3
  • 16
  • 42