声明式 Pipeline 语法
声明式流水线必须包含在一个 Pipeline 块中,比如以下是一个 Pipeline 块的格式:
pipeline {
/* insert Declarative Pipeline here */
}
在声明式流水线中有效的基本语句和表达式遵循与 Groovy 的语法同样的规则,但有以下例外:
- ➢ 流水线顶层必须是一个 block,即 pipeline{};
- ➢ 分隔符可以不需要分号,但是每条语句都必须在自己的行上;
- ➢ 块只能由 Sections、Directives、Steps 或 assignment statements 组成;
- ➢ 属性引用语句被当做是无参数的方法调用,比如 input 会被当做 input()。
一、Sections
声明式流水线中的 Sections 不是一个关键字或指令,而是包含一个或多个 Agent、Stages、post、Directives 和 Steps 的代码区域块。
1. Agent
有很多种Agent 表示整个流水线或特定阶段中的步骤和命令执行的位置,该部分必须在 pipeline 块的顶层被定义,也可以在 stage 中再次定义,但是 stage 级别是可选的。
- any:在任何可用的代理上执行流水线,配置语法:
pipeline {
agent any
}
- none:表示该 Pipeline 脚本没有全局的 agent 配置。当顶层的 agent 配置为 none 时,每个 stage 部分都需要包含它自己的 agent。配置语法:
pipeline {
agent none
stages {
stage('Stage For Build'){
agent any
}
}
}
- label:选择某个具体的节点执行 Pipeline 命令,例如:agent { label ‘my-defined-label’ }。配置语法:
pipeline {
agent none
stages {
stage('Stage For Build'){
agent {
label 'my-slave-label' }
}
}
}
-
node:和 label 配置类似,只不过是可以添加一些额外的配置,比如 customWorkspace;
-
dockerfile:使用从源码中包含的 Dockerfile 所构建的容器执行流水线或 stage。此时对应的 agent 写法如下:
agent {
dockerfile {
filename 'Dockerfile.build'
dir 'build'
label 'my-defined-label'
additionalBuildArgs '--build-arg version=1.0.2'
}
}
dockerfile需要编译的过程,很慢
一般不去使用dockerfile ,docker常用
- docker:相当于 dockerfile,可以直接使用 docker 字段指定外部镜像即可,可以省去构建的时间。比如使用 maven 镜像进行打包,同时可以指定 args,一般静态的时候使用:
agent{
docker{
image 'maven:3-alpine'
label 'my-defined-label'
args '-v /tmp:/tmp'
}
}
- kubernetes:Jenkins 也支持使用 Kubernetes 创建 Slave,也就是常说的动态 Slave。配置示例如下:
agent {
kubernetes {
label podlabel
yaml """
kind: Pod
metadata:
name: jenkins-agent
spec:
containers:
- name: kaniko
image: gcr.io/kaniko-project/executor:debug
imagePullPolicy: Always
command:
- /busybox/cat
tty: true
volumeMounts:
- name: aws-secret
mountPath: /root/.aws/
- name: docker-registry-config
mountPath: /kaniko/.docker
restartPolicy: Never
volumes:
- name: aws-secret
secret:
secretName: aws-secret
- name: docker-registry-config
configMap:
name: docker-registry-config
"""
}
2. 配置示例
示例 1:假设有一个 Java 项目,需要用 mvn 命令进行编译,此时以使用 maven 的镜像作为 agent。配置如下:
Jenkinsfile (Declarative Pipeline) // 可以不要此行
pipeline {
agent {
docker 'maven:3-alpine' }
stages {
stage('Example Build') {
steps {
sh 'mvn -B clean verify'
}
}
}
}
示例 2:本示例在流水线顶层将 agent 定义为 none,那么此时 stage 部分就需要必须包含它自己的 agent 部分。在stage(‘Example Build’)部分使用 maven:3-alpine 执行该阶段步骤,在stage(‘Example Test’)部分使用 openjdk:8-jre 执行该阶段步骤。
此时 Pipeline 如下:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent none
stages {
stage('Example Build') {
agent {
docker 'maven:3-alpine' }
steps {
echo 'Hello, Maven'
sh 'mvn --version'
}
}
stage('Example Test') {
agent {
docker 'openjdk:8-jre' }
steps {
echo 'Hello, JDK'
sh 'java -version'
}
}
}
}
示例 3:上述的示例也可以用基于 Kubernetes 的 agent 实现。比如定义具有三个容器的 Pod,分别为 jnlp(基于http)(负责和 Jenkins Master 通信)、build(负责执行构建命令)、kubectl(负责执行 Kubernetes相关命令),在 steps 中可以通过 containers 字段,选择在某个容器执行命令:
pipeline {
agent {
kubernetes {
cloud 'kubernetes-default'
slaveConnectTimeout 1200
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- args: