pipeline流水线

pipline:

官方介绍;https://jenkins.io/2.0
语法学习:https://www.jenkins.io/doc/book/pipeline/

pipline是帮助Jenkins实现CI到CD转变的重要角色,是运行在jenkins2.X版本的核心插件,简单来说Pipline就是一套运行于Jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂发布流程,从而实现单个任务很难实现的复杂流程编排和任务可视化,Pipeline 的实现方式是一套Groovy DSL,任何发布流程都可以表述为一段 Groovy 脚本

有声明式和脚本式语法区别,新版本推荐使用声明式(兼容groovy语法),脚本式为groovy

pipline 优势:

  • 可持续性:jenkins的重启或者中断后不影响已经执行的Pipline Job
  • 支持暂停:pipline可以选择停止并等待人工输入或批准后再继续执行
  • 可扩展:通过 groovy 的编程更容易的扩展插件。
  • 并行执行:通过groovy脚本可以实现step,stage间的并行执行,和更复杂的相互依赖关系

内置语法帮助文档:ip:端口/pipeline-syntax

推荐插件

Git
Git Parameter		#可以在传参时列出git仓库中分支、标签,很好用
Git Pipeline for Blue Ocean
GitLab
Credentials
Credentials Binding
Pipeline
Pipeline: Declarative		#可配合流水线生成器使用
Pipeline SCM API for Blue Ocean
Pipeline Graph View		#可以查看每个流水线,每个步骤块执行时间,很好用
Dashboard for Blue Ocean
Build With Parameters
Dynamic Extended Choice Parameter Plug-In
Dynamic Parameter Plug-in
Extended Choice Parameter
List Git Branches Parameter
Kubernetes		#部署到k8s时需要使用,博主还是建议在使用k8s部署时,使用argocd,可实现比Jenkins更高级的功能(自动灰度、蓝绿、A/B、流量迁移),适合云原生gitops,可查看博主argocd篇
Kubernetes CLI
Kubernetes Credentials
Image Tag Parameter
Active Choices

声明式

所有内容都定义在pipeline{}块中,基本遵循groovy语法

推荐在流水线中,对变量的引用使用单引号,而非双引号,避免在进程中可以看到关键数据

注意点

  • 流水线顶层必须是一个 block,即 pipeline{}
  • 分隔符可以不需要分号,但是每条语句都必须在自己的行上
  • 块只能由 Sections、Directives、Steps 或 assignment statements 组成
  • 属性引用语句被当做是无参数的方法调用,比如 input 会被当做 input()

完整语法

pipeline {
  agent 值           //agent为执行管道的节点
      any,任何节点执行
      none,不做全局配置,但各个stage块都要指定agent
      label,以节点标签选择方式执行,如:agent {label 'master'}
      node,类似label,但可添加额外配置
      dockerfile,直接从源码中的dockerfile文件构建容器,执行流水线或stage
      docker,类似dockerfile,可直接使用docker字段指定镜像,同时传参
      kubernetes,创建动态slave,以job pod方式运行,具体参阅下面案例
  environment {       //全局变量
    NAME = 'hj'
    KUBECONFIG = credentials('kubernetes-cluster')
    Harbor = credentials('harbor-account')
    tag = sh(script:"[ -z ${app_vs} ] && echo `date +'%F-%H%M'` || echo ${app_vs}", returnStdout: true).trim()
    CC = """${sh(
         returnStdout: true,
         //returnStdout.trim() : true	默认不会删除字符串的末尾空格,可使用trim()函数删除
         script: 'echo -n "clang"'   //将执行结果赋值给CC
    )}"""
    EXIT_STATUS = """${sh(
         returnStatus: true,
         script: 'ps |grep xx'      //将命令执行的返回状态赋值给EXIT_STATUS
    )}"""
  }
  options {
    timeout(time: 1, unit: 'HOURS')  //超时时间1小时,如果不加unit参数默认为1分
    timestamps()                     //所有输出每行都会打印时间戳
    buildDiscarder(logRotator(numToKeepStr: '3'))       //保留三个历史构建版本
    quietPeriod(10)
    retry(3)            //流水线失败后重试次数
    preserveStashes(buildCount: 5)		//当流水线中使用stash时,流水线构建完成后标记的内容会被删除,当需要重新执行流水线且回到指定标记目录时,此配置指定保留stash标记的文件数量,默认1个,也就是最近完成。如果指定了 buildCount 超出 1 到 5 范围的数字,则管道将失败并出现验证错误
    disableResume()		//禁用重启jenkins后恢复任务
  }
  parameters {
    string(name: 'DEPLOY_ENV', defaultValue:  'staging', description: '1')      //执行构建时需要手动配置字符串类型参数,之后赋值给变量
    text(name:  'DEPLOY_TEXT', defaultValue: 'One\nTwo\nThree\n', description: '2')     //执行构建时需要提供文本参数,之后赋值给变量
    booleanParam(name: 'DEBUG_BUILD',  defaultValue: true, description: '3')        //布尔型参数
    choice(name: 'CHOICES', choices: ['one', 'two', 'three'], description: '4')     //选择形式列表参数
    password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'A  secret password')       //密码类型参数,会进行加密
    imageTag(name: 'DOCKER_IMAGE', description: '', image: 'kubernetes/kubectl', filter: '.*', defaultTag: '', registry: 'https://192.168.10.15', credentialId: 'harbor-account', tagOrder: 'NATURAL')   //获取镜像名称与tag
    gitParameter(
        name: 'branch', 
        type: 'PT_BRANCH', 
        defaultValue: '', 
        description: '选择Git分支进行构建', 
        branchFilter: '.*', 
        listSize: '10', 
        quickFilterEnabled: true, 
        selectedValue: 'TOP', 
        sortMode: 'DESCENDING'
   ) //第一次创建流水线时,显示找不到分支,所以需要手动指定默认分支拉第一遍就行
   extendedChoice(
        description: '选择发布的应用', 
        descriptionPropertyValue: '', 
        multiSelectDelimiter: ',', 
        name: 'apps', 
        quoteValue: false, 
        saveJSONParameterToFile: false, 
        type: 'PT_CHECKBOX', 
        value: 'gateway,order', 
        visibleItemCount: 50
    ) //多选参数,多微服务选择
  }
  triggers {
    upstream(upstreamProjects: 'env', threshold: hudson.model.Result.SUCCESS)   //当env构建成功时构建这个流水线
    cron('H * * * *')   //每隔1小时执行一次
  }
  stages {
    stage('build') {        #流水线执行过程
      agent any
      environment {
        Harbor_url = 'http://192.168.10.15'
        DEBUG_FLAGS = '-g'
      }
      input {
        message "还继续么?"
        ok "继续"
        submitter "tom,bob"   //只允许tom和bob输入,空则允许所有
        parameters {
          string(name: 'PERSON', defaultValue: 'y', description: 'is continute')    //用PERSON变量接收输入值
        }
      }
      when {
        //当 BRANCH_NAME 为 main 或 master,并且 DEPLOY_TO 为 master 或 main 时才会执行
        expression { BRANCH_NAME ==~ /(main|master)/ }
        anyOf {
          environment name: 'DEPLOY_TO', value: 'main'
          environment name: 'DEPLOY_TO', value: 'master'
        }
      }
      steps {
        echo "${PERSON} = y is ok"
        archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true 	//捕获与包含模式 ( **/target/*.jar ) 匹配生成的文件,并将它们保存到 Jenkins 控制器以供以后检索
      }
      steps {         #具体执行的内容
        echo 1
        sh """
          env
          echo $Harbor_USR
          echo $Harbor_PSW
          echo $Harbor
          git branch: "$BRANCH", credentialsId: 'gitlab-key', url: 'git@192.168.10.14:root/env.git'   //使用gitParameter,必须有这个,获取上面gitParameter定义的BRANCH变量的值
          //git([url: 'git://example.com/amazing-project.git', branch: 'master'])		同上,但可包含多个仓库、分支
          echo "$env.BUILD_ID"
          echo ""$BUILD_ID""
          echo ${params.DEPLOY_ENV}		//引用parameters 中定义的参数变量
        """
        sh('echo $Harbor_url')		//单引号可避免关键数据泄漏,在执行主机中ps命令查看时,只能看到变量名,看不到值
        sh "printenv"
        stash includes: '**/target/*.jar', name: 'app' 		//匹配文件,并命名为app,以便在同一管道中重复使用,管道完成执行后,将从 Jenkins 控制器中删除隐藏的文件
      }
      post {
        always {...}
        change {}
        regression {}
        failure {}
        success {}
        unstable {}
        aborted {}
        unsuccessful {}
        cleanup {}
      }
    }
    stage('test') {
      failFast true     //一个步骤错误,直接退出,其他的也不执行
      steps {
        unstash 'app'		//返回到build步骤中,stash标记的app的工作目录
        sh 'make'
      }
      parallel {        //并行执行
        when {
          expression {
            currentBuild.result == null || currentBuild.result == 'SUCCESS' 	//前面的stage的执行结果为空,或为成功,test步骤才执行
          }
        }
        stage('Branch A') {
          steps {
            echo "On Branch A"
          }
        }
        stage('Branch B') {
          input {
            message "是否继续运行?"
            ok "继续"
            parameters {
              choice choices: ['yes','no'], description: '是否部署:yes(允许),no(退出)', name: 'run_app'
            }
          }
          stages {
            stage('Nested 1') {
              steps {
                echo "In stage Nested 1 within Branch C"
              }
            }
            stage('Nested 2') {
              steps {
               echo "In stage Nested 2 within Branch C"
              }
            }
          }
        }
    }
    stage('deploy') {
      agent {
        label 'master'
        node {
          label 'master'
          customWorkspace '/tmp/data'
        }
        //dockerfile true		直接使用git仓库中dockerfile
        dockerfile {
          filename 'Dockerfile.build'     //dockerfile文件名
          dir 'build'         //执行构建时的工作目录
          label 'master'      //标签选择,执行的node节点
          additionalBuildArgs '--build-arg version=1.0'       //构建参数
        }
        docker {
          image '192.168.0.10/k8s/alpine:latest'      //镜像地址
          label 'master'      //标签选择
          args '-v /tmp:/tmp'
          registryUrl 'https://myregistry.com/'
          registryCredentialsId 'myPredefinedCredentialsInJenkins'
          reuseNode true		//默认容器中工作区都是临时的,此选项时所有工作区保持同步
        }
        kubernetes {
          cloud 'kubernetes'         //k8s云,在jenkins中定义的k8s集群
          name pod名           //pod名称,仅用于继承
          namespace ns            //ns名
          label 标签        //节点标签,在指定node节点运行流水线
          defaultContainer '容器'
          slaveConnectTimeout         //连接超时时间
          inheritFrom 'mypod'     //可以引用1到多个podTemplate,空格分隔,按顺序引用,后面覆盖前面
          yamlFile 'yaml文件'
          yaml '''            //直接定义pod模板
              apiVersion: v1
              kind: Pod
              metadata:
                labels:
                  node: master
              spec:
                containers:
                - name: maven
                  image: maven:alpine
                  ports:
                  envVars:
                  command:
                  - sleep
                  args:
                  - 99d
                  tty: true        //使用tty
                  livenessProbe:      //存活探测
                  alwaysPullImage: 镜像     //容器在启动时拉的镜像
                  runAsUser: uid
'''
          retries 2           //pod失败时重试次数
          containers('容器名') {        //引用容器模板,执行自定义命令
            sh 'mvn -version'
          }
          serviceAccount sa
          nodeSelector 标签     //节点标签选择器
          customWorkspace 路径          //自定义工作目录
          workspaceVolume 类型          //jenkins的工作目录,类型如下
              persistentVolumeClaimWorkspaceVolume(claimName: "jenkins-agent", mountPath: "/", readOnly: "false")         //使用pvc
              nfsWorkspaceVolume(serverAddress: "192.168.10.254", serverPath: "/nfs", readOnly: "false")              //使用nfs
              dynamicPVC(storageClassName: "nfs-client", requestsSize: "1Gi", accessModes: "ReadWriteMany")          //动态申请 pvc,任务执行结束后删除
              emptyDirWorkspaceVolume()       //临时目录,任务执行结束后会随着 pod 删除被删除,主要功能多个任务 container 共享 jenkins 工作目录
              hostPathWorkspaceVolume(hostPath: "/opt/workspace", readOnly: false)        //挂载 node 节点本机目录,注意挂载本机目录注意权限问题,可以先创建设置 777 权限,否则默认 kubelet 创建的目录权限为 755 默认其他用户没有写权限,执行流水线会报错
              configMapVolume             //cm挂载,只读的
              secretVolume                //secret只读挂载
          envVars             //应用于所有容器的环境变量
              envVar          //一个环境变量,其值是内联定义的
              secretEnvVar    //一个环境变量,其值派生自 Kubernetes 密钥
          imagePullSecrets        //harbor的秘钥
          annotations 注解
          podRetention            //控制保留代理 Pod 的行为
              never()
              onFailure()
              always()
              default()
          activeDeadlineSeconds
              never()
              onFailure()
          idleMinutes             //允许 Pod 保持活动状态以供重用,直到自对其执行上一步以来经过配置的分钟数
          showRawYaml true        //启用或禁用原始容器清单的输出。默认值为 true
          runAsUser uid           //容器运行uid
          hostNetwork false       //使用物理主机网卡
          containerLog 容器名        //从容器中获取运行日志
          returnLog false         //返回日志,而不是打印到构建日志,默认false
          tailingLines 行数         //返回最后几行日志
          sinceSeconds 秒          //获取日志几秒
          limitBytes 字节           //获取字节数日志
        }
      }
    }
  }
}

sections

包含一个或多个 Agent、Stages、 post、Directives 和 Steps 的代码区域块

agent

Agent 表示整个流水线或特定阶段中的步骤和命令执行的位置
必须在 pipeline 块的顶层被定义,也可以在 stage 中再次定义,但是 stage 级别是可选的

配置值
any

可以在任何节点执行流水线

none

没有全局的 agent 配置。当顶层的 agent 配置为 none 时, 每个 stage 部分都需要包含它自己的 agent

label

以节点标签形式选择某个具体的节点执行,如:agent {label 'my-defined-label'}

node

类似label,但可以添加额外的配置,改默认工作目录

dockerfile

从源码中包含的 Dockerfile ,构建容器执行流水线或 stage

docker

相当于dockerfile,可直接使用docker字段指定外部镜像,可省去maven镜像打包,同时指定arg

Kubernetes

创建 Slave,也就是常说的动态 Slave,包含内容如下
官方文档:https://github.com/jenkinsci/kubernetes-plugin/
cloud: Configure Clouds 的名称,指定到其中一个 k8s
slaveConnectTimeout: 连接超时时间
yaml: pod 定义文件,jnlp 容器的配置必须有配置无需改变,其余 containerd 根据自己情况指定
workspaceVolume:持久化 jenkins 的工作目录
persistentVolumeClaimWorkspaceVolume:挂载已有 pvc

案例
例1:k8s
pipeline {
  agent {
    kubernetes {
      cloud 'kubernetes'
      slaveConnectTimeout 1200
      workspaceVolume emptyDirWorkspaceVolume()
      yaml '''
kind: Pod
metadata:
  name: jenkins-agent
spec:
  containers:
  - args: [\'$(JENKINS_SECRET)\', \'$(JENKINS_NAME)\']
    image: '192.168.10.15/kubernetes/jnlp:alpine'
    name: jnlp
    imagePullPolicy: IfNotPresent
  - command:
      - "cat"
    image: "192.168.10.15/kubernetes/alpine:latest"
    imagePullPolicy: "IfNotPresent"
    name: "date"
    tty: true
  - command:
      - "cat"
    image: "192.168.10.15/kubernetes/kubectl:apline"
    imagePullPolicy: "IfNotPresent"
    name: "kubectl"
    tty: true
  restartPolicy: Never
'''
    }
  }
  environment {
    MY_KUBECONFIG = credentials('kubernetes-cluster')
  }
  stages {
    stage('Data') {
      steps {
        container(name: 'date') {
          sh """
            date
          """
        }
      }
    }
    stage('echo') {
      steps {
        container(name: 'date') {
          sh """
            echo 'k8s is pod'
          """
        }
      }
    }
    stage('kubectl') {
      steps {
        container(name: 'kubectl') {
          sh """
            kubectl get pod -A  --kubeconfig $MY_KUBECONFIG
          """
        }
      }
    }
  }
}
例2:docker
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'
      }
    }
  }
}

post

用于流水线结束后的进一步处理,比如错误通知等。Post 可以针对流水线不同的结果做出不同的处理,就像开发程序的错误处理,类似py的try catch
​定义在 Pipeline 或 stage 中

条件
  • always,无论 Pipeline 或 stage 的完成状态如何,都允许运行该 post 中定义的指令
  • changed,只有当前 Pipeline 或 stage 的完成状态与它之前的运行不同时,才允许在该 post 部分运行该步骤
  • fixed:当本次 Pipeline 或 stage 成功,且上一次构建是失败或不稳定时,允许运行该 post 中定义的指令
  • regression:当本次 Pipeline 或 stage 的状态为失败、不稳定或终止,且上一次构建的 状态为成功时,允许运行该 post 中定义的指令
  • failure:只有当前 Pipeline 或 stage 的完成状态为失败(failure),才允许在 post 部分运行该步骤,通常这时在 Web 界面中显示为红色
  • success:当前状态为成功(success),执行 post 步骤,通常在 Web 界面中显示为蓝色 或绿色
  • unstable:当前状态为不稳定(unstable),执行 post 步骤,通常由于测试失败或代码 违规等造成,在 Web 界面中显示为黄色
  • aborted:当前状态为终止(aborted),执行该 post 步骤,通常由于流水线被手动终止触发,这时在 Web 界面中显示为灰色
  • unsuccessful:当前状态不是 success 时,执行该 post 步骤
  • cleanup:无论 pipeline 或 stage 的完成状态如何,都允许运行该 post 中定义的指令。和 always 的区别在于,cleanup 会在其它执行之后执行

steps

在给定的 stage 指令中执行的一个或多个步骤,执行具体的内容

案例
例:
stage('build') {
  steps {
    echo 1
    sh """
      echo 2
    """
  }
}

Directives

可用于一些执行 stage 时的条件判断或预处理一些数据
Directives 不是一个关键字或指令,而是包含了 environment、options、parameters、triggers、stage、tools、 input、when 等配置

Environment

在流水线中配置的一些环境变量,根据配置的位置决定环境变量的作用域

credentials()函数

用于在 Jenkins 环境中通过标识符访问预定义的凭证
对于类型为 Secret Text 的凭证,credentials()可以将该 Secret 中的文本内容赋值给环境变量。
对于类型为标准的账号密码型的凭证,指定的环境变量为 username 和 password,并且也会定义两个额外的环境变量,分别为MYVARNAME_USR和MYVARNAME_PSW

案例:
例:以harbor账号密码为例
pipeline {
  environment {
    Harbor = credentials('harbor-account')
  }
  stages {
    stage('env') {
      steps {
        sh '''
          echo $Harbor_USR        #用户名
          echo $Harbor_PSW        #密码
          echo $Harbor            #用户:密码
        '''
      }
    }
  }
}

options

其他指令,非必选项,写配置在pipeline、stage块,stage中仅支持 retry、 timeout、timestamps

  • buildDiscarder :保留多少个流水线的构建记录
  • disableConcurrentBuilds:禁止流水线并行执行,防止并行流水线同时访问共享资源导致流水线失败。
  • disableResume :如果控制器重启,禁止流水线自动恢复。
  • newContainerPerStage:agent 为 docker 或 dockerfile 时,每个阶段将在同一个节点的新容器中运行,而不是所有的阶段都在同一个容器中运行。
  • quietPeriod:流水线静默期,也就是触发流水线后等待一会在执行,手动触发的构建不生效
  • retry:流水线失败后重试次数。
  • timeout:设置流水线的超时时间,超过流水线时间,job 会自动终止。如果不加 unit 参数默认为 1 分。
  • timestamps:为控制台输出时间戳。
  • skipStagesAfterUnstable()

Parameters

在触发流水线时应该提供的参数列表,这些用户指定参数的值可以通过 params 对象提供给流水线的 step(步骤)。只能定义在 pipeline 顶层

支持参数类型
  • string:字符串类型的参数。
  • text:文本型参数,一般用于定义多行文本内容的变量。
  • booleanParam:布尔型参数。
  • choice:选择型参数,一般用于给定几个可选的值,然后选择其中一个进行赋值。
  • password:密码型变量,一般用于定义敏感型变量,在 Jenkins 控制台会输出为 *
插件Parameters
  • imageTag:镜像 tag,需要安装 Image Tag Parameter 插件后使用
  • gitParameter:获取 git 仓库分支,需要 Git Parameter 插件后使用

Triggers

实现自动触发流水线执行任务,可以通过 Webhook、Cron、 pollSCM 和 upstream 等方式触发流水线

Cron

定时构建假如某个流水线构建的时间比较长,或者某个流水线需要定期在某个时间段执行构建,可以 使用 cron 配置触发器,比如周一到周五每隔四个小时执行一次

语法

分 时 日 月 周 与系统cron一样

支持

@yearly
@annually
@monthly
@weekly
@daily
@midnight		12:00 到凌晨 2:59 之间的某个时间
@hourly

注:H 的意思不是 HOURS 的意思,而是 Hash 的缩写。主要为了解决多个流水线在同一时间同时运行带来的系统负载压力

triggers {
    cron('H */4 * * 1-5')   //周一到周五每隔四个小时执行一次
    cron('H/12 * * * *')   //每隔12分钟执行一次
    cron('H * * * *')   //每隔1小时执行一次
}

Upstream

根据上游 job 的执行结果决定是否触发该流水线。比如当 job1 或 job2 执行成功时触发该流水线

支持的状态
hudson.model.Result.状态
currentBuild.result == 状态
  • SUCCESS
  • UNSTABLE
  • FAILURE
  • NOT_BUILT
  • ABORTED

tools

允许引用在Jenkins中定义的工具,必须提前在web界面定义好

支持的工具

  • maven
  • jdk
  • gradle

案例

pipeline {
    agent any
    tools {
        maven 'apache-maven-3.0.1'
    }
    stages {
        stage('Example') {
            steps {
                sh 'mvn --version'
            }
        }
    }
}

Input

实现在流水线中进行交互式操作,比如选择要部署的环境、是否继续执行某个阶段等,在stage块使用

支持选项

  • message:必选,需要用户进行 input 的提示信息,比如:“是否发布到生产环境?”;
  • id:可选,input 的标识符,默认为 stage 的名称;
  • ok:可选,确认按钮的显示信息,比如:“确定”、“允许”;
  • submitter:可选,允许提交 input 操作的用户或组的名称,如果为空,任何登录用户均可提交 input;
  • parameters:提供一个参数列表供 input 使用

案例

#配置一个提示消息为 “还继续么”、确认按钮为 “继续”、提供一个 PERSON 的变量的参数,并且只能由登录用户为 alice 和 bob 提交的 input 流水线
pipeline {
  agent any
  stages {
    stage('Example') {
      input {
        message "还继续么?"
        ok "继续"
        submitter "alice,bob"
        parameters {
          string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
        }
      }
      steps {
        echo "Hello, ${PERSON}, nice to meet you."
      }
    }
  }
}

when

根据条件执行
when 指令必须包含至少 一个条件。如果 when 包含多个条件,所有的子条件必须都返回 True,stage 才能执行
可结合 not、allOf、anyOf 语法达到更灵活的条件匹配

内置状态表达式

状态与upstream中使用的一致

currentBuild.result == 状态

内置条件

  • branch:当正在构建的分支与给定的分支匹配时,执行这个 stage。注意,branch 只适用于多分支流水线,可选参数comparator,值:

    • EQUALS 用于简单的字符串比较
    • GLOB,全部匹配
    • REGEXP 用于正则表达式匹配
  • changelog:匹配提交的 changeLog 决定是否构建,例如:when

  • environment:当指定的环境变量和给定的变量匹配时,执行这个 stage,例如:when

  • equals:当期望值和实际值相同时,执行这个 stage,例如:when {equals expected: 2, actual: currentBuild.number};

  • expression:当指定的 Groovy 表达式评估为 True,执行这个 stage,例如:when {expression { return params.DEBUG_BUILD} };

  • tag:如果 TAG_NAME 的值和给定的条件匹配,执行这个 stage,例如:when {tag "release-"};

  • not:当嵌套条件出现错误时,执行这个 stage,必须包含一个条件,例如:when {not { branch 'master'} };

  • allOf:当所有的嵌套条件都正确时,执行这个 stage,必须包含至少一个条件,例如:when {allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production'} };

  • anyOf:当至少有一个嵌套条件为 True 时,执行这个 stage,例如:when {anyOf { branch 'master'; branch 'staging'} }。

  • triggeredBy:条件满足时,执行指定触发器

内置前置条件

默认某个 stage 的 agent,在进入该 stage 的 agent 后,该 stage 的 when 条件才会被评估,可使用前置条件提前判断

  • beforeAgent:如果 beforeAgent 为 true,则会先评估 when 条件。在 when 条件为 true 时,才会进入该 stage
  • beforeInput:如果 beforeInput 为 true,则会先评估 when 条件。在 when 条件为 true 时,才会进入到 input 阶段;
  • beforeOptions:如果 beforeInput 为 true,则会先评估 when 条件。在 when 条件为 true 时,才会进入到 options 阶段;

案例

例1:当分支为 main 时执行 Example Deploy
pipeline {
  agent any
  stages {
    stage('Example Build') {
      steps {
        echo 'Hello World'
      }
    }
    stage('Example Deploy') {
      when {
        branch 'main' //多分支流水线,分支为才会执行。
      }
      steps {
        echo 'Deploying'
      }
    }
  }
}

例2:分支为 main 或 DEPLOY_TO 为 main 或 master 时执行 Deploy

 pipeline {
  agent any
  stages {
    stage('Example Deploy') {
      when {
        anyOf {
          branch 'main'
          environment name: 'DEPLOY_TO', value: 'main'
          environment name: 'DEPLOY_TO', value: 'master'
        }
      }
      steps {
        echo 'Deploying'
      }
    }
  }
}

例3:当 BRANCH_NAME 为 main 或 master,并且 DEPLOY_TO 为 master 或 main 时才会执行 Example Deploy

pipeline {
  agent any
  stages {
    stage('Example Deploy') {
      when {
        expression { BRANCH_NAME ==~ /(main|master)/ }
        anyOf {
          environment name: 'DEPLOY_TO', value: 'main'
          environment name: 'DEPLOY_TO', value: 'master'
        }
      }
      steps {
        echo 'Deploying'
      }
    }
  }
}
例4:
when { 
    branch pattern: "release-\\d+", comparator: "REGEXP"
} 

Parallel

在声明式流水线中可以使用 Parallel 字段,即可很方便的实现并发构建,比如对分支 A、B、 C 进行并行处理

案例

例:
pipeline {
  agent any
  stages {
    stage('Non-Parallel Stage') {
      steps {
        echo 'This stage will be executed first.'
      }
    }
    stage('Parallel Stage') {
      failFast true         //表示其中只要有一个分支构建执行失败,就直接推出不等待其他分支构建
      parallel {
        stage('Branch A') {
          steps {
            echo "On Branch A"
          }
        }
        stage('Branch B') {
          steps {
            echo "On Branch B"
          }
        }
        stage('Branch C') {
          stages {
            stage('Nested 1') {
              steps {
                echo "In stage Nested 1 within Branch C"
              }
            }
            stage('Nested 2') {
              steps {
               echo "In stage Nested 2 within Branch C"
              }
            }
          }
        }
      }
    }
  }
}

matrix

矩阵,可包含多个stepsstagesparallel,进行组合使用,用法与并行类似

scripts

允许在声明式管道中执行脚本式

pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'

                script {
                    def browsers = ['chrome', 'firefox']
                    for (int i = 0; i < browsers.size(); ++i) {
                        echo "Testing the ${browsers[i]} browser"
                    }
                }
            }
        }
    }
}

变量

KUBERNETES_JENKINS_URL jenkins url
jenkins.host.address

静态变量

查看Jenkins内置变量: ip:端口/pipeline/syntax/globals#env

常见变量
  • BUILD_ID:当前构建的 ID,与 Jenkins 版本 1.597 + 中的 BUILD_NUMBER 完全相同
  • BUILD_NUMBER:当前构建的 ID,和 BUILD_ID 一致
  • BUILD_TAG:用来标识构建的版本号,格式为:jenkins-\({JOB_NAME}-\){BUILD_NUMBER}, 可以对产物进行命名,比如生产的 jar 包名字、镜像的 TAG 等;
  • BUILD_URL:本次构建的完整url
  • JOB_NAME:本次构建的项目名称
  • NODE_NAME:当前构建节点的名称;
  • JENKINS_URL:Jenkins 完整的 URL,需要在 SystemConfiguration 设置;
  • WORKSPACE:执行构建的工作目录
  • env.变量名:引用这些构建信息

动态变量

动态变量是根据某个指令的结果进行动态赋值,变量的值根据指令的执行结果而不同

  • returnStdout:将命令的执行结果赋值给变量,trim()函数可删除末尾空格
  • returnStatus:将命令的执行状态赋值给变量
案例
pipeline {
  agent any
  environment {
    CC = """${sh(
         returnStdout: true,
         script: 'echo -n "clang"'   //如果使用shell命令的echo赋值变量最好加-n取消换行
         )}"""
    EXIT_STATUS = """${sh(
         returnStatus: true,
         script: 'exit 1'
         )}"""
  }
  stages {
    stage('Example') {
      environment {
        DEBUG_FLAGS = '-g'
      }
      steps {
        sh 'printenv'
      }
    }
  }
}

脚本式

1到多个node块完成流水线

node {
    stage('Build') {
        //
    }
    stage('Test') {
        //
    }
    stage('Deploy') {
        //
    }
}
posted @ 2023-11-21 14:26  suyanhj  阅读(315)  评论(0)    收藏  举报