前言

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

  • 找到终端的临时密码登陆
  • 安装推荐的依赖
  • 创建新的 pipeline 类型的 item
  • 点击左侧 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 让人相对困惑最多的地方就是重写环境变量,但是只要记住下面这三条规则,就可以搞定一切了

  • withenv(["with_env_var=come on"]) {} 内置函数的这种写法,可以重写任意环境变量
  • 定义在 environment {} 的环境变量不能被脚本式定义的环境变量(env.key="value")重写
  • 脚本式环境变量只能重写脚本式环境变量

这三点是硬规则,没涵盖在这 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 环境变量,了解这些基本上就满足绝大多数应用场景了,当再遇到环境变量问题时,可以回过来翻看一下了,有解决的困惑吗?

到此这篇关于10分钟搞定让你困惑的 jenkins 环境变量的文章就介绍到这了,更多相关jenkins 环境变量内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!