0

I have set some environment variables as below :

environment {
      IMG_TARGET = "registry/cloud-environemnt-azu:1.x.x"
      CREDENTIALS = 'credentials-token'
      BUILD_DIR = 'Builddir'
      DOMAIN_DIR = 'Domaindir'
      BUILD_SOLUTION = 'Dir.Builddir.sln'
   }

Some variables are used throughout the Jenkins pipeline and I am looking to separate them from environment variables, such that only credentials and image target are in environment variables.

Is there a way I can use global list/variable/map to store non-environment variables, like :

List<String> variables = [
      BUILD_DIR = 'Builddir'
      DOMAIN_DIR = 'Domaindir'
      BUILD_SOLUTION = 'Dir.Builddir.sln'
   ]

If so, how can I refer a variable from this list? The variables are being referenced across multiple stages in the pipeline

s_neenu
  • 95
  • 2
  • 7

2 Answers2

0

You can have an environment section for your pipeline and if needed, within each stage define a new environment section to override exisiting variables or define new ones. Example:

pipeline {
    agent any

    environment {
        FOO = "bar"
        NAME = "Joe"
    }

    stages {
        stage("Env Variables") {
            environment {
                NAME = "Alan" // overrides pipeline level NAME env variable
                BUILD_NUMBER = "2" // overrides the default BUILD_NUMBER
            }

            steps {
                echo "FOO = ${env.FOO}" // prints "FOO = bar"
                echo "NAME = ${env.NAME}" // prints "NAME = Alan"
                echo "BUILD_NUMBER =  ${env.BUILD_NUMBER}" // prints "BUILD_NUMBER = 2"

                script {
                    env.SOMETHING = "1" // creates env.SOMETHING variable
                }
            }
        }

        stage("Override Variables") {
            steps {
                script {
                    env.FOO = "IT DOES NOT WORK!" // it can't override env.FOO declared at the pipeline (or stage) level
                    env.SOMETHING = "2" // it can override env variable created imperatively
                }

                echo "FOO = ${env.FOO}" // prints "FOO = bar"
                echo "SOMETHING = ${env.SOMETHING}" // prints "SOMETHING = 2"

                withEnv(["FOO=foobar"]) { // it can override any env variable
                    echo "FOO = ${env.FOO}" // prints "FOO = foobar"
                }

                withEnv(["BUILD_NUMBER=1"]) {
                    echo "BUILD_NUMBER = ${env.BUILD_NUMBER}" // prints "BUILD_NUMBER = 1"
                }
            }
        }
    }
}
 

Another option is to use parameterised jobs in declarative pipelines and if you're interested, you can read more here.

farzado
  • 71
  • 3
  • Thanks, this looks right. But the variables are being across multiple stages, can I try something with a private static final map, holding all the variables? – s_neenu Aug 18 '20 at 15:25
  • 1
    As far as I know, that's not an option. – farzado Aug 19 '20 at 01:50
0

You can set environment variable specific to each stage by including environment block within the stage like below.

pipeline {
    agent any
    stages {
        stage ("Test Stage"){
           environment {
              TEST_VARIABLE=test
           }
           steps {
             echo "Hello"
           }
        }
    }
}

If you want all non environment variable into single component then you can use map instead of List, as map will store the data in key value pair and you can retrieve any key at any point of time, with List you cannot store the value as a key value pair.

pipeline {
    agent any
    stages {
        stage ("Test Stage"){
            steps {
                script {
                    def testMap = [BUILD_DIR:'Builddir',DOMAIN_DIR:'Domaindir',BUILD_SOLUTION:'Dir.Builddir.sln']
                    testMap.each {
                        entry -> echo "${entry.key}"
                    }
                    echo "${testMap['DOMAIN_DIR']}"
                }
            }
        }
    }
}

Thanks,

Kiruba
  • 1,322
  • 8
  • 15
  • Will ${testMap['DOMAIN_DIR']} work if I try referencing a global map? My variables are being called in shell scripts across various stages, something like : `dotnet build ${BUILD_DIR}/${BUILD_SOLUTION}.csproj` – s_neenu Aug 18 '20 at 15:29
  • 1
    Yes it should work, you need to define this map globally and can refer from any place in the pipeline script. – Kiruba Aug 18 '20 at 15:47
  • Declaring variables in a map - `private static final Map VARIABLES = [ BUILD_DIR = 'Builddir' DOMAIN_DIR = 'Domaindir' BUILD_SOLUTION = 'Dir.Builddir.sln' ]` and calling them like, ```VARIABLES.BUILD_DIR``` worked for me! – s_neenu Aug 21 '20 at 14:05