Declarative Pipeline 语法简介

发表时间 ·

本文介绍 Jenkins Declarative Pipeline 语法,由于 原文档 的信息过于繁杂,将常用的和罕见的混在一起,难以找到有用信息。本文试着将常用的收集在一起,方便查阅。背景知识请参考 《Jenkins Pipeline 语法简介》,另有《Jenkins Scripted Pipeline 语法简介》

基本特点

顾名思义,Declarative Pipeline 的设计意图,是使用户将所需要的 Pipeline 各种维度的参数 声明 出来,而不是描述出来。相对 Scripted Pipeline , Declarative Pipeline 缺少灵活性,所以 Scripted Pipeline 中使用的部分语法,Declarative Pipeline 中都不能直接使用。

Declarative Pipeline 的特点是结构化的声明语句,各模块的从属关系比较固定,类似填写Jenkins 配置 Job 页面的表单。固定格式的声明语句,还有利于从 BlueOcean 中查看工作流。

基本语法

Declarative Pipeline的基本单元是预设指令(directives)。并不需要记忆预设指令的用法,在 Jenkins 系统中专门有一个 指令生成器(Directive Generator)可供使用。

下面是个简单的例子:

pipeline {
  agent { label 'slave' }
  stages {
    stage('Source') { // 拉取代码
      steps {
        git branch: 'develop', url: 'https://'
      }
    }
    stage('Build') {
      tools {
        gradle ...
      }
    }
    stage('Test') {
      steps {
        script{
           mocha ...
        }
      }
    }
  }
}

各种预设指令(Directive)的从属关系如下:图中,实线框表示必选模块,虚线框表示可选模块。点击指令名称,可以直达对应章节。

下面逐项解释每一种 Directive 的参数和基本用法。

agent

agent 指令用于指定所在模块(pipeline、stage)的运行环境,可以是Jenkins 节点机或者 docker 容器。取值如下:

  • label
    表示节点机的 label,在 Jenkins 的 Node List 里设置
agent { label 'slave' }
  • none
    pipeline 顶层必须设置 agent,如果每个 stage 里有单独设置 agent,那么 pipeline 的 agent 需要设置为 none
agent none
  • docker
    指定在 docker 容器内执行
agent {
    docker {
         image 'images:tag' 
    }
}

如果 agent 需要用变量动态指定 label,请使用 Scripted Pipeline

environment

指定所在模块(pipeline、stage)的环境变量, key = value 的形式。Job 的参数,需要通过 environment 环境变量的方式 ${params.xxxx} 传递给执行脚本。

上图中的 type 就需要以下面的方式定义环境变量

environment {
    USER = 'username'
    PASSWORD = 'xxxxxx'
    type = "${params.type}"
}

triggers

指定如何触发 Pipeline ,这个选项里以时间条件触发最为常用:

triggers { 
    cron('H */4 * * 1-5')
}

crontab 的写法(用 H 代替 0)和设置页面上的一致。其实最方便的还是从界面上设置。

libraries

由于 Declarative Pipeline 的声明格式比较固定,如果有需要重复执行的语句片段,需要抽象为函数,就难以支持。可以使用 Shared Libraries 将共同的语句提取出来。

其实如果是简单的逻辑,可以使用Scripted Pipeline 实现。

options

这是所在模块(pipeline、stage)的运行参数设置,有下面一些用途:

options {
    timestamps()   //打开控制台日志的时间戳
    retry(3)    // 指定失败后的重试次数
    quietPeriod(30)    // 指定启动前等待的秒数
    timeout(time: 1, unit: 'HOURS')     // 指定任务的超时时间,超时将放弃该任务
}

parameters

这是 Job 的运行参数设置,决定 Build With Parameters 界面上的参数列表。只有当 Job 运行一次、解析一次 Jenkinsfile 以后才会更新在界面上。

在 Pipeline 文件的其他模块里,parameters 的设置以 params 对象形象出现,可以用来读取自定义的参数。各类型的参数定义如下:

parameters { 
    string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') 
    booleanParam(name: 'TOGGLE', defaultValue: true, description: 'Toggle this value')
    choice(name: 'CHOICE', choices: ['One', 'Two', 'Three'], description: 'Pick something')
    password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'Enter a password')
}

tools

这是在 Jenkins 里 Manage Jenkins – Global Tool Configuration 里设置过的工具

stages

stages是 pipeline 模块下的必选项,这是所有 stage 的集合,其中要包含至少一个 stage

stage

stage 真正执行语句的模块,有以下的特点:

  • 每一个 stage 在 Blue Ocean 界面上对应一个圆圈;
  • stage可以定义多个;
  • stage 有一个必选参数,就是名称,写在 stage 后面的括号里: stage('Example') {...}
  • stage 里有许多参数和 顶级 pipeline 相同,下面逐个介绍:
agent

如果 pipeline 中的 agent 设置为 none,则每个 stage 中必须设置 agent

environment

pipeline 里的 environment , 规定了当前 stage 内部的环境变量。

tools

pipeline 里的 tools , 规定了当前 stage 内部适用的工具。

input
在 stage 开始执行前,暂停执行stage,等待用户输入信息。并不适用全自动化流水线。
input {
  message '请输入信息'
  ok '确定'
}
when

条件判断(类似 if),决定所在的 stage 是否继续执行。when 的用法需要分两个维度解释:

  • 语句维度:

when 里支持一些内置的判断条件,比如:

when { 
    environment name: 'DEPLOY_TO', value: 'production'     // 判断环境变量
    equals expected: 2, actual: currentBuild.number    // 判断变量的值
    expression { BRANCH_NAME ==~ /(production|staging)/ }     // Groovy布尔表达式
    triggeredBy 'TimerTrigger'   // 判断触发原因
    branch 'master'    // 多分支流水线里,判断当前所在的分支
}
  • 逻辑维度:
when 里的条件支持与、或、非等逻辑运算: allOf{}, anyOf{}, not{}. 它们之间可以互相嵌套至任意深度。
when {
    allOf {
        branch 'production'
        environment name: 'DEPLOY_TO', value: 'production'
    }
}

多个条件并列默认是与关系,@allOf{}@ 可以省略,上面的例子等效于:

when {
    branch 'production'
    environment name: 'DEPLOY_TO', value: 'production'
}
steps

真正的执行语句是放在 steps 里的,这里可以包括许多 预先定义好的 step , 这里列出一些常用的:

steps {
    echo 'debugging'
    sleep 120, unit: 'DAYS'
    retry 3
    error()    // 
    dir       // 指定工作目录
    readFile
    fileExists
    withEnv
    script
}

post

post 用于后处理,位于 pipeline 顶级或者 stage 内部。当一定场景满足后,执行条件块内的 steps

post 支持的 steps 和 stages 里的 steps 相同。下面是各种常用的场景:

条件 执行场合
always 总是执行
success 前面的 stage 全部成功时执行;如果 post 位于 stage 内部,则是 stage 成功时执行
failure 前面的 stage 有失败时执行;如果 post 位于 stage 内部,则是 stage 失败时执行

嵌套执行结构

stage 下又可以嵌套 stages,继续向下嵌套多个 stage,呈顺序执行。

并行执行结构

一个 stage 可以声明为多个 stage 的并行执行,只要再加一层 parallel 指令,parallel 内的各个 stage 将并行执行,但是内部不能继续嵌套 parallel。基本结构为:

stages {
    stage('Parallel Stage') {
        parallel {
            stage('Branch A') {
                ...
            }
            stage('Branch B') {
                ...
            }
            stage('Branch C') {
                ...
            }
        }
    }
}

但是由于 pipeline 文件本身是 Groovy 代码,所以并没有规定在 pipeline {} 以外不允许有 Groovy 代码。正相反,额外的辅助代码,可以带来更多更灵活的功能。


相关文章   欢迎到 留言板 写下你的看法。
  本页面内容采用 署名协议 CC-BY 授权。欢迎转载,请保留原文链接