pipeline

Jenkins2.x 实践指南--pipeline语法讲解

2021-10-15  本文已影响0人  卢纪超

Jenkins pipeline 是基于Groovy语言实现的一种DSL(领域特定语言),用于描述整条流水线是如何进行的。

1. pipeline的组成

1.1最简结构

以下从pipeline最简结构----Hello World 查看Jenkins file文件的构成:

pipeline {
    agent any

    stages {
        stage('Hello') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

1.2 步骤(Steps)

pipeline基本结构决定pipeline整体流程,但真正“做事”的还是pipeline中的每一个步骤。步骤是pipeline中已经不能在拆分的最小操作。

步骤是可插拔的。现有的插件不用修改或者只需要简单修改,就能在Jenkins pipeline中当成一个步骤来使用,大大降低了从现有依赖界面的插件过渡到pipeline中步骤的成本。

2. post部分

post {
    failure {
        mail to: 'team@example.com', subject: 'The Pipeline failed :('
    }  
}

post 部分是在整个pipeline或者阶段完成后一些附件的步骤。

post步骤是可选的,所以并不包含在pipeline最简结构中,但并不代表它作用不大。

根据pipeline或阶段的完成状态,post部分分成多种条件块,包括

post部分完整示例:

pipeline {
    agent any

    stages {
        stage('build') {
            steps {
                echo "build stage"
            }

            post {
                always {
                    echo "stage post always"
                }
            }
        }
    }
    post {
        changed  {
            echo "pipeline post changed"
        }

        always {
            echo "pipeline post always"
        }
        
        success {
            echo "pipeline post success"
        }
        
        //....
    }
}

3. pipeline 支持的指令

基本结构满足不了现实多变的需求,Jenkins pipeline 通过各种指令(directive)来丰富自己。指令可以被理解为对Jenkins pipeline基本结构的补充。

Jenkins pipeline 支持的指令有:

4.配置pipeline本身

options指令用于配置整个Jenkins pipeline本身的选项。根据具体的选项不同,可以将其放在pipeline块或stage块中。

常见的几个选项:

5.在声明式pipeline中使用脚本

在使用声明式pipeline时,直接在steps块中写if-else,或者定义一个变量,Jenkins都会报错。也就是不能再steps块中写Groovy代码。

Jenkins pipeline专门提供了一个script步骤,能在script步骤中像写代码一样写pipeline逻辑。

下面的例子是分别在不同的浏览器上跑测试。

pipeline {
    agent any
    
    stages {
        stage('Example') {
            steps {
                script {
                   def browers = ['chrome', 'firefox']
                   for(int i = 0; i < browers.size(); ++i){
                        echo "Testing the ${browers[i] brower"
                        }
                   }
                }
            }
        }
    }

在script块中其实就是Groovy代码。如果在script步骤中写了大量的逻辑,则说明你应该把这些逻辑拆分到不同的阶段,或者放到共享库中。共享库是一种扩展Jenkins pipeline的技术。

6. pipeline内置基础步骤

6.1 文件目录相关步骤

deleteDir:删除当前目录

deleteDir是一个无参步骤,删除的是当前工作目录。通常它与dir步骤一起使用,用于删除指定目录下的内容。

dir:切换到目录

默认pipeline工作在工作目录空间下,dir步骤可以让我们切换到其他目录。使用方法如下:

{
    dir("/var/logs"){
        deleteDir()
    }
}
fileExists: 判断文件是否存在。

如果参数是相对路径,则判断在相对当前工作目录下,该文件是否存在,结果返回布尔类型。

fileExits('/tmp/a.jar')判断/tmp/a.jar文件是否存在。

isUnix:判断是否在类UNIX系统

如果当前pipeline运行在一个类UNIX系统上,则返回true

pwd:确认当前目录

pwd与Linux的pwd命令一样,返回当前所在目录。它有一个布尔类型的可选参数:tmp。如果参数值为true,则返回与当前工作空间关联的临时目录。

writeFile:将内容写入指定文件中

writeFile支持的参数有:

readFile:读取文件内容

读取指定文件的内容,以文本返回。readFile支持的参数书有:

示例如下:

{
    //"amvua2lucyBib299r" 是"jenkins book" 进行Base64编码后的值
    writeFile(file: "base64file", text: "amvua2lucyBib299r", encoding;'Base64')
    def content = readFile(file: "base64file",encoding: 'UTF-8')
    echo "${content}"
    //打印结果: jenkins book
}

6.2 产出相关步骤

stash:保存临时文件

stash步骤可以将一些文件保存起来,以便被同一次构建的其他步骤或阶段使用。如果这个pipeline的所有阶段在同一台机器上执行,则说他是步骤是多余的。所以,通常需要stash的文件都是要跨Jenkins node使用的。

stash步骤会将文件存储在tar文件中,对于大文件的stash操作将会消耗Jenkins master的计算资源。Jenkins官方文档推荐,当文件大小为5~100MB时,应考虑使用其他替代方案。

stash步骤的参数列表如下:

除了name参数,其他 参数都是可选的。excludes和includes使用的是Ant风格路径表达式。

unstash:取出之前stash的文件

unstash步骤只有一个name参数,即stash时的 唯一标识。通常stash和unstash步骤同时使用。

示例如下:

pipeline {
    agent any
    stages {
        stage('stash'){
            agent { label "master" }
            steps {
                writeFile file: 'a.txt',text: "$BUILD_NUMBER"
                stash(name: "abc",includes: "a.txt")
            }
        }
        stage('unstash')
        {
            agent {label "node2" }
            steps{
                unstash("abc")
                def content = readFile("a.txt")
                echo "${content}"
            }
        }
    }
}

stash步骤在master节点上执行,而unstash步骤在node2节点上执行

6.3 命令相关步骤

Pipeline:Nodes and Processes插件提供的步骤。它是Pipeline插件的一个组件,基本不需要单独安装。

sh: 执行shell命令

sh步骤支持的参数有:

returnStatus和returnStdout参数一般不会同时使用,因为返回值只能有一个。如果同时使用,则只有returnStatus参数生效。

bat、powershell步骤

bat步骤执行的是WIndows的批处理命令。powershell步骤执行的是PowerShell脚本,支持3+版本。这两个步骤支持的参数与sh步骤一样。

6.4 其他步骤

error:主动报错,中止当前pipeline

error步骤的执行类似于抛出一个异常。它只有一个必须参数:message。通常省略参数:error("There is an error")。

tool:使用预定义的工具

如果在Global Tool Configuration(全局工具配置)中配置了 工具,可以通过tool步骤得到工具路径。

steps {
    script {
        def t = tool name: 'docker', type: 'org.jenkinsci.plugins.docker.commons.tools.DockerTool'
        echo "${t}" //将打印 /var/lib/docker
    }
}

tool步骤支持的参数有:

每个插件的type值都不一样,而且绝大多数的文档根本不屑type值。除了到该插件的源码中查找,还有一种方法可以让我们快速找到type值,就是前往 Jenkins pipeline代码片段生成器中生成该 tool不走的代码即可。

timeout:代码块超时时间

为timeout步骤闭包内运行的代码设置超时时间限制。如果超时,将。抛出一个 org.jenkinsci.plugins.workflow.steps.FlowInterruptException异常。timeout步骤支持如下参数:

waitUntil:等待条件满足

不断重复waitUntil块内的代码,直到条件为true。waitUntil不负责处理块内代码的异常,遇到异常时直接向外抛出。waitUntil步骤最好与timeout步骤共同使用,避免死循环。示例如下:

timeout(50) {
    waitUntil {
        script {
            def r = sh script: 'curl http://exmaple', returnStatus:true
            return( r==0 )
        }
    }
}
retry:重复执行块

执行N次闭包内的脚本。如果其中某次执行抛出异常,则只中止本次执行,并不会中止整个retry的执行。同时,在执行retry的过程中,用户是无法中止pipeline的。

steps {
    retry(20) {
        script {
            sh script: 'curl http://exmaple', returnStatus:true
        }
    }
}
sleep:让pipeline休眠一段时间

sleep步骤可用于简单地暂停pipeline,其支持的参数有:

sleep(120) //休眠120秒
sleep(time: '2', unit: 'MINUTES') //休眠2分钟
上一篇下一篇

猜你喜欢

热点阅读