DEV Community

Aleksander
Aleksander

Posted on

Generating parallel stages in Jenkinsfile according to passed parameters

Let's say that you have an app that you want to test with different versions of Oracle DB.

Sometimes you want to run tests for given pairs. Sometimes for one, sometimes for a few, sometimes for all.

  • version A of your app with Oracle 11
  • version A of your app with Oracle 12
  • version B of your app with Oracle 11
  • and so on

You can create different pipelines for different cases, but why not make it easier?

Here we will create a declarative pipeline that will run different jobs depending on the selected parameters.

1. We need to decide how we will pass parameters

For our use-case the easiest way would be to use booleanParam

    parameters {
        booleanParam(defaultValue: false, name: "oracle11a", description: "Oracle 11 + App Version A")
        booleanParam(defaultValue: false, name: "oracle12a", description: "Oracle 12 + App Version A")
        booleanParam(defaultValue: false, name: "oracle11b", description: "Oracle 11 + App Version B")
...
    }
Enter fullscreen mode Exit fullscreen mode

Why booleanParam? Because all parameters in Jenkinsfile are stored as a map. So, our key in that map would be the name of the parameter and the value will be true or false (depending on did we select it or not in the UI)

2. We need to store additional information about our test cases.

Above the pipeline {...} we will create a map with parameters that we will need.

useful_map = [:]

def populate_useful_map() {
    useful_map["oracle11a"] = ["oracle11", "appVersionA"]
    useful_map["oracle12a"] = ["oracle12", "appVersionA"]
    useful_map["oracle11b"] = ["oracle11", "appVersionB"]
    ...
}
Enter fullscreen mode Exit fullscreen mode

Here we create and populate our map of parameters that we want to have to pass to another job/test script/etc.

3. We will create all stages that we will want to run

So, for each parameter, if it was selected on the UI we will get values from the useful_map and create a stage with a call to another job defined in Jenkins which will run tests with given versions of DB and our application.

params.each { key, value ->
   if (value) {
      def oracle_db = useful_map[key][0];
      def app_version = useful_map[key][1];
      stages_to_run["${oracle_db} + ${app_version}"] =
        {stage("${oracle_db} + ${app_version}") {
          build(job: "pipeline-to-run-our-tests", 
                propagate: true,
                parameters: [
    string(name: 'ORACLE_DB_VERSION', value: "${oracle_db}"),
    string(name: 'APP_VERSION', value: "${app_version}")
                ])
        }
    }
Enter fullscreen mode Exit fullscreen mode

4. We want to run all the job created in parallel

All work is done, now we just need to pass stages_to_run that we created in step 3 to parallel function

stage('In parallel') {
            steps {
                script {
                    parallel stages_to_run
                }
            }
        }
Enter fullscreen mode Exit fullscreen mode

Discussion (0)