正如
在SCM中定义流水线中所讨论的,Jenkinsfile
是一个文本文件,它包含了 Jenkins 流水线的定义并被检入源代码控制。以下流水线实现了基本的三个阶段的连续交付。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Building..'
}
}
stage('Test') {
steps {
echo 'Testing..'
}
}
stage('Deploy') {
steps {
echo 'Deploying....'
}
}
}
}
Jenkinsfile (Scripted Pipeline)
node {
stage('Build') {
echo 'Building....'
}
stage('Test') {
echo 'Testing....'
}
stage('Deploy') {
echo 'Deploying....'
}
}
不是所有的流水线都有相同的三个阶段, 但这是一个很好的起点,可以为大多数项目定义它们。下面这一节将演示在 Jenkins 的测试安装中一个简单流水线的创建和执行。
使用文本编辑器, 理想情况,它支持
Groovy
语法高亮, 在项目的根目录下创建一个 Jenkinsfile
。
上面的声明式流水线示例包含了实现连续交付流水线的最低必要结构。 agent
directive是必需的, 它指示Jenkins为流水线分配一个执行器和工作区。 没有 agent
指令的话, 声明式流水线不仅无效, 它也不可能完成任何工作! 通过默认的 agent
指令确保源代码仓库被检出并在后续阶段中提供步骤。
脚本化流水线的更先进的用法, 上面的 node
例子是关键的第一步,因为它为流水线分配了一个执行器和工作区。
本质上, 在没有 node
的情况下, 流水线无法工作! 从 node
内,
业务的第一步是检出这个项目的源代码。由于 Jenkinsfile
被直接从源代码控制中拉取出来,流水线提供了一个快速且简单的方式来访问源代码的正确修改 。
Jenkinsfile (Scripted Pipeline)
node {
checkout scm (1)
/* .. snip .. */
}
<1>checkout
步骤将会从源代码控制中检出代码;scm
是一个特定的变量, 它指示 checkout
步骤 clone 触发流水线运行的特定修改。
构建
对于许多项目来说, 流水线中 "work" 的开始就是 "build" 阶段。通常流水线的这个阶段是源代码组装, 编译, 或打包。 Jenkinsfile
文件 not 替代现有的例如 GNU/Make、 Maven、 Gradle 等的构建工具,但可以将其视为一个将项目的开发周期的多个阶段 (构建、 测试、 部署等) 绑定在一起的粘合层。
Jenkins 有许多插件用于在一般使用中实际调用任何构建工具, 但是这个例子只需要从 shell 步骤(sh
)调用 make
。sh
步骤假设系统是 Unix /基于 Linux 的, 对于基于 Windows 的系统可以使用 bat
。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'make' (1)
archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true (2)
}
}
}
}
Jenkinsfile (Scripted Pipeline)
node {
stage('Build') {
sh 'make' (1)
archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true (2)
}
}
1 |
sh 步骤调用 make 命令,如果命令返回零退出代码继续。 任何非零的退出代码都将失败。 |
2 |
archiveArtifacts 捕获构建包含模式匹配的文件
(**/target/*.jar ) 并保存他们到 Jenkins主机用来以后检索。 |
|
档案组件不是使用外部组件仓库(例如 Artifactory 或 Nexu)的替代 ,被认为只是基本报告和文件档案。
|
测试
运行自动化测试是任何成功的持续交付过程的重要组成部分。因此,Jenkins 有许多测试记录, 报告,
和可视化工具, 这些都是由
许多插件提供的。
在基本级别上, 当测试失败, 让 Jenkins 记录 web UI 中报告和可视化的失败是很有用的。 下面的例子使用 junit
步骤, 由
JUnit 插件提供。
在下面的例子中, 如果测试失败, 流水线就会被标记为 "不稳定", 这是由 web UI 中的黄色球表示的。 基于记录的测试报告,
Jenkins 也可以提供历史趋势分析和可视化。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Test') {
steps {
/* `make check` returns non-zero on test failures,
* using `true` to allow the Pipeline to continue nonetheless
*/
sh 'make check || true' (1)
junit '**/target/*.xml' (2)
}
}
}
}
Jenkinsfile (Scripted Pipeline)
node {
/* .. snip .. */
stage('Test') {
/* `make check` returns non-zero on test failures,
* using `true` to allow the Pipeline to continue nonetheless
*/
sh 'make check || true' (1)
junit '**/target/*.xml' (2)
}
/* .. snip .. */
}
1 |
使用内联的 shell 条件 (sh 'make || true' ) 确保
sh 步骤总是看到零退出代码, 使 junit 步骤有机会
捕获和处理测试报告。在下一节[handling-failure]中,对它的替代方法有更详细的介绍。 |
2 |
junit 捕获并关联与包含模式 (**/target/*.xml )匹配的 JUnit XML 文件。 |
部署
部署可以暗示各种步骤, 这取决于项目或组织的要求,并且可能是从发布构建的组件到服务器, 到将代码推送到生产系统的任何东西。
在示例流水线的这个阶段, "Build" 和 "Test" 阶段都已成功执行。从本质上讲, "Deploy" 阶段只有在之前的阶段都成功完成后才会进行, 否则流水线会提前退出。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Deploy') {
when {
expression {
currentBuild.result == null || currentBuild.result == 'SUCCESS' (1)
}
}
steps {
sh 'make publish'
}
}
}
}
Jenkinsfile (Scripted Pipeline)
node {
/* .. snip .. */
stage('Deploy') {
if (currentBuild.result == null || currentBuild.result == 'SUCCESS') { (1)
sh 'make publish'
}
}
/* .. snip .. */
}
1 |
假设 currentBuild.result 变量允许流水线
确定是否有任何测试失败。在这种情况下, 值为
UNSTABLE 。 |
假设在示例的 Jenkins 流水线中所有的操作都执行成功,
每个成功的流水线运行会有相关的存档的构建组件,
报告在 Jenkins 中的的测试结果和完整的控制台输出。
脚本化的流水线包含条件测试(如上所示), 循环,
try/catch/finally 块甚至函数。 下一节将会详细的介绍高级的脚本化流水线语法。