国际惯例
什么是jenkins pipeline
Jenkins Pipeline(或简称为“Pipeline”,大写字母为“P”)是一套插件,支持在Jenkins中实现和集成连续交付管道。
持续交付(CD)管道是将软件从版本控制直接传递给用户和客户的过程的自动表达。对软件的每次更改(在源代码管理中提交)都会在发布的过程中经历一个复杂的过程。此过程涉及以可靠且可重复的方式构建软件,以及通过多个测试和部署阶段推进构建的软件(称为“构建”)。
Pipeline提供了一组可扩展的工具,用于通过管道域特定语言(Pipeline domain-specific language)语法“作为代码”对简单到复杂的传输管道进行建模。
Jenkins管道的定义被写入一个文本文件(称为Jenkinsfile),该文件又可以提交给项目的源代码控制库。这是“作为代码的管道”的基础;将CD管道视为应用程序的一部分,以便像任何其他代码一样进行版本控制和审查。
语法Pipeline Syntax
- Jenkinsfile可以使用两种语法编写 – Declarative和Scripted。
- 声明性和脚本化管道的构造从根本上不同。
Declarative Pipeline
在Declarative Pipeline语法中,pipeline块定义了整个管道中完成的所有工作。
在Declarative Pipeline中有效的基本语句和表达式遵循与Groovy语法相同的规则,但有以下例外:
- Pipeline的顶级必须是一个块,特别是:pipeline {}
- 没有分号作为语句分隔符。 每个声明都必须独立
- 块只能由章节,指令,步骤或赋值语句组成。(Sections, Directives, Steps, or assignment statements.)
- 属性引用语句被视为无参数方法调用。 例如,输入被视为输入()
您可以使用声明性指令生成器(Declarative Directive Generator)来帮助您开始配置声明性管道中的指令和部分。
章节Sections
通常包含一个或多个Directives or Steps。
关键字 | 意义 | 常见选项 |
---|---|---|
agent | 指定整个管道或特定阶段在Jenkins环境中的执行位置,具体取决于代理程序部分的放置位置。 该部分必须在管道块内的顶层定义,但阶段级使用是可选的。 | any, none, label, node, docker, dockerfile |
post | post部分定义了一个或多个附加步骤,这些步骤在完成Pipeline或stage的运行时运行(取决于Pipeline中post部分的位置)。 | always, changed, fixed, regression, aborted, failure, success, unstable, cleanup |
stages | 包含一个或多个阶段指令的序列 | |
steps | 定义了在给定阶段指令中要执行的一系列一个或多个步骤。 |
指令Directives
关键字 | 意义 | 常见选项 |
---|---|---|
environment | 指定一系列键 – 值对,它们将被定义为所有步骤或阶段特定步骤的环境变量,具体取决于环境指令在管道中的位置。 | credentials() |
options | 允许在Pipeline中配置特定于Pipeline的选项。 | buildDiscarder, checkoutToSubdirectory, disableConcurrentBuilds, newContainerPerStage, overrideIndexTriggers, preserveStashes, quietPeriod, retry, skipDefaultCheckout,skipStagesAfterUnstable, timeout,timestamps |
parameters | 提供了用户在触发Pipeline时应提供的参数列表 | string, test, booleanParam, choice, file, password |
triggers | 定义了重新触发管道的自动方式。 对于与GitHub或BitBucket等源集成的管道,可能不需要触发器,因为基于webhooks的集成可能已经存在。 目前可用的触发器是cron,pollSCM和upstream。 | cron, pollSCM, upstream |
stage | 位于阶段部分。Pipeline所做的所有实际工作都将包含在一个或多个阶段指令中。 | |
tools | 定义用于自动安装和放置PATH的工具的部分。 如果未指定agent none,则忽略此项。引用的工具名必须在Manage Jenkins → Global Tool Configuration中预定义 | maven,jdk,gradle |
input | 允许您使用输入步骤提示输入。 在应用any选项之后,在进入stage的agent或评估其状态之前,stage将暂停。 如果输入被批准,则stage将继续。 作为输入提交的一部分提供的任何参数将在该阶段的其余部分的环境中可用 | message, id, ok, submitter, submitterParameter, parameters |
when | 允许Pipeline根据给定的条件确定是否应该执行该阶段。 when指令必须至少包含一个条件。 | beforeAgent, branch, buildingTag, changelog, changeset, changeRequest, environment, equal, expression, tag, not, allof, anyof |
并行串行
串行stages – Sequential Stages
声明性管道中的阶段可以按顺序声明要在其中运行的嵌套阶段的列表。
请注意,一个stage有且仅有一个steps, parallel, or stages,最后一个是连续阶段。
stages中各stage的阶段不能包含parallel或stage(s)本身,但它们允许使用阶段的所有其他功能,包括agent, tool, when。
串行stagesのExample
并行stages – Parallel
在并行块中声明多个嵌套阶段,这些阶段将并行执行。
关键字 – failFast
并行stagesのExample
Steps
使用step段
记录的所有可用步骤
脚本步骤script
步骤采用Scripted Pipeline块并在Declarative Pipeline中执行。 对于大多数用例,声明性管道中的脚本步骤应该是不必要的,
应将非平凡大小和/或复杂性的脚本块移动到共享库( Shared Libraries
)中
Scripted Pipeline
Scripted Pipeline与Declarative Pipeline一样,构建在底层Pipeline子系统之上。
与Declarative不同,Scripted Pipeline实际上是一个使用Groovy构建的通用DSL 。
Groovy语言提供的大多数功能都可供Scripted Pipeline的用户使用,这意味着它可以是一个非常富有表现力和灵活性的工具,可以用来创建连续的传递管道。
在脚本管道语法中,一个或多个节点块在整个管道中执行核心工作。 虽然这不是Scripted Pipeline语法的强制要求,但将Pipeline的工作限制在节点块中会做两件事:
- 通过向Jenkins队列添加项目来计划要运行的块中包含的步骤。 只要执行程序在节点上空闲,步骤就会运行。
- 创建工作空间(特定于该特定管道的目录),可以对从源控件检出的文件执行工作。
流程控制Flow Control
Scripted Pipeline从Jenkins文件的顶部向下连续执行,就像Groovy或其他语言中的大多数传统脚本一样。
因此,提供流控制依赖于
- Groovy表达式。
- try/catch/finally blocks
Steps
脚本管道不会引入任何特定于其语法的步骤; 管道步骤参考包含管道和插件提供的所有步骤,比如aws ec2。
与普通groovy的区别 Differences from plain Groovy
为了提供持久性,这意味着运行管道可以在Jenkins主服务器重新启动后继续存在,Scripted Pipeline必须将数据序列化回主服务器。由于这个设计要求,一些Groovy习语,例如collection.each {item→/ * perform operation * /}不完全受支持。
Declarative Pipeline与Scripted Pipeline异同
当Jenkins Pipeline首次创建时,Groovy被选为基础。 Jenkins长期以来一直使用嵌入式Groovy引擎为管理员和用户提供高级脚本编写功能。此外,Jenkins Pipeline的实现者发现Groovy是构建现在被称为“Scripted Pipeline”DSL的坚实基础。
由于它是一个功能齐全的编程环境,Scripted Pipeline为Jenkins用户提供了极大的灵活性和可扩展性。 Groovy学习曲线通常不适合给定团队的所有成员,因此创建Declarative Pipeline是为了为Jenkins Pipeline创作提供更简单,更具见解性的语法。
两者基本上都是相同的Pipeline子系统。它们都是“Pipeline as code”的持久实现。他们都能够使用Pipeline内置的步骤或插件提供的步骤。两者都能够使用共享库。
然而,它们的区别在于语法和灵活性。声明性限制了用户可以使用更严格和预定义的结构,使其成为更简单的连续交付管道的理想选择。 Scripted提供的限制非常少,因为结构和语法的唯一限制往往由Groovy本身定义,而不是任何管道专用系统,使其成为高级用户和需求更复杂的用户的理想选择。顾名思义,Declarative Pipeline鼓励声明性编程模型。 [3]而脚本管道遵循更为命令式的编程模型。