使用 Jenkinsfile
创建 Jenkinsfile
Jenkinsfile
是一个文本文件,它包含了 Jenkins 流水线的定义并被检入源代码控制仓库。下面的流水线实现了基本的三阶段持续交付流水线。
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Building..'
}
}
stage('Test') {
steps {
echo 'Testing..'
}
}
stage('Deploy') {
steps {
echo 'Deploying....'
}
}
}
}
对于许多项目来说,流水线“工作”的开始就是“构建”阶段。通常流水线的这个阶段包括源代码的组装、编译或打包。Jenkinsfile
文件不能替代现有的构建工具,如 GNU/Make、Maven、Gradle 等,而应视其为一个将项目的开发生命周期的多个阶段(构建、测试、部署等)绑定在一起的粘合层。
构建
Jenkins 有许多插件可以用于调用几乎所有常用的构建工具,不过这个例子只是从 shell 步骤(sh
)调用 make
。sh
步骤假设系统是基于 Unix/Linux 的,对于基于 Windows 的系统可以使用 bat
替代。
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'make'
archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true
}
}
}
}
-
sh
步骤调用make
命令,只有命令返回的状态码为零时才会继续。任何非零的返回码都将使流水线失败。 -
archiveArtifacts
捕获符合模式(**/target/*.jar
)匹配的交付件并将其保存到 Jenkins master 节点以供后续获取。
测试
运行自动化测试是任何成功持续交付过程得重要组成部分,因此,Jenkins 有许多测试记录,报告和可视化工具,这些都是由各种插件提供的。最基本的,当测试失败时,让 Jenkins 记录这些失败以供汇报以及在 web UI 中可视化是很有用的。下面的例子使用由 JUnit 插件提供的 junit
步骤。
pipeline {
agent any
stages {
stage('Test') {
steps {
/* `make check` 在测试失败后返回非零的退出码;
* 使用 `true` 允许流水线继续进行
*/
sh 'make check || true'
junit '**/target/*.xml'
}
}
}
}
- 使用内联的 shell 条件(
sh 'make || true'
)确保sh
步骤总是看到退出码是零,使junit
步骤有机会捕获和处理测试报告。在下面处理故障一节中,对它的替代方法有更详细的介绍。 - junit 捕获并关联与包含模式(
\**/target/*.xml
)匹配的 JUnit XML 文件。
部署
部署可以隐含许多步骤,这取决于项目或组织的要求,并且可能是从发布构建的交付件到 Artifactory 服务器,到将代码推送到生产系统的任何东西。 在示例流水线的这个阶段,“Build(构建)” 和 “Test(测试)” 阶段都已成功执行。从本质上讲,“Deploy(部署)” 阶段只有在之前的阶段都成功完成后才会进行,否则流水线会提前退出。
pipeline {
agent any
stages {
stage('Deploy') {
when {
expression {
currentBuild.result == null || currentBuild.result == 'SUCCESS'
}
}
steps {
sh 'make publish'
}
}
}
}
使用Jenkinsfile工作
字符串插值
Jenkins 使用与 Groovy 相同的规则进行字符串插值。 Groovy 的字符串插值支持可能会使很多新手感到困惑。尽管 Groovy 支持使用单引号或双引号声明一个字符串,例如:
def singlyQuoted = 'Hello'
def doublyQuoted = "Word"
只有后面的字符串才支持基于美元符($
)的字符串插值,例如:
def username = 'Jenkins'
echo 'Hello Mr. ${username}'
echo "I said, Hello Mr. ${username}"
使用环境变量
Jenkins 流水线通过全局变量 env 提供环境变量,它在 Jenkinsfile 文件的任何地方都可以使用。Jenkins 流水线中可访问的完整的环境变量列表记录在 ${YOUR_JENKINS_URL}/pipeline-syntax/globals#env
,并且包括:
BUILD_ID
当前构建的 ID,与 Jenkins 版本 1.597+ 中创建的构建号 BUILD_NUMBER 是完全相同的。
BUILD_NUMBER
当前构建号,比如 “153”。
BUILD_TAG
字符串 jenkins-${JOB_NAME}-${BUILD_NUMBER}
。可以放到源代码、jar 等文件中便于识别。
BUILD_URL
可以定位此次构建结果的 URL(比如 http://buildserver/jenkins/job/MyJobName/17/ )
EXECUTOR_NUMBER
用于识别执行当前构建的执行者的唯一编号(在同一台机器的所有执行者中)。这个就是你在“构建执行状态”中看到的编号,只不过编号从 0 开始,而不是 1。
JAVA_HOME
如果你的任务配置了使用特定的一个 JDK,那么这个变量就被设置为此 JDK 的 JAVA_HOME。当设置了此变量时,PATH 也将包括 JAVA_HOME 的 bin 子目录。
JENKINS_URL
Jenkins 服务器的完整 URL,比如 https://example.com:port/jenkins/ (注意:只有在“系统设置”中设置了 Jenkins URL 才可用)。
JOB_NAME
本次构建的项目名称,如 “foo” 或 “foo/bar”。
NODE_NAME
运行本次构建的节点名称。对于 master 节点则为 “master”。
WORKSPACE
通过Git拉取源码构建项目的变量
GIT_BRANCH
GIT_COMMIT
GIT_PREVIOUS_COMMIT
GIT_PREVIOUS_SUCCESSFUL_COMMIT
GIT_URL
workspace 的绝对路径。
引用或使用这些环境变量就像访问 Groovy Map 的 key 一样, 例如:
pipeline {
agent any
stages {
stage('Example') {
steps {
echo "Running ${env.BUILD_ID} on ${env.JENKINS_URL}"
echo "Running $env.BUILD_ID on $env.JENKINS_URL"
echo "Running ${BUILD_ID} on ${JENKINS_URL}"
}
}
}
}