Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use jenkins environment variable in Jenkinsfile if statement

I am trying to use an if statement in my Jenkinsfile for multi branch pipeline project. For the sake of this question, assume I have a text file in my current directory called 'scan.txt'. The text file is generated with a bash command

echo "False" > scan.txt

So the only content is the string "False"

I set an arbitrary environment variable in my Jenkinsfile to the contents of scan.txt like so:

script {
    env.TEXT = readFile 'scan.txt'
}

If I do

echo "${env.TEXT}" 

outside the script block then the jenkins console shows False for that step, as expected.

However, all of my attempts at checking if it is equal to "False" have failed. I have tried the following immediately after the script block:

if (env.TEXT.equals("False")) {
    //do something
}

if (env.TEXT.matches("False")) {
    //do something
}


if (env.TEXT == "False") {
    //do something
}

and none of them work. All of these conditions are boolean false. The documentation for the read file pipeline step states it returns a string of the file contents https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/#code-readfile-code-read-file-from-workspace so I'm not sure what's going on here. Does anyone have any insights?

Thanks

like image 825
Dalton Sweeney Avatar asked Mar 01 '17 23:03

Dalton Sweeney


People also ask

How do I view environment variables in Jenkinsfile?

All environment variables are accessible using env , e.g. ${env. JOB_NAME} .

How do you declare a variable in Jenkinsfile?

Environment variables can be defined using NAME = VALUE syntax. To access the variable value you can use these three methods $env.NAME , $NAME or ${NAME} There are no differences between these methods.

Can Jenkins use system environment variables?

Environment variables are global key-value pairs Jenkins can access and inject into a project. Use Jenkins environment variables to avoid having to code the same values for each project. Other benefits of using Jenkins environment variables include improved security.


2 Answers

The problem is that when you do echo "False" > scan.txt echo will leave a line break at the end of the file, you can se this if you echo env.TEXT in your pipeline script.

So what you need to do is use String.trim() before checking if it equals False, trim will remove all white spaces at the beginning and end. Additionally, the best way of testing if a string contains is to use Boolean.parseBoolean(), it does all the hard work for you.

Let's try this:

node {
    sh 'echo "False" > output.txt'
    def val = readFile 'output.txt'
    echo "${val}"
    echo "${val.trim()}"
    if (val.equals("False")) { // This will print No
        echo "Yes"
    } else {
        echo "No"
    }
    if (val.trim().equals("False")) { // This will print Yes
        echo "Yes"
    } else {
        echo "No"
    }
    if (!Boolean.parseBoolean(val)) { // This will print Yes
        echo "Yes"
    } else {
        echo "No"
    }
}

And on the output we get:

Started by user jon
[Pipeline] node
Running on master in /var/lib/jenkins/workspace/pl
[Pipeline] {
[Pipeline] sh
[pl] Running shell script
+ echo False
[Pipeline] readFile
[Pipeline] echo
False

[Pipeline] echo
False
[Pipeline] echo
No
[Pipeline] echo
Yes
[Pipeline] echo
Yes
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

As you can se, we have an extra line break when we do the first echo step. Also note that Boolean.parseBoolean() handles the string without any trimming.

like image 115
Jon S Avatar answered Sep 28 '22 18:09

Jon S


here is some cases, hope it will save time for some people:

node {

sh 'echo "False" > output.txt'
def val = readFile 'output.txt'
echo "${val}"
echo "${val.trim()}"
if ( "${val.trim()}" ==~ /False/ ) {
    echo "Match Yes trim"
} else {
    echo "Match No trim"
}

if ( "${val}" ==~ /(?ms)False/ ) {
    echo "Match Yes (?ms)"
} else {
    echo "Match No (?ms)"
}

if ( "${val}" ==~ /(?ms)False.*/ ) {
    echo "Match Yes (?ms).*"
} else {
    echo "Match No (?ms).*"
}

if ( "${val}" =~ /False/ ) {
    echo "Match Yes 1="
} else {
    echo "Match No 1="
}

}

Output:

[Pipeline] sh
+ echo False
[Pipeline] readFile
[Pipeline] echo
False

[Pipeline] echo
False
[Pipeline] echo
Match Yes trim
[Pipeline] echo
Match No (?ms)
[Pipeline] echo
Match Yes (?ms).*
[Pipeline] echo
Match Yes 1=

Where (?ms) means multi line and s for dot matching new line in regex.

Note that echo "False" > will add newline to the file. This either needs to be trimmed or echo -n used.

like image 41
Arunas Bartisius Avatar answered Sep 28 '22 17:09

Arunas Bartisius