Search code examples
jenkinsjenkins-pipelinejenkins-declarative-pipeline

why is this environment variable evaluated every time it is used?


I have noticed this (to me) strange behaviour. I have this Jenkins declarative pipeline:

#!groovy

pipeline {

    agent {
        node {
            label 'mine-agent-pod'
        }
    }

    environment {
        MARKER = """run-${sh(
            returnStdout: true,
            script: "date -Ins | sed 's/[^a-zA-Z0-9-]/_/g'"
        ).trim()}"""
        STATUS_DATA = "status-data-${MARKER}.json"
    }

    stages {

        stage('Setup') {
            steps {
                sh("""echo MARKER=${MARKER}""")
                sh("""echo STATUS_DATA=${STATUS_DATA}""")
            }
        }

    }
}

I wanted the MARKER to be a kinda of ID I would use to mark all temporary stuff I create in a build (and I like it to be a date). But looks like MARKER is evaluated whenever it is used, as the output of the build shows (notice how nanoseconds part of the string differs):

[Pipeline] sh
+ echo MARKER=run-2020-07-07T12_04_23_369785902_00_00
MARKER=run-2020-07-07T12_04_23_369785902_00_00
[Pipeline] sh
+ echo STATUS_DATA=status-data-run-2020-07-07T12_04_23_727188019_00_00.json
STATUS_DATA=status-data-run-2020-07-07T12_04_23_727188019_00_00.json

Why is that? How to achieve having "static" variable?


Solution

  • After a couleague's great advice, defining variable outside of pipeline helped:

    #!groovy
    
    def MARKER = """run-${ new Date().format("yyyy-MM-dd'T'HH:mm:ss.SZ") }"""
    
    pipeline {
    
        agent {
            node {
                label 'sat-cpt'
            }
        }
    
        environment {
            STATUS_DATA = "status-data-${MARKER}.json"
        }
    
        stages {
    
            stage('Setup') {
                steps {
                    sh("""echo MARKER=${MARKER}""")
                    sh("""echo STATUS_DATA=${STATUS_DATA}""")
                }
            }
    
        }
    }
    

    This prints:

    [Pipeline] sh
    + echo MARKER=run-2020-07-08T19:41:56.130+0000
    MARKER=run-2020-07-08T19:41:56.130+0000
    [Pipeline] sh
    + echo STATUS_DATA=status-data-run-2020-07-08T19:41:56.130+0000.json
    STATUS_DATA=status-data-run-2020-07-08T19:41:56.130+0000.json