Search code examples
bashjenkinsgroovyjenkins-pipeline

Jenkinsfile groovy, setting global variable that is only evaluated once, and creating another variable from first var


I have this code:

#!groovy
pipeline {
    agent any
    environment {
      def SUPER_VAR = sh(returnStdout: true, script: """openssl rand -base64 12""").trim()
      SUPER_VALUE = sh(returnStdout: true, script: """echo ${SUPER_VAR}""").trim()
      SUPER_DUPER_VALUE = sh(returnStdout: true, script: """echo ${SUPER_VAR}""").trim()
    }
    stages {
        stage("initialise") {
            steps {
              script {
                    sh "echo SUPER_VAR \${SUB_VAR}"
                    sh "echo SUPER_VALUE \${SUPER_VALUE}"
                    sh "echo SUPER_DUPER_VALUE \${SUPER_DUPER_VALUE}"
                    sh "env"
              }
            }
        }
    }
}

My desired output is, where each time I call / create a new var, the value is the same:

[Pipeline] { (initialise)
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ echo SUPER_VAR
SUPER_VAR
[Pipeline] sh
+ echo SUPER_VALUE FSDYe8VNL3VTvASj
SUPER_VALUE FSDYe8VNL3VTvASj
[Pipeline] sh
+ echo SUPER_DUPER_VALUE FSDYe8VNL3VTvASj
SUPER_DUPER_VALUE FSDYe8VNL3VTvASj
[Pipeline] sh

What happens in jenkins is this:

[Pipeline] { (initialise)
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ echo SUPER_VAR
SUPER_VAR
[Pipeline] sh
+ echo SUPER_VALUE FSDYe8VNL3VTvASj
SUPER_VALUE FSDYe8VNL3VTvASj
[Pipeline] sh
+ echo SUPER_DUPER_VALUE NSmVwW9xz6IPG5AO
SUPER_DUPER_VALUE NSmVwW9xz6IPG5AO
[Pipeline] sh

Every time I created a var based on SUPER_VAR it seems the script is ran again, and I get different output.

How does one register output of script in to a global var, so it can later be used to create new vars globally?


Solution

  • This is what I am using as a solution, I have to define vars in each stage, it looks dirty, but it works.

    This way, the initial value SUPER_VAR will only be evaluated once, and subsequently we can use sub-elements of these vars.

    My use case, I do not want to use more jenkins plugins to get aws sts assume. SUPER_VAR calls sts assume, and returns credentials, I run jq against it, and get a dictionary registered in SUPER_VAR.

    In every stage I run jq to extract credentials for aws for sts assume to work.

    #!groovy
    pipeline {
        agent any
        environment {
          def SUPER_VAR = sh(returnStdout: true, script: """openssl rand -base64 12""").trim()
    
        }
        stages {
            stage("initialise") {
                environment {
                    SUPER_VALUE = sh(returnStdout: true, script: """echo ${SUPER_VAR}""").trim()
                    SUPER_DUPER_VALUE = sh(returnStdout: true, script: """echo ${SUPER_VAR}""").trim()
                }
                steps {
                  script {
                        sh "echo SUPER_VAR \${SUB_VAR}"
                        sh "echo SUPER_VALUE \${SUPER_VALUE}"
                        sh "echo SUPER_DUPER_VALUE \${SUPER_DUPER_VALUE}"
                        sh "env"
                  }
                }
            }
            stage("go again") {
                environment {
                    SUPER_VALUE = sh(returnStdout: true, script: """echo ${SUPER_VAR}""").trim()
                    SUPER_DUPER_VALUE = sh(returnStdout: true, script: """echo ${SUPER_VAR}""").trim()
                }
                steps {
                  script {
                        sh "echo SUPER_VAR \${SUB_VAR}"
                        sh "echo SUPER_VALUE \${SUPER_VALUE}"
                        sh "echo SUPER_DUPER_VALUE \${SUPER_DUPER_VALUE}"
                        sh "env"
                  }
                }
            }
        }
    }