Jenkins Pipeline 语法

pipeline 简介

pipeline 基本语法

agent

post

stages/stage/steps

environment

options

parameters

tool

when

scripts

triggers

共享库

pipeline basic steps 插件用法

git plugin 插件用法

publish html report 插件用法

借助 Jenkins 生成 pipeline 代码

 

 

Pipeline 简介

Jenkins2.x 的核心是使用 pipeline 来构建项目,也就是流水线,将 Jenkins1.0 版本中基于表单的配置信息比如 JDK/SVN 以及参数的配置都转变成了代码,即 pipeline as Code。

传统的表单方式有以下缺点:

  • 需要大量的 web 表单交互,有时候需要进行很多次的切换,比较繁琐。
  • 不能进行版本管理。
  • 可重用性差。

而采用 pipeline 的方式,项目的所有流程和配置都写在 Jenkinsfile 文件中,移植时只要将此文件拷贝即可,无须繁琐的配置;而且 pipeline 可以很直观的看到每个阶段的构建情况,再结合上 Blue Ocean 可以进行强大的流水线监控,方便、直观、及时地获取到构建结果。

在 Jenkins 中,把每一段管道比作是不同的 Job,不同 Job 的链接就需要用到 Pipeline 插件。Jenkins 的工作流程可以简单概括为 build-deploy-test-release,每个流程之间我们都可以用 Pipeline 来连接,大致如下效果图:

Jenkins pipeline 是基于 Groovy 语言实现的一种 DSL(Domain-Specific Language,领域特定语言),可以理解为适用于 Jenkins 的编程语言。

pipeline 支持两种语法:脚本式语法(scripted pipeline)和声明式语法(declarativepipeline)。早期的 pipeline plugin 只支持脚本式语法,声明式语法是在 pipeline2.5 之后新增加的,相对而言,声明式语法更简单,即使没有 groovy 语言的基础也能进行基本的操作。Jenkins 社区的动向也是偏向于声明式语法,所以以声明式语法为例进行说明。

 

Pipeline 基本结构

pipeline{
    agent any
    stages{
        stage('build'){
            steps{
                echo 'build steps'
            }
        }
    }
}

以上是最最基本的一个 pipeline 结构,具体的含义如下:

  • pipeline:后面用一对 {} 也就是闭包,表示整条流水线,里面是流水线中具体的处理流程。
  • agent:用来指定整个流水线或者某一个阶段在哪个机器节点上执行。如果是 any 的话表示该流水线或者阶段可以运行在任意一个定义好的节点上。这个指令必须要有,而且一般会放在顶层  pipeline{...} 的下一层,在 stage{...} 中也可以使用 agent,但是一般不这么用。
  • stages:后面跟一对 {},类似于一个容器,封装了一个或多个 stage,也就是将不同的阶段组织在一起;例如 build 是一个 stage, test 是第二个 stage,deploy 是第三个 stage。通过 stage 隔离,让  Pipeline 代码读写非常直观。
  • stage:后面跟一对 {},流水线中的某个阶段,其中封装了多个执行步骤,每个阶段都需要有个名称。
  • steps:封装了在一个阶段中的一个或多个具体的执行步骤。在本例中 echo 就是一个步骤。

接下来我们一一介绍上面提到的 pipeline 中包含的最基本的几个 section,以及另外一些可选的 section。

 

agent

用来指定 pipeline 的执行节点,一般放在顶层的 pipeline 中。agent 部分支持几种不同的参数以此来适应不同的应用场景。

1)any

作用:表示可以在任意的节点或者代理上执行此 pipeline。

代码示例:

pipeline {
  agent any
}

2)none

作用:在 pipeline 的顶层应用中使用此参数的话表示不会为整个 pipeline 指定执行的节点,需要在每个 stage 部分用 pipeline 指定执行的节点。

代码示例:

pipeline {
    agent none
    stages {
        stage('test'){
            agent {
                label '具体的节点名称'
            }
        }
    }
} 

3)label

作用:在标签指定的可用代理上执行 pipeline 或 stage,比如 agent {label "label"} 表示流水线或者阶段可以运行在任何一个具有 label 标签的代理节点上。

代码示例:

pipeline {
    agent {
        label '具体的一个节点 label 名称'
    }
}

4)自定义工作空间

作用:代理节点的标签新增了一个特性,允许为流水线或阶段指定一个自定义的工作空间,用 customWorkspace 指令来指定。和 label 功能类似。

代码示例:

pipeline {
    agent {
        node {
            label "xxx-agent-机器"
            customWorkspace "${env.JOB_NAME}/${env.BUILD_NUMBER}"
        }
    }
} 

处的 node 可以换成 label,但是为了避免 Docker 代理节点中的 label 用法混淆,一般用 node 表示。这种类型的 agent 在实际工作中的使用场景是最多的

测试代码

pipeline {
    agent {
        node {
            label "xxx-agent-机器"
            customWorkspace "${env.JOB_NAME}/${env.BUILD_NUMBER}"
        }
    } 
    stages {
        stage ("Build") {
            bat "dir"  //执行windows下的bat命令
        } 
        stage ('test') {
            echo ${JAVA_HOME}  //打印JAVA_HOME
        }
    }
}

以将以上代码段放到 Jenkinsfile 中或者在 Jenkins ui 中去执行。

 

POST

post 部分用来指定 pipeline 或者 stage 执行完毕后的一些操作,比如发送邮件、环境清理等。post 部分在 Jenkins 代码中是可选的,可以放到顶层,也就是和 agent 同级,也可以放到stage 中。在 post 代码块中支持多种指令,比如:always、success、failure、aborted、unstable、changed 等等,我们一一来介绍。

1)always

作用:当 pipeline 执行完毕后一定会执行的操作,不管成功还是还失败。比如说文件句柄的关闭或者数据库的清理工作等。

代码示例:

pipeline {
    agent any
    stages {
        stage ("Build") {
            bat "dir"
        }
    } 
    post {
        always {
            script {
                //写相关清除/恢复环境等操作代码
            }
        }
    }
}

2)success

作用:当 pipeline 执行完毕后且构建结果为成功状态时才会执行的操作。

代码示例:

pipeline {
    agent any
    stages {
        stage ("Build") {
            bat "dir"
        }
    } 
    post {
        success{
            script {
            //写相关清除/恢复环境等操作代码
            }
        }
    }
}

3)failure

作用:当 pipeline 执行完毕后且构建结果为失败时执行的操作,比如发送错误日志给相关人员。

4)changed

作用:当 pipeline 执行完毕后且构建状态和之前不一致时执行的操作。

5)aborted

作用:当 pipeline 被手动终止时执行的操作。

6)unstable

作用:当 pipeline 构建结果不稳定时执行的操作。

7)以上命令的组合

在 post 部分是可以包含多个条件块,也就是以上命令的组合,比如:

pipeline {
    agent any
    stages {
        stage ("Build") {
            bat "dir"
        }
    }
    post {
        always {
            script {
                echo "post always "
            }
        } 
        success{
            script {
                echo "post success"
            }
        } 
        failure{
            script {
                echo "post failure"
            }
        }
    }
}

  

stages/stage/steps

  • stagesPipeline 中单个阶段的操作封装到 stages 中,stages 中可以包含多个 stage。
  • stage一个单独的阶段,实际上所有实际工作都将包含在一个或多个 stage 指令中。stage{…} 里面有一个强制的字符串参数,用来描述这个 stage 的作用,这个字符串参数是不支持变量的,只能你自己取名一个描述字段。
  • steps一个 stage 下至少有一个 steps,一般也就是一个 steps。可以在 steps 下写调用一个或者几个方法,也就是两三行代码。

有以下注意点

  • 在声明式 pipeline 脚本中,有且只有一个 stages。
  • 一个 stage{…} 必须有且只有一个 steps{…}, 或者 parallel{…} 或者 stages {…},多层嵌套只支持在最后一个 stage{…} 里面。
  • 在声明式语法中只支持 steps,不支持在 steps {…} 里面嵌套写 step{…}。

 代码示例:

pipeline {
    agent any
    stages {
        stage('build') {
            steps { echo 'build' }
        }
        stage ('test') {
            steps { echo "${JAVA_HOME}" }  //打印 JAVA_HOME
        }
    }
}

 

environment

作用:通过键值对的方式定义整个 pipeline 或者 stage 中使用的环境变量。

代码示例:

pipeline {
    agent any
    environment {
        test = true
    } 
    stages {
        stage('build') {
            steps {
                script{
                    if(test == true) {
                    // 一些特定的操作
                        echo 'sucess'
                    }
                }
            }
        }
    }
}

 

options

options 指令在 pipeline 也是可选的。用来指定一些属性和值,这些预定义的选项可以应用到整个流水线中,可以理解为在 Jenkins web 表单里一个项目的基本配置中定义的事情。

1)retry

作用:表示 Jenkins 中的 job 执行失败后继续进行几次尝试。可以放到顶层的 pipeline 中也可以放到 stage 中。注意:这个次数是指总次数,包括第 1 次失败。

pipeline {
    agent any
    options {
        retry(3)
    }
    stages {
        stage('test') {
            steps {
                // 步骤
            }
        }
    }
}

2)buildDiscarder

作用:保留指定数量的流水线执行,包含控制台输出以及制品。当 pipeline 指定完毕后,会在工作空间中保存制品和执行日志,如果执行次数太多的会话,这些内容会占用很多的存储空间,使用该参数后会只保留最近指定次数的构建结果,自动清理之前的内容。

代码示例

pipeline {
    agent any
    options {
        buildDiscarder(logRotator(numToKeepStr:'3'))
    }
    stages {
        stage('test') {
            steps {
                // 步骤
            }
        }
    }
}

明:logRotator 元素并没有什么作用,主要是历史原因。

3)checkoutToSubdirectory

作用:指定检出到工作空间的子目录中。Jenkins 从代码管理库中拉取代码时默认检出到工作空间的根目录,如果想修改的话可以用此参数。

代码示例

pipeline {
    agent any
    options {
        checkoutToSubdirectory('subdir')
    }
    stages {
        stage('test') {
            steps {
                // 步骤
            }
        }
    }
}

4)disableConcurrentBuilds

作用:阻止 pipeline 同时执行。默认的情况下 pipeline 是可以同时执行多次的,如果为了防止同时访问共享资源或者防止一个较快的并发执行把较慢的并发执行给碾压的场景可以使用此参数禁止并发执行。

代码示例:

pipeline {
    agent any
    options {
        disableConcurrentBuilds()
    }
    stages {
        stage('test') {
            steps {
                // 步骤
            }
        }
    }
}

5)timeout

作用:为流水线的执行设置一个超时时间。如果超过这个值就会把整个流水线终止。时间单位可以是 SECONDS(秒),MINUTES(分钟),HOURS(小时)。

代码示例

pipeline {
    agent any
    options {
        timeout(time:10, unit:'HOURS')
    }
    stages {
        stage('test') {
            steps {
                // 步骤
            }
        }
    }
}

6)skipDefaultCheckout

作用:删除隐式的 checkout scm 语句,因此可以从 Jenkinsfile 定义的流水线中跳过自动的源码检出功能。

代码示例

options {
    skipDefaultCheckout()
}

  

parameters

parameters 用来在 pipeline 中实现参数化构建,也就是根据用户指定的不同参数执行不同的操作。pipeline 支持很多种类型的参数,有字符串参数,布尔选择参数,下拉多选参数等。

1)字符串参数

作用:开始构建前需要用户输入字符串,比如 ip 或者 url。

代码示例:

pipeline {
    agent any
    parameters {
        string(name: 'DEPLOY_ENV', defaultValue: 'release', description: '')
    }
}

2)布尔值参数

作用:定义一个布尔类型参数,在执行构建前用户在 Jenkins UI 上选择是还是否,选择是执行这部分代码,否则会跳过这部分。比如:执行完毕后环境的清理工作。

代码示例:

pipeline {
    agent any
    parameters {
        booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '')
    }
}

3)文本参数

作用:支持写很多行的字符串。

代码示例:

pipeline {
    agent any
    parameters {
        text(name: 'Welcome_text', defaultValue: 'One\nTwo\nThree\n',description: '')
    }
}

4)选择参数

作用:支持用户从多个选择项中选择一个值用来表示这个变量的值。比如:选择服务器类型、选择版本号等。

代码示例:

pipeline {
    agent any
    parameters {
        choice(name: 'ENV_TYPE', choices: ['test', 'dev', 'product'], description: 'testmeans test env,….')
    }
}

5)文件参数

作用:参数化构建 UI 上提供一个文件路径的输入框,Jenkins 会自动去根据用户提供的网络路径去查找并下载。

代码示例:

pipeline {
    agent any
    parameters {
        name: 'FILE', description: 'Some file to upload')
    }
}

6)密码参数

作用:密码(password)参数就是在 Jenkins 参数化构建 UI 提供一个暗文密码输入框。

例如,需要登录到服务器做自动化操作,为了安全起见,就不能用名为的 string 类型参数,而是 password 方式。

代码示例:

pipeline {
    agent any
    parameters {
        password(name: 'PASSWORD', defaultValue: 'test', description: 'A secret password')
    }
}

测试执行

注意:

保存之后,左侧菜仍然单是 Build now,而并不是 Build with Parameters,这个是正常的,需要先点击 Build now,先完成第一个构建,Jenkins 第二个构建才会显示代码中的三个参数。刷新之后,就可以看到参数化构建这个菜单。

  

tool

作用:定义自动安装和放置工具的路径。

对于 agent none,这个关键字将被忽略,因为没有任何节点或者代理可以用来安装工具。此指令主要是为了三大工具(jdk、gradle、maven)提供环境变量服务。一旦配置完成,tools 指令可以让我们指定的工具需要在我们已经选择的代理节点上自动安装在配置路径下。

代码示例 1

pipeline {
    agent any
    tools {
        jdk 'jdk1.8'
    }
    stages {
        stage('test') {
            steps {
                sh 'java -version'
            }
        }
    }
}

说明:

tools {
    jdk 'jdk1.8'
}

左侧的 jdk 是流水线模型中定义的特殊字符串,目前,在声明式流水线中可以指定的合法的工具类型如下:ant、git、gradle、jdk、maven、jgit 等。

右侧的 jdk8 映射的是全局工具配置中的名称字段(管理 Jenkins → Global ToolConfiguration 中预配置)。例如,上面代码我写了 jdk1.8,那么必须在 Jenkins 管理-->全局工具配置中有别名为 jdk1.8 配置。

一旦这样设置后,jdk 工具会被自动安装到指定的路径下,然后我们可以在流水线步骤中简单的使用  jdk1.8 字符串替代 JAVA_HOME 路径,Jenkins 会把它映射到我们系统中安装的 JDK。

代码示例 2

pipeline{
    agent any
    parameters {
        string(name: 'gradleTool', defaultValue: 'gradle3', description: 'gradle version')
    }
    tools{
        gradle "${params.gradleTool}"
    }
}

:如果需要输入一个特定的版本来使用,这个 tools 指令可以使用一个参数的值。

注意:当前生命式语法有一个局限就是当这个流水线第一次运行时,Jenkins 不能识别出该构建需要一个参数,需要先手动构建一次。

 

when

when{…} 是写在 stage{…} 里面一层条件控制,允许 pipeline 根据给定的条件来决定是否执行某个阶段。when 指令必须至少包含一个条件,也可以含多个条件,这与子条件嵌套在一个 allOf 条件中一样。

更复杂的条件结构可使用嵌套条件建:not,allOf 或 anyOf,嵌套条件可以嵌套到任意深度。下面来看看 when{…} 支持的一些内置条件命令。

1)branch

作用:当正在构建的分支与给出的分支模式匹配时执行。注意,仅适用于多分支 pipeline。

代码示例:

when { branch 'master' }

2)environment

作用:当指定的环境变量与给定的值相同时执行。

代码示例:

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

3)expression

作用:当给定的 Groovy 表达式返回 true 时执行。

代码示例:

when { expression { return params.DEBUG_BUILD } }

4)not

作用:当嵌套条件为 false 时执行,必须包含一个条件。

代码示例:

when { not { branch 'master' } }

5)allOf

作用:当所有嵌套条件都为真时执行,必须至少包含一个条件。

代码示例:

when {
    allOf {
    branch 'master';
        environment name: 'DEPLOY_TO',
        value: 'production' 
    }
}

6)anyOf

作用:当至少一个嵌套条件为真时执行,必须至少包含一个条件。

代码示例:

when { anyOf { branch 'master'; branch 'staging' } }

7)buildingTag

作用:如果 pipeline 所执行的暧昧被打了 tag 则执行。

代码示例:

when { buildingTag() }

测试代码

pipeline {
    agent any
    environment {
        quick_test = false
    }
    stages {
        stage('Example Build') {
            steps {
                script {
                    echo 'Hello World'
                }
            }
        }
        stage('Example Deploy') {
            when {
                expression {
                    return (quick_test == "true" )
                }
            }
            steps {
                echo 'Deploying'
            }
        }
    }
}

environment 里面定义了一个键值对“quick_test = false”, 第二个 stage('ExampleDeploy') 因为不满足 when{…}里面的条件就不会执行。

  

script

作用:用来在声明式流水线中写非声明式代码的地方,允许你定义一定代码块/闭包用来囊括非声明式的语法,其实就是在 script 中写 Groovy 代码。比如 if...else 等语句。

代码示例:

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

 

triggers

用来指定使用什么类型的触发器来自动启动流水线构建。注意:这些触发器并不适合用于多分支流水线、github 组织等类型的任务。我们介绍 4 种不同的触发器:cron、pollSCM、upstream 以 githubPush。

1)cron

作用:按照指定的周期有规律的执行流水线,就是闹钟一样,一到时间点就执行。

代码示例:

pipeline {
    agent any
    triggers {
        cron ('0 0 * * *')
    } 
    stages {
        stage('test') {
            steps {
                // 步骤
            }
        }
    }
}

说明:

cron 包含 5 个字段,这些字段以空格或者 Tab 键分割,用来指定多久去执行一次构建。格式为:

  • MINUTES:一小时内的分钟,取值范围(0-59)
  • HOURS:一天内的小时,取值范围(0-23)
  • DAYMONTH :一个月中的某一天,取值范围(1-31)
  • MONTH :月份,取值范围(1-12)
  • DAYWEEK:一周中的星期几,取值范围(0-7)。0 和 7 都表示星期日

还可以使用特殊的字符一次指定多个值:

  • *:匹配所有的值
  • N:匹配 M-N 之间的值
  • M-N/<VALUE>或者*/<value>:表示每隔<value>,比如*/5 每隔 5 分钟
  • A,B,...Z:多个枚举值
  • H:可以用于任何字段,用来告诉 Jenkins 在一个范围内使用该项目名的散列值计算出一个唯一的偏移量,这个偏移量于范围内的最小值相加后定义为实际的执行时间。注意:这个值是项目名的散列值,那么每一个值都与其他项目是不同的,但是同一个项目的值是不变的。

H 符号在实际的项目中是非常推荐使用的,因为在大型的项目中可能存在多个同一时刻需要执行任务,比如(0 0 * * *),都需要在半夜零点启动,那么使用 H 后,从散列算法获得的偏移量,就可以错开执行具有相同 cron 时间的项目。

2)upstream

作用:由上游的任务构建完毕后触发本任务的执行。比如说需要先执行完编译打包和发布后才能执行测试脚本。

代码示例:

triggers {
    upstream threshold: 'UNSTABLE', upstreamProjects: 'jobA,jobB'
}

说明:

upstreamProjects:指定上游任务的名称,有多个任务时用逗号分隔 。

threshold:指定上游任务的执行结果是什么值时触发,是枚举类型 hudson.model.Result 的某一个值,包括:

  • SUCCESS:构建成功;
  • UNSTABLE:存在一些错误,但不至于构建失败;
  • FAILURE:构建失败。

注意:需要手动触发一次 pipeline 的执行,让 Jenkins 加载 pipeline 后,trigger 指令才会生效。

3)pollSCM

作用:轮询代码仓库,也就是定期到代码仓库询问代码是否有变化,如果有变化就执行。语法和 cron 是一样的。理论上轮询的越频繁越好,但是在一定的构建时间内,如果有多次代码提交,当构建失败时无法马上知道是哪一次的提交导致的,所以这个指令不是很常用,一般是用 webhook,当有代码提交的时候主动通知到 Jenkins。

代码示例

pipeline {
    agent any
    triggers {
        pollSCM('h/5 * * * *')
    }
    stages {
        stage('test') {
            steps {
                // 步骤
            }
        }
    }
}

4)Generic Webhook Trigger

需要安装 Generic Webhook Trigger(简称 GWT)插件才能使用,安装方式见 3.3 节。安装完之后,Jenkins 会暴露一个 API:http://<Jenkins_URL>/generic-webhook-trigger/invoke,当 GWT 插件接收到 JSON 或者 XML 的 HTTP POST 请求后,根据请求的参数和 Jenkins 中项目的匹配情况来决定执行哪个 Jenkins 项目。注意:项目创建完成后,一定要手动执行一次,这样 pipeline 的触发条件才会生效。

4.1 Generic Webhook Trigger 触发条件的结构

代码格式:

triggers {
    GenericTrigger
    causeString: 'Generic Cause',
    genericHeaderVariables: [[key: 'header', regexpFilter: '']],
    genericRequestVariables: [[key: 'request', regexpFilter: '']],
    genericVariables: [[defaultValue: '', expressionType: 'XPath', key: 'ref', regexpFilter:'', value: '$.ref']],
    printContributedVariables: true,
    printPostContent: true,
    regexpFilterExpression: '',
    regexpFilterText: '',
    token: 'secret'
}

总结起来可以分为 5 部分:

  • genericVariables/genericHeaderVariables/genericRequestVariables:从 HTTP POST 请求提取参数。
  • token:用于标识待触发的 Jenkins 项目。
  • regexpFilterExpression/regexpFilterText:根据请求参数判断是否触发 Jenkins 项目的执行。
  • printContributedVariables/printPostContent/causeString:日志打印控制。
  • webhook:响应控制。

 4.2 提取请求参数

genericVariables:提取 POST body 中的请求参数。

用法

genericVariables: [[defaultValue: '', expressionType: 'XPath', key: 'ref', regexpFilter: '',value: '$.ref']]

说明

  • expressionType: 可选,'XPath'默认是 JSONPath,采用默认值的话不会有此参数,还可以设置为 XPath。
  • value:JSON 表达式或者 XPath 表达式,取决于 expressionType 的类型。
  • key:一个变量名,用来存储从 POST body 提取出的值,可以用于 pipeline 其它步骤。
  • defaultValue:可选,当没有提取到时使用此值返回。
  • regexpFilter:可选,过滤表达式,用来对提取出的值进行过滤。

genericHeaderVariables:从 URL 中提取参数

用法: genericHeaderVariables: [[key: 'header', regexpFilter: '']]

说明

  • key:一个变量名,用来存储从 URL 提取出的值,可以用于 pipeline 其它步骤。
  • regexpFilter:对提取出的值进行过滤。
  • genericRequestVariables:从 HTTP Header 中提取参数。和 genericHeaderVariables 用法类似。

4.3 token

用法: token: 'secret'

说 明 : 用 来 标 识 一 个 pipeline 在 Jenkins 中 的 唯 一 性 。 当 Jenkins 接 收 到generic-webhook-trigger/invoke 接口的请求时,会将请求传递给 GWT 插件,GWT 插

件内部会遍历 Jenkins 中所有的项目,找到 Generic Webhook Trigger 配置 token 和请求中相同 token 的项目,触发这些项目的执行。

4.4 触发请求参数

如果配置了以下 2 项,即使 token 值匹配了,还要继续判断以下条件是否满足,才能真正触发项目的执行。

  • regexpFilterExpression:正则表达式。
  • regexpFilterText:需要匹配的 key。

4.5 日志打印控制

  • printContributedVariables:布尔类型,打印提取后的变量和变量值。
  • printPostContent:布尔类型,打印 webhook 请求信息。
  • causeString:字符串类型,用来表示 pipeline 被触发执行的原因,一般引用直接提取的变量。

 

共享库

当 Jenkins 上建立很多个 pipeline 项目的时候,就会有一些公共的代码在每个项目中都要去重复的编写,当这些代码需要做一些扩展或者修改的时候就需要把所有项目中全部改一遍,维护的成本太高,编写的效率太低。比如发送邮件的功能是所有项目都需要的,邮件模板都写在每个 pipeline 项目中的话视觉效果极差。可以使用 pipeline 共享库(shared library)的技术解决这一问题。

1)共享库的代码结构

共享库有 3 个部分组成:resources 目录、src 目录和 vars 目录。示例如下:

  1. resources 目录:一般将非 groovy 文件存放在此目录中,比如 XML 文件或者 JSON文件,可以通过外部库中的 libraryResource 步骤加载。 
  2. src 目录:是使用标准 java 目录结构的 groovy 文件,目录中的类称为库类(Library class),这些类必须实现 Serializable 接口,以此保证在流水线停止或者重新启动时能正确的恢复。在流水线中使用 src 目录中的类时,需要注意要使用包名,同时因为是 groovy 代码,所以还要用 script 命令包起来。
  3. vars 目录:这个是我们要介绍的重点。此目录下存放的可以在 pipeline 中直接调用的全局变量,在 pipeline 中使用的函数名就是文件名,当文件中定义了 call 方法时,它可以像常规流水线步骤一样被调用。这个call方法就相当于这个公共方法的main方法。记住一个原则,一个公共方法,写一个 groovy 类文件,这个 groovy 文件的名称就是这个公共方法的函数名称,在其他 pipeline 项目中调用这个方法就是直接写这个groovy 类名称。

共享库的定义和使用一般分为以下 4 步:

  1. 根据工作实际需要编写共享库的源代码;
  2. 将源代码放到代码管理仓库中;
  3. 在 Jenkins 全局配置中定义共享库;
  4. 在 pipeline 项目或中 Jenkinsfile 中通过@Library 引用共享库。

2)编写共享库文件

注意:库文件中包含中文的话一定要保存为 ANSI 格式,否则可能会出现乱码的情况。

我们主要将常用的一些功能封装到 vars 目录来演示,其它高级的用法可以根据实际的需要进一步研究。在 vars 目录下创建 2 个文件,分别名为 command.groovy 的文件,如下:

 再创建名为 say.groovy 的文件,内容如下:

3)Jenkins 中配置共享库

 

 

4)通过@Library 注解使用共享库

在 pipeline 的上方使用@Library 引入共享库。

语法:@Library('<libname>[@<version>]')_ [<import statement>]

说明:

  • libname:表示库名,必须要有。
  • version:版本号以@开头,可以是代码仓库的标签、分支名或者其他规范。
  • _:下划线,表示一次性静态加载 src 目录下所有的代码到 classpath 中,如果没有后面的 import 语句,就必须有此下划线。
  • import:可以没有,表示导入指定的方法,如果没有指定表示导入共享库中所有的方法。

使用示例:

//加载一个库的默认版本
@Library('share-lib')_

//加载一个库的指定版本
@Library('share-lib@2.0')_

//加载多个库
@Library(['share-lib@release1.0','myLib'])_

//带导入语句
@Library('share-lib@2.0') import static org.demo.Utils.*

Pipeline Basic Steps 插件用法

pipeline basic steps 是 pipeline 最基础的一个插件,在安装 pipeline 的时候默认会自动安装,可以在 Jenkins 环境,插件管理下的 installed 下面找到这个插件。

1)readFile

作用:读取指定文件的内容,以字符串的形式返回。

参数说明

  • file:相对于当前工作空间的文件路径,也可以用绝对路径表示;
  • encoding:读取文件时的编码方式,默认是根据你当前平台的编码去解析。如果读取的是二进制文件,会采用 Base64 转码的字符串输出。
import hudson.model.*;

println env.JOB_NAME
println env.BUILD_NUMBER

pipeline{
    agent any
    stages{
        stage("init") {
            steps{
                script {
                    file = "../../jobs/test_pipeline_demo/demo.txt"
                    file_contents = readFile file
                    println file_contents
                }
            }
        }
    }
}

明:将 jobs/test_pipeline_demo 目录下的 demo.txt 文件内容读出并打印。

2)writeFile

作用:writeFile 和 readFile 类似,是简单的文本文件进行写操作。如果明确知道是 json 或其他类型文件,那么就可以用其他插件的 readJson 来读取。

参数说明

  • file相对于当前工作空间的文件路径,也可以用绝对路径表示,路径不存在会创建。
  • text:要写入的文件内容。
  • encoding:写入文件时的编码方式,默认使用的是当前平台的编码。

3)deleteDir() 方法

作用:默认递归删除 WORKSPACE 下的文件和文件夹,这个方法是没有参数,一般与 dir 一起使用。当执行完每一个 stage 里面的代码,需要在 post{...}里面写一些 clean up 操作,如果这个操作是清空 WORKSPACE 的话,就可以使用 deleteDir()。特别是生产环境,需要节约 Jenkins 服务器的磁盘空间,清空 WORKSPACE 是很有必要的操作。

用法:deleteDir()

4)mail

邮件功能在 Jenkins 中是非常有用的,当构建完成后无论成功还是失败都需要将构建结果通知到相关人员,邮件是最常见的选择。在 pipeline 中发送邮件之前,需要先按照 3.3.7 部分配置完毕。我们可以借助片段生成器查看该插件支持的参数:

需要注意的是 Body MIME Type 这个选项默认就是 text/plain,可以指定为 text/html。

5)dir

作用:切换操作目录。

代码示例:

import hudson.model.*;

println env.JOB_NAME
println env.BUILD_NUMBER

pipeline{
    agent any
    stages{
        stage("dir") {
            steps{
                println env.WORKSPACE
                dir(".."){
                    echo "pwd"
                }
            }
        }
    }
}

6. echo("message")和 error("error_message")

作用:echo和 groovy 中的 println 没有任何区别。一般来说使用 echo 就是打印 info debug级别的日志输出用,如果遇到错误,就可以使用 error(“error message”),如果出现执行到 error 方法,Jenkins job 会退出并显示失败效果。

7)fileExists

作用:判断一个文件是否存在,返回值是布尔类型,true 就表示文件存在,false 表示文件存在。

8. isUnix()

作用:判断当前运行的 Jenkins node 环境是 linux 还是 windows,如果返回是 true 表示是 linux/mac 系统,如果返回是 false,表示当前 Jenkins job 运行在 windows 的系统上。

import hudson.model.*;

println env.JOB_NAME
println env.BUILD_NUMBER

pipeline{
    agent any
    stages {
        stage("isUnix") {
            steps{
                script {
                    if(isUnix() == true) {
                        echo("this Jenkins job running on a linux-like system")
                    }else {
                        error("the Jenkins job running on a windows system")
                    }
                }
            }
        }
    }
}

9)pwd()

作用:返回当前所在的目录。由于 Jenkins 支持 windows 和 linux,但是 linux 是 pwd,windows 上是 dir。所以这个插件就干脆支持一个方法,统称为 pwd()。

 

git plugin 插件用法

作用:使用 git 命令 checkout 出项目的代码,在 pipeline 代码中,很常见在不同 stage 中使用不同 git 仓库地址的代码,所以 git SCM 操作,可以写在不同 stage 中。

import hudson.model.*;

println env.JOB_NAME
println env.BUILD_NUMBER

pipeline{
    agent any
    stages{
        stage("test") {
            steps{
                script {
                    println "test"
                }
            }
        }
        stage("git checkout") {
            steps{
                script {
                    checkout([$class: 'GitSCM',
                    branches: [[name: '*/master']],
                    doGenerateSubmoduleConfigurations: false,
                    userRemoteConfigs: [[credentialsId: 'gtihub', url:
                    'https://github.com/kongsh8778/pipelinetest']]])
                }
            }
        }
    }
}

 

publish html report 插件用法

作用:将测试完成后生成的 html 格式的测试报告展示在 Jenkins 中,无需再切换到目录用浏览器打开。

import hudson.model.*;

pipeline{
    agent any
    parameters {
        string(name: 'BROWSER_TYPE', defaultValue: 'chrome', description: 'Type a
        browser type, should be chrome/firefox')
        string(name: 'TEST_SERVER_URL', defaultValue: '', description: 'Type the
        test server url')
        string(name: 'NODE', defaultValue: 'win-anthony-demo', description:
        'Please choose a windows node to execute this job.')
    }
    stages{
        stage("test"){
            steps{
                script{
                    browser_type = BROWSER_TYPE?.trim()
                    test_url = TEST_SERVER_URL?.trim()
                    win_node = NODE?.trim()
                    echo 'test'
                }
            }
        }
    }
    post {
        always{
            script{
                publishHTML (target: [
                    allowMissing: false,
                    alwaysLinkToLastBuild: false,
                    keepAll: true,
                    reportDir: '../../jobs/test_pipeline_demo/report',
                    reportFiles: '接口测试报告.html',
                    reportName: "接口测试报告"
                ])
            }
        }
    }
}

件参数说明

  • reportDir:项目中保存 html 文件的地方,这里写的是一个相对路径写法,相对于当前工作目录的路径,不写的话默认是项目根目录。
  • reportFiles:需要展示的 html 文件名,也可以同时写多个 html 文件,逗号隔开。
  • reportName:这个参数指定的字符串会在 Jenkins 构建 Job 页面显示的菜单名称,后面会看到这个名称,这个名称可以随意修改。

构建结果

手动构建后,在项目首页左侧的导航栏可以看到上一步 reportName 值指定的菜单名:

单击接口测试报告,可以看到如下展示结果:

 

借助 Jenkins 生成 pipeline 代码

通过之前的介绍我们对 pipeline 常用的语法有了初步的印象,但是如果完全记住所有的指令还有第 3 方插件的指令也是不太现实的事情。其实 Jenkins 为我们提供了流水线语法在线生成的功能,我们基于表单的格式填好后,会 Jenkins 会帮助我们生成 pipeline 的代码。

1)进入任意一个 pipeline 项目,单击配置选项:

 

2)进入流水线选项卡,单击左下角的流水线语法:

3)选择“片段生成器”,可以查看所有内置的和已安装插件支持的命令

以 dir 为例:

选择“Declarative Pipeline directive”,可以查看声明式 pipeline 的语法

 

posted @ 2021-04-23 17:26  Juno3550  阅读(6202)  评论(0编辑  收藏  举报