zoukankan      html  css  js  c++  java
  • Jenkins中插件 pipeline 中声明式流水线的语法

    1. 声明式流水线
    2. 脚本化流水线
     
    声明式流水线
    pipeline {
        agent any
        stages {
            stage('Example') {
                steps {
                    echo 'Hello World'
                }
            }
        }
    }
    

     脚本化流水线

     
    node {
        stage('Example') {
            if (env.BRANCH_NAME == 'master') {
                echo 'I only execute on the master branch'
            } else {
                echo 'I execute elsewhere'
            }
        }
    }
    

      

    node('slave001') { 最外层必须是node节点,这里单独制定运行的jenkins节点,通常不用指定,由jenkins master分配任务即可。这种写法属于Scripted Pipeline。
    stage('Prepare') {} stage是一个阶段的语法,括号里阶段名称。脚本从node开始,按顺序向下执行。遇到的第一个stage就是第一个阶段。
    使用echo xxxx来输出文字,给出进度信息。
    checkout scm 是Jenkins固定获取代码的方法,会输出Check out from version control。
    pom = readMavenPom file: 'location/pom.xml' 是读取workspace下相对目录的pom文件。这个需要Jenkins 安装Pipeline Utility Steps插件。通过${pom.groupId}-${pom.artifactId}来获取pom信息. 我的pom在子module location里。
    docker_host = "docker.ryan-miao.com" 声明一个全局的变量,如果只想在方法体 {}中使用,可以加def。
    ${docker_host} 变量可以通过这样类似shell的方式获取。
    build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim() 用来获取git的commit id
    Build阶段执行docker命令打包,把我们的变量传递到Dockerfile. 我的Dockerfile同样在子module location下。
    withCredentials可以调用存储在Jenkins里的凭证。这个需要安装Credentials Binding Plugin.
    input会产生一个交互式的按钮,需要手动点击通过才会继续,否则暂停。这个只是暂停下一步,线程还在运行。所以,需要单独提出node之外,再添加一个超时设置。参见“input” step blocks executor
    stash暂存文件,参见官方文档. 主要用来把这次build过程中的某个文件给暂存,只在本次build有效。本次不需要。
    timeout 主要用来设置超时,参见官方文档, 时间单位有: NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS。这里等待用户确认是否继续,若超过10分钟还没有确认,则停止。
     

     

    声明性Pipeline

    声明性Pipeline是Jenkins Pipeline 的一个相对较新的补充, 它在Pipeline子系统之上提出了一种更为简化和有意义的语法。
    所有有效的声明性Pipeline必须包含在一个pipeline块内,例如:
    pipeline {
        /* insert Declarative Pipeline here */
    }
     
    声明性Pipeline中有效的基本语句和表达式遵循与Groovy语法相同的规则 ,但有以下例外:
    • Pipeline的顶层必须是块,具体来说是:pipeline { }
    • 没有分号作为语句分隔符。每个声明必须在自己的一行
    • 块只能包含章节, 指令,步骤或赋值语句。
    • 属性引用语句被视为无参数方法调用。所以例如,输入被视为input()
    您可以使用 声明性指令生成器 来帮助您配置声明性Pipeline中的指令和部分。

    Sections

    声明性Pipeline中的Sections通常包含一个或多个指令或步骤。

    代理 agent

    agent指定整个Pipeline或特定stage将在Jenkins环境中执行的位置,具体取决于该agent 部分的位置。该部分必须在pipeline块内的顶层定义,stage块内的agent是可选的 。
    是否必填
    参数 如下面所描述的
    允许出现在 在顶级pipeline块和每个stage块中。
     
     
     
    参数
    为了支持Pipeline作者可能拥有的各种使用场景,agent部分支持几种不同类型的参数。这些参数可以应用于pipeline块的顶层,也可以应用在每个stage指令内。
    • any - 在任何可用的代理上执行Pipeline或stage。例如:agent any
    • none - 当在pipeline块的顶层应用时,将不会为整个Pipeline运行分配全局代理,并且每个stage部分将需要包含其自己的agent部分。例如:agent none
    • label - 使用提供的标签在Jenkins环境中可用的代理上执行Pipeline或stage性执行。例如:agent { label 'my-defined-label' }
    • node - agent { node { label 'labelName' } }行为和 agent { label 'labelName' }相同,但node允许其他选项(如customWorkspace)。
    • docker - 用给定的容器执行Pipeline,或stage,将被动态地提供一个预先配置成基于Docker-based Pipelines的节点,或和label参数匹配的任选节点。 docker还可以接受一个args参数,可以直接将参数传递给docker run命令。例如:agent { docker 'maven:3-alpine' }或
    agent {
        docker {
            image 'maven:3-alpine'
            label 'my-defined-label'
            args  '-v /tmp:/tmp'
        }
    }
    • dockerfile -
      使用从Dockerfile源存储库中包含的容器构建容器来执行Pipeline或stage 。为了使用此选项,Jenkinsfile必须从Multibranch Pipeline或Pipeline from SCM加载。通常Dockerfile在源码库的根路径:agent { dockerfile true }。如果Dockerfile在其他目录中建立,请使用以下dir选项:agent { dockerfile { dir 'someSubDir' } }。您可以使用additionalBuildArgs选项将其他参数传递给docker build ...命令,如agent { dockerfile { additionalBuildArgs '--build-arg foo=bar' } }。
    常用选项
    下面是可以用于两个或多个agent的常用选项。在没有明确说明的情况下选项是可选的。
    label - 一个字符串。在这些标签上运行Pipeline或每个stage。此选项可用于node,docker和dockerfile,并且 对于node是必需的。
    customWorkspace - 一个字符串。运行Pipeline或每个stage, 在这个agent的自定义的工作空间内,而不是默认的。它可以是相对路径,在这种情况下,自定义工作区将位于节点上的工作空间根目录下,也可以是绝对路径。例如:
    agent {
        node {
            label 'my-defined-label'
            customWorkspace '/some/other/path'
        }
    }
     
    reuseNode - 一个布尔值,默认为false。如果为true,则在同一工作空间中,而不是完全在新节点上运行Pipeline顶层指定的节点上的容器。此选项适用于docker和dockerfile,并且仅在agent的每个stage内才有效果。
    Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent { docker 'maven:3-alpine' }
        stages {
            stage('Example Build') {
                steps {
                    sh 'mvn -B clean verify'
                }
            }
        }
    }
     

    发布 post

    post定义将在Pipeline运行或stage结束时运行的操作。一些条件后的块的内支持post: always,changed,failure,success,unstable,和aborted。这些块允许在Pipeline运行或stage结束时执行步骤,具体取决于Pipeline的状态。
    是否必填
    参数 没有
    允许出现在 在顶级pipeline块和每个stage块中。
     
     
     
    条件
    Always - 无论Pipeline运行的完成状态如何都会运行。
    changed - 只有当前Pipeline运行的状态与先前完成的Pipeline的状态不同时,才能运行。
    Failure - 仅当当前Pipeline处于“失败”状态时才运行,通常在Web UI中用红色指示表示。
    success - 仅当当前Pipeline具有“成功”状态时才运行,通常在具有蓝色或绿色指示的Web UI中表示。
    Unstable - 只有当前Pipeline具有“不稳定”状态,通常由测试失败,代码违例等引起,才能运行。通常在具有黄色指示的Web UI中表示。
    Aborted - 只有当前Pipeline处于“中止”状态时,才会运行,通常是由于Pipeline被手动中止。通常在具有灰色指示的Web UI中表示。
    Cleanup - 无论管道或stage的状态如何,在跑完所有其他的post条件后运行此条件下 的post步骤。
    Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent any
        stages {
            stage('Example') {
                steps {
                    echo 'Hello World'
                }
            }
        }
        post {
            always {
                echo 'I will always say Hello again!'
            }
        }
    }
    

      

     
    1. 通常,该post部分应放在Pipeline末端
    2. post条件块包含的步骤和steps中的步骤用法相同

    stage stages

    包含一个或多个stage指令的序列,该stages部分是Pipeline 描述的大部分“工作”所在的位置。建议stages至少为持续交付流程的每个独立部分包含至少一个stage指令,例如构建,测试和部署。
    是否必填
    参数 没有
    允许出现在 在pipeline内只有一次。
     
     
     
     
     
     
    stages部分一般跟在agent, options等后面。
     
    pipeline {
        agent any
        stages {
            stage('Example') {
                steps {
                    echo 'Hello World'
                }
            }
        }
    }
    

      

     

    步骤 steps

    steps部分定义了在给定stage指令中执行的一系列一个或多个步骤。
    是否必填
    参数
    没有
    允许出现在
    每个stage块内
     
     
     
    例如
    Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent any
        stages {
            stage('Example') {
                steps {
                    echo 'Hello World'
                }
            }
        }
    }
    

     

    指令 Directives

    环境 environment

    environment指令指定一系列键值对,这些键值对将被定义为所有step或特定stage的step的环境变量,具体取决于environment指令位于Pipeline中的位置。
    该指令支持一种特殊的助手方法credentials(),可以通过Jenkins环境中的标识符来访问预定义的凭据。对于类型为“Secret Text”的凭据,该 credentials()方法将确保环境变量中包含该Secret Text内容。对于“标准用户名和密码”类型的凭证,指定的环境变量将被设置为username:password并且将自动定义两个附加的环境变量:MYVARNAME_USR和MYVARNAME_PSW。
    是否必填
    参数 没有
    允许出现在 在pipeline块内或stage内
     
     
     
    例如:
    Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent any
        environment {
            CC = 'clang'
        }
        stages {
            stage('Example') {
                environment {
                    AN_ACCESS_KEY = credentials('my-prefined-secret-text')
                }
                steps {
                    sh 'printenv'
                }
            }
        }
    }
    

     

    • environment顶级pipeline块中使用的指令将适用于Pipeline中的所有步骤
    • 在一个stage中定义的environment指令只将给定的环境变量应用于该stage中的步骤
    • environment具有一个帮助方法credentials(),可用于在Jenkins环境中通过其标识符访问预定义的凭据
     

    选项 options

    options指令允许在Pipeline内配置Pipeline专用选项。Pipeline提供了许多这些选项,例如buildDiscarder,但它们也可能由插件提供,例如 timestamps。
    是否必填
    参数 没有
    允许出现在 在pipeline块内,只有一次

     

     

     

    可用选项

    • buildDiscarder
      持久化工件和控制台输出,用于保存Pipeline最近几次运行的数据。例如:options { buildDiscarder(logRotator(numToKeepStr: '1')) }
    • checkoutToSubdirectory
      在工作区的子目录中执行源代码检出。例如:options { checkoutToSubdirectory('foo') }
    • disableConcurrentBuilds
      不允许并行执行Pipeline。可用于防止同时访问共享资源等。例如:options { disableConcurrentBuilds() }
    • preserveStashes
      保留已完成构建的存储,用于stage重新启动。例如:options { preserveStashes() }保存最近完成的构建中的stash,或者options { preserveStashes(5) }保留最近五个完成的构建中的stash。
    • quietPeriod
      设置管道的静默期(以秒为单位),覆盖全局默认值。例如:options { quietPeriod(30) }
    • retry
      如果失败,请按指定的次数重试整个管道。例如:options { retry(3) }
    • skipDefaultCheckout
      在agent指令中默认跳过源代码检出。例如:options { skipDefaultCheckout() }
    • skipStagesAfterUnstable
      一旦构建状态进入了“不稳定”状态,就跳过stage。例如:options { skipStagesAfterUnstable() }
    • timeout
      设置Pipeline运行的超时时间,之后Jenkins应该中止Pipeline。例如:options { timeout(time: 1, unit: 'HOURS') }
    • timestamps
      当执行时,预处理由Pipeline生成的所有控制台输出运行时间。例如:options { timestamps() }
    例如: 指定一个小时的全局执行超时,之后Jenkins将中止Pipeline运行
    Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent any
        options {
            timeout(time: 1, unit: 'HOURS')
        }
        stages {
            stage('Example') {
                steps {
                    echo 'Hello World'
                }
            }
        }
    }
     
    

      

    stage选项
    stage的options指令类似于Pipeline根目录中的options指令。但是,stage的 options只能包含与stage相关的步骤,如retry,timeout或timestamps,或声明性选项,如skipDefaultCheckout。
    在stage内,options在进入agent或检查任何when条件之前调用指令中的步骤。
    可用的stage选项
    • skipDefaultCheckout
      默认情况下,在agent指令中跳过检查源代码管理中的代码。例如:options { skipDefaultCheckout() }
    • timeout
      设置此stage的超时时间,之后Jenkins应该中止该stage。例如:options { timeout(time: 1, unit: 'HOURS') }
    • retry
      如果失败,请重试此stage指定次数。例如:options { retry(3) }
    • timestamps
      当执行时,预处理由Pipeline生成的所有控制台输出运行时间。例如:options { timestamps() }
    • 例如:为stageExample指定一小时的执行超时,之后Jenkins将中止Pipeline运行。
    pipeline {
        agent any
        stages {
            stage('Example') {
                options {
                    timeout(time: 1, unit: 'HOURS')
                }
                steps {
                    echo 'Hello World'
                }
            }
        }
    }
    

      

    参数 parameters

    parameters指令提供用户在触发Pipeline时应提供的参数列表。这些用户指定的参数的值通过该params对象可用于Pipeline步骤,具体用法见示例
    是否必填
    参数 没有
    允许出现在 在pipeline块内,只有一次
     
     
     
    可用参数
    • string
      字符串类型的参数,例如: parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') }
    • 文本
      一个text参数,可以包含多行,例如: parameters { text(name: 'DEPLOY_TEXT', defaultValue: 'One Two Three ', description: '') }
    • booleanParam
      一个布尔参数,例如: parameters { booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '') }
    • choice
      选择参数,例如: parameters { choice(name: 'CHOICES', choices: ['one', 'two', 'three'], description: '') }
    • file
      一个文件参数,指定用户在计划构建时要提交的文件,例如: parameters { file(name: 'FILE', description: 'Some file to upload') }
    • password
      密码参数,例如: parameters { password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'A secret password') }
    Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent any
        parameters {
            string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
            text(name: 'BIOGRAPHY', defaultValue: '', description: 'Enter some information about the person')
            booleanParam(name: 'TOGGLE', defaultValue: true, description: 'Toggle this value')
            choice(name: 'CHOICE', choices: ['One', 'Two', 'Three'], description: 'Pick something')
            password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'Enter a password')
            file(name: "FILE", description: "Choose a file to upload")
        }
        stages {
            stage('Example') {
                steps {
                    echo "Hello ${params.PERSON}"
                    echo "Biography: ${params.BIOGRAPHY}"
                    echo "Toggle: ${params.TOGGLE}"
                    echo "Choice: ${params.CHOICE}"
                    echo "Password: ${params.PASSWORD}"
                }
            }
        }
    }
    

     

    触发器 triggers

    triggers指令定义了Pipeline应重新触发的自动化方式。对于与源代码集成的Pipeline,如GitHub或BitBucket,triggers可能不需要基于webhook的集成可能已经存在。目前只有两个可用的触发器是cron和pollSCM。
    需要
    没有
    参数
    没有
    允许
    只有一次,在pipeline块内。
    • cron
      接受一个cron风格的字符串来定义Pipeline应重新触发的常规间隔,例如: triggers { cron('H 4/* 0 0 1-5') }
    • pollSCM
      接受一个cron风格的字符串来定义Jenkins应该检查新的源更改的常规间隔。如果存在新的更改,则Pipeline将被重新触发。例如:triggers { pollSCM('H 4/* 0 0 1-5') }
    该pollSCM触发器仅在Jenkins 2.22或更高版本可用
    Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent any
        triggers {
            cron('H 4/* 0 0 1-5')
        }
        stages {
            stage('Example') {
                steps {
                    echo 'Hello World'
                }
            }
        }
    } 

    Jenkins cron 语法

    Jenkins cron语法遵循cron实用程序的语法 (略有不同)。具体来说,每行包含由TAB或空格分隔的5个字段:
    分钟 小时 DOM DOW
    一小时内的分钟数(0-59) 一天中的小时(0-23) 每月的某一天(1-31) 月(1-12) 星期几(0-7),其中0和7是星期日。
     
     
     
     
    要为一个字段指定多个值,可以使用以下运算符。按优先顺序排列,
    • * 指定所有有效值
    • M-N 指定一系列值
    • M-N/X或者按照指定范围或整个有效范围的*/X间隔步长X
    • A,B,…,Z 枚举多个值
    为了允许定期计划的任务在系统上产生均匀负载,应尽可能使用符号H(“哈希”)。例如,使用0 0 * * *十几个日常工作将导致午夜大量飙升。相比之下,使用H H * * *仍然会每天执行一次,但不能同时执行,更好地使用有限的资源。
    所述H符号可以与范围内使用。例如,H H(0-7) * * * 表示从凌晨12:00(午夜)到早上7:59之间的某个时间段。您也可以使用H带有或不带范围的步长间隔。
    H符号可以被认为是在一定范围内的随机值,但它实际上是作业名称的hash值,而不是随机函数的哈希值,所以对于给定的项目该值仍然是稳定的。
    请注意,对于月份日期字段,由于月份长度可变,短期周期(例如/3或 H/3)将不会在大多数月份结束时始终如一地工作)。例如,/3 将在第1st, 4th, …31st 天运行, 然后在下个月的第一天运行。 哈希总是在1-28的范围内运行, 所以 H/3在一个月末将产生3到6天的空隙。(更长的周期也会有不一致的长度,但效果可能相对不太明显。)
    以#开头的行和空行将被当做注释忽略。
    此外,还有如下方便的别名:@yearly,@annually,@monthly, @weekly,@daily,@midnight,和@hourly。这些使用哈希系统进行自动平衡。例如,@hourly和H * * * *都意味着在一小时内的任何时间。 @midnight实际上意味着在凌晨12:00到凌晨2:59之间的某个时间。
    每十五分钟(也许在:07,:22,:37,:52)
    triggers{ cron('H/15 * * * *') }
    每小时上半场每十分钟一次(三次,也许在:04,:14,:24)
    triggers{ H(0-29)/10 * * * *) }
    从上午9:45开始每小时45分钟一次,每个工作日下午3:45结束。
    triggers{ 45 9-16/2 * * 1-5) }
    每个工作日上午9点到下午5点之间每两小时一次(可能在上午10:38,下午12点38分,下午2点38分,下午4点38分)
    triggers{ H H(9-16)/2 * * 1-5) }
    除了12月之外,每个月的1日和15日每天一次
    triggers{ H H 1,15 1-11 *) }

    阶段 stage

    stage指令在stages部分中,应包含步骤部分,可选agent部分或其他特定于stage的指令。实际上,Pipeline完成的所有实际工作都将包含在一个或多个stage指令中。
    是否必填 至少一个
    参数 一个必填参数,一个用于stage名称的字符串
    允许出现在 在stages内
     
     
     
    例如:Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent any
        stages {
            stage('Example') {
                steps {
                    echo 'Hello World'
                }
            }
        }
    }
    

      

     

    工具 tools

    定义自动安装和放置工具的部分PATH。如果指定agent none,这将被忽略。
    是否必填
    参数
    没有
    允许出现在
    在pipeline块或stage块内
     
     
     
    支持的工具
    • maven
    • jdk
    • gradle
    例如:  工具名称必须在Jenkins 管理Jenkins → 全局工具配置中预置。
    Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent any
        tools {
            maven 'apache-maven-3.0.1'
        }
        stages {
            stage('Example') {
                steps {
                    sh 'mvn --version'
                }
            }
        }
    }
    

      

     

    输入 input

    stage的input指令允许您使用input步骤提示输入 。在进入stage的agent或评估其when状态之前,stage将处于暂停状态。如果input 获得批准,stage则将继续。作为input提供的任何参数将在stage的剩下部分的环境中可用 。
    配置选项
    • message
      必填。这将在用户提交input时呈现给用户。
    • id
      这是一个可选的标识符input。默认为stage名称。
    • ok
      input表单上“ok”按钮的可选文本。
    • submitter
      允许提交此input选项的用户或外部组名列表,用逗号分隔。默认允许任何用户。
    • submitterParameter
      要使用submitter名称设置的环境变量的名称,可选(如果存在)。
    • parameters
      用于提示提供的可选参数列表。有关更多信息,请参阅参数
    Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent any
        stages {
            stage('Example') {
                input {
                    message "Should we continue?"
                    ok "Yes, we should."
                    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指令允许Pipeline根据给定的条件确定是否执行该stage。when指令必须至少包含一个条件。如果when指令包含多个条件,则所有子条件必须都返回true,stage将会执行。这与子条件嵌套在一个allOf条件中相同(见下面的例子)。
    更复杂的条件结构可使用嵌套条件建:not,allOf或anyOf。嵌套条件可以嵌套到任意深度。
    是否必填
    参数 没有
    允许出现在 在stage指令内
     
     
     
    内置条件
    • branch
      当正在构建的分支与给出的分支模式匹配时执行stage,例如:when { branch 'master' }。请注意,这仅适用于多分支Pipeline。
    • environment
      当指定的环境变量设置为给定值时执行stage,例如: when { environment name: 'DEPLOY_TO', value: 'production' }
    • expression
      当指定的Groovy表达式求值为true时执行stage,例如: when { expression { return params.DEBUG_BUILD } }
    • not
      当嵌套条件为false时执行stage。必须包含一个条件。例如:when { not { branch 'master' } }
    • allOf
      当所有嵌套条件都为真时,执行舞台。必须至少包含一个条件。例如:when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }
    • anyOf
      当至少一个嵌套条件为真时执行舞台。必须至少包含一个条件。例如:when { anyOf { branch 'master'; branch 'staging' } }
    Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent any
        stages {
            stage('Example Build') {
                steps {
                    echo 'Hello World'
                }
            }
            stage('Example Deploy') {
                when {
                    branch 'production'
                }
                steps {
                    echo 'Deploying'
                }
            }
        }
    }
    Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent any
        stages {
            stage('Example Build') {
                steps {
                    echo 'Hello World'
                }
            }
            stage('Example Deploy') {
                when {
                    branch 'production'
                    environment name: 'DEPLOY_TO', value: 'production'
                }
                steps {
                    echo 'Deploying'
                }
            }
        }
    }
    Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent any
        stages {
            stage('Example Build') {
                steps {
                    echo 'Hello World'
                }
            }
            stage('Example Deploy') {
                when {
                    allOf {
                        branch 'production'
                        environment name: 'DEPLOY_TO', value: 'production'
                    }
                }
                steps {
                    echo 'Deploying'
                }
            }
        }
    }
    Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent any
        stages {
            stage('Example Build') {
                steps {
                    echo 'Hello World'
                }
            }
            stage('Example Deploy') {
                when {
                    branch 'production'
                    anyOf {
                        environment name: 'DEPLOY_TO', value: 'production'
                        environment name: 'DEPLOY_TO', value: 'staging'
                    }
                }
                steps {
                    echo 'Deploying'
                }
            }
        }
    }
    Jenkinsfile (Declarative Pipeline)
    pipeline {
        agent any
        stages {
            stage('Example Build') {
                steps {
                    echo 'Hello World'
                }
            }
            stage('Example Deploy') {
                when {
                    expression { BRANCH_NAME ==~ /(production|staging)/ }
                    anyOf {
                        environment name: 'DEPLOY_TO', value: 'production'
                        environment name: 'DEPLOY_TO', value: 'staging'
                    }
                }
                steps {
                    echo 'Deploying'
                }
            }
        }
    }
    

      

     

    顺序执行的stage(Sequential Stages)

    声明性Pipeline中的stage可以按顺序声明待运行的stage列表。需要注意的是一个stage有且只能有一个 steps,parallel或者stages,stages是顺序执行的。stage内的stage无法进一步含有parallel或stages ,但他们允许使用stage的所有其他功能,包括 agent,tools,when等等。
    pipeline {
        agent none
        stages {
            stage('Non-Sequential Stage') {
                agent {
                    label 'for-non-sequential'
                }
                steps {
                    echo "On Non-Sequential Stage"
                }
            }
            stage('Sequential') {
                agent {
                    label 'for-sequential'
                }
                environment {
                    FOR_SEQUENTIAL = "some-value"
                }
                stages {
                   stage('In Sequential 1') {
                       steps {
                           echo "In Sequential 1"
                       }
                   }
                   stage('In Sequential 2') {
                       steps {
                           echo "In Sequential 2"
                       }
                   }
                }
            }
        }
    }
     
    

      

    并行的stage(Parallel)

    声明性Parallel中的stage可以在parallel块中声明多个嵌套stage,这些stage将并行执行。需要注意的是一个stage有且只能有一个steps,stages或parallel。嵌套的stages本身不能包含其他parallelstage,但在其他方面的行为与stage相同,包括顺序执行的stage列表stages。任何包含parallel的stage都不能包含agent或者tools,因为那些和steps没有关系。
    此外,您可以通过添加failFast true到包含parallel的stage中,使得其中一个失败时中止所有parallel内的stage。
    pipeline {
        agent any
        stages {
            stage('Non-Parallel Stage') {
                steps {
                    echo 'This stage will be executed first.'
                }
            }
            stage('Parallel Stage') {
                when {
                    branch 'master'
                }
                failFast true
                parallel {
                    stage('Branch A') {
                        agent {
                            label "for-branch-a"
                        }
                        steps {
                            echo "On Branch A"
                        }
                    }
                    stage('Branch B') {
                        agent {
                            label "for-branch-b"
                        }
                        steps {
                            echo "On Branch B"
                        }
                    }
                    stage('Branch C') {
                        agent {
                            label "for-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"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

      

     

    步骤 Steps

    声明性Pipeline可以使用“ Pipeline步骤”引用中记录的所有可用步骤 ,其中包含一个完整的步骤列表,并附加以下列出的步骤,仅在声明性Pipeline中支持。

    脚本 script

    script步骤需要一个script Pipeline,并在声明性Pipeline中执行。对于大多数场景,声明Pipeline中的script步骤不是必须的,但它可以提供一个有用的“escape hatch”。量大的或者复杂的script块应该转移到共享库中。
    Jenkinsfile (Declarative Pipeline)
    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"
                        }
                    }
                }
            }
        }
    }

    Scripted Pipeline

    Scripted Pipeline,如声明式Pipeline,构建在底层Pipeline子系统之上。不像声明式Pipeline,Scripted Pipeline是一个基于Groovy构建的,通用、高效的DSL。由Groovy语言提供的大多数功能都提供给Scripted Pipeline的用户,这意味着它是一个非常富有表现力和灵活性的工具,可以通过这些工具来创建持续构建的Pipeline。

    Flow Control

    Scripted Pipeline从顶部顺序执行,与Jenkinsfile Groovy或其他语言中的大多数传统Scripted一样。因此,提供流量控制取决于Groovy表达式,例如 if/else条件,例如:
    Jenkinsfile (Scripted Pipeline)
    node {
        stage('Example') {
            if (env.BRANCH_NAME == 'master') {
                echo 'I only execute on the master branch'
            } else {
                echo 'I execute elsewhere'
            }
        }
    }
     
    可以管理Scripted Pipeline流控制的另一种方式是使用Groovy的异常处理支持。当步骤由于任何原因而导致异常时。处理错误行为必须使用Groovy 中的try/catch/finally块,例如:
    Jenkinsfile (Scripted Pipeline)
    node {
        stage('Example') {
            try {
                sh 'exit 1'
            }
            catch (exc) {
                echo 'Something failed, I should sound the klaxons!'
                throw
            }
        }
    }

    Steps

    如“ 入门指南 ”所述,Pipeline最基本的部分是“步骤”。从根本上说,步骤告诉Jenkins 要做什么,并且作为Declarative和Scripted Pipeline语法的基本构建块。
    Scripted Pipeline并没有介绍这是专门针对它的语法的任何步骤; Pipeline步骤参考 ,其中包含Pipeline和插件提供的完整步骤列表。

    与Groovy的区别

    为了提供持久性(运行中的Pipeline可以在重新启动Jenkins主站后保留),Scripted Pipeline必须将数据序列化到master节点。由于这个设计要求,一些Groovy语法如collection.each { item -> /* perform operation */ }没有完全支持。有关 更多信息,请参见 JENKINS-27421JENKINS-26481

    语法比较

    当Jenkins Pipeline首次创建时,Groovy被选为执行引擎。Jenkins已经使用嵌入式Groovy引擎很长时间,为管理员和用户提供高级脚本功能。此外,Jenkins Pipeline的实现者发现Groovy是建立“Scripted Pipeline”DSL的坚实基础。
    由于它是一个功能齐全的编程环境,Scripted Pipeline为Jenkins用户提供了极大的灵活性和可扩展性。Groovy学习曲线通常不适用于给定团队的所有成员,因此,创建声明性Pipeline是为了创作Jenkins Pipeline提供一个更简单和更有见解的语法。
    两者基本上是底层相同的Pipeline 子系统。它们都是“Pipeline代码”的持久实现。他们都能够使用Pipeline内置的插件或插件提供的步骤。两者都可以利用共享库
    不同之处在于语法和灵活性。声明性限制了用户具有更严格和预定义结构的可用性,使其成为更简单连续输送Pipeline的理想选择。脚本化提供了极少的限制,因为Groovy本身只能对结构和语法进行限制,而不是任何Pipeline专用系统,使其成为高级用户和具有更复杂要求的用户的理想选择。顾名思义,Declarative Pipeline鼓励声明式编程模型。 尽管Scripted Pipeline遵循更命令性的编程模型。
     
     

     
    Pipeline stages中的stage含有stages
    认真看,可以看到这些特点。
     
    所有的stage,都会内嵌在最外层的stages{…}
    一个stage{…}下可以内嵌有且只有一个stages{…}
    多层嵌套只支持在最后一个stage{…}里面
    嵌套越多越复杂,最简单就是观察每一个stage的大括号的范围
    原则上,我们尽量少写嵌套的stage{…},写了嵌套就意味很难维护。但是有时候,由于业务逻辑需要,和stage{…}组织结构好看,我们会写嵌套,嵌套里面可能存在顺序和平行的stage{…} 前面我们演示的demo都是顺序,也就是一个接着一个执行
     
    pipeline {
        agent none
        stages {
            stage('11111111') {
                steps {
                    echo "11111111"
                }
            }
            stage('22222') {
                stages {
                   stage('222222aaaaa1') {
                       steps {
                           echo "222222aaaaa1"
                       }
                   }
                   stage('In 222222aaaa2') {
                       steps {
                           echo "222222aaaa2"
                       }
                   }
                }
            }
            stage('33333') {
                steps {
                    echo "33333"
                }
            }
        }
    }
    并行stage{…}需要用到指令paraller, 有一个paraller{…} 里面包含多个stage{…},最后一个stage{…}内部支持嵌套多个stages{…}。在paraller{…}如果要设置只要里面有一个stage{…}运行失败就强制停止,可以使用表达式failFast true 来条件控制。
     
    并行stage{…}举例:
     
    pipeline {
        agent any
        stages {
            stage('Non-Parallel Stage') {
                steps {
                    echo 'This stage will be executed first.'
                }
            }
            stage('Parallel Stage') {
                failFast true
                parallel {
                    stage('并行一') {
                        steps {
                            echo "并行一"
                        }
                    }
                    stage('并行二') {
                        steps {
                            echo "并行二"
                        }
                    }
                    stage('并行三') {
                        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"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
     
    pipeline {
        agent any    
        stages {
            stage('Non-Parallel Stage') {
                steps {
                    echo 'This stage will be executed first.'
                }
            }
            stage('Parallel Stage') {
                failFast true
                parallel {
                    stage('并行一') {
                        steps {
                            echo "并行一"
                        }
                    }
                    stage('并行二') {
                        steps {
                            echo "并行二"
                        }
                    }
                    stage('并行三') {
                        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"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

      

    关于这个并行,我创建了一个jenkins job,跑一下就可以帮助你了解。
    并行1 并行2  并行3 三个stage之间的关系是并行的,上面截图显示都执行成功。这里我们测试一下如果并行二发生报错,会发生生成。在并行二里面的echo 改成echo1,再次运行。
     
    由于我们添加了代码failFast true,但是并行二这个stage发生了报错。本来并行1 并行2 并行3下面两个嵌套的stage都在同一时间并发执行,但是这个job最终的结果是aborted, 从控制台日志或者UI显示灰色能看出来确实是中止了。
     
    总结一下,paraller{…}这个要会使用,使用这个表示并行执行里面的多个stage。这里举例一下这个使用场景,例如我有一个模块的代码分别要在windows 和mac 和linux上三种环境下去测试。那么我可以提前准备好三个环境的agent node机器,然后一套环境写一个stage,把这三个stage都放在paraller{…}里面,让三个并行测试。paraller{…}上面一层这个stage名称就可以叫xxx模块兼容性测试。因为这三个环境都同等重要,你就可以设置failFast true,只要有一个不通过,就中止运行pipeline下面的代码。关于嵌套,非不得已,不要去使用,确实让其他人不好读代码和不好维护。
     
    流程控制
     
    由于pipeline是基于groovy语言开发的,所以支持在pipeline{...}代码块写流程控制语句代码和循环代码。原则上,大部分java和groovy的语法都可以在pipeline上得到很好的处理,但是还是有一些是不好兼容的,所以,Jenkins特意为了更好使用pipeline,开发了一些工具类,方便我们更好地在step中处理各种需求。接下来,我要带大家一起学习https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/
     
    这个页面的一些常用的工具类的使用,算是一个实战练习过程吧。pipeline语法就学习完了,对了还有一种script pipeline我不打算介绍,从头到尾我们都在学习更容易维护和直观的Declarative Pipeline模式。下面写一个if控制语句来展开接下来我们要实战的练习。
    pipeline {
        agent any    
        stages {
            stage('flow control') {
                steps {
                    script {
                        if ( 10 == 10) {
                            println "pass"
                        }else {
                            println "failed"
                        }
                    }
                }
            }
        }
    }
     
    

      

    ------------------------- A little Progress a day makes you a big success... ----------------------------
  • 相关阅读:
    Html页中使用OCX控件
    Delphi 7 升级到 Delphi 2010 总结
    Delphi2010下的FillChar
    机器学习之基于朴素贝叶斯文本分类算法
    JDBC对MySQL数据库存储过程的调用
    HDU1788 Chinese remainder theorem again【中国剩余定理】
    Hadoop分布式文件系统--HDFS结构分析
    【php学习笔记】ticks篇
    怎样退出App之前唤醒还有一个App?
    Java 实现策略(Strategy)模式
  • 原文地址:https://www.cnblogs.com/qianjinyan/p/14981608.html
Copyright © 2011-2022 走看看