10分钟搞定让你困惑的 Jenkins 环境变量

简介: 10分钟搞定让你困惑的 Jenkins 环境变量

前言


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


但是当向骨架中填充内容的时候,尤其如何利用环境变量(系统内置 | 自定义),多数人都会变得比较混乱,浪费很多时间,本文就帮助大家快速通关环境变量


微信图片_20220511191551.png

准备


如果你想一边阅读本文,一边实践,但是没有 Jenkins 服务可用,又想快速尝试,可以应用 Docker 一个命令快速搭建 Jenkins 服务


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


微信图片_20220511191628.gif


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


打开浏览器输入:localhost:8080


  1. 找到终端的临时密码登陆


  1. 安装推荐的依赖


  1. 创建新的 Pipeline 类型的 Item


  1. 点击左侧 Config,然后在页面底部 Pipeline 部分输入我们接下来写的脚本进行测试就好了


微信图片_20220511191746.png


就是这么简单.....


认识 Jenkins 环境变量


Jenkins 环境变量就是通过 env 关键字暴露出来的 全局变量,可以在 Jenkins 文件的 任何位置使用


其实和你使用的编程语言中的全局变量没有实质差别


查看 Jenkins 系统内置环境变量


Jenkins 在系统内置了很多环境变量方便我们快速使用,查看起来有两种方式:


方式一:


直接在浏览器中访问 ${YOUR_JENKINS_HOST}/env-vars.html 页面就可以,比如 http://localhost:8080/env-vars.html ,每个变量的用途写的都很清楚


微信图片_20220511191839.png


方式二


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


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


直接 Save - Build, 在终端 log 中你会看到相应的环境变量,并且可以快速看到他们当前的值


微信图片_20220511191932.png


通常这两种方式可以结合使用


读取环境变量


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


微信图片_20220511191955.png


如果你在 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"'
            }
        }
    }
}


可以看到结果是一样一样滴,不管有几种,记住第一种最稳妥


微信图片_20220511192031.png


内置的环境变量虽好,但也不能完全满足我们自定义的 pipeline 的执行逻辑,所以我们也得知道如何定义以及使用自定义环境变量


自定义 Jenkins 环境变量


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


微信图片_20220511192109.png


还是看个实际例子吧:


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}"
                }
            }
        }
    }
}


来看运行结果:


微信图片_20220511192146.png


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


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


重写 Jenkins 环境变量


Jenkins 让人相对困惑最多的地方就是重写环境变量,但是只要记住下面这三条规则,就可以搞定一切了


  1. withEnv(["WITH_ENV_VAR=Come On"]) {} 内置函数的这种写法,可以重写任意环境变量


  1. 定义在 environment {} 的环境变量不能被脚本式定义的环境变量(env.key="value")重写


  1. 脚本式环境变量只能重写脚本式环境变量


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


微信图片_20220511192240.gif


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


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}"
                }
            }
        }
    }
}


来验证一下结果吧


微信图片_20220511192316.png


微信图片_20220511192328.png


看到这,基本的设置应该就没有什么问题了,相信你也发现了,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"
                    }
                }
            }
        }
    }
}


来看运行结果:


微信图片_20220511192421.png


如果你写过 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}"
            }
        }
    }
}


微信图片_20220511192501.png


总结


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



相关文章
|
jenkins 持续交付
Jenkins 插件之环境变量插件EnvInject(学习笔记十三)
一 Master/Slave的Node Properties 用来定义slave特定的变量,例如很多的命令所在的路径。  二 job中的build parameter 设置后在build启动的时候提示修改也可以使用默认值。
2389 0
|
jenkins Shell 持续交付
Jenkins环境变量问题
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/catoop/article/details/79637160 通过Jenkins 执行相关sh的时候,环境变量中,不会默认继承/etc/profile 和 ~/.profile 等环境变量。
3153 0
|
jenkins Shell 持续交付
|
1月前
|
jenkins Devops Java
DevOps实践:Jenkins在持续集成与持续部署中的价值
【10月更文挑战第27天】在快速发展的软件开发领域,DevOps实践日益重要。Jenkins作为一款流行的开源自动化服务器,在持续集成(CI)和持续部署(CD)中扮演关键角色。本文通过案例分析,探讨Jenkins在Java项目中的应用,展示其自动化构建、测试和部署的能力,提高开发效率和软件质量。
64 2
|
4月前
|
jenkins 持续交付 开发者
自动化部署:使用Jenkins和Docker实现持续集成与交付
【8月更文挑战第31天】本文旨在为读者揭示如何通过Jenkins和Docker实现自动化部署,从而加速软件开发流程。我们将从基础概念讲起,逐步深入到实际操作,确保即使是初学者也能跟上步伐。文章将提供详细的步骤说明和代码示例,帮助读者理解并应用这些工具来优化他们的工作流程。
|
15天前
|
监控 jenkins Linux
从 Jenkins 持续集成出发:探究如何监控员工电脑屏幕
Jenkins 在企业信息化管理中用于自动化构建、测试和部署,提高开发效率。本文讨论了其重要性,并从技术角度探讨了屏幕监控的可能性,但明确反对非法监控,强调应合法合规地管理企业和尊重员工隐私。
56 12
|
1月前
|
运维 jenkins Java
Jenkins在持续集成与持续部署中的价值
Jenkins在持续集成与持续部署中的价值
|
1月前
|
jenkins Devops 测试技术
DevOps实践:Jenkins在持续集成与持续部署中的价值
【10月更文挑战第26天】随着DevOps理念的普及,Jenkins作为一款开源自动化服务器,在持续集成(CI)与持续部署(CD)中发挥重要作用。本文通过某中型互联网企业的实际案例,展示了Jenkins如何通过自动化构建、持续集成和持续部署,显著提升开发效率、代码质量和软件交付速度,帮助企业解决传统手工操作带来的低效和错误问题。
74 4
|
2月前
|
jenkins Shell 持续交付
Jenkins持续集成GitLab项目 GitLab提交分支后触发Jenkis任务 持续集成 CI/CD 超级详细 超多图(二)
Jenkins持续集成GitLab项目 GitLab提交分支后触发Jenkis任务 持续集成 CI/CD 超级详细 超多图(二)
83 0
|
2月前
|
jenkins Shell 持续交付
Jenkins持续集成GitLab项目 GitLab提交分支后触发Jenkis任务 持续集成 CI/CD 超级详细 超多图(一)
Jenkins持续集成GitLab项目 GitLab提交分支后触发Jenkis任务 持续集成 CI/CD 超级详细 超多图(一)
236 0