什么是 Jenkins Pipline
Jenkins 流水线是一套插件,它集成持续交付流水线到 Jenkins。流水线提供了一组可扩展的工具,用于通过流水线语法将简单到复杂的交付流水线建模为“代码”.对流水线的定义通常写在一个文本文件中Jenkinsfile
,该文件可以被提交到项目的源代码的控制仓库,这是"流水线即代码"的表现形式。
为什么要使用 Jenkins Pipeline
本质上,Jenkins是一个自动化引擎,流水线向 Jenkins 中添加了一组强大的工具,支持通过对一系列的相关任务进行建模,用户可以利用流水线的很多特性:
- 流水线是在代码中实现的,通常会被一同提交到源代码控制,使团队有编辑,审查和迭代他们的交付流水线的能力。
- 流水线可以从 Jenkins 的主分支的计划内和计划外的重启中存活下来。
- 流水线可以有选择的停止或等待人工输入或批准,然后才能继续运行流水线。
- 流水线支持复杂的现实世界的 CD 需求,包括 fork/join,循环,并行执行工作的能力。
- 流水线插件支持扩展与其他插件集成
Jenkins Pipline 语法概述
Jenkinsfile
能使用两种语法进行编写 - 声明式和脚本化。
声明式和脚本化的流水线从根本上是不同的:
- 相比脚本化的流水线语法,声明式提供更丰富的语法特性,
- 声明式是为了使编写和读取流水线代码更容易而设计的。
然而,现实情况中,写到Jenkinsfile
中的许多单独的语法组件(或者 "步骤"),通常都是声明式和脚本化相结合
声明式流水线
在声明式流水线语法中,pipeline
块定义了整个流水线中完成的所有的工作。
pipeline {
agent any // 在任何可用的代理上,执行流水线或它的任何阶段
stages {
stage('Build') { // 定义 "Build" 阶段
steps {
// 执行与 "Build" 阶段相关的步骤
}
}
stage('Test') { // 定义"Test" 阶段
steps {
// 执行与"Test" 阶段相关的步骤
}
}
stage('Deploy') { // 定义 "Deploy" 阶段
steps {
// 执行与 "Deploy" 阶段相关的步骤
}
}
}
}
- pipline
- 是声明式流水线的一种特定语法,他定义了包含执行整个流水线的所有内容和指令的一个块
- agent
- 声明式流水线的一种特定语法,它指示 Jenkins 为整个流水线分配一个执行器 (在节点上)和工作区
- any:在任何可用的代理上执行流水线,配置语法
pipeline {
agent any
}
- none:表示该 Pipeline 脚本没有全局的 agent 配置。当顶层的 agent 配置为 none 时, 每个 stage 部分都需要包含它自己的 agent。配置语法
pipeline {
agent none
stages {
stage('Stage For Build'){
agent any
}
}
}
- label:以节点标签形式选择某个具体的节点执行 Pipeline 命令,例如:agent { label 'my-defined-label' }。节点需要提前配置标签。
pipeline {
agent none
stages {
stage('Stage For Build'){
agent { label 'role-master' }
steps {
echo "role-master"
}
}
}
}
- stage
- 声明式流水线中 stage 是必选的,是执行任务的概念性地不同的的子集
- steps
- 是声明式流水线的一种特定语法,它描述了在这个
stage
中要运行的步骤
脚本化流水线
在脚本化流水线语法中,一个或多个node
块在整个流水线中执行核心工作。 虽然这不是脚本化流水线语法的强制性要求
node { // 在任何可用的代理上,执行流水线或它的任何阶段
stage('Build') { // 定义 "Build" 阶段。 stage 块 在脚本化流水线语法中是可选的。 然而,在脚本化流水线中实现 stage 块 ,可以清楚的显示Jenkins UI中的每个 stage 的任务子集
// 执行与 "Build" 阶段相关的步骤
}
stage('Test') { // 定义 "Test" 阶段
// 执行与 "Test" 阶段相关的步骤
}
stage('Deploy') { // 定义 "Deploy" 阶段
// 执行与 "Deploy" 阶段相关的步骤
}
}
- node
- 脚本化流水线的特定语法,它指示 Jenkins 在任何可用的代理/节点上执行流水线,等同于声明式中的 agent
- stage
- 脚本化流水线中 stage 是可选的,是执行任务的概念性地不同的的子集,但定义 stage 可以在 UI 中清晰的看到不同模块的分割和执行状态
流水线示例
下面是对同一个任务过程的两种语法的示例
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'make'
}
}
stage('Test'){
steps {
sh 'make check'
junit 'reports/**/*.xml'
}
}
stage('Deploy') {
steps {
sh 'make publish'
}
}
}
}
node {
stage('Build') {
sh 'make'
}
stage('Test') {
sh 'make check'
junit 'reports/**/*.xml'
}
stage('Deploy') {
sh 'make publish'
}
}
语法比较
在 Jenkins 团队最开始设计 Jenkins 流水线的时候,他们选择 Groovy 作为其基础语法并设计了脚本化的流水线语法,使用嵌入式 Groovy 引擎来为管理员和用户提供高级脚本功能。
由于 Groovy 本身是一种具有功能齐全的编程语言环境,脚本化流水线为 Jenkins 用户提供了大量的灵活性性和可扩展性。 但是,Groovy 学习曲线通常不适合团队的所有成员,因此 Jenkins 团队重新设计了声明式的流水线来为编写 Jenkins 流水线提供一种更简单、更模板化的语法。
两者本质上是相同的流水线系统。都是 "流水线即代码" 的表现形式。它们都能够使用构建到流水线中或插件提供的步骤。但是它们的主要区别在于语法和灵活性。
- 声明式限制了用户必须使用更严格和预定义的结构, 使其成为更简单的持续交付流水线的理想选择。
- 脚本化提供了很少的限制,以至于对脚本和语法的唯一限制往往是由 Groovy 语法本身定义的,而不是任何特定于流水线的规则,这使其成为那些有更复杂需求的人的理想选择。
顾名思义,声明式流水线鼓励声明式编程模型。 而脚本化流水线遵循一个更命令式的编程模型
创建 Jenkins Pipline
流水线可以通过以下任一方式来创建:
- 通过经典 UI : 可以通过经典 UI 在 Jenkins 中直接输入基本的流水线。
- 在源码管理系统中 : 你可以手动编写一个
Jenkinsfile
文件,然后提交到项目的源代码管理仓库中。 - 通过 Blue Ocean : Blue Ocean 是 Jenkins 专门为 pipeline 设计的友好性界面版本,在 Blue Ocean 中通过可视化的方式设置一个流水线项目后,Blue Ocean UI 会帮你编写流水线的
Jenkinsfile
文件。