一、为什么要用Jenkinsfile
流水线支持两种语法,即声明式和脚本式,这两种语法都支持构建持续交付流水线。并且都可以用来在 Web UI 或 Jenkinsfile 中定义流水线,不过通常将 Jenkinsfile 放置于代码仓库中(当然也可以放在单独的代码仓库中进行管理)。
创建一个 Jenkinsfile 并将其放置于代码仓库中,有以下好处:
- 方便对流水线上的代码进行复查/迭代;
- 对管道进行审计跟踪;
- 流水线真正的源代码能够被项目的多个成员查看和编辑。
二、环境变量
1、静态变量
Jenkins 有许多内置变量可以直接在 Jenkinsfile 中使用,可以通过 JENKINS_URL/pipeline-syntax/globals#env 获取完整列表。目前比较常用的环境变量如下:
BUILD_ID:当前构建的 ID,与 Jenkins 版本 1.597+中的 BUILD_NUMBER 完全相同;
BUILD_NUMBER:当前构建的 ID,和 BUILD_ID 一致;
BUILD_TAG:用来标识构建的版本号,格式为:jenkins-{JOB_NAME}-{BUILD_NUMBER},可以对产物进行命名,比如生产的 jar 包名字、镜像的 TAG 等;
BUILD_URL:本次构建的完整 URL,比如:http://buildserver/jenkins/job/MyJobName/17/;
JOB_NAME:本次构建的项目名称;
NODE_NAME:当前构建节点的名称;
JENKINS_URL:Jenkins 完整的 URL,需要在 System Configuration 设置;
WORKSPACE:执行构建的工作目录。
上述变量会保存在一个 Map 中,可以使用 env.BUILD_ID 或 env.JENKINS_URL 引用某个内置变量:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps {
echo "Running ${env.BUILD_ID} on ${env.JENKINS_URL}"
}
}
}
}
对应的脚本式流水线如下:
Jenkinsfile (Scripted Pipeline)
node {
echo "Running ${env.BUILD_ID} on ${env.JENKINS_URL}"
}
除了上述默认的环境变量,也可以手动配置一些环境变量:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
environment {
CC = 'clang'
}
stages {
stage('Example') {
environment {
DEBUG_FLAGS = '-g'
}
steps {
sh 'printenv'
}
}
}
}
上述配置了两个环境变量,一个 CC 值为 clang,另一个是 DEBUG_FLAGS 值为-g。但是两者定义的位置不一样,CC 位于顶层,适用于整个流水线,而 DEBUG_FLAGS 位于 stage 中,只适用于当前 stage。
2、动态变量
动态变量是根据某个指令的结果进行动态赋值,变量的值根据指令的执行结果而不同。如下所示:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
environment {
// 使用 returnStdout
CC = """${sh(
returnStdout: true,
script: 'echo "clang"'
)}"""
// 使用 returnStatus
EXIT_STATUS = """${sh(
returnStatus: true,
script: 'exit 1'
)}"""
}
stages {
stage('Example') {
environment {
DEBUG_FLAGS = '-g'
}
steps {
sh 'printenv'
}
}
}
}
returnStdout:将命令的执行结果赋值给变量,比如上述的命令返回的是 clang,此时 CC的值为“clang ”。注意后面多了一个空格,可以用.trim()将其删除;
returnStatus:将命令的执行状态赋值给变量,比如上述命令的执行状态为 1,此时EXIT_STATUS 的值为 1。
三、凭证管理
Jenkins 的声明式流水线语法有一个 credentials()函数,它支持 secret text(加密文本)、username 和 password(用户名和密码)以及 secret file(加密文件)等。接下来看一下一些常用的凭证处理方法。
1、加密文本
本实例演示将两个 Secret 文本凭证分配给单独的环境变量来访问 Amazon Web 服务,需要提前创建这两个文件的 credentials(实践的章节会有演示),Jenkinsfile 文件的内容如下:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent {
// Define agent details here
}
environment {
AWS_ACCESS_KEY_ID = credentials('jenkins-aws-secret-key-id')
AWS_SECRET_ACCESS_KEY = credentials('jenkins-aws-secret-access-key')
}
stages {
stage('Example stage 1') {
steps {
//
}
}
stage('Example stage 2') {
steps {
//
}
}
}
}
说明:
上述示例定义了两个全局变量 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY,这两个变量引用的是 credentials 的两个加密文本,并且这两个变量均可以在 stages 直接引用(通过AWS_SECRET_ACCESS_KEY 和AWS_ACCESS_KEY_ID)。
注意:
如果在 steps 中使用 echo $AWS_ACCESS_KEY_ID,此时返回的是****
,加密内容不会被显示出来。
2、用户名密码
本示例用来演示 credentials 账号密码的使用,比如使用一个公用账户访问 Bitbucket、GitLab、Harbor 等。假设已经配置完成了用户名密码形式的 credentials,凭证 ID 为 jenkins-bitbucket-common-creds。
可以用以下方式设置凭证环境变量(BITBUCKET_COMMON_CREDS 名称可以自定义):
environment {
BITBUCKET_COMMON_CREDS = credentials('jenkins-bitbucket-common-creds')
}
上述的配置会自动生成 3 个环境变量:
BITBUCKET_COMMON_CREDS :包 含一个 以 冒号 分隔 的 用户 名和 密 码, 格式 为username:password;
BITBUCKET_COMMON_CREDS_USR:仅包含用户名的附加变量;
BITBUCKET_COMMON_CREDS_PSW:仅包含密码的附加变量。
此时,调用用户名密码的 Jenkinsfile 如下:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent {
// Define agent details here
}
stages {
stage('Example stage 1') {
environment {
BITBUCKET_COMMON_CREDS = credentials('jenkins-bitbucket-
common-creds')
}
steps {
//
}
}
stage('Example stage 2') {
steps {
//
}
}
}
}
此时环境变量的凭证仅作用于 stage 1,也可以配置在顶层对全局生效
3、加密文件
需要加密保存的文件,也可以使用 credential,比如链接到 Kubernetes 集群的 kubeconfig 文件等。
假如已经配置好了一个 kubeconfig 文件,此时可以在 Pipeline 中引用该文件:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent {
// Define agent details here
}
environment {
MY_KUBECONFIG = credentials('my-kubeconfig')
}
stages {
stage('Example stage 1') {
steps {
sh("kubectl --kubeconfig $MY_KUBECONFIG get pods")
}
}
}
}
更多其它类型的凭证可以参考:https://www.jenkinschina.com/doc/book/pipeline/jenkinsfile/#%E5%A4%84%E7%90%86%E5%87%AD%E8%AF%81。
四、参数处理
声明式流水线支持很多开箱即用的参数,可以让流水线接收不同的参数以达到不同的构建效果,在 Directives 小节讲解的参数均可用在流水线中。
在 Jenkinsfile 中指定的 parameters 会在 Jenkins Web UI 自动生成对应的参数列表,此时可以在 Jenkins 页面点击 Build With Parameters 来指定参数的值,这些参数可以通过 params 变量被成员访问。
假设在 Jenkinsfile 中配置了名为 Greeting 的字符串参数,可以通过${params.Greeting}访问该参数,比如:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
parameters {
string(name: 'Greeting', defaultValue: 'Hello', description: 'How
should I greet the world?')
}
stages {
stage('Example') {
steps {
echo "${params.Greeting} World!"
}
}
}
}
对应的脚本式流水线如下:
Jenkinsfile (Scripted Pipeline)
properties([parameters([string(defaultValue: 'Hello', description: 'How should I greet the world?', name: 'Greeting')])])
node {
echo "${params.Greeting} World!"
}
五、使用多个代理
流水线允许在 Jenkins 环境中使用多个代理,这有助于更高级的用例,例如跨多个平台执行构建、测试等。
比如,在 Linux 和 Windows 系统的不同 agent 上进行测试:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent none
stages {
stage('Build') {
agent any
steps {
checkout scm
sh 'make'
stash includes: '**/target/*.jar', name: 'app'
}
}
stage('Test on Linux') {
agent {
label 'linux'
}
steps {
unstash 'app'
sh 'make check'
}
post {
always {
junit '**/target/*.xml'
}
}
}
stage('Test on Windows') {
agent {
label 'windows'
}
steps {
unstash 'app'
bat 'make check'
}
post {
always {
junit '**/target/*.xml'
}
}
}
}
}
评论区