Search code examples
bashshelljenkinsjenkins-pipeline

Unable to substitute variable in bash script inside Jenkinsfile


I am facing a very weird issue in my groovy based Jenkinsfile. I have a variable which I need to substitute inside my shell script for the name of the docker container. But no matter what I try it is never able to read that variable. The fact that it makes it weird is I can read the value of variable after and before the script statement, but not inside it.

Can anyone explain why is this issue and how to fix this?

Section of my Jenkinsfile -

stage('Snyk Scan') {
                    if (params.buildDockerImage == 'true') {
                        println(ANSI_BOLD + ANSI_GREEN + "build_tag with value as: " + build_tag + ANSI_NORMAL) // this works
                        sh("echo build tag is ${build_tag}") // this works too
                        sh '''
                    export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"
snyk container test ${hub_org}/player:${build_tag} --json | snyk-to-html -d -o snyk_results.html
                    '''
                    sh("echo build tag is ${build_tag}") // even this works
                    }
                }

When I see the console output it is as -

22:54:42  + snyk container test registery/sunbidrded/player: --json
22:54:42  + snyk-to-html -d -o snyk_results.html
22:54:47  Vulnerability snapshot saved at snyk_results.html
[Pipeline] sh
22:54:47  + echo build tag is container_scanning_ad2aecee29_23
22:54:47  build tag is container_scanning_ad2aecee29_23

as you can see in the portion of snyk container test registery/sunbidrded/player: after colon build_tag is always blank.

I have tried enclosing the ${hub_org}/player:${build_tag} inside double quotes, and also tried storing the string inside a variable and then substituting it in statement, but that also doesn't work.

I have defined the build_tag here -

node('build-slave') {
    try {
        String ANSI_GREEN = "\u001B[32m"
        ... // (other color variables)

        ansiColor('xterm') {
            timestamps {
                stage('Checkout') {
                    if (!env.hub_org) {
                        println(ANSI_BOLD + ANSI_RED + "Uh Oh! Please set a Jenkins environment variable named hub_org with value as registery/sunbidrded" + ANSI_NORMAL)
                        error 'Please resolve the errors and rerun..'
                    } else {
                        println(ANSI_BOLD + ANSI_GREEN + "Found environment variable named hub_org with value as: " + hub_org + ANSI_NORMAL)
                    }
                }
                // cleanWs()
                checkout scm
                commit_hash = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
                build_tag = sh(script: "echo " + params.github_release_tag.split('/')[-1] + "_" + commit_hash + "_" + env.BUILD_NUMBER, returnStdout: true).trim()
                echo "build_tag: " + build_tag

                stage('Customize dependencies') {
                    ...
                }
                stage('Snyk Setup') {
                    ...
                }
...

Solution

  • The insight given by @Matthew Schuchard is correct. It helped me identify what the issue exactly was.

    I only had to make further small modification to get the NVM commands executed and the variable build_tag substituted as -

    sh """
    export NVM_DIR="\$HOME/.nvm"
    [ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh"
    [ -s "\$NVM_DIR/bash_completion" ] && . "\$NVM_DIR/bash_completion"
    snyk container test ${hub_org}/player:${build_tag} --json | snyk-to-html -d -o snyk_results.html
    """