Jenkins - Pipeline详解

1 - Jenkins Pipeline

在Jenkins 2.0中,基于 Jenkins Pipeline,用户能够在一个 JenkinsFile 中快速实现一个项目的从构建、测试以到发布的完整流程,灵活方便地实现持续交付,而且能够保存和管理这个流水线的定义。
也就是说,Jenkins 2.0把Jenkins1.0中相关配置信息都转换成Code形式,即Pipeline as Code。html

Jenkinsfile 定义了流水线的各个阶段,在每一个阶段能够执行相应的任务,实现了构建步骤代码化、构建过程视图化。
不一样的Jenkins Plugin 扩展了Pipeline DSL可用的步骤和操做。node

1.1 使用条件

  • Jenkins 2.x或更高版本
  • 安装了Pipeline插件

1.2 建立方式

以流水线任务为例:
在Jenkins job配置页面的pipeline部分,能够选择pipeline script 或者 pipeline script from SCM
点击“Pipeline Syntax”能够查看Pipeline内置文档。docker

  • pipeline script : 直接script输入框里面输入pipeline script语句便可
  • pipeline script from SCM : 配置代码存储地址,并指定Jenkinsfile路径

2 - 脚本式(Scripted Pipeline)

在Scripted Pipeline的JenkinsFile 中能够定义多个 Groovy 函数来扩展 Jenkins Pipeline 的能力
所以这种方式受 Jenkins 的限制较少,能够灵活控制和定义一个流水线,实现复杂的功能。express

  • Node: Jenkins 节点,是执行 Step 的具体运行环境
  • Stage: 每一个 Stage 表明一组操做,是一个逻辑分组的概念,能够跨多个 Node
  • Step: 最基本的操做单元,例如:执行Shell脚本、构建Docker镜像等。

3 - 声明式(Declarative Pipeline)

使用预约义的结构,Jenkins 已经预置了不少描述流水线的结构,能够快速创建流水线
虽然一样支持写 Groovy 脚本,官方推荐将Groovy 脚本内容定义在 Shared Libraries 中
因为须要使用预约义的结构,对于复杂性的功能难以有效支持
为与BlueOcean脚本编辑器兼容,一般建议使用Declarative Pipeline的方式进行编写,这种语法结构也会是将来的趋势。apache

3.1 经常使用结构

全部有效的Declarative Pipeline必须包含在一个pipeline块内。
除了个别限定外,Declarative Pipeline中的基本语句和表达式遵循与Groovy语法相同的规则。并发

pipeline {
    agent {}
	options {}
	parameters {}
    stages {
        stage {
		    when {}
            steps {}
		}
		parallel {
		    stage {}
			stage {}
		}
	}
    post {
	   always {}
	}
}

stagesmaven

  • 是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(自定义运行的工做空间)等

	
环境变量
- 能够为全局或stage定义变量,例如`environment { aaa = 'bbb' }`
- 经过 env 访问自定义的和Jenkins预置的环境变量,例如`${env.JOB_NAME}`


参数
- 经过 parameters 定义参数,例如`parameters { string(defaultValue: "xxx", description: 'yyy', name: 'zzz') }`
- 经过 params 访问构建时的参数,例如`${params.xxx}`
- 支持booleanParam, choice, credentials, file, text, password, string等参数类型

options
- 在Pipeline自己内配置Pipeline专用选项
- 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' }`


when
- 经过 when 根据给定的条件肯定是否执行该阶段,控制流程走向
- 必须至少包含一个条件
- 多种内置条件
    - branch : 当正在构建的分支与给出的分支模式匹配时执行(仅适用于多分支Pipeline)
    - environment : 当指定的环境变量设置为给定值时执行
    - expression : 当指定的Groovy表达式求值为true时执行
    - not : 当嵌套条件为false时执行。必须包含一个条件
    - allOf : 当全部嵌套条件都为真时执行。必须至少包含一个条件
    - anyOf : 当至少一个嵌套条件为真时执行。必须至少包含一个条件

Parallel	
- 经过 parallel 定义并发步骤
- 对耗时长,相互不存在依赖的stage可使用此方式提高运行效率
- 除了parallel stage,单个parallel里的多个step也可使用并行的方式运行

	
超时、重试
- 经过 timout 定义超时时间,例如`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 定义Pipeline自动化触发的方式
- cron : 以cron风格来定义Pipeline触发的常规间隔
- pollSCM : 以cron风格来定义Jenkins检查SCM源更改的常规间隔。若是存在新的更改,则Pipeline将被从新触发

4 - 声明式与脚本式的比较

都是pipeline代码的持久实现,都可以使用pipeline内置的插件或者插件提供的steps,二者均可以利用共享库扩展。
不一样之处在于语法和灵活性:工具

  • Declarative pipeline对用户来讲,语法更严格,有固定的组织结构,更容易生成代码段,使其成为用户更理想的选择。可是
  • Scripted pipeline更加灵活,由于Groovy自己只能对结构和语法进行限制,对于更复杂的pipeline来讲,用户能够根据本身的业务进行灵活的实现和扩展。

5 - pipeline-syntax

5.1 变量

  • 环境变量: https:// /env-vars.html/
  • Global Variable Reference: https:// /pipeline-syntax/globals

5.2 代码段生成器

  • Snippet Generator: https:// /pipeline-syntax/
  • 内置的“Snippet Generator”程序有助于为单个步骤生成代码段。
  • 只须要选择所需的步骤并配置,而后单击生成Pipeline脚本以建立一个能够复制并粘贴到Pipeline中的Pipeline代码段。

6 - 参考信息