流水线语法

本节是建立在 流水线入门内容的基础上,而且,应当被当作一个参考。 对于在实际示例中如何使用流水线语法的更多信息, 请参阅本章在流水线插件的2.5版本中的 使用 Jenkinsfile部分, 流水线支持两种离散的语法,具体如下对于每种的优缺点, 参见语法比较。

正如 本章开始讨论的, 流水线最基础的部分是 “步骤”。基本上, 步骤告诉 Jenkins 要做什么,以及作为声明式和脚本化流水线语法的基本构建块。

对于可用步骤的概述, 请参考 流水线步骤引用,它包含了一个构建到流水线的步骤和 插件提供的步骤的全面的列表。

声明式流水线

声明式流水线是最近添加到 Jenkins 流水线的 [1],它在流水线子系统之上提供了一种更简单,更有主见的语法。

所有有效的声明式流水线必须包含在一个 pipeline 块中, 比如:

pipeline {
    /* insert Declarative Pipeline here */
}

在声明式流水线中有效的基本语句和表达式遵循与 Groovy的语法同样的规则, 有以下例外:

  • 流水线顶层必须是一个 block, 特别地: pipeline { }
  • 没有分号作为语句分隔符,,每条语句都必须在自己的行上。
  • 块只能由 节段, 指令, 步骤, 或赋值语句组成。 *属性引用语句被视为无参方法调用。 例如, input被视为 input()

节段


声明式流水线中的节段通常包含一个或多个 指令 或 步骤。

代理

agent 部分指定了整个流水线或特定的部分, 将会在Jenkins环境中执行的位置,这取决于 agent 区域的位置。该部分必须在 pipeline 块的顶层被定义, 但是 stage 级别的使用是可选的。

Required

Yes

Parameters

Described below

Allowed

In the top-level pipeline block and each stage block.

参数

为了支持作者可能有的各种各样的用例流水线, agent 部分支持一些不同类型的参数。这些参数应用在pipeline块的顶层, 或 stage 指令内部。

  • any在任何可用的代理上执行流水线或阶段。例如: agent any
  • none当在 pipeline 块的顶部没有全局代理, 该参数将会被分配到整个流水线的运行中并且每个 stage 部分都需要包含他自己的 agent 部分。比如: agent none
  • label在提供了标签的 Jenkins 环境中可用的代理上执行流水线或阶段。 例如: agent { label 'my-defined-label' }
  • nodeagent { node { label 'labelName' } } 和 agent { label 'labelName' } 一样, 但是 node 允许额外的选项 (比如 customWorkspace )。
  • docker使用给定的容器执行流水线或阶段。该容器将在预置的 node上,或在匹配可选定义的label 参数上,动态的供应来接受基于Docker的流水线。 docker 也可以选择的接受 args 参数,该参数可能包含直接传递到 docker run 调用的参数, 以及 alwaysPull 选项, 该选项强制 docker pull ,即使镜像名称已经存在。 比如: agent { docker 'maven:3-alpine' } 或
agent {
    docker {
        image 'maven:3-alpine'
        label 'my-defined-label'
        args  '-v /tmp:/tmp'
    }
}
  • dockerfile执行流水线或阶段, 使用从源代码库包含的 Dockerfile 构建的容器。为了使用该选项, Jenkinsfile 必须从多个分支流水线中加载, 或者加载 “Pipeline from SCM.” 通常,这是源代码仓库的根目录下的 Dockerfile : agent { dockerfile true }. 如果在另一个目录下构建 Dockerfile , 使用 dir 选项: agent { dockerfile {dir 'someSubDir' } }。如果 Dockerfile 有另一个名称, 你可以使用 filename 选项指定该文件名。你可以传递额外的参数到 docker build ... 使用 additionalBuildArgs 选项提交, 比如 agent { dockerfile {additionalBuildArgs '--build-arg foo=bar' } }。 例如, 一个带有 build/Dockerfile.build 的仓库,期望一个构建参数 version:
agent {
    // Equivalent to "docker build -f Dockerfile.build --build-arg version=1.0.2 ./build/
    dockerfile {
        filename 'Dockerfile.build'
        dir 'build'
        label 'my-defined-label'
        additionalBuildArgs  '--build-arg version=1.0.2'
    }
}

常见选项

有一些应用于两个或更多 agent 的实现的选项。他们不被要求,除非特别规定。

  • label一个字符串。该标签用于运行流水线或个别的 stage。该选项对 node, docker 和 dockerfile 可用, node要求必须选择该选项。
  • customWorkspace一个字符串。在自定义工作区运行应用了 agent 的流水线或个别的 stage, 而不是默认值。 它既可以是一个相对路径, 在这种情况下,自定义工作区会存在于节点工作区根目录下, 或者一个绝对路径。比如:
agent {
    node {
        label 'my-defined-label'
        customWorkspace '/some/other/path'
    }
}

pipeline语法学习

  • pipeline语法分为脚本式语法和声明式语法
最简单的pipeline语法实例
pipeline{
    //pipeline:代表整条流水线,包含整个流水线的逻辑
    agent any
    // 流水线执行的地点
    stages{
    //多个stage的容器 (每一个stages部分至少包含一个stage)   
        stage("build"){
            steps{
                echo "hello word"
            }
        }
    }
}
//以上的三个部分都是必须的少一个语法模块不成立 Jenkins就会报错
post语法模块
post {
    //post模块是在构建后完成的后所附加的步骤。
    always{
        //不论当前完成状态是什么,都执行。
    }
    changed{
        //只要当前完成状态与上一次完成状态不同就执行。
    }
    fixed{
        //上一次完成状态为失败或不稳定(unstable),当前完成状态为 成功时执行。
    }
    regression{
        //上一次完成状态为成功,当前完成状态为失败、不稳定或中 止(aborted)时执行。
    }
    aborted{
        //当前执行结果是中止状态时(一般为人为中止)执行。
    }
    failure{
        //当前完成状态为失败时执行
    }
    success{
        //执行成功时
    }
    unstable{
        //当前完成状态为不稳定时执行
    }
    cleanup{
        //清理条件块。
    }   
}
pipeline所支持的语法指令模块
environment{
        //用于设置环境变量 可定义在Stage或者pipeline部分
    }
    tools{
        //可定义pipeline或者stage部分,他会自动下载并安装我们指定的工具,并将器加入path变量中
    }
    input{
        //定义在stage部分,会暂停pipeline提示你输入内容
    }
    parallel{
        //并行执行多个step 也可以多阶段并行执行
    }
    parameters{
        //parmeters是执行pipeline前传入的一些参数
    }
    triggers{
        //pipeline的触发器,主要用于条件触发 
    }
    when{
    	//满足当前when的定义的时候,阶段才执行
    }
pipeline流水线的控制模块
  • options可以配置整个jenkins任务,也可以配置某个单个stage模块
options {
        //配置整个Jenkins任务,可以将其放入stage块中
        buildDiscarder(logRotator(numTokeepStr:'10'))
        //保存最近历史构建记录的数量以及日志,保存多少。 
        checkoutToSubdirectory('sudbir')
        //指定代码检出到工作空间的子目录中。
        disableConcurrentBuilds()
        //默认情况下jenkins是可以同时执行多次的,此模块是禁止同时执行
        newContainerPerStage()
        //当agent为docker或者dockerfile时,指定在同一个jenkins节点上
        retry()
        //可以被指定在stage模块中,当发生失败进行重试
        timeout(time: 10 , unit : 'HOURS')
        //可以被指定在stage模块中,当运行时间超时将中止执行
    }
pipeline中使用声明脚本

script模块,可以写一代码

pipeline{
    agent any
    stages{
        stage("Example"){
            steps{
                script {
                    def browser = ['chrome','firefox']
                    for ( int i = 0 ; i < browser.size(); ++i ){
                        echo "Testing the ${browser[i]} browser"
                    }
                }
            }
        }
    }
}
pipeline内置基础步骤
文件目录相关的操作
dir("/var/logs"){
	//切换到工作目录下,默认工作时在当前任务的工作空间
	deleteDir()
	//删除当前目录
	isUnix()
	//判断当前是是否为Linux系统
	fileExists("")
	//判断文件是否存在
	writeFile(file:'',text:'' enconding:'')
	//将内容写在文件中,文件路径,文件内容,文件编码
	readFile(file:'',enconding:'')
	//读取指定文件,以文本返回,
}
示例:
pipeline{
    agent any
    stages{
        stage("Example"){
            steps{
                script {
                    writeFile(file:"test.txt",text:"测试",encoding:"UTF-8")
                    def content = readFile(file:"test.txt",encoding:"Base64")
                    echo "${content}"
                }
            }
        }
    }
}

Stash临时保存文件

pipeline{
    agent none 
    stages{
        stage("stash"){
            agent { label "master" }
            steps { 
                script{
                    writeFile (file: "a.txt" , text : "$BUILD_NUMBER")
                    stash(name: "abc" , includes : "a.txt")
                }

            }
        }
        stage("unstash"){
            agent { label "node1" }
            steps {
                script {
                    unstash("abc")
                    def content = readFile("a.txt")
                    echo "${content}"
                }
            }
        }
    }
}

stash保存临时文件,可以被同一个构建的其他步骤或这阶段使用,主要用于跨节点读取信息的时候使用,stash步骤会将文件存储在tar中,对于大文件,stash的操作将会消耗Jenkins master的计算资源。

unstash:去除之前stash的文件 只有一个参数,当于stash的标识相同的时候,则会读取。

命令相关的的步骤

sh步骤支持的参数有:

  • script:要执行的脚本
  • encoding:脚本执行后输出的日志的编码,默认职位脚本所运行的系统编码
  • returnStatus:布尔类型,默认返回的时状态码,如果returnstatus时非零状态码
  • returnStdout: 布尔类型,如果为true,则任务的标准输入将作为步骤返回值。而不是打印到构建日志中.

bat、powershell步骤

其他步骤

error: 主动报错中止当前pipeline(步骤的执行类似于抛出一个异常。它只有一个必需参数:message。 通常省略参数:error(“there’s an error”))

pipeline声明式语法when的用法
pipeline{
    agent any 
    stages{
       stage{
           when {
               branch 'master'
               //判断分支是不是住分支后执行
           }
       }
       stage{
           when {
               changelog '.*\\[xxx\\].+$'
               //如果版本控制库的changelog符合正则表达式,则执行
           }
       }
       stage{
          when{
              environment name: '变量名称' , value: 'xxxxx'
              //如果环境变量的值与给定的值相同,则执行
          } 
       }
       stage{
           when {
               equals expected: 2 , actual: currentBuild.number
               //如果期望值与给定的值相同,则执行
           }
       }
       stage{
           when{
               expression {
                   return env.BTANCH_NAME != 'master'
               }
           }
       }
       stage{
           when {
               buildingTag()
               //如果pipeline所执行的代码被打了tag
               tag "release_*"
               //tag名称匹配时这样的执行
           }
       }
       stage{
           when {
               allof {
                   //所有条件都必须符合。
               }
               anyof {
                   //只有一个条件符合
               }
           }
       }
    }
}

实例

pipeline{
    agent{ label "XXXXX" }
    stages{
        stage("下载版本包"){
            steps{
                bat encoding: 'UTF-8', returnStdout: true, script: 
                '''
                @echo off 
                echo hello
                '''
            }
        }
        stage("钉钉通知"){
            steps{
                echo "钉钉通知"
            }
        }
        stage("各类数据库部署"){
            parallel{
                stage("Mysql部署"){
                    when { expression { return ( Mysql == "true" ) } }
                    steps{
                        echo "部署成功"
                    }
                }
                stage("Orcale部署"){
                    when { expression { return ( Orcale == "true" ) } }
                    steps{
                        echo "部署成功"
                    }
                }
                stage("SQLserver部署"){
                    when { expression { return ( SQLserver == "true" ) } }
                    steps{
                        echo "部署成功"
                    }
                }
            }
        }    
    }
    post{
        always{
            echo "========always========"
        }
        success{
            echo "========pipeline executed successfully ========"
        }
        failure{
            echo "========pipeline execution failed========"
        }
    }
}
pipeline{
    agent{
        label "XXX"
    }
    options {
        buildDiscarder logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '30', numToKeepStr: '100')
    }
    parameters {
        text defaultValue: '', description: '请输入版本号:', name: 'BUILD_VERSION'
    }
    stages{
        stage('build version'){
             steps{
                 deleteDir()
             }   
        }
        stage('download version'){
            steps{
                 sh label: 'node1', script: '''
				 echo "下载"
				 '''
            }
        }
        stage('show version'){
            steps{
                script {
                    def jobName=build_Version
                    manager.addShortText(jobName)  
                }
            }
        }
    }
	post{
        always{
            echo "========always========"
        }
        success{
            echo "========pipeline executed successfully ========"
        }
        failure{
            echo "========pipeline execution failed========"
        }
    }
}