Search code examples
jenkinsjenkins-pipeline

Define and access a variable in multiple steps of a jenkins pipeline


I came here from this post Defining a variable in shell script portion of Jenkins Pipeline

My situation is the following I have a pipeline that is updating some files and generating a PR in my repo if there are changes in the generated files (they change every couple of weeks or less).

At the end of my pipeline I have a post action to send the result by email to our teams connector.

I wanted to know if I could somehow generate a variable and include that variable in my email.

It looks something like this but off course it does not work.

#!groovy
String WasThereAnUpdate = '';

pipeline {
    agent any
    environment {
        GRADLE_OPTS = '-Dorg.gradle.java.home=$JAVA11_HOME'
    }
    stages {
        stage('File Update') {
            steps {
                sh './gradlew updateFiles -P updateEnabled'
            }
        }
        stage('Create PR') {
            steps {
                withCredentials(...) {
                    sh '''
                        if [ -n \"$(git status --porcelain)\" ]; then
                            WasThereAnUpdate=\"With Updates\"
                            ...
                        else
                            WasThereAnUpdate=\"Without updates\"
                        fi
                    '''
                }
            }    
        }
    }
    post {
        success {
            office365ConnectorSend(
                message: "Scheduler finished: " + WasThereAnUpdate,
                status: 'Success',
                color: '#1A5D1C',
                webhookUrl: 'https://outlook.office.com/webhook/1234'
            )
        }
    }
}

I've tried referencing my variable in different ways ${}, etc... but I'm pretty sure that assignment is not working. I know I probably could do it with a script block but I'm not sure how I would put the script block inside the SH itself, not sure this would be possible.

Thanks to the response from MaratC https://stackoverflow.com/a/64572833/5685482 and this documentation I'll do it something like this:

#!groovy
def date = new Date()
String newBranchName = 'protoUpdate_'+date.getTime()

pipeline {
    agent any
    stages {
        stage('ensure a diff') {
            steps {
                sh 'touch oneFile.txt'
            }
        }
        stage('AFTER') {
            steps {
                script {
                    env.STATUS2 = sh(script:'git status --porcelain', returnStdout: true).trim()
                }
            }
        }
    }
    post {
        success {
            office365ConnectorSend(
                message: "test ${env.STATUS2}",
                status: 'Success',
                color: '#1A5D1C',
                webhookUrl: 'https://outlook.office.com/webhook/1234'
            )
        }
}

Solution

  • In your code

    sh '''
        if [ -n \"$(git status --porcelain)\" ]; then
            WasThereAnUpdate=\"With Updates\"
            ...
        else
            WasThereAnUpdate=\"Without updates\"
        fi
    '''
    

    Your code creates a sh session (most likely bash). That session inherits the environment variables from the process that started it (Jenkins). Once it runs git status, it then sets a bash variable WasThereAnUpdate (which is a different variable from likely named Groovy variable.)

    This bash variable is what gets updated in your code.

    Once your sh session ends, bash process gets destroyed, and all of its variables get destroyed too.

    This whole process has no influence whatsoever on Groovy variable named WasThereAnUpdate that just stays what it was before.