乐趣区

关于java:10分钟搞定让你困惑的-Jenkins-环境变量

前言

Jenkins,DevOps 技术栈的外围之一,CI/CD 离不开编写 Pipeline 脚本,上手 Jenkins,简略查一下文档,你就应该不会被 agent,stages,step 这类关键词弄懵,也能很快构建出 pipeline 的骨架

然而当向骨架中填充内容的时候,尤其如何利用 环境变量(零碎内置 | 自定义),少数人都会变得比拟凌乱,节约很多工夫,本文就帮忙大家疾速通关环境变量

筹备

如果你想一边浏览本文,一边实际,然而没有 Jenkins 服务可用,又想疾速尝试,能够利用 Docker 一个命令疾速搭建 Jenkins 服务

docker container run --rm -p 8080:8080 -p 50000:50000 --name=jenkins -v $(pwd):/var/jenkins_home jenkins/jenkins

2021 年了,本地没有 Docker 说不过去了,过去瞧瞧 Docker 系列是否入得了你的法眼?

关上浏览器输出:localhost:8080

  1. 找到终端的长期明码登陆
  2. 装置举荐的依赖
  3. 创立新的 Pipeline 类型的 Item
  4. 点击左侧 Config,而后在页面底部 Pipeline 局部输出咱们接下来写的脚本进行测试就好了

就是这么简略 …..

意识 Jenkins 环境变量

Jenkins 环境变量就是通过 env 关键字裸露进去的 全局变量 ,能够在 Jenkins 文件的 任何地位应用

其实和你应用的编程语言中的全局变量没有本质差异

查看 Jenkins 零碎内置环境变量

Jenkins 在零碎内置了很多环境变量不便咱们疾速应用,查看起来有两种形式:

形式一:

间接在浏览器中拜访 ${YOUR_JENKINS_HOST}/env-vars.html 页面就能够,比方 http://localhost:8080/env-vars.html,每个变量的用处写的都很分明

形式二

通过执行 printenv shell 命令来获取:

pipeline {
    agent any

    stages {stage("Env Variables") {
            steps {sh "printenv"}
        }
    }
}

间接 Save – Build, 在终端 log 中你会看到相应的环境变量,并且能够疾速看到他们以后的值

通常这两种形式能够联合应用

读取环境变量

下面咱们说了 env 是环境变量的关键字,然而读取 Jenkins 内置的这些环境变量,env 关键字是可有可无, 但不能没了底裤,都要应用 ${xxx} 包围起来。以 BUILD_NUMBER 这个内置环境变量举例来说明就是这样滴:

如果你在 Jenkins 文件中应用 shell 命令,应用这些内置环境变量甚至能够不必 {},来看一下:

pipeline {
    agent any

    stages {stage("Read Env Variables") {
            steps {echo "带 env 的读取形式:${env.BUILD_NUMBER}"
                echo "不带 env 的读取形式:${BUILD_NUMBER}"
                sh 'echo"shell 中读取形式 $BUILD_NUMBER"'
            }
        }
    }
}

能够看到后果是一样一样滴,不论有几种,记住第一种最稳当

内置的环境变量虽好,但也不能齐全满足咱们自定义的 pipeline 的执行逻辑,所以咱们也得晓得如何定义以及应用自定义环境变量

自定义 Jenkins 环境变量

Jenkins pipeline 分申明式(Declarative)和 脚本式(imperative)写法,相应的环境变量定义形式也略有不同,归纳起来有三种形式:

还是看个理论例子吧:

pipeline {
    agent any

    environment {FOO = "bar"}

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

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

                script {env.SCRIPT_VARIABLE = "Thumb Up"}

                echo "SCRIPT_VARIABLE = ${env.SCRIPT_VARIABLE}"

                withEnv(["WITH_ENV_VAR=Come On"]) {echo "WITH_ENV_VAR = ${env.WITH_ENV_VAR}"
                }
            }
        }
    }
}

来看运行后果:

留神:withEnv(["WITH_ENV_VAR=Come On"]) {} 这里的 = 号两侧不能有空格,必须是 key=value 的模式

一个残缺的 pipeline 通常会有很多个 stage,环境变量在不同的 stage 有不同的值是很常见的,晓得如何设置以及读取环境变量后,咱们还得晓得如何重写环境变量

重写 Jenkins 环境变量

Jenkins 让人绝对困惑最多的中央就是重写环境变量,然而只有记住上面这三条规定,就能够搞定所有了

  1. withEnv(["WITH_ENV_VAR=Come On"]) {} 内置函数的这种写法,能够重写任意环境变量
  2. 定义在 environment {} 的环境变量不能被脚本式定义的环境变量(env.key="value")重写
  3. 脚本式环境变量只能重写脚本式环境变量

这三点是硬规定,没涵盖在这 3 点规定之内的也就是被容许的了

三条规定就有点让人头大了,农夫选豆种,举例为证吧

pipeline {
    agent any

    environment {
        FOO = "你当像鸟飞往你的山"
        NAME = "Tan"
    }

    stages {stage("Env Variables") {
            environment {
                  // 会重写第 6 行 变量
                NAME = "RGYB" 
                  // 会重写零碎内置的环境变量 BUILD_NUMBER
                BUILD_NUMBER = "10" 
            }

            steps {
                  // 应该打印出 "FOO = 你当像鸟飞往你的山"
                echo "FOO = ${env.FOO}" 
                  // 应该打印出 "NAME = RGYB"
                echo "NAME = ${env.NAME}" 
                  // 应该打印出 "BUILD_NUMBER = 10"
                echo "BUILD_NUMBER =  ${env.BUILD_NUMBER}" 

                script {
                      // 脚本式创立一个环境变量
                    env.SCRIPT_VARIABLE = "1" 
                }
            }
        }

        stage("Override Variables") {
            steps {
                script {
                      // 这里的 FOO 不会被重写,违反 Rule No.2
                    env.FOO = "Tara"
                      // SCRIPT_VARIABLE 变量会被重写,合乎 Rule No.3
                    env.SCRIPT_VARIABLE = "2" 
                }

                  // FOO 在第 37 行重写失败,还会打印出 "FOO = 你当像鸟飞往你的山"
                echo "FOO = ${env.FOO}" 
                  // 会打印出 "SCRIPT_VARIABLE = 2"
                echo "SCRIPT_VARIABLE = ${env.SCRIPT_VARIABLE}" 

                  // FOO 会被重写,合乎 Rule No.1
                withEnv(["FOO=Educated"]) { 
                      // 应该打印 "FOO = Educated"
                    echo "FOO = ${env.FOO}" 
                }

                  // 情理同上
                withEnv(["BUILD_NUMBER=15"]) {
                      // 应该打印出 "BUILD_NUMBER = 15"
                    echo "BUILD_NUMBER = ${env.BUILD_NUMBER}"
                }
            }
        }
    }
}

来验证一下后果吧

看到这,根本的设置应该就没有什么问题了,置信你也发现了,Jenkins 设置环境变量和编程语言的那种设置环境变量还是略有不同的,后者能够将变量赋值为对象,但 Jenkins 就不行,因为 在 Jenkins 文件中,所有设置的值都会被当成 String,难道没方法利用 Boolean 值吗?

Jenkins 中应用 Boolean 值

如果设置一个变量为 false,Jenkins 就会将其转换为 "false", 如果想应用 Boolean 来做条件判断,必须要调用 toBoolean() 办法做转换

pipeline {
    agent any

    environment {IS_BOOLEAN = false}

    stages {stage("Env Variables") {
            steps {
                script {
                      // Hello 会被打印进去,因为非空字符串都会被认为是 Boolean.True
                    if (env.IS_BOOLEAN) {echo "Hello"}

                      // 真正的 Boolean 比拟
                    if (env.IS_BOOLEAN.toBoolean() == false) {echo "日拱一兵"}
                  
                      // 真正的 Boolean 
                    if (!env.IS_BOOLEAN.toBoolean()) {echo "RGYB"}
                }
            }
        }
    }
}

来看运行后果:

如果你写过 Pipeline,你肯定会晓得,写 Pipeline 是离不开写 shell 的,有些时候,须要将 shell 的执行后果赋值给环境变量,Jenkins 也有办法反对

Shell 后果赋值给环境变量

实现这种形式很简略,只须要记住一个格局:sh(script: 'cmd', returnStdout:true)

pipeline {
    agent any

    environment {// 应用 trim() 去掉后果中的空格
        LS_RESULT = "${sh(script:'ls -lah', returnStdout: true).trim()}"
    }

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

总结

对于 Jenkins 环境变量,理解这些基本上就满足绝大多数利用场景了,当再遇到环境变量问题时,能够回过来翻看一下了,有解决的困惑吗?

日拱一兵 | 原创

退出移动版