43

I have tried all sort of ways but nothing seems to be working. Here is my jenkinsfile.

def ZIP_NODE
def CODE_VERSION
pipeline{
    /*A declarative pipeline*/

    agent {
        /*Agent section*/ 
        // where would you like to run the code 
        label 'ubuntu' 
        }
    options{
        timestamps()
        }
    parameters {
        choice(choices: ['dev'], description: 'Name of the environment', name: 'ENV')
        choice(choices: ['us-east-1', 'us-west-1','us-west-2','us-east-2','ap-south-1'], description: 'What AWS region?', name: 'AWS_DEFAULT_REGION')
        string(defaultValue: "", description: '', name: 'APP_VERSION')

        }
    stages{
        /*stages section*/
        stage('Initialize the variables') {
            // Each stage is made up of steps
            steps{
                script{
                    CODE_VERSION='${BUILD_NUMBER}-${ENV}'
                    ZIP_NODE='abcdefgh-0.0.${CODE_VERSION}.zip'
                }
            }                
        }
        stage ('code - Checkout') {
            steps{
                checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'xxxxxxxxxxxxxxxxxxxxxxxxxx', url: 'http://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.git']]]) 
            }  
        }

        stage ('code - Build'){
            steps{
                sh ''' 
                    echo ${JOB_NAME}
                    pwd
                    echo ${ZIP_NODE}
                    echo 'remove alraedy existing zip files'
                    rm -rf *.zip
                    zip -r ${ZIP_NODE} . 
                    chmod 777 $ZIP_NODE 
                ''' 
            }
        }
        stage('Deploy on Beanstalk'){
            steps{
                build job: 'abcdefgh-PHASER' , parameters: [[$class: 'StringParameterValue', name: 'vpc', value: ENV], [$class: 'StringParameterValue', name: 'ZIP_NODE', value: ZIP_NODE], [$class: 'StringParameterValue', name: 'CODE_VERSION', value: CODE_VERSION], [$class: 'StringParameterValue', name: 'APP_VERSION', value: BUILD_NUMBER], [$class: 'StringParameterValue', name: 'AWS_DEFAULT_REGION', value: AWS_DEFAULT_REGION], [$class: 'StringParameterValue', name: 'ParentJobName', value: JOB_NAME]]
            }
        }
    } 

}

The output of step script in stage ('Initialize the variables') gives me nothing, It is not setting the value of global variable ZIP_NODE:

[Pipeline] stage
[Pipeline] { (Initialize the variables)
[Pipeline] script
[Pipeline] {
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage

And then we go to stage (code - Build) we do not get the value of ZIP_NODE. See echo statement at 22:34:17

[Pipeline] stage
[Pipeline] { (code - Build)
[Pipeline] sh
22:34:16 [abcdefgh-ci-dev-pipeline] Running shell script
22:34:17 + echo abcdefgh-ci-dev-pipeline
22:34:17 abcdefgh-ci-dev-pipeline
22:34:17 + pwd
22:34:17 /home/advisor/Jenkins/workspace/abcdefgh-ci-dev-pipeline
22:34:17 + echo
22:34:17 
22:34:17 + echo remove alraedy existing zip files

Thanks to @awefsome, I had some observation which I would like add in details: When I use below code I get desired output i.e. correct value of ZIP_NODE:

 stage ('code - Build'){
            steps{
                sh "echo ${JOB_NAME} && pwd && echo ${ZIP_NODE} && echo 'remove alraedy existing zip files' && rm -rf *.zip && zip -r ${ZIP_NODE} . && chmod 777 $ZIP_NODE"
            }
        }

But when I use below code I do not get the value of ZIP_NODE:

stage ('code - Build'){
            steps{

                sh ''' 
                        echo ${ZIP_NODE}
                        echo ${JOB_NAME}
                        pwd
                        echo ${ZIP_NODE}
                        echo ${CODE_VERSION}
                        #rm -rf .ebextensions
                        echo 'remove alraedy existing zip files'
                        rm -rf *.zip
                        zip -r ${ZIP_NODE} . 
                        chmod 777 $ZIP_NODE 
                    '''
            }
        }
Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
Sunil
  • 707
  • 1
  • 7
  • 13

5 Answers5

41
sh '''
'''

should be

sh """
"""

with single quotes the variables don't get processed.

Simon
  • 2,994
  • 3
  • 28
  • 37
33

Try following and see how it goes:

def ZIP_NODE
def CODE_VERSION
pipeline{
    /*A declarative pipeline*/

    agent {
        /*Agent section*/ 
        // where would you like to run the code 
        label 'master' 
        }
    options{
        timestamps()
        }
    parameters {
        choice(choices: ['dev'], description: 'Name of the environment', name: 'ENV')
        choice(choices: ['us-east-1', 'us-west-1','us-west-2','us-east-2','ap-south-1'], description: 'What AWS region?', name: 'AWS_DEFAULT_REGION')
        string(defaultValue: "", description: '', name: 'APP_VERSION')

        }
    stages{
        /*stages section*/
        stage('Initialize the variables') {
            // Each stage is made up of steps
            steps{
                script{
                    CODE_VERSION="${BUILD_NUMBER}-${ENV}"
                    ZIP_NODE="abcdefgh-0.0.${CODE_VERSION}.zip"
                }
            }                
        }
        stage ('code - Checkout') {
            steps{
                println "checkout skipped"
                //checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'xxxxxxxxxxxxxxxxxxxxxxxxxx', url: 'http://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.git']]]) 
            }  
        }

        stage ('code - Build'){
            steps{
                sh "echo ${JOB_NAME} && pwd && echo ${ZIP_NODE} && echo 'remove alraedy existing zip files' && rm -rf *.zip && zip -r ${ZIP_NODE} . && chmod 777 $ZIP_NODE"
            }
        }
        stage('Deploy on Beanstalk'){
            steps{
                println "build job skipped"
                //build job: 'abcdefgh-PHASER' , parameters: [[$class: 'StringParameterValue', name: 'vpc', value: ENV], [$class: 'StringParameterValue', name: 'ZIP_NODE', value: ZIP_NODE], [$class: 'StringParameterValue', name: 'CODE_VERSION', value: CODE_VERSION], [$class: 'StringParameterValue', name: 'APP_VERSION', value: BUILD_NUMBER], [$class: 'StringParameterValue', name: 'AWS_DEFAULT_REGION', value: AWS_DEFAULT_REGION], [$class: 'StringParameterValue', name: 'ParentJobName', value: JOB_NAME]]
            }
        }
    } 
}

I got following output:

Started by user jenkins
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
Running on Jenkins in /Users/Shared/Jenkins/Home/workspace/test
[Pipeline] {
[Pipeline] timestamps
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Initialize the variables)
[Pipeline] script
[Pipeline] {
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (code - Checkout)
[Pipeline] echo
21:19:06 checkout skipped
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (code - Build)
[Pipeline] sh
21:19:06 [test] Running shell script
21:19:06 + echo test
21:19:06 test
21:19:06 + pwd
21:19:06 /Users/Shared/Jenkins/Home/workspace/test
21:19:06 + echo abcdefgh-0.0.17-dev.zip
21:19:06 abcdefgh-0.0.17-dev.zip
21:19:06 + echo 'remove alraedy existing zip files'
21:19:06 remove alraedy existing zip files
21:19:06 + rm -rf '*.zip'
21:19:06 + zip -r abcdefgh-0.0.17-dev.zip .
21:19:06 
21:19:06 zip error: Nothing to do! (try: zip -r abcdefgh-0.0.17-dev.zip . -i .)
[Pipeline] }
[Pipeline] // stage
awefsome
  • 1,431
  • 1
  • 13
  • 11
  • Same issue persists – Sunil Aug 29 '18 at 17:25
  • I have edited my answer to accommodate output as well. It seems to be working atleast at my end. Can you please elaborate it little bit more, what exact error are you getting after making changes as suggested in the answer. – awefsome Aug 29 '18 at 19:25
  • Below code works: stage ('code - Build'){ steps{ sh "echo ${JOB_NAME} && pwd && echo ${ZIP_NODE} && echo 'remove alraedy existing zip files' && rm -rf *.zip && zip -r ${ZIP_NODE} . && chmod 777 $ZIP_NODE" } } but this does not stage ('code - Build'){ steps{ sh ''' echo ${ZIP_NODE} ''' } } – Sunil Aug 30 '18 at 11:27
  • For me it works only if I define the global variable without "def"and without type specification. – Alexander Samoylov Jun 16 '20 at 10:30
  • is the same pattern possible however with powershell inline script rather than sh inline? – JohnZaj Aug 19 '20 at 15:37
  • I tried different suggestions but nothing worked. This answer worked for me. Thanks @awefsome – Muhammad Tariq Jan 01 '21 at 17:25
9

Global environments on jenkins should be outside the pipeline ,can be initialized/used inside the scripts, and of course known by all scopes inside the pipeline:

example:

def internal_ip

pipeline {
    agent { node { label "test" } }
        stages {
            stage('init') {
                steps {
                    script {
                        def x
                        if(env.onHold.toBoolean() == true){
                            x=1
                        }else{
                            x=2
                        }
                        internal_ip = sh (
                            script: "echo 192.168.0.${x}",
                            returnStdout: true
                        ).trim()   
                    }
                }
            }
            stage('test') {
                steps {
                    script {
                        echo  "my internal ip is: ${internal_ip}"
                    }
                }
            }
        }    
    }
}
avivamg
  • 12,197
  • 3
  • 67
  • 61
7

In addition to @avivamg's answer which is correct.

One remaining problem is that if you want to access Jenkins' environment variables (see http://<JENKINS_URL>/env-vars.html/) to initialize these globals, e.g.:

def workspaceDir=${WORKSPACE}

you get:

groovy.lang.MissingPropertyException: No such property: WORKSPACE for class: groovy.lang.Binding

The idea of :

def workspaceDir

pipeline {
    
    environment {
        workspaceDir=${WORKSPACE}
    }

    stages {
        stage('Globals test') {
            steps {
                script {
                   echo "workspaceDir=${workspaceDir}"
                   echo workspaceDir
                }
            }
        }
    }
}

leads to the output:

workspaceDir=null
null

since there are two different contexts involved: environment and Groovy, which apparently are independent from each other.

It works with:

environment {
    workspaceDir=${WORKSPACE}
}

but that's an environment variable then, not a variable in the Groovy context.

Declaring and initializing in the Groovy context works via stage(s):

def workspaceDir

pipeline {

    stages {
        stage('Initializing globals') {
            steps {
                script {
                    workspaceDir = "${WORKSPACE}"
                }
            }
        }

        stage('Globals test') {
            steps {
                script {
                   echo "workspaceDir=${workspaceDir}"
                   echo workspaceDir
                }
            }
        }
    }
}

Output:

workspaceDir=C:\Users\jenkins\AppData\Local\Jenkins\.jenkins\workspace\Globals-test-project
C:\Users\jenkins\AppData\Local\Jenkins\.jenkins\workspace\Globals-test-project
Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
  • 1
    This is because env vars are immutable when declared at the environment scope. When declared in a script scope, they are fully mutable. In either case they can only be strings, though. My go-to resource on this is https://e.printstacktrace.blog/jenkins-pipeline-environment-variables-the-definitive-guide/ – Max Cascone Dec 21 '21 at 16:24
-1

My experience with using global variables inside groovy shellscript is to declare them global and then use a stage environment variable. It looks that the shell script has only access to this private environment variables and not global. As sample:

environment{
  COMMIT_ID = "foo"
}               
stages{
stage('Build'){
  environment {
    commitId = sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
  }
  steps {
    script {
      COMMIT_ID = commitId
    }
  }
}
stage ('Build-Win-Container'){
  environment {
    commitId = "${COMMIT_ID}"
  }
  steps{
    sh label: 'build/push container', script: '''
    echo "With Windows commitId: ${commitId}"
    '''
  }
}
}

I tried dozen of ways also from stackoverflow but none was working the way to access the variable inside the shell script. I think this is because the shell script is an private instance inside a step and only has access to variables inside this step (my opinion) So I set an global environment variable Fill this inside step 1 with a script Set a environment variable inside the next step and fill it there. Finaly it was available inside the shell script. No other way worked for me.

IFThenElse
  • 131
  • 1
  • 10
  • 1
    `''' ... "... ${commit}"'''` isn't interpolated inside a [triple-single-quoted string](https://groovy-lang.org/syntax.html#_triple_single_quoted_string). You have to use a [triple-double-quoted string](https://groovy-lang.org/syntax.html#_triple_double_quoted_string). – Gerold Broser Sep 19 '21 at 09:32