Jenkins - Pipeline详解
1 - Jenkins Pipeline
在Jenkins 2.0中,基于 Jenkins Pipeline,用户可以在一个 JenkinsFile 中快速实现一个项目的从构建、测试以到发布的完整流程,灵活方便地实现持续交付,并且可以保存和管理这个流水线的定义。
也就是说,Jenkins 2.0把Jenkins1.0中相关配置信息都转换成Code形式,即Pipeline as Code。
Jenkinsfile
- 是一个文本文件,包含了流水线的逻辑,定义了流水线的各个阶段,在每个阶段可以执行相应的任务;
- 是流水线概念在Jenkins中的表现形式,实现了构建步骤代码化、构建过程视图化;
- 不同的Jenkins Plugin 扩展了Pipeline DSL可用的步骤和操作。
Jenkins Pipeline的特点与优势
- 自动化:代码定义和实现持续交付流程的自动化,减少人工干预,降低出错风险,提高效率
- 易维护:维护和更改流程,只需更改代码
- 易观测:通过Pipeline的图形界面,方便用户查看和追踪流程的状态
- 易集成:可与外部系统集成,从而实现更强大的持续交付流程
- 易扩展:可使用各种插件扩展功能,从而满足用户的不同需求
1.1 使用条件
- Jenkins 2.x或更高版本
- 安装了Pipeline插件
1.2 创建方式
以流水线任务为例:
在Jenkins job配置页面的pipeline部分,可以选择pipeline script 或者 pipeline script from SCM
点击“Pipeline Syntax”可以查看Pipeline内置文档。
- pipeline script : 直接script输入框里面输入pipeline script语句即可
- pipeline script from SCM : 配置代码存储地址,并指定Jenkinsfile路径
1.3 pipeline 语法
通过Groovy语言来实现pipeline。
2 - 脚本式(Scripted Pipeline)
在Scripted Pipeline的JenkinsFile 中可以定义多个 Groovy 函数来扩展 Jenkins Pipeline 的能力,实现脚本式pipeline,其实就是在写Groovy代码。
因此这种方式受 Jenkins 的限制较少,可以灵活控制和定义一个流水线,实现复杂的功能。
- Node: Jenkins 节点,是执行 Step 的具体运行环境
- Stage: 每个 Stage 代表一组操作,是一个逻辑分组的概念,可以跨多个 Node
- Step: 最基本的操作单元,例如:执行Shell脚本、构建Docker镜像等。
3 - 声明式(Declarative Pipeline)
更简单更结构化的语法,更适合阅读和理解。
使用预定义的结构,Jenkins 已经预置了很多描述流水线的结构,可以快速建立流水线
虽然同样支持写 Groovy 脚本,官方推荐将Groovy 脚本内容定义在 Shared Libraries 中
由于需要使用预定义的结构,对于复杂性的功能难以有效支持
为与BlueOcean脚本编辑器兼容,通常建议使用Declarative Pipeline的方式进行编写,这种语法结构也会是未来的趋势。
3.1 常用结构
所有有效的Declarative Pipeline必须包含在一个pipeline块内。
除了个别限定外,Declarative Pipeline中的基本语句和表达式遵循与Groovy语法相同的规则。
pipeline {
agent {}
options {}
parameters {}
stages {
stage {
when {}
steps {}
}
parallel {
stage {}
stage {}
}
}
post {
always {}
}
}
stages 阶段集合
- 是stage的集合,Pipeline完成的所有实际工作都将包含在一个或多个stage指令中
- 一般情况下,stages至少包含一个stage指令,用于连接各个交付过程,如构建,测试和部署等
stage 执行阶段
- 用来区分pipeline的各个阶段
- 包含的steps部分定义了具体操作内容
- stage与stages可以互相嵌套,stage中可以包含stages
steps 操作步骤
- 包含一个或多个具体操作步骤
- 可以使用Steps reference(https://
/pipeline-syntax/html)中的所有可用步骤 - script步骤可以提供一个有效的功能增强
3.2 常用语法
# agent 节点
- 通过 agent 定义整个Pipeline或特定阶段的执行环境,实现灵活调度资源
- Agent在Pipeline中必需存在
- 参数
- any : 在任何可用的agent 上执行Pipeline或stage
- none : 当在pipeline块的顶层使用none时,将不会为整个Pipeline运行分配全局agent ,每个stage部分将需要包含其自己的agent部分
- label : 指定具体的 Jenkins Slave Node,也可以单独指定Stage的执行环境
- docker : 执行Pipeline或stage时会动态启动一个docker节点执行Pipelines,还可以接受一个args,直接传递给docker run调用
- dockerfile : 使用从Dockerfile源存储库中包含的容器来构建执行Pipeline或stage
- node : 在node中可以定义 label 和 customWorkspace(自定义运行的工作空间)等
# environment 环境变量
- 可以为全局或stage定义变量,例如`environment { aaa = 'bbb' }`
- 通过 env 访问自定义的和Jenkins预置的环境变量,例如`${env.JOB_NAME}`
# parameters 参数
- 通过 parameters 定义参数,例如`parameters { string(defaultValue: "xxx", description: 'yyy', name: 'zzz') }`
- 通过 params 访问构建时的参数,例如`${params.xxx}`
- 支持booleanParam, choice, credentials, file, text, password, string等参数类型
- 通过代码定义参数,必须执行pipeline初始化(执行一次)之后,才会将参数显示在UI页面
# options 运行选项
- 配置Pipeline专用选项,定义pipeline的运行参数
- 可以在pipeline{}中定义,也可以在stage{}中定义
- buildDiscarder : pipeline保持构建的最大个数
- disableConcurrentBuilds : 不允许并行执行Pipeline,可用于防止同时访问共享资源等
- skipStagesAfterUnstable : 一旦构建状态进入了“Unstable”状态,就跳过此stage
- timeout : 设置Pipeline运行的超时时间,例如`options { timeout(time: 1, unit: 'HOURS') }`
- retry : 失败后,重试整个Pipeline的次数,例如`options { retry(3) }`
- timestamps : 预定义由Pipeline生成的所有控制台输出时间,例如`options { timestamps() }`
# tools 工具
- 通过tools可自动安装工具,并放置环境变量到PATH。如果agent none,将被忽略。
- 工具名称必须在Jenkins的全局工具配置中存在。
- 示例`tools { maven 'apache-maven-3.5.2' }`
# sh
用于执行 Shell 命令,可以使用三双引号包裹多条命令或者Shell脚本
# script
指令用于在Pipeline中执行一段Groovy脚本实现更复杂的逻辑
# when 条件限定
- 通过 when 根据给定的条件确定是否执行该阶段,控制流程走向
- 必须至少包含一个条件
- 多种内置条件
- branch : 当正在构建的分支与给出的分支模式匹配时执行(仅适用于多分支Pipeline)
- environment : 当指定的环境变量设置为给定值时执行
- expression : 当指定的Groovy表达式求值为true时执行
- not : 当嵌套条件为false时执行。必须包含一个条件
- allOf : 当所有嵌套条件都为真时执行。必须至少包含一个条件
- anyOf : 当至少一个嵌套条件为真时执行。必须至少包含一个条件
# Parallel 并发执行
- 通过 parallel{} 定义并发步骤
- 对耗时长,相互不存在依赖的stage可以使用此方式提升运行效率
- 除了parallel stage,单个parallel里的多个step也可以使用并行的方式运行
- 可以通过`failFast: true`语句来限定当其中一个阶段失败,则全部失败
# timeout&retry 超时&重试
- 通过 timeout 定义超时时间,例如`timeout(time: 3, unit: "MINUTES") { xxxyyyzzz }`
- 通过 retry 定义重试次数,例如`retry(3) { xxxyyyzzz }`
# post 构建后操作
- 通过 post 定义资源清理、通知等,也就是定义Pipeline或stage运行结束时的操作
- 与Stages平级
- 有多种不同的condition: always、success、failure、unstable、changed
- always : 总是运行,无论Pipeline运行的完成状态如何。
- changed : 只有当前Pipeline运行的状态与先前完成的Pipeline的状态不同时,才能运行。
- failure : 仅当前Pipeline处于“失败”状态时才运行,通常在Web UI中用红色指示表示。
- success : 仅当前Pipeline具有“成功”状态时才运行,通常在具有蓝色或绿色指示的Web UI中表示。
- unstable : 仅当前Pipeline具有“不稳定”状态时才运行,通常在具有黄色指示的Web UI中表示。
- aborted : 只有当前Pipeline处于“中止”状态时,才会运行,通常在具有灰色指示的Web UI中表示。
# triggers 触发器
- 通过 triggers 定义Pipeline自动化触发的方式
- cron : 以cron风格来定义Pipeline触发的常规间隔,定时触发
- pollSCM : 以cron风格来定义Jenkins检查SCM源更改的常规间隔。如果存在新的更改,则Pipeline将被重新触发
- upstream : 由上游作业触发,可以根据作业状态判断
# input 手工输入
- 通过 input{}语句块可以在阶段运行前弹出一个选项框页面和用户进行交互(参数输入、步骤选择等)
- 在stage{}中使用input{},结合message、parameters{}和steps{}可以实现执行过程中提示用户进行确认和选择的场景
4 - 声明式与脚本式的比较
都是pipeline代码的持久实现,都能够使用pipeline内置的插件或者插件提供的steps,两者都可以利用共享库扩展。
不同之处在于语法和灵活性:
- Declarative pipeline对用户来说,语法更严格,有固定的组织结构,更容易生成代码段,使其成为用户更理想的选择。
- Scripted pipeline更加灵活,因为Groovy本身只能对结构和语法进行限制,对于更复杂的pipeline来说,用户可以根据自己的业务进行灵活的实现和扩展。
5 - Jenkins Pipeline 语法及开发工具
使用生成器辅助编写 Pipeline 脚本,减少手动编写的工作量。
- 片段生成器: 帮助用户以图形界面的方式生成Pipeline脚本的代码片段
- 声明式指令生成器(Declarative Directive Generator):主要用于生成声明式语法风格Pipeline指令的代码片段
本机信息
- 代码段生成器 Snippet Generator:
https://<jenkins-server-url>/pipeline-syntax/
,插件和内置方法的用法,需先安装对应插件 - 声明式语法生成器 Declarative Directive Generator:
https://<jenkins-server-url>/directive-generator/
,生成对应语法代码 - 流水线语法html文件:
https://<jenkins-server-url>/pipeline-syntax/html
- 环境变量:
https://<jenkins-server-url>/env-vars.html/
- 全局变量参考 Global Variable Reference:
https://<jenkins-server-url>/pipeline-syntax/globals
,系统内置变量 - IntelliJ IDEA GDSL:
https://<jenkins-server-url>/pipeline-syntax/gdsl
官网在线信息
- 流水线在线文档 Online Documentation: https://www.jenkins.io/doc/book/pipeline/
- 声明式语法在线文档 Declarative Online Documentation: https://jenkins.io/doc/book/pipeline/syntax/
- 示例参考 Examples Reference: https://www.jenkins.io/doc/pipeline/examples/
5.1 变量
- 环境变量:
https://<jenkins-server-url>/env-vars.html/
- 全局变量参考 Global Variable Reference:
https://<jenkins-server-url>/pipeline-syntax/globals
- 全局变量在pipeline{}中定义,在所有阶段生效。局部变量在stage{}中定义,仅在当前阶段生效。
- 局部变量优先级高于全局变量。
5.2 代码段生成器
- Snippet Generator:
https://<jenkins-server-url>/pipeline-syntax/
- 获得插件和内置方法的用法,需先安装对应插件
- 内置的“Snippet Generator”程序有助于为单个步骤生成代码段。
- 只需要选择所需的步骤并配置,然后单击生成Pipeline脚本以创建一个可以复制并粘贴到Pipeline中的Pipeline代码段
5.3 流水线回放
- 可以在不修改项目设置,使用原pipeline代码进行调试
- 允许修改并回放一个构建过的流水线,就算是已经加载过的步骤,同样能够被修改
6 - 参考信息
- Jenkins中文文档 : https://www.w3cschool.cn/jenkins/
- 用代码描述流水线-Jenkins Pipeline 详解 : http://www.uml.org.cn/jchgj/201802051.asp
行动是绝望的解药!
欢迎转载和引用,但请在明显处保留原文链接和原作者信息!
本博客内容多为个人工作与学习的记录,少数内容来自于网络并略有修改,已尽力标明原文链接和转载说明。如有冒犯,即刻删除!
以所舍,求所得,有所获,方所成。