HomeAboutArchivesTools & ResourcesSupport me
Hi! πŸ‘‹ I'm Szymon

I help you become a better software developer.

  • 1.15kFollowers
  • 2.36kSubscribers
  • 110Followers
  • 30.2kReputation

Latest posts from the Jenkins Pipeline Cookbook

Jenkins Declarative Pipeline with the dynamic agent - how to ...
5 Common Jenkins Pipeline Mistakes
How to catch curl response in Jenkins Pipeline?
How to time out Jenkins Pipeline stage and keep the pipeline ...
Jenkins Scripted Pipeline vs. Declarative Pipeline - the 4 pr...
Using Jenkins Pipeline parallel stages to build Maven project...
Building Java and Maven docker images using parallelized Jenk...
More

Popular categories

  • Groovy Cookbook28
  • Jenkins Pipeline Cookbook9
  • Programmer's Bookshelf6
  • Micronaut Cookbook4
  • Ratpack Cookbook4
  • Learning Java4
  • jq cookbook3
  • How to3
  • Blog Reports2

Don't miss anything - join my newsletter

Additional materials and updates for subscribers. No spam guaranteed.
Unsubscribe at any time.

Did you like this article?

Spread the !
  • β˜•οΈ
  1. e.printstacktrace.blog
  2. Jenkins Pipeline Cookbook

Jenkins Pipeline Environment Variables - The Definitive Guide

  • November 2, 2019
  • 5 min. read
  • 0 Comments

Have you run into troubles when you started using Jenkins Environment Variables in your Jenkinsfile? In this blog post, I show you how to use environment variables, how to override them, how to work with boolean values, and how to store a result of sh step in the env variable. After reading this article, Jenkins env variables won’t surprise you anymore!

Table of Contents
  • List environment variables
    • Using env-vars.html
    • Using shell command
  • Reading environment variables
  • Setting environment variables
  • Overriding environment variables
  • Storing Boolean values in environment variables
  • Capturing sh command output in the env variable

What is Jenkins Environment Variable?

Jenkins Environment Variable is a global variable exposed through the env variable and used anywhere in the Jenkinsfile. Any value stored in the env variable gets stored as a String type. Environment Variables can be set either at the pipeline top level, at the specific stage level, or inside the script block.

List environment variables

Let’s start by listing all available environment variables. Two different ways allow you to do so.

Using env-vars.html

You can open ${YOUR_JENKINS_HOST}/env-vars.html page on your Jenkins master server to get a list of all environment variables listed on an HTML page.

Using shell command

Alternatively, you can list all environment variables by executing the printenv shell command.

Listing 1. Jenkinsfile
pipeline {
    agent any

    stages {
        stage("Env Variables") {
            steps {
                sh "printenv"
            }
        }
    }
}
It might be useful to use printenv | sort command combination to get a sorted list of env variables.

Reading environment variables

You can access environment variables in pipeline steps through the env object, e.g., env.BUILD_NUMBER will return the current build number. You can also use a shorthand version BUILD_NUMBER, but in this variant may be confusing to some users - it misses the context that the BUILD_NUMBER comes from the environment variable.

Listing 2. Jenkinsfile
pipeline {
    agent any

    stages {
        stage("Env Variables") {
            steps {
                echo "The build number is ${env.BUILD_NUMBER}"
                echo "You can also use \${BUILD_NUMBER} -> ${BUILD_NUMBER}"
                sh 'echo "I can access $BUILD_NUMBER in shell command as well."'
            }
        }
    }
}

Setting environment variables

The environment variables can be set declaratively using environment { } block, imperatively using env.VARIABLE_NAME, or using withEnv(["VARIABLE_NAME=value"]) {} block.

Listing 3. Jenkinsfile
pipeline {
    agent any

    environment {
        FOO = "bar"
    }

    stages {
        stage("Env Variables") {
            environment {
                NAME = "Alan"
            }

            steps {
                echo "FOO = ${env.FOO}"
                echo "NAME = ${env.NAME}"

                script {
                    env.TEST_VARIABLE = "some test value"
                }

                echo "TEST_VARIABLE = ${env.TEST_VARIABLE}"

                withEnv(["ANOTHER_ENV_VAR=here is some value"]) {
                    echo "ANOTHER_ENV_VAR = ${env.ANOTHER_ENV_VAR}"
                }
            }
        }
    }
}

Overriding environment variables

Jenkins Pipeline supports overriding environment variables. There are a few rules you need to be aware of.

  • The withEnv(["env=value]) { } block can override any environment variable.

  • The variables set using environment {} block cannot be overridden using imperative env.VAR = "value" assignment.

  • The imperative env.VAR = "value" assignment can override only environment variables created using imperative assignment.

Here is an exemplary Jenkinsfile that shows all three different use cases.

Listing 4. Jenkinsfile
pipeline {
    agent any

    environment {
        FOO = "bar"
        NAME = "Joe"
    }

    stages {
        stage("Env Variables") {
            environment {
                NAME = "Alan" // overrides pipeline level NAME env variable
                BUILD_NUMBER = "2" // overrides the default BUILD_NUMBER
            }

            steps {
                echo "FOO = ${env.FOO}" // prints "FOO = bar"
                echo "NAME = ${env.NAME}" // prints "NAME = Alan"
                echo "BUILD_NUMBER =  ${env.BUILD_NUMBER}" // prints "BUILD_NUMBER = 2"

                script {
                    env.SOMETHING = "1" // creates env.SOMETHING variable
                }
            }
        }

        stage("Override Variables") {
            steps {
                script {
                    env.FOO = "IT DOES NOT WORK!" // it can't override env.FOO declared at the pipeline (or stage) level
                    env.SOMETHING = "2" // it can override env variable created imperatively
                }

                echo "FOO = ${env.FOO}" // prints "FOO = bar"
                echo "SOMETHING = ${env.SOMETHING}" // prints "SOMETHING = 2"

                withEnv(["FOO=foobar"]) { // it can override any env variable
                    echo "FOO = ${env.FOO}" // prints "FOO = foobar"
                }

                withEnv(["BUILD_NUMBER=1"]) {
                    echo "BUILD_NUMBER = ${env.BUILD_NUMBER}" // prints "BUILD_NUMBER = 1"
                }
            }
        }
    }
}

5 Common Jenkins Pipeline Mistakes πŸ”₯

In this Jenkins Pipeline tutorial video, I reveal five common Jenkins Pipeline mistakes and I explain how those mistakes can be avoided. If you're new to the Jenkins declarative pipeline and you want to take your knowledge to the next level, this video will show you some best practices and resources for further learning. Watch now »

Storing Boolean values in environment variables

There is one popular misconception when it comes to using environment variables. Every value that gets stored as an environment variable gets converted to a String. When you store boolean’s false value, it gets converted to "false". If you want to use that value in the boolean expression correctly, you need to call "false".toBoolean() method.[1]

Listing 5. Jenkinsfile
pipeline {
    agent any

    environment {
        IS_BOOLEAN = false
    }

    stages {
        stage("Env Variables") {
            steps {
                script {
                    if (env.IS_BOOLEAN) {
                        echo "You can see this message, because \"false\" String evaluates to Boolean.TRUE value"
                    }

                    if (env.IS_BOOLEAN.toBoolean() == false) {
                        echo "You can see this message, because \"false\".toBoolean() returns Boolean.FALSE value"
                    }
                }
            }
        }
    }
}

Capturing sh command output in the env variable

You can also capture output of a shell command as an environment variable. Keep in mind that you need to use sh(script: 'cmd', returnStdout:true) format to force sh step[2] to return an output so it can be captured and stored in a variable. Also, if you want to avoid capturing the new line character that is usually present in the shell command output, call trim() method to remove all whitespace from the beginning and the end of the captured output.

Listing 6. Jenkinsile
pipeline {
    agent any

    environment {
        LS = "${sh(script:'ls -lah', returnStdout: true).trim()}"
    }

    stages {
        stage("Env Variables") {
            steps {
                echo "LS = ${env.LS}"
            }
        }
    }
}

Wrapping sh step with the Groovy string is only needed when you capture command’s output in the environment block of the declarative pipeline. If you don’t do it that way, the pipeline syntax validation fails instantly, saying that it expects string value on the right side of the assignment. When you capture the output inside the script block, however, you don’t have to call sh from the inside of the Groovy string. The following code will work just fine in this case.

Listing 7. Jenkinsfile
pipeline {
    agent any

    stages {
        stage("Env Variables") {
            steps {
                script {
                    env.LS = sh(script:'ls -lah', returnStdout: true).trim()
                    echo "LS = ${env.LS}"
                    // or if you access env variable in the shell command
                    sh 'echo $LS'
                }
            }
        }
    }
}

1. Read more about "The Groovy Truth" here - https://groovy-lang.org/semantics.html#_strings
2. https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#sh-shell-script
  • groovy
  • jenkins
  • jenkins-pipeline
  • cicd
  • continuous-integration

Jenkins Pipeline Cookbook

Using SDKMAN! as a docker image for Jenkins Pipeline - a step by step guide

  • November 6, 2019
  • 5 min. read
  • 0 Comments

A few days ago, I was struggling with some Docker images I use in my Jenkins CI environment. I run some Jenkins Pipelines, and I like to define build environment as code using custom Docker images. Everything was fine until I had to consider running different Java or Maven versions. I decided to use one of my favorite command-line tools - SDKMAN!, to build a highly configurable build environment.

Jenkins Pipeline Cookbook

How to time out Jenkins Pipeline stage and keep the pipeline running?

  • April 16, 2020
  • 5 min. read
  • 0 Comments

The declarative Jenkins Pipeline allows us to define timeout either at the pipeline level or the...

Jenkins Pipeline Cookbook

Building Java and Maven docker images using parallelized Jenkins Pipeline and SDKMAN!

  • November 11, 2019
  • 5 min. read
  • 0 Comments

In the last article, I have shown you how you can build a docker image for Jenkins Pipeline usin...

Jenkins Pipeline Cookbook

Jenkins Scripted Pipeline vs. Declarative Pipeline - the 4 practical differences

  • January 22, 2020
  • 5 min. read
  • 0 Comments

If you read this blog post, there is a high chance you’re looking for information about pr...

Any thoughts or ideas?

Let's talk in the comment's section πŸ’¬

Want to put a code sample in the comment? Read the Syntax highlighting guide for more information.
Empty
Latest blog posts
  • Merging JSON files recursively in the command-line
  • Jenkins Declarative Pipeline with the dynamic agent - how to configure it?
  • Groovy Ecosystem Usage Report (2020)
  • How to convert JSON to CSV from the command-line?
  • 5 Common Jenkins Pipeline Mistakes
  • How to merge two maps in Groovy?
  • Building stackoverflow-cli with Java 11, Micronaut, Picocli, and GraalVM
  • How to catch curl response in Jenkins Pipeline?
  • Atomic Habits - book review
  • Parsing JSON in command-line with jq: basic filters and functions (part 1)
Trending videos
How to merge two JSON files in the command-line using jq? | #jq #json #curl

In this jq tutorial video, I show you how you can merge two JSON files in the command-line using jq JSON processor. I explain...

Jenkins Declarative Pipeline vs Scripted Pipeline - 4 key differences | #jenkinspipeline

Jenkins Pipeline as a code is a new standard for defining continuous integration and delivery pipelines in Jenkins. The scrip...

Useful links
  • Start here
  • About
  • Archives
  • Resources
  • Privacy Policy
  • Merchandise
  • My Kit
  • RSS
  • Support the blog
Popular categories
  • Groovy Cookbook28
  • Jenkins Pipeline Cookbook9
  • Programmer's Bookshelf6
  • Micronaut Cookbook4
  • Ratpack Cookbook4
  • Learning Java4
  • jq cookbook3
  • How to3
  • Blog Reports2
Popular tags
affiliate async benchmark blogging book career cicd continuous-integration curl devops docker git github graalvm gradle grails groovy haskell hexo java java-8 jenkins jenkins-pipeline jenkinsfile jmh jq json junit learning maven metaprogramming micronaut native-image non-blocking progress ratpack reactive-programming reading recursion review rxjava sdkman session split spock stackoverflow string tail-call tail-recursion unit-test
  • Designed by @wololock
  • Created with Hexo
  • Hosted on GitHub
  • Deployed with Circle CI
  • License CC BY-NC-SA 4.0