3
votes

We're trying to write a declarative Jenkinsfile build script to run several steps in parallel in each of several stages, however we need to prevent multiple builds from running at the same time because they depend on the same resource. Hence, we've tried to use locking to lock all of the stages such that a build can finish completely before another one attempts to use the same resources.

However, we've found that locking stages requires nesting the stages in a parent and that parallel steps can only be included in a top-level stage: WorkflowScript: 24: Parallel stages or branches can only be included in a top-level stage

Essentially what we're trying to do is this:

#!/usr/bin/env groovy

pipeline {
    agent any

    stages {
        stage('parent') {
            options {
                lock('resource')
            }
            stages {
                stage('build') {
                    steps {
                        parallel( 
                            'app1': { build("app1") },
                            'app2': { build("app2") },
                        )
                    }
                }

                stage('deploy') {
                    steps {
                        parallel(
                            'app1': { deploy("app1") },
                            'app2': { deploy("app2") },
                        )
                    }
                }
            }
        }
    }
}

Are there any workarounds to achieve this behaviour?

1

1 Answers

2
votes

Does this fix your problem?

pipeline {
    agent any
    options {
        lock('resource')
    }
    stages {
        stage('build') {
            parallel {
                stage('app1') {
                    steps {
                        echo("build app1")
                    }
                }
                stage('app2') {
                    steps {
                        echo("build app2") 
                    }
                }
            }
        }
        stage('deploy') {
            parallel {
                stage('app1') {
                    steps {
                        echo("deploy app1")
                    }
                }
                stage('app2') {
                    steps {
                        echo("deploy app2") 
                    }
                }
            }
        }
    }
}

You might need to update to the latest pipeline code This locks the resource for the whole job. If you want to lock the resource for each of the parallel stages, I would suggest the stages are not parallel