joeの小窝

Loading...

pipeline详解

pipeline语法

1、固定结构

pipeline {
    agent 任何
    stages {
        stage("阶段名"){
            steps{
                // 执行命令
            }

        }
    }

}

2、states参数

一个基本的stage示例

stages {  // stages 包括了所有
    //下载代码
    stage("GetCode"){   //为阶段指定名称
        steps{  //步骤
            timeout(time:5,unit:"MINUTES"){
                script{ //具体的运行代码
                    println('获取代码')
                }
            }
        }
    }
    //构建
    stage("Build"){
        steps{
            timeout(time:20, unit:"MINUTES"){
                script{
                    println('应用打包')
                }
            }
        }
    }
    //代码扫描
    stage("CodeScan"){
        steps{
            timeout(time:30, unit:"MINUTES"){
                script{
                    print("代码扫描")
                }
            }
        }
    }
}

1、stage

stage是实际执行任务的阶段,任务必须位于stage中,默认情况下,stage是自上而下依次执行的


pipeline {
    agent any
    stages {
        stage ("Check www.example.com response code") {
            steps{
                sh  '''
                    TOKEN="test-token"
                    GROUP_ID="-000000000"
                    CODE=$(curl -o /dev/null -s -w %{http_code} www.example.com)
                    
                    
                    if [ "${CODE}" != "200" ]; then
                      message="www.example.com response code != 200."
                      curl -X GET "https://api.telegram.org/bot${TOKEN}/sendMessage" \
                          -d "chat_id=${GROUP_ID}&text=${message}"
                    fi                
                '''
            }
        }
    }
}

2、steps

stage中必须包含steps,steps是具体执行任务的步骤,所有执行任务的操作必须位于steps中

steps里面常用的命令

echo 'Hello World' // echo 输出信息

sh 'pwd'  // sh执行linux命令

git url: 'https://gitee.com/xxx/test.git', branch: 'main' // git拉取代码


container('busybox') {   // 进入容器执行命令,k8s专用
    sh 'echo 我在 busybox 里执行'
}

3、script

这个作用就比较简单了,在stage中调用groovy的代码块,groovy的代码块不能直接写在steps当中,必须使用script包起来,标明这是groovy语句

stage("build") {
    steps{
        scripte{
            println("运行构建")
        }

    }
}

3、agent参数

agent只能位于pipeline和stage段中

一个基本的agent的示例

agent {
    node {   // 运行在带有master节点的上
        label "master"
    }
}

使用docker作为agent

agent {
    docker {
        label "arm64"  // 指定运行docker节点上含有的标签
        image "busybox" // 使用什么镜像拉取容器  
        args "sleep 3600" // 启动容器的参数
        alwaysPull false // 镜像拉取策略
    }
}

配置kubernetes的pod作为agent

agent{
    kubernetes {
        cloud 'kubernetes' // 连接的k8s
        inheritFrom "golang-kaniko" // 使用这个容器模版作为基础模版,这个模板里面有jnlp容器
        showRawYaml false // 输出的时候不展示详细信息
        yaml """
apiVersion: v1
kind: Pod
metadata:
  name: golang
  namespace: devops
spec:
……  



        """
    }

}

还有另外2种写法

agent any // 使用任意一个节点

agent none  // 不指定agent,意味着在stage时,需要指定agent

4、environment

全局变量配置在pipeline下

局部变量配置在stage下

配置在pipeline下声明

pipeline {
    agent any
    environment {  // 全局变量
        activeEnv = 'dev'
    }
    stages {
        stage("example") {
            environment {  // 局部变量
                ack="qqq"

            }
            steps{
                sh "printenv"
            }
        }
    }
}

测试代码

pipeline {
    agent {
        kubernetes {
            cloud "k8s"
            showRawYaml true
            yaml ""    // 不指定pod模板
        }
    }

    environment {
        key = "key01"  // 全局变量
    }

    stages {
        stage("hello") {
            environment {
                key2 = "key02"  // 局部变量
            }
            steps {
                echo "${key}"  // 输出信息 ${} 输出
                echo "${key2}"  
            }
        }
    }
}

需要注意的地方

  • key = "value" 中间必须要有空格,字符串引起来

  • yaml为空的话 "" 一对引号即可

[Pipeline] {
[Pipeline] echo
key01
[Pipeline] echo
key02
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // podTemplate
[Pipeline] End of Pipeline
Finished: SUCCESS

5、credentials插件

在流水线中需要使用某个凭证的时候,jenkins给我们提供了一个获取凭证的方式,就是使用credentials插件

pipeline {
    agent {
        kubernetes {
            cloud "k8s"
            showRawYaml true
            yaml ""  
        }
    }

    environment {
        key = "key01"
        gitee_user = credentials("1")  // 凭证的id
    }

    stages {
        stage("hello") {
            environment {
                key2 = "key02"
            }
            steps {
                echo "${key}"
                echo "${key2}"
                echo "${gitee_user_USR}"  // _USR就是获取用户名
                echo "${gitee_user_PSW}"  // _PSW就是获取密码,密文的
            }
        }
    }
}

6、options

options用于定义pipeline运行时的约束,如是否在执行pipeline时打印时间戳,如果pipeline执行超过2小时,则强行终止并判定失败;禁止并行(这里的并行并不是指pipeline语法中的parallel,而是说一个任务不能有两个job同时运行)等等。

示例

options {
    timestamps() //日志会有时间  安装插件 timestamps
    skipDefaultCheckout() //删除隐式checkout scm语句,默认拉取代码,只是我们看不到而已
    disableConcurrentBuilds() //禁止并行
    timeout(time: 2, unit: 'HOURS')
}
 

常用options说明如下:

  • buildDiscarder:为最近的流水线运行的特定数量保存组件和控制台输出
  • disableConcurrentBuilds:关闭并行执行构建,可被用来防止同时访问共享资源等
  • overrideIndexTriggers:允许覆盖分支索引触发器的默认处理
  • skipDefaultCheckout:在pipeline中,如果配置有代码仓库,则agent会默认检出代码,此选项用于跳过这个默认动作
  • skipStagesAfterUnstable:一旦构建状态变得unstable,则跳过该阶段
  • checkoutToSubdirectory:在工作空间的子目录中自动的执行源码检出
  • timeout:设置流水线运行的超时时间
timeout(time: 30, unit: 'MINUTES')
pipeline {
    agent {
        kubernetes {
            cloud "k8s"
            showRawYaml true
            yaml ""  
        }
    }
    options {
        timestamps()  // 显示时间
        disableConcurrentBuilds() // 禁止并行运行
        skipDefaultCheckout()  // 禁止隐式拉取代码
    }
    environment {
        key = "key01"
        gitee_user = credentials("1")
    }

    stages {
        stage("hello") {
            environment {
                key2 = "key02"
            }
            steps {
                echo "${key}"
                echo "${key2}"
                echo "${gitee_user_USR}"
                echo "${gitee_user_PSW}"
            }
        }
    }
}

img

7、parameters

传参的字段

1、bool类型

一个变量,设置为bool值,然后根据这个来进行判断

pipeline {
    agent {
        kubernetes {
            cloud "k8s"
            showRawYaml true
            yaml ""
                    }
            }
    parameters {   // 定义类型
        booleanParam (
            name: "verify",
            defaultValue: true,
            description: "是否开启license授权"
        )
    }
    stages {
       stage ("bool案例") {
           steps {
                sh "echo ${verify}"
           }
           
       } 
    }   
}

写好后,需要新构建一次,会构建失败,然后再次查看就会出现下面这个页面,这个是正常的

img

pipeline {
    agent {
        kubernetes {
            cloud "k8s"
            showRawYaml true
            yaml ""
                    }
            }
    parameters {
        booleanParam (
            name: "verify",
            defaultValue: true,
            description: "是否开启license授权"
        )
    }
    stages {
       stage ("bool案例") {
           steps {
                sh "echo ${verify}"
           }
           
       }
       stage ("判断值") {
           steps {
               script {
               def isverify = Boolean.valueOf(verify)  // Boolean.valueOf(verify) 将其转换为bool类型的,这样就能根据布尔值来执行对应的任务
               if (isverify) {
                   echo "true"
               }
               else {
                   echo "false"
               }
               }
           }
           
       }
    }   
    
    
}

2、字符串类型

显示的页面就是自己输入字符串

parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') }

pipeline {
    agent {
        kubernetes {
            cloud "k8s"
            showRawYaml true
            yaml ""
                    }
            }
    parameters {
        string(
            name: "person",   // 定义一个变量person 
            defaultValue: "my jenkins", // 默认值为这个,可以在web界面修改
            description: "hello"   // 描述信息
            )
    }
    stages {
        
        stage ("执行字符串类型")
        {
            steps{
                echo "hello ${params.person}"
            }
        }
    }
    
}

可以自定义修改这个默认值

img

3、选择参数类型

这个是最经常使用的

可以基于这个来选择拉取的分支,或者有多套jenkins环境的时候,可以选择

parameters { 
    choice(name: 'DEPLOY_ENV', choices: 'dev\ntest\nstaging', description: '请选择要部署的环境') 
}


pipeline {
    agent {
        kubernetes {
            cloud "k8s"
            showRawYaml true
            yaml ""
                    }
            }
    parameters {
        choice(
            name: "deploy_env",
            choices: "dev\ntest\n",
            description: "请选择要部署的环境"
            )
    }
    stages {
        
        stage ("选择参数类型")
        {
            steps{
                echo "hello ${params.deploy_env}"
            }
        }
    }

    
    
}

从固定的分支或者环境选择,这个是非常常用的

img

8、条件语句

1、groovy语法判断

是最方便的,比声明式的方便多了

pipeline {
    agent any
    parameters {
        choice(name: "env",choices: ['staging','uat','prod'])
    }
    stages {
        steps {
            script{
                if (params.env == "staging"){
                // do staging processing
                echo "deploy to test env"
                }
                else if(params.env == 'uat'){
                    echo "deploy to poc uat"
                }
                else if(params.env == 'prod'){
                    echo "deploy to prod env"
                }
            }
        }
    }
}

when语句使用

pipeline{
    agent any
    parameters {
        choice(name: 'env', choices: ['staging', 'uat', 'prod'])
    }
    stages{
        stage("Deploy"){
            parallel{
                stage("staging env"){
                    when {
                        expression { params.env == "staging" } 
                    }
                    steps{
                        // do staging processing
                        echo "deploy to staging env"
                    }
                }
                stage("UAT uat"){
                    when {
                        expression { params.env == "uat" } 
                    }
                    steps{
                        // do uat processing
                        echo "deploy to uat env"
                    }
                }
                stage("Prod env"){
                    when {
                        expression { params.env == "prod" } 
                    }
                    steps{
                        // do prod processing
                        echo "deploy to prod env"
                    }
                }
            }
        }
    }
}

2、when判断

1、branch

特定分支时构建

pipeline {
    agent any
    stages{
        stage("deploy to test"){
            when {
                branch "test"
            }
            steps {
                echo "deploy to test env"
            }
        }
        stage("deploy to prod"){
            when {
                branch "prod"
            }
            steps {
                echo "deploy to prod env"
            }
        }
    }
}

2、environemnt

判断环境系变量的值是否与定义的相同

pipeline {
    agent any
    stages {
        stage("deploy to test"){
            when {
                environment name: "env",value: "prod"   // env值为prod就执行下面
            }
            steps {
                echo "deploy to prod env"
            }
        }
    }

}

3、expression

用于判断groovy表达式的返回值,返回值为true/false

返回值为true就执行

返回值为false就不执行


pipeline{
    agent any
    parameters {
        choice(name: 'env', choices: ['staging', 'uat', 'prod'])
    }
    stages{
        stage("Deploy"){
            parallel{
                stage("staging env"){
                    when {
                        expression { params.env == "staging" } 
                    }
                    steps{
                        // do staging processing
                        echo "deploy to staging env"
                    }
                }
                stage("UAT uat"){
                    when {
                        expression { params.env == "uat" } 
                    }
                    steps{
                        // do uat processing
                        echo "deploy to uat env"
                    }
                }
                stage("Prod env"){
                    when {
                        expression { params.env == "prod" } 
                    }
                    steps{
                        // do prod processing
                        echo "deploy to prod env"
                    }
                }
            }
        }
    }
}

9、并行构建

就是同时执行,速度提升了

1、stage内并行

在同一个 stage 内部,我们可以并行的执行多个 step,这些step会在同一台 agent 上并行执行。需要说明的是,由于agent只能在stage级别设置,所以这些并行的step不能跨agent执行:

stage('run-parallel') {
   steps {
       parallel(
           a: {
               echo "task 1"
           },
           b: {
               echo "task 2"
           }
       }
   }
}

2、stage级别并行

要支持Stage级别并行,需要安装两个插件:

  • Pipeline: Model API
  • Pipeline: Model Definition

在下面的示例中,会先执行stage1,然后并行执行stage2.1和stage2.2,最后执行stage3:

pipeline {
    agent any
    stages {
        stage('Stage1') {
            agent { 
                label "test1" 
            }
            steps {
                timestamps {
                    echo 'the job which run first.'
                    sleep 5
                }
            }
        }
        stage('Parallel Stage') {
            parallel {
                stage('Stage2.1') {
                    agent { 
                         label "test2" 
                     }
                    steps {
                        timestamps {
                            echo "the first parallel job which will run on test2"
                            sleep 5
                            echo "the first parallel job complete."
                        }
                    }
                }
                stage('Stage2.2') {
                    agent { 
                      label "test3" 
                    }
                    steps {
                        timestamps {
                            echo "the second parallel job which will run on test3"
                            sleep 10
                            echo "the second parallel job complete."
                        }
                    }
                }
            }
        }
        stage('Stage3') {
            agent { 
              label "test1" 
            }
            steps {
                timestamps {
                    echo 'the last job which will run on test1'
                }
            }
        }
    }
}

3、多stage分组并行

这里需要用到嵌套stage,将多个stage嵌入一个stages中,并行运行stages。下面的示例中,Stage1率先执行,然后并行运行Stage2.1和Stage2.2,其中Stage2.2中又嵌套了两个Stage,分别是Stage2.2.1和Stage2.2.2,需要说明的是,这两个Stage并不是并行的:

pipeline {
    agent any    
    stages {
        stage('Stage1') {
            steps {
                echo 'This stage will be run first.'
            }
        }
        stage('Stage2') {
            failFast true
            parallel {
                stage('Stage2.1') {
                    steps {
                        echo "Stage2.1"
                    }
                }
                stage('Stage2.2') {
                    stages {
                        stage('Stage2.2.1') {
                            steps {
                                echo "Stage2.2.1"
                            }
                        }
                        stage('Stage2.2.2') {
                            steps {
                                echo "Stage2.2.2"
                            }
                        }
                    }
                }
            }
        }
    }
}

10、triggers

定义好了后,先执行一遍,才能刷新出来,跟上面的参数字段一样,先要执行一遍才行

triggers指令用于定义流水线触发的一些机制与条件。常规情况下,我们的项目都是基于手动点击部署,这种策略尤其适用于线上环境,但在测试环境,乃至于预发环境,应该对自动构建有更高的集成度,使开发者只关注于开发,而不必过多纠结构建的过程。

目前流水线支持的触发器有三种:cron, pollSCMupstream

1、cron

pipeline {
    agent any
    triggers {
        cron('H 02 * * *')  // cron('00 02 * * *')
    }
    stages {
        stage('cronjob test') {
            steps {
                echo '这是一个定期执行的任务'
            }
        }
    }
}

需要说明的是,上面用到了一个H关键字,H亦即Hash,表示当前位置跨度范围内随机一值。假如我们使用定时任务功能,管理了大量的机器,那么如果在同一时间突然批量的机器执行任务,势必会产生负载不均衡的情况,这个时候就可以这样写:H 02 * * *表示凌晨两点的一个小时中,随机的一个时间点执行任务。

  • 同时还可以用一些别名来简化操作。
    • @yearly:每年执行一次
    • @monthly:每月执行一次
    • @weekly:每周执行一次
    • @daily:每天执行一次
    • @midnight:代表半夜12点到凌晨2:59之间的某个时间。
    • @hourly:每小时执行一次

2、pipelin

定期对代码仓库进行检测,如果有变化,则自动触发构建。

pipeline {
    agent any
    triggers {
        pollSCM('* * * * *')
    }
    stages {
        stage('cronjob test') {
            steps {
                echo '每分钟检测一次代码仓库的变化'
            }
        }
    }
}

3、upstream

当B项目的执行依赖A项目的执行结果时,A就是B的上游项目,在Jenkins2.22以上的版本中,可以通过upstream关键字进行这种关系的表示。

triggers {
    // job1,job2都是任务名称
    upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SUCCESS)
}

hudson.model.Result是一个枚举用于指示上游项目状态,包含以下指令:

  • ABORTED:任务被手动终止。
  • FAILURE:构建失败。
  • SUCCESS:构建成功。
  • UNSTABLE:存在一些错误,但不至于构建失败。
  • NOT_BUILT:再多阶段构建时,前面阶段的问题导致后面阶段无法执行

执行linux命令就需要使用sh

git echo 都是jenkins内置的不需要使用sh

posted @ 2026-04-15 15:41  乔的港口  阅读(28)  评论(0)    收藏  举报