Jenkinsfile

创建一个Jenkinsfile,它被检入源代码控制.这样可以提供一些好处:

  • pipeline上的代码审查/迭代
  • pipeline的审计跟踪
  • 管道的唯一真实来源,可以由项目中的多个成员查看和编辑(便于团队合作).

创建Jenkinsfile

如“入门”部分所述,Jenkinsfile是一个包含Jenkins管道定义的文本文件,并被检入源代码控制。 考虑以下pipeline,实施基本的三阶段连续输送pipeline。

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                echo 'Building..'
            }
        }
        stage('Test') {
            steps {
                echo 'Testing..'
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying....'
            }
        }
    }
}

并非所有的管道都将具有相同的三个阶段,但是对于大多数项目来说,这是一个很好的起点。 以下部分将演示在Jenkins的测试安装中创建和执行简单的pipeline。

假设已经有一个项目的源码管理库,并且已经在Jenkins中按照说明定义了一个pipeline

使用文本编辑器,理想的是支持Groovy语法高亮显示的文本编辑器,在项目的根目录中创建一个新的Jenkins文件。

上述声明性管道示例包含实现连续传送piperline的最小必要结构。 需要的代理指令指示Jenkins为piperline分配一个执行器和工作区。 没有agent指令,piperline声明无效,所以不能做任何工作! 默认情况下,agent指令确保源已被检出,并可用于后续阶段的步骤

对于有效的声明性管道,Stage指令和steps指令也是必需的,因为它们会指示Jenkins执行什么以及应在哪个阶段执行。

对于脚本管道更高级的使用,上面的示例节点是分配管道的执行器和工作空间的关键第一步。 实质上,没有节点,管道不能做任何工作! 从节点内部,业务的第一个顺序是checkout此项目的源代码。 由于Jenkins文件被直接从源代码控制中pull,所以Pipeline提供了一种快速简单的方法来访问源代码的正确版本

node {
    checkout scm
    /* .. snip .. */
}

chechout步骤将从源代码控制中检出代码; scm是一个特殊变量,指示检出步骤克隆触发此pipeline运行的特定版本。

Build

对于大多数项目而言,piperline的"工作"的开始就是"build"阶段.通常,管道的这个阶段将是源码组装,编译或打包的地方.Jenkinsfile不能替代现有的构建工具,例如GNU/Make/Maven/Gradle等.而是将其视为粘合层来绑定项目开发生命周期的多个阶段(build,test,deploy,etc).

Jenkins有一些插件,用于调用几乎任何通用的构建工具,但是这个例子将简单的从shell步骤(sh)调用Make.sh步骤假定系统是基于Unix/Linux的.

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                sh 'make'
                archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true
            }
        }
    }
}
  • sh步骤调用make命令,只有当命令返回值为0时才会继续。 任何非零退出代码将失败piperline。
  • archiveArtifacts捕获与include模式(* / target / 。jar)匹配的文件,并将其保存到Jenkins主数据库以供以后检索。

    archiveArtifacts不能替代使用诸如Artifactory或Nexus之类的外部工件存储库,只能用于基本报告和文件归档。

Test

运行自动化测试是任何成功的连续传送过程的重要组成部分。 因此,Jenkins有许多插件提供的测试记录,报告和可视化设备。 在基本层面上,当有测试失败时,让Jenkins在Web UI中记录报告和可视化的故障是有用的。 下面的示例使用由JUnit插件提供的junit步骤。

在下面的示例中,如果测试失败,则管道被标记为“不稳定”,如Web UI中的黄色球。 根据记录的测试报告,Jenkins还可以提供历史趋势分析和可视化。

pipeline {
    agent any

    stages {
        stage('Test') {
            steps {
                /* `make check` returns non-zero on test failures,
                * using `true` to allow the Pipeline to continue nonetheless
                */
                sh 'make check || true'
                junit '**/target/*.xml'
            }
        }
    }
}
  • 使用内联条件(sh'make || true)确保sh步骤始终看到零退出代码,使junit步骤有机会捕获和处理测试报告。 下面的“处理故障”部分将详细介绍其他方法。
  • junit捕获并关联与包含模式匹配的JUnit XML文件(* / target / 。xml)。

Deploy

部署可能是步骤的各种变体,具体取决于项目或者组织的要求,可能是从构建的artifacts发送到artifacty服务器,将代码推送到生产系统的任何步骤.

在piperline示例的这个阶段,“构建”和“测试”阶段都已成功执行。 实际上,“部署”阶段只能在上一阶段成功完成,否则管道将早退。

pipeline {
    agent any

    stages {
        stage('Deploy') {
            when {
              expression {
                currentBuild.result == null || currentBuild.result == 'SUCCESS'
              }
            }
            steps {
                sh 'make publish'
            }
        }
    }
}

访问currentBuild.result变量允许管道确定是否有任何测试失败。 在这种情况下,该值将是“不稳定”。

假设一切都在Jenkins Pipeline示例中成功执行,每个成功的Pipeline运行都会将存档的关联构建工件,报告的测试结果和完整的控制台输出全部放在Jenkins中。 Script Piperline可以包括条件测试(如上所示),循环,try / catch / finally块甚至函数。 下一节将详细介绍这种高级脚本管道语法。

Piperline高级语法

字符串插值

Jenkins管道使用与Groovy相同的规则进行字符串插值。 Groovy的字符串插值支持可能会让很多新来的语言感到困惑。 虽然Groovy支持使用单引号或双引号声明一个字符串,例如:

def singlyQuoted = 'Hello'
def doublyQuoted = "World"

只有第二个字符串支持基于美元符号($)的字符串插值,例如:

def username = 'Jenkins'
echo 'Hello Mr. ${username}'
echo "I said, Hello Mr. ${username}"

将会输出结果:

Hello Mr. ${username}
I said, Hello Mr. Jenkins

了解如何使用字符串插值对于使用一些管道更高级的功能至关重要。

环境变量

Jenkins管道通过全局变量env公开环境变量,该变量可从Jenkins文件中的任何位置获得。 假设Jenkins主机在localhost:8080上运行,那么在本地主机:8080 / pipeline-syntax / globals#env中记录了可从Jenkins Pipeline中访问的环境变量的完整列表,其中包括:

BUILD_ID

当前版本ID,与Jenkins版本1.597+中创建的builds相同,为BUILD_NUMBER

JOB_NAME

此构建项目的名称,如“foo”或“foo / bar”。

JENKINS_URL

完整的Jenkins网址,例如example.com:port/jenkins/(注意:只有在“系统配置”中设置了Jenkins网址时才可用)

参考或使用这些环境变量可以像访问Groovy中的Map任何key一样完成,例如:

pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                echo "Running ${env.BUILD_ID} on ${env.JENKINS_URL}"
            }
        }
    }
}

设置环境变量

Declarative和Scripted Pipeline两种语法,在Jenkins piperline中设置环境变量是不同的。 Declarative Piperline支持environment指令,而Scripted Pipeline的用户必须使用withEnv步骤。

pipeline {
    agent any
    environment {
        CC = 'clang'
    }
    stages {
        stage('Example') {
            environment {
                DEBUG_FLAGS = '-g'
            }
            steps {
                sh 'printenv'
            }
        }
    }
}
  • 顶层piperline块中使用的environment指令将适用于piperline中的所有步骤。
  • 在stage中定义的environment指令将仅将给定的环境变量应用于stage中的步骤。

参数

声明式管道支持开箱即用的参数,允许管道在运行时通过parameters指令接受用户指定的参数。 使用脚本管道配置参数通过properties步骤完成,可以在代码段生成器中找到。

如果您使用“Build with Parameters”选项配置管道来接受参数,那么这些参数可以作为params变量的成员访问。

假设在Jenkins文件中配置了一个名为“Greeting”的String参数,它可以通过$ {params.Greeting}访问该参数:

pipeline {
    agent any
    parameters {
        string(name: 'Greeting', defaultValue: 'Hello', description: 'How should I greet the world?')
    }
    stages {
        stage('Example') {
            steps {
                echo "${params.Greeting} World!"
            }
        }
    }
}

声明式管道默认通过其post部分支持强大的故障处理,允许声明许多不同的“后置条件”,例如:always,unstable,success,failure和changed。 “Piperline语法”提供了有关如何使用各种条件的更多详细信息。

pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                sh 'make check'
            }
        }
    }
    post {
        always {
            junit '**/target/*.xml'
        }
        failure {
            mail to: team@example.com, subject: 'The Pipeline failed :('
        }
    }
}

然而脚本管道依赖于Groovy内置的try / catch / finally语义来处理管道执行过程中的故障。

在上面的测试示例中,sh步骤被修改为从不返回非零退出代码(sh'make check || true')。 这种方法虽然有效,但是意味着以下阶段需要检查currentBuild.result以了解是否有测试失败。

处理这种情况的另一种方法是保留管道中的早期退出行为,同时仍然给予junit机会捕获测试报告,是使用一系列try / finally块

使用多代理

在所有以前的例子中,只使用了一个代理。 这意味着Jenkins将分配一个可用的执行节点,无论它是如何标记或配置的。 不仅可以覆盖此行为,而且Pipeline可以在同一个Jenkins文件中使用Jenkins环境中的多个代理,这对于更多的高级用例(如在多个平台上执行构建/测试)是有用的。

在下面的示例中,“build”阶段将在一个代理上执行,并且构建的结果将在“Test”阶段中分别标记为“linux”和“windows”的两个后续代理程序中重用。

pipeline {
    agent none
    stages {
        stage('Build') {
            agent any
            steps {
                checkout scm
                sh 'make'
                stash includes: '**/target/*.jar', name: 'app' 
            }
        }
        stage('Test on Linux') {
            agent { 
                label 'linux'
            }
            steps {
                unstash 'app' 
                sh 'make check'
            }
            post {
                always {
                    junit '**/target/*.xml'
                }
            }
        }
        stage('Test on Windows') {
            agent {
                label 'windows'
            }
            steps {
                unstash 'app'
                bat 'make check' 
            }
            post {
                always {
                    junit '**/target/*.xml'
                }
            }
        }
    }
}
  • stash步骤允许捕获匹配包含模式(* / target / 。jar)的文件,以在同一个管道中重用。 一旦管道完成执行,垃圾文件将从Jenkins主站中删除。
  • agent/node中的参数允许任何有效的Jenkins标签表达式。 有关详细信息,请参阅管道语法部分。
  • unstash将从Jenkins主机中检索名为“stash”的管道的当前工作空间。
  • bat脚本允许在基于Windows的平台上执行批处理脚本。

可选步骤参数

Piperline遵循Groovy语言约定,允许在方法参数中省略括号。 许Pinperline步骤还使用命名参数语法作为在Groovy中创建Map的简写,它使用语法[key1:value1,key2:value2]。 发表如下功能等同的语句:

git url: 'git://example.com/amazing-project.git', branch: 'master'
git([url: 'git://example.com/amazing-project.git', branch: 'master'])

为方便起见,当仅调用一个参数(或只有一个必需参数)时,可能会省略参数名称,例如:

sh 'echo hello' /* short form  */
sh([script: 'echo hello'])  /* long form */

高级脚本管道

Scripted Pipeline是基于Groovy的领域专用语言,大多数Groovy语法可以在脚本Piperline中使用而无需修改。

并行执行

上面的例子在线性系列中的两个不同平台上运行测试。 实际上,如果完成检查执行需要30分钟,“测试”阶段现在需要60分钟才能完成!

幸运的是,Pipeline具有内置的用于并行执行Scripted Pipeline的功能,并在适当命名的并行步骤中实现。 重构上述示例以使用parallel步骤:

stage('Build') {
    /* .. snip .. */
}

stage('Test') {
    parallel linux: {
        node('linux') {
            checkout scm
            try {
                unstash 'app'
                sh 'make check'
            }
            finally {
                junit '**/target/*.xml'
            }
        }
    },
    windows: {
        node('windows') {
            /* .. snip .. */
        }
    }
}

而不是在“linux”和“windows”标签的节点上执行测试,它们现在将在Jenkins环境中存在必需容量的情况下并行执行。

Copyright © www.gitbook.com/@herryZ 2016 all right reserved,powered by Gitbook该文件修订时间: 2018-10-23 06:06:32

results matching ""

    No results matching ""