Marvin Kallohn
Marvin Kallohn

Reputation: 1103

Updating environment global variable in Jenkins pipeline from the stage level - is it possible?

I have a Jenkinsfile with some global variables and some stages. can I update the global variable out from a stage?

An example:

pipeline {
  agent any

  environment {                 
    PASSWD = "${sh(returnStdout: true, script: 'python -u do_some_something.py')}"
    ACC = "HI"
  }

  stage('stage1') {
      when { expression { params.UPDATE_JOB == false } }

      steps{
        script {
          def foo= sh(  returnStdout: true, script: 'python -u do_something.py ')
          env.ACC =  foo
          println foo
          print("pw")
          println env.PASSWD
       }
     }  
   }
}

Is it possible to update the ACC variable with the value from foo, so that I can use the ACC Variable in the next stage?

Upvotes: 90

Views: 117022

Answers (4)

Szymon Stepniak
Szymon Stepniak

Reputation: 42184

There is one way to override the environment variable defined in the environment {} block - you can use withEnv() block (doc) that will allow you to override the existing env variable. It won't change the value of the environment defined, but it will override it inside the withEnv() block. Take a look at the following example:

pipeline {
  agent any 

  stages {
    stage("Test") {
      environment {
        FOO = "bar"
      }

      steps {
        script {
          withEnv(["FOO=newbar"]) {
            echo "FOO = ${env.FOO}" // prints: FOO = newbar
          }
        }
      }
    }
  }
}

Alternatively, there is one trick you might want to use. You can refer to ACC environment variable in two ways:

  • explicitly by env.ACC
  • implicitly by ACC

The value of env.ACC cannot be changed once set inside environment {} block, but ACC behaves in the following way: when the variable ACC is not set then the value of env.ACC gets accessed (if exists of course). But when ACC variable gets initialized in any stage, ACC refers to this newly set value in any stage. Consider the following example:

pipeline {
    agent any
    
    environment {
        FOO = "initial FOO env value"
    }
    
    stages {
        stage("Stage 1") {
            steps {
                script {
                    echo "FOO is '${FOO}'" // prints: FOO is 'initial FOO env value'
                
                    env.BAR = "bar"
                }
            }
        }
        
        stage("Stage 2") {
            steps {
                echo "env.BAR is '${BAR}'" // prints: env.BAR is 'bar'
                echo "FOO is '${FOO}'" // prints: FOO is 'initial FOO env value'
                echo "env.FOO is '${env.FOO}'" // prints: env.FOO is 'initial FOO env value'
                script {
                    FOO = "test2"
                    env.BAR = "bar2"
                }
            }
        }
        
        stage("Stage 3") {
            steps {
                echo "FOO is '${FOO}'" // prints: FOO is 'test2'
                echo "env.FOO is '${env.FOO}'" // prints: env.FOO is 'initial FOO env value'
                echo "env.BAR is '${BAR}'" // prints: env.BAR is 'bar2'
                
                script {
                    FOO = "test3"
                }
                
                echo "FOO is '${FOO}'" // prints: FOO is 'test3'
            }
        }
    }
}

And as you can see in the above example, the only exception to the rule is if the environment variable gets initialized outside the environment {} block. For instance, env.BAR in this example was initialized in Stage 1, but the value of env.BAR could be changed in Stage 2 and Stage 3 sees changed value.


I also encourage you to check my video "Jenkins Pipeline Environment Variables explained".

Upvotes: 194

redseven
redseven

Reputation: 1065

Better to use a "normal" (groovy) variable and define the environment var only for the stage where you really need it. It means you can change the value in a previous stage only.

def myvar = 'initial'
pipeline {
    agent any
    stages {
        stage('One'){
            steps {
                script{
                    echo myvar
                    myvar = "value from stage One"
                    echo myvar
                } 
            }
        }
         stage('Two'){
            steps {
                script{
                    echo myvar
                    myvar = "value from stage Two"
                    echo myvar
                } 
            }
        }
        stage('Three'){
            environment {
                MYVAR = "${myvar}"
            }
            steps{
                sh'''
                    echo $MYVAR
                '''
            }
        }
    }
}

and the output is like:

[Pipeline] stage
[Pipeline] { (One)
...
[Pipeline] echo
initial
[Pipeline] echo
value from stage One
...
[Pipeline] stage
[Pipeline] { (Two)
...
[Pipeline] echo
value from stage One
[Pipeline] echo
value from stage Two
...
[Pipeline] stage
[Pipeline] { (Three)
...
[Pipeline] sh
+ echo value from stage Two
value from stage Two

Upvotes: 1

Stephen Quan
Stephen Quan

Reputation: 25956

Each stage can read, write, or append to a script that helps pass the environment variables from stage to stage.

pipeline {
    agent any
    
    stages {
        stage('Set A and B') {
            steps {
                sh '''#!/bin/bash -xe
                echo "" > jobinfo.sh
                A=3
                echo "A=${A}" >> jobinfo.sh
                B=4
                echo "B=${B}" >> jobinfo.sh
                '''
            }
        }
        
        stage('Set C') {
            steps {
                sh '''#!/bin/bash -xe
                . jobinfo.sh
                ((C=A+B))
                echo "C=${C}" >> jobinfo.sh
                '''
            }
        }

        stage('Result') {
            steps {
                sh '''#!/bin/bash -xe
                . jobinfo.sh
                echo "Result is ${C}" # 7
                '''
            }
        }
    }
}

Upvotes: 1

user16647678
user16647678

Reputation: 3

loggedInUser = ""
node ("cm-windows") {
withEnv(["UserLoggedIn='Vrishali'"]) {
  echo env.UserLoggedIn       
   stage('Setup'){
    def buildCause = currentBuild.getBuildCauses()[0]
    def buildPrincipal = [type:"unknown", name:""]
    def buildUserCause = 
    currentBuild.getRawBuild().getCause(hudson.model.Cause.UserIdCause)
    buildPrincipal = [type:"user", name:buildCause.userId]
    print "Prining.."
    print buildCause.userId
    print "Checking the env var"
    print env.UserLoggedIn
    echo "[*] Starting build (id: ${env.UserLoggedIn}) on ${env.UserLoggedIn}"  
    loggedInUser = buildCause.userId
    echo "Loggedin user"
    print loggedInUser
    echo loggedInUser
   } 
}
stage ('override env'){         
   withEnv(["UserLoggedIn=${loggedInUser}"]) {
       echo "inside 2 stgae"
        echo loggedInUser
        print loggedInUser 
        echo "env"
        echo env.UserLoggedIn
   }
}

}

Upvotes: -4

Related Questions