Pipeline语法

  • 介绍

本文基于入门介绍,仅仅时一个语法参考。至于如何在特定的例子中运用Pipeline语法,请参考Jenkins Pipeline。从插件Pipeline plugin的2.5版本开始,Pipeline支持两种格式的语法。对于它们之间的区别请参考语法对比。

正如在入门介绍里说的,流水线最主要的就是”步骤“。基本上,就是步骤来告诉Jenkins该干什么,它是申明式和脚本式流水线语法的基础。

你可以在流水线步骤参考中,找到一份可用的步骤列表。

  • 申明Pipeline

申明式流水线是最近添加到Jenkins流水线功能中的,这种语法更加简单。

所有合法的申明式流水线必须在 pipeline 代码块中,例如:

在申明式流水线中,基本的语句和表达式是遵循 Groovy语法 ,但是有以下几个例外:

流水线的顶层必须是一个代码块: pipeline { }

不需分号作为语句的分隔符。每个语句单独占一行

只能包括段落、步骤、或者赋值语句

属性引用语句被当作无参数的方法调用。例如:input会当作方法input()

  • 段落

在申明式流水线中,通常包括一个或者多个指令或者步骤。

  • 代理agent

代理指定了整个流水线或者特定的阶段的运行环境。它必须在pipeline块的顶层定义,而在阶段中是可选的。

参数

为了支持多种情况的流水线使用场景,代理(agent)支持几种不同类型的参数。这些参数既可以在顶层的pipeline块也可以在每个阶段中使用。

any

在任意可用的代理上执行流水线。例如: agent any

none

当在顶层的pipeline块中使用时,不会有全局的代理分配给整个流水线,每个阶段都需要包含个人的代理。例如:agent none

label

根据Jenkins环境中提供的标签,确定一个可用的代理来chiding流水线或者阶段。例如:agent { label 'my-defined-label' }

node

agent { node { label 'labelName' } } 和 agent { label 'labelName' }一样,但是 node 允许增加选项(例如 customWorkspace

docker

在指定的容器里执行流水线或者阶段,容器会被动态分配到预先配置好的基于Docker的流水线节点,或者通过label参数来匹配。docker也有一个可选参数args,该参数会直接传递给docker run来执行;还有一个alwaysPull 选项,及时镜像名已经存在了依然会强制执行docker pull。例如:agent { docker 'maven:3-alpine' } 或者:

 dockerfile

由码线中的Dockerfile构建出来的容器,执行流水线或者阶段。为了使用该特性,Jenkinsfile 必须是在多分支流水线或者从SCM中加载。约定Dockerfile 在码线的根目录中,可以是agent { dockerfile true } 。如果Dockerfile 在另外一个目录中,可以使用参数dir :agent { dockerfile { dir 'someSubDir' } } 。如果Dockerfile 有其他的名称,你可以通过参数filename 指定文件名称。你可以通过参数additionalBuildArgs 给命令docker build ... 传递额外的选项,例如agent { dockerfile { additionalBuildArgs '--build-arg foo=bar' } } 。例如:一个码线有文件build/Dockerfile.build,并需要一个构建参数version

通用选项Common Options

有一些选项可以在多种代理实现中使用。没有指定的话,就不是必须的。

label

字符串。可以在流水线或者 stage上。

该选项可以在 nodedocker 和 dockerfile中使用,但对于 node是必须的。

customWorkspace

字符串。指定工作空间,而不使用默认的。可以是相对于节点上的根工作空间,也可以是绝对路径。例如:

该选项可以用在 node, docker 和 dockerfile

reuseNode

布尔值,默认为false。如果为true,则在相同的工作空间中运行,而不是每次创建新的。

该选项可以在 docker 和 dockerfile中使用,而且只有在 agent 配置到单独的 stage中才能使用。

Jenkinsfile (Declarative Pipeline)
Jenkinsfile (Declarative Pipeline)
  • post

 

  • 阶段stages
  • 步骤steps
  • 指令Directive
  • 环境environment
  • 选项options
  • 参数parameters
  • 触发器triggers
  • 阶段stage
  • 工具tools
  • 输入input
  • 条件when

 

指令when 允许流水线根据条件来决定是否要执行特定的阶段。指令when 必须至少包含一个条件。如果指令when 包含多个条件,所有的条件都必须为true才可以会执行该阶段。这和allOf 条件是类似的(请参考下面的例子)。

更复杂的结构可以使用嵌套:not, allOf,或 anyOf。可以嵌套任意深度。

内置条件:

分支branch
当匹配分支名称时执行,例如: when { branch 'master' }。这只有在多分支流水线中才可以使用。
环境environment
当指定的环境变量值和给定的一样时执行,例如: when { environment name: 'DEPLOY_TO', value: 'production' }
表达式expression
当Groovy表达式为true时,例如: when { expression { return params.DEBUG_BUILD } }
not
当嵌套条件值为false时执行。必须包含一个条件。例如: when { not { branch 'master' } }
allOf
当嵌套条件为true时执行。必须至少包含一个。例如: when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }
anyOf
当任意一个表达式为true时。必须至少包含一个。例如: when { anyOf { branch 'master'; branch 'staging' } }

在进入阶段的代理节点之前计算when表达式

默认情况下,when 条件是在进入阶段的代理之后计算。然而,通过增加选项beforeAgent 可以改变。如果把选项beforeAgent 设置为true,就会首先计算when 条件,只有在值为true时才会进入。

示例1:

Jenkinsfile (Declarative Pipeline)

示例2:

示例3:

示例4:

示例5:

示例6:

  • 并发parallel

阶段是可以并行执行的。注意,在阶段内必须要只能有一个steps 或 parallel。任何包含parallel 的阶段不能包括agent 或 tools,也不包括steps

另外,当有一个任务失败后,你可以强制整个并行失败。只要设置参数failFast 为true就可以。

示例:

  • 步骤
  • 脚本

script 可以在申明时的流水线中执行脚本时步骤。大多数情况下 script 是用不到的。

示例:

  • 脚本化流水线

脚本化流水线可以使用普通的Groovy语法,因此,它可以实现很强大的功能。

  • 流程控制
  • 步骤
  • 语法对比

在Jenkins流水线刚被开发出来时,采用Groovy作为基础。Jenkins已经很长时间内采用嵌入式的Groovy引擎提供了高级脚本功能给管理员和普通用户。也就是说,基于Groovy脚本的流水线指的就是脚本化流水线。

As it is a fully featured programming environment, Scripted Pipeline offers a tremendous amount of flexibility and extensibility to Jenkins users. The Groovy learning-curve isn’t typically desirable for all members of a given team, so Declarative Pipeline was created to offer a simpler and more opinionated syntax for authoring Jenkins Pipeline.

The two are both fundamentally the same Pipeline sub-system underneath. They are both durable implementations of “Pipeline as code.” They are both able to use steps built into Pipeline or provided by plugins. Both are able to utilize Shared Libraries

Where they differ however is in syntax and flexibility. Declarative limits what is available to the user with a more strict and pre-defined structure, making it an ideal choice for simpler continuous delivery pipelines. Scripted provides very few limits, insofar that the only limits on structure and syntax tend to be defined by Groovy itself, rather than any Pipeline-specific systems, making it an ideal choice for power-users and those with more complex requirements. As the name implies, Declarative Pipeline is encourages a declarative programming model. [3] Whereas Scripted Pipelines follow a more imperative programming model.. [4]

  • 参考

本文为原创,如果您当前访问的域名不是surenpi.com,请访问“素人派”。

发表评论

电子邮件地址不会被公开。 必填项已用*标注