如何使用Jenkins声明式流水线


Jenkins为您提供了两种开发管道代码的方式:脚本式和声明式。

脚本式流水线(也称为“传统”流水线)基于Groovy作为其特定于域的语言。 而声明式流水线提供了简化且更友好的语法,并带有用于定义它们的特定语句,而无需学习Groovy。

Jenkins的流水线插件版本2.5引入了对声明式流水线的支持。

在本文中,我们将介绍开发声明式流水线脚本的所有可用指令,这将清楚地说明其功能。

声明式流水线语法

必须使用pipeline语句定义有效的声明式流水线,并包括以下必需的部分:

  • agent
  • stages
  • stage
  • steps

另外,还有这些可用的指令:

  • environment (在流水线或阶段级别定义)
  • input (阶段级别定义)
  • options (在流水线或阶段级别定义)
  • parallel
  • parameters
  • post
  • dcript
  • tools
  • triggers
  • when

现在,我们将从所需的指令/部分开始,对列出的每个指令/部分进行描述。

agent

Jenkins通过将分布式构建委托给“代理/agent”节点来提供执行分布式构建的能力。 这样做可以使您仅使用Jenkins服务器的一个实例来执行多个项目,而工作负载却被分配给了它的代理。 有关如何配置主/代理模式的详细信息超出了本博客的范围。 请参阅Jenkins分布式构建以获取更多信息。

代理应标记上标签,以便彼此轻松识别。 例如,节点可以通过其平台(Linux,Windows等),其版本或位置等来标记。 “agent”部分配置流水线可以在哪些节点上运行。 指定agent any意味着Jenkins将在任何可用节点上运行作业。

其用法的一个示例可以是:

pipeline {
    agent any
...
}

stages

本部分允许在流水线上生成不同的阶段,这些阶段将在运行作业时显示为不同的段。

一个包含阶段语句的示例流水线:

pipeline {
    agent any
    stages {
        ...
    }
}

stage

必须在“stages”部分上定义至少一个“stage”部分。 它将包含流水线将执行的工作。 阶段必须命名,因为Jenkins将在界面上显示每个阶段,如下所示:

stage视图

Jenkins根据定义的阶段以图形方式拆分流水线执行,并显示它们的持续时间以及是否成功。

上一个图像的流水线脚本如下所示:

pipeline {
    agent any
    stages {
        stage ('build') {
            ...
        }
        stage ('test: integration-&-quality') {
            ...
        }
        stage ('test: functional') {
            ...
        }
        stage ('test: load-&-security') {
            ...
        }
        stage ('approval') {
            ...
        }
        stage ('deploy:prod') {
            ...
        }
    }
}

steps

最后一个必需的部分是“steps”,它被定义为在“stage”内。 在“steps”部分中必须至少定义一个步骤。

对于Linux和MacOS,支持使用shell。 这是一个例子:

steps {
    sh 'echo "A one line step"'
    sh ''' 
    echo "A multiline step"'
    cd /tests/results
    ls -lrt
    '''
}

对于Windows,可以使用bat或PowerShell,如下所示:

steps {  
    bat "mvn clean test -Dsuite=SMOKE_TEST -Denvironment=QA"
    powershell ".\funcional_tests.ps1"
}

其他非必需的指令将在以下段落中说明。

environment

可以在阶段或流水线级别定义此指令,这将决定其定义的范围。 在“pipeline”级别使用“environment”时,其定义将对所有管道步骤均有效。 相反,如果它是在“stage”中定义的,则它仅对特定阶段有效。

该指令的示例用法:

在“pipeline”级别:

pipeline {
    agent any
    environment {
        OUTPUT_PATH = './outputs/'
    }
    stages {
        stage ('build') {
        ...
    }
    ...
    }
}

在”stage”级别:

pipeline {
    agent any
    stages {
        stage ('build') {
            environment {
                OUTPUT_PATH = './outputs/'
            }
            ...
        }
        ...
    }
}

input

“input”指令在阶段级别定义,提供提示输入的功能。 该阶段将被暂停,直到用户手动确认为止。

以下配置选项可用于此指令:

  • message:这是必需的选项,其中指定了要显示给用户的消息。
  • id:可选标识符。 默认情况下,使用“阶段”名称。
  • ok:“确定”按钮的可选文本。
  • submitter:允许提交输入的用户或外部组名的可选列表。 默认情况下,允许任何用户。
  • submitterParameter:要使用提交者名称设置的环境变量的可选名称(如果存在)。
  • parameters:提交者将提供的可选参数列表。

这是包含此指令的示例流水线:

pipeline {
    agent any
    stages {
        stage ('build') {
            input{
               message "Press Ok to continue"
               submitter "user1,user2"
                parameters {
                   string(name:'username', defaultValue: 'user', description: 'Username of the user pressing Ok')
                }
            }
            steps { 
                echo "User: ${username} said Ok."
            }
        }
    }
}

options

在流水线级别定义,此指令将对整个流水线的特定选项进行分组。 可用的选项有:

  • buildDiscarder
  • disableConcurrentBuilds
  • overrideIndexTriggers
  • skipDefaultCheckout
  • skipStagesAfterUnstable
  • checkoutToSubdirectory
  • newContainerPerStage
  • timeout
  • retry
  • timestamps

请参阅Jenkins声明式流水线选项,以获取有关此内容的完整参考。

例如,您可以通过以下操作将流水线配置为在失败前重试3次:

pipeline {
    agent any
    options {
        retry(3)
    }
    stages {
        echo 'do something'
    }
}

parallel

Jenkins流水线阶段可以在内部嵌套其他阶段,这些阶段将并行执行。 这是通过在脚本中添加“parallel”指令来完成的。 使用示例:

stage('run-parallel-branches') {
    steps {
        parallel(
            a: {
                echo "Tests on Linux"
            },
            b: {
            echo "Tests on Windows"
            }
        )
    }
}

从声明式流水线1.2版开始,引入了一种新语法,使并行语法的使用更像声明式的。

使用此新语法重写的先前脚本如下所示:

pipeline {
    agent none
    stages {
        stage('Run Tests') {
            parallel {
                stage('Test On Windows') {
                    agent {
                        label "windows"
                    }
                steps {
                    bat "run-tests.bat"
                }
                }
                stage('Test On Linux') {
                    agent {
                        label "linux"
                    }
                    steps {
                        sh "run-tests.sh"
                    }
                }
            }
        }
    }
}

上述的任何一个流水线都将如下所示:

declarative2-1.png

由于两个脚本都运行特定的平台测试,因此它们将在不同的节点上运行测试。 如果您的Jenkins服务器具有足够的CPU,则还可以通过使用多线程将并行用于在同一节点上同时运行阶段。

使用并行阶段时有一些限制:

  • stage指令可以具有parallel指令或steps指令,但不能同时具有两者。
  • parallel指令中的一个stage指令不能嵌套另一个parallel指令,仅允许steps。
  • 在内部具有parallel指令的stage指令不能定义“agent”或“tools”指令。

parameters

该指令允许您定义脚本中要使用的参数列表。 一旦触发流水线,应提供参数。 应该在“pipeline”级别定义它,并且整个流水线只允许一个指令。

字符串和布尔值是可以使用的有效参数类型。

pipeline {
    agent any
    parameters {
        string(name: 'user', defaultValue: 'John', description: 'A user that triggers the pipeline')
    }
    stages {
        stage('Trigger pipeline') {
            steps {
                echo "Pipeline triggered by ${params.USER}"
            }
        }
    }
}

post

可以在流水线级别或每个阶段上添加post,一旦阶段或流水线完成,便会执行其中包含的语句。可以使用几个post条件来控制是否执行该post:

  • always:无论完成状态如何,都会执行步骤。
  • changed:仅当完成结果与上次运行的状态不同时才执行。
  • fixed:仅在完成结果是成功且上次运行失败时执行
  • regression:仅在当前执行失败,中止或不稳定并且上一次运行成功时执行。
  • aborted:仅在流水线或阶段中止时才执行步骤。
  • failure:仅在流水线或阶段失败时才执行步骤。
  • success:仅在流水线或阶段成功时才执行步骤。
  • unstable:仅当流水线或阶段不稳定时才执行步骤。

由于流水线post包含的句子将在脚本的末尾运行,因此可以在此处执行清除任务或通知等。

pipeline {
    agent any
    stages {
        stage('Some steps') {
            steps {
                echo 'do something'
            }
        }
    }
    post {
        always {
            echo "Pipeline finished"
            bat './performCleanUp.bat'
        }
    }
}

script

此步骤用于将脚本化流水线语句添加到声明式流水线中,从而提供更多功能。 此步骤必须包括在“stage”级别。

脚本块可以多次用于不同的项目。 这些块使您可以扩展Jenkins功能,并可以实现为共享库。 可以在Jenkins共享库中找到有关此内容的更多信息。 同样,可以将共享库导入并使用到“script”中,从而扩展了流水线功能。

接下来,我们将提供示例流水线。 第一个只有一个包含一段脚本化流水线代码的块,而第二个将展示如何导入和使用共享库:

pipeline {
    agent any
    stages {
        stage('Sample') {
            steps {
                echo "Scripted block"
                script {

                }
            }
        }
    }
}

有关此主题的更多信息,请参阅如何使用Jenkins脚本式流水线的文章。

tools

可以在流水线级别或阶段级别添加“tools”指令。 它允许您指定要在脚本上使用的Maven,JDK或Gradle版本。 必须在“全局工具配置”Jenkins菜单上配置这些工具中的任何一个,在撰写本文时,这三个工具都受支持。

另外,Jenkins将尝试安装列出的工具(如果尚未安装)。 通过使用此指令,可以确保安装了项目所需的特定版本。

pipeline {
    agent any
    tools {
        maven 'apache-maven-3.0.1'
    }
    stages {
         echo 'do something'
    }
}

triggers

触发器允许Jenkins通过使用以下任何一个可用的方式自动触发流水线:

  • cron:通过使用cron语法,它可以定义何时重新触发管道。
  • pollSCM:通过使用cron语法,它允许您定义Jenkins何时检查新的源存储库更新。 如果检测到更改,则将重新触发流水线。(从Jenkins 2.22开始可用)。
  • upstream:将Jenkins任务和阈值条件作为输入。 当列表中的任何任务符合阈值条件时,将触发流水线。

带有可用触发器的示例流水线如下所示:

pipeline {
    agent any
    triggers {
        //Execute weekdays every four hours starting at minute 0
        cron('0 */4 * * 1-5')
    }
    stages {
        ...
    }
}



pipeline {
    agent any
    triggers {
        //Query repository weekdays every four hours starting at minute 0
        pollSCM('0 */4 * * 1-5')
    }
    stages {
        ...
    }
}


pipeline {
    agent any
    triggers {
        //Execute when either job1 or job2 are successful
        upstream(upstreamProjects: 'job1, job2', threshold: hudson.model.Result.SUCCESS)
    }
    stages {
        ...
    }
}

when

可以根据“when”指令中定义的条件执行流水线步骤。如果条件匹配,将运行相应阶段中定义的步骤。它应该在阶段级别定义。

有关条件及其说明的完整列表,请参阅Jenkins声明式流水线“when”指令。

例如,流水线使您可以在具有多个分支的项目上执行任务。 这被称为多分支流水线,其中可以根据分支名称(例如“master”,“ feature*”,“development”等)采取特定的操作。 这是一个示例流水线,它将运行master分支的步骤:

pipeline {
    agent any
    stages {
        stage('Deploy stage') {
            when {
                branch 'master'
            }
            steps {
                echo 'Deploy master to stage'
            }
        }
    }
}

最后2个Jenkins声明式流水线提示

声明式流水线语法错误在脚本开始时报告。 这是一个很好的功能,因为您不会浪费时间,直到某个步骤未能意识到拼写错误或拼写错误。

如前所述,流水线可以以声明式或脚本式编写。而且,声明式方法建立在脚本式方法的基础之上,通过添加”script”步骤,可以很容易地进行扩展。

Jenkins流水线已在CI/CD环境中广泛使用。 不管是使用声明式或脚本式管道都具有多个优点。 在本文中,我们介绍了编写示例脚本展示声明式流水线的所有语法元素。 就像我们已经说过的那样,声明式提供了更加友好的语法,而无需Groovy知识。


 关注微信公众号

DevOps持续交付公众号ID:devopscd

 目录
 标签