linuxjenkinsgroovyjenkins-pipeline

Misunderstanding of the groovy syntax in the jenkinsfile


I noticed a very strange behavior of the jenkinsfile output when it comes to triple quotes. I have a declared BUILD_DIR variable in the environment section:

environment {
        BUILD_DIR = "${WORKSPACE}/build"
    }

I also have two stages, one with """ and the other with ''':

stage('Stage1') {
    steps {
        sh label: 'Stage1 ...', script: """
            echo ${BUILD_DIR}
            echo '${BUILD_DIR}'
            echo "${BUILD_DIR}"
        """
    }
}
stage('Stage2') {
    steps {
        sh label: 'Stage2 ...', script: '''
            echo ${BUILD_DIR}
            echo '${BUILD_DIR}'
            echo "${BUILD_DIR}"
        '''
    }
}

But the console output is as follows:

+ echo /home/builder/workspace/build
/home/builder/workspace/build
+ echo /home/builder/workspace/build
/home/builder/workspace/build
+ echo /home/builder/workspace/build
/home/builder/workspace/build

+ echo /home/builder/workspace/build
/home/builder/workspace/build
+ echo ${BUILD_DIR}
${BUILD_DIR}
+ echo /home/builder/workspace/build
/home/builder/workspace/build

So my questions are:

I'm not very familiar with the groovy syntax so I'm really confused by such a behavior


Solution

  • In the first case, Groovy string interpolation is taking place, so things get replaced even before they are passed to the shell.

    What your shell (bash) is executing is this script:

    echo /home/builder/workspace/build
    echo '/home/builder/workspace/build'
    echo "/home/builder/workspace/build"
    

    Now, echo is a bash builtin that strips the quotes and prints the output unquoted.

    You can observe the same behavior by running this in any shell:

    $ echo /home/builder/workspace/build
    $ echo '/home/builder/workspace/build'
    $ echo "/home/builder/workspace/build"
    

    In the second case, because of the triple single-quote, there is no Groovy string interpolation, so what your shell (bash) is executing is this (different) script:

    echo ${BUILD_DIR}
    echo '${BUILD_DIR}'
    echo "${BUILD_DIR}"
    

    It just so happens that the shell has an environment variable named BUILD_DIR which was set by Jenkins agent when you defined

    environment {
        BUILD_DIR = "${WORKSPACE}/build"
    }
    

    Since ${VARIABLE} is a string interpolation format for bash too -- in addition to more used $VARIABLE - bash can interpolate that string with a value of BUILD_DIR environment variable, as it does in the first and the third line. The use of a single-quote prevents that interpolation, so in the second line no interpolation is taking place, and the string is printed verbatim.

    You can observe the same behavior by running this in any shell:

    $ export BUILD_DIR=some-string
    $ echo ${BUILD_DIR}
    $ echo '${BUILD_DIR}'
    $ echo "${BUILD_DIR}"