0

I am using a declarative pipeline in a Jenkinsfile but I would like to derive some variables from a parameter. For example given:

parameters {
   choice(name: 'Platform',choices: ['Debian9', 'CentOS7'], description: 'Target OS platform', )
}

I would like to add a block like:

script {
  switch(param.Platform) {
     case "Centos7":
         def DockerFile = 'src/main/docker/Jenkins-Centos.Dockerfile'
         def PackageType = 'RPM'
         def PackageSuffix = '.rpm'
         break
     case "Debian9":
     default:
         def DockerFile = 'src/main/docker/Jenkins-Debian.Dockerfile'
         def PackageType = 'DEB'
         def PackageSuffix = '.deb'
         break
  }
}

Such that I can use variables elsewhere in the pipeline. For example:

agent { 
   dockerfile {
       filename "$DockerFile"
   }
}

etc..

but script is illegal in the parameter, environment & agent sections. It can only be used in steps.

I need to use the parameter in the agent block and I want to avoid repeating myself where the variables are used in different steps.

Is there a sane way to achieve this? My preferences in order are:

  • a declarative pipeline
  • a scripted pipeline (less good)
  • via a plugin to the Jenkins UI (least good)

A shared library might be appropriate here regardless of whether it is actually shared.

The intention is to support a multi-configuration project by creating a parameterised build and invoking it for different parameter sets with a red/blue status light for each configuration. It could be that I have assumed an 'old fashioned' design. In which case an acceptable answer would explain the modern best practice for creating a multi-configuration multi-branch pipeline. Something like: https://support.cloudbees.com/hc/en-us/articles/115000088431-Create-a-Matrix-like-flow-with-Pipeline or Jenkins Pipeline Multiconfiguration Project

See also Multiconfiguration / matrix build pipeline in Jenkins for less specific discussion of best practices.

Bruce Adams
  • 4,953
  • 4
  • 48
  • 111

4 Answers4

1

Never really used the Jenkins declarative pipeline before but I think the way you refer to params is incorrect?

I think it might be: ${params.Platform} or params.Platform instead of param.

So something like the below maybe?

pipeline {
    agent any
    stages {
        stage('example') {
            steps {
                script {
                    switch(${params.Platform}) {
                        ...
                    }
                }
            }
        }
    }
}

As I said, never really used it before so not 100%. I was just looking at the syntax used for parameters on the docs: https://jenkins.io/doc/book/pipeline/syntax/#parameters

hhami
  • 176
  • 10
  • The issue is not the syntax for the switch (which is down to me being new to groovy) but where I can put it. I need the parameter for the agent block. Is a script block legal there? – Bruce Adams May 08 '19 at 09:18
  • I see. I didn't realise that was your issue. Is there a need for your parameters to have the numbers in them? For example, something like this may work: `filename "src/main/docker/Jenkins-$Platform.Dockerfile"` if you change the parameter to only allow options of "Debian" and "Centos". – hhami May 09 '19 at 10:07
0

I think that the key for solving your issue is the declaration of your variables. Do not use def if you want your variable to be accessible from other stages.

Here is an example of a solution for your issue :

pipeline{
    agent none
    parameters {
        choice(name: 'Platform',choices: ['Debian9', 'CentOS7'], description: 'Target OS platform', )
    }
    stages{
        stage('Setting stage'){
            agent any
            steps {
                script {
                    switch(params.Platform){
                        case 'CentOS7' :
                            DockerFile = 'src/main/docker/Jenkins-Centos.Dockerfile'
                            PackageType = 'RPM'
                            PackageSuffix = '.rpm'
                            break
                        case 'Debian9' :
                            DockerFile = 'src/main/docker/Jenkins-Debian.Dockerfile'
                            PackageType = 'DEB'
                            PackageSuffix = '.deb'
                            break
                    }
                }
            }
        }
        stage('Echo stage'){
            agent { 
                dockerfile {
                    filename "$DockerFile"
                }
            }
            steps{
                echo PackageType
                echo PackageSuffix
            }
        }
    }
}
SmartTom
  • 691
  • 7
  • 14
0

What is definitely possible on windows:

stage('var from groovy') {
    steps {
        script {
             anvar = "foo"
        }

        bat "${anyvar}"
    }
}
Nikolai Ehrhardt
  • 570
  • 4
  • 14
-1

This is an example that I have in production

def dest_app_instance = "${params.Destination}"

switch(dest_app_instance) {
  case "CASE1":
    dest_server = "server1"
    break
  case "CASE2":
    dest_server = "server2"
    break 
}
Adam vonNieda
  • 1,635
  • 2
  • 14
  • 22