
它是 Pipeline 插件套件的关键组件,为 Pipeline 步骤提供标准执行引擎,基于在 Jenkins 控制器进程中运行的自定义 Groovy 解释器。
(原则上,其他执行引擎也可以得到支持,FlowDefinition 是 API 入口点,但尚未有原型实现,而且编写一个引擎可能会是一项非常艰巨的工作。)
Pipeline Groovy 脚本代码,例如
retry(3) {
for (int i = 0; i < 10; i++) {
branches["branch${i}"] = {
node {
retry(3) {
checkout scm
}
sh 'make world'
}
}
}
parallel branches
会作为 Groovy 程序运行,其中某些被称为 步骤(steps) 的特殊函数调用会执行 Jenkins 特有的操作。
在此示例中,步骤 parallel 由本插件定义,而 、、 和 由 Pipeline 套件中的其他插件定义。全局变量 由 Pipeline Multibranch 插件定义。
noderetrycheckoutshscmGroovy 脚本会被编译为名为 WorkflowScript 的类,因此堆栈跟踪中显示的是这个名称,而不是脚本文件名(例如 Jenkinsfile)。
与从命令行运行的常规 Groovy 程序不同,每当执行 异步 操作(包括大多数 Pipeline 步骤)时,Pipeline 构建程序的完整状态都会保存到磁盘。
Jenkins 可能在构建运行期间重启,并会从上次中断的位置继续运行该程序。
这并非为了高效而设计,因此应仅限于与 Jenkins 功能直接相关的高级“胶水”代码;
您项目自身的构建逻辑应在构建节点上通过外部程序运行,放在 sh 或 bat 步骤中。
JIRA 中的 Pipeline Groovy 史诗 涵盖了 Groovy 解释器的一些已知限制。 这些问题源于 Pipeline 无法直接运行 Groovy,而必须拦截每个操作以保存程序状态。
Pipeline 沙箱史诗 涵盖了与 Groovy 沙箱 相关的问题,该沙箱用于防止恶意 Pipeline 脚本控制 Jenkins。 在禁用沙箱的情况下运行的脚本可以直接调用 Jenkins 内部 API,对于缺少的步骤功能来说,这可能是一种有用的变通方法,但出于安全原因,只有管理员才能批准此类脚本。
Pipeline 片段生成器史诗 涵盖了与根据实时配置表单提供步骤语法示例的工具相关的问题。
此插件以前称为“Workflow CPS plugin”或“Workflow Groovy Plugin”。因此,它的 Maven artifactId 是 workflow-cps,而不是 pipeline-groovy。
该插件使用 Groovy CPS 库 在程序编译时对其实施 续延传递风格变换。
标准 Groovy 编译器用于创建 AST,但字节码的生成会被 CompilationCustomizer 拦截,它会将大多数操作替换为抛出特殊“错误”CpsCallableInvocation 的变体。
然后,该错误会被引擎捕获,引擎利用其中的信息(例如即将传递给方法调用的参数)将控制权传递给下一个续延。
Pipeline 脚本可以使用 @NonCPS 注解标记指定的方法。
这些方法随后会被正常编译(沙箱安全检查除外),因此其行为与 Java 平台、Groovy 运行时或 Jenkins 核心或插件代码中的“二进制”方法非常相似。
@NonCPS 方法可以安全地将非 Serializable 对象用作局部变量,但不应接受不可序列化的参数,也不应返回或存储不可序列化的值。
您不能在 @NonCPS 方法中调用常规(CPS 变换后的)方法或 Pipeline 步骤,因此它们最适合用于在执行一些计算后,将摘要传回主脚本。
特别要注意,对二进制类中定义的方法(例如 Object.toString())的 @Override 通常应标记为 @NonCPS,因为调用它们的通常是二进制代码。
某些类型的对象本质上不适合按原样序列化,但我们希望在程序图中保留对它们的引用。
一个例子是 Executor(~ 内置节点或代理节点上的执行器槽位),它是 node 步骤传递给其块中任何步骤(尤其是 sh/bat)的上下文的一部分。
Pipeline 使用 Pickle API 来替换这些对象的可安全序列化版本。
重启后从磁盘加载 WorkflowRun 时,程序状态会被反序列化,pickles 也会并行反序列化(“再水合”)。
当所有 pickles 都成功反序列化并将生成的对象放回程序状态后,程序便会重新开始运行,并调用 StepExecution.onResume 以恢复定时器等。
所有程序逻辑都在“CPS VM 线程”内运行,它只是一个 Java 线程池,可以运行二进制方法并确定接下来要执行哪个续延。
parallel 步骤使用“绿色线程”(也称为协作式多任务处理):它会为各种操作记录逻辑线程(~ 分支)名称,但并不会真正同时运行它们。
程序看起来可能像是在并发执行任务,但这只是因为大多数步骤异步运行,而 VM 线程处于空闲状态,并且它们可能在时间上重叠。
除了在 VM 线程上实际运行 Groovy 代码的通常很短暂的时间段外,不会消耗任何 Java 线程。
执行器小部件仅在 VM 线程繁忙时才在内置节点上显示“轻量级”执行器的条目;通常它是隐藏的。