pipeline(3)

Jenkinsfile使用

创建一个Jenkinsfile,并提交到代码库,进行源代码控制,好处:
1)Pipeline上的代码审查/迭代
2)Pipeline的审计跟踪
3)Pipeline的唯一真实来源,可以由项目的多个成员查看和编辑。

Pipeline支持两种语法:Declarative(在Pipeline 2.5中引入)和Scripted Pipeline。两者都支持持续集成 Pipeline。两者都可以定义一个流水线Jenkinsfile,通常使用Jenkinsfile文件保存源代码并进行代码版本控制是最佳做法。

  1. 创建Jenkins文件
    Jenkinsfile是一个包含Jenkins Pipeline定义的文本文件,并使用版本库进行代码控制。
    如下Pipeline,完成了基本的三个阶段的持续集成Pipeline。
    声明式:
    Jenkinsfile (Declarative Pipeline)
    pipeline {
    agent any
    stages {
    stage(‘Build’) {
    steps {
    echo ‘Building…’
    }
    }
    stage(‘Test’) {
    steps {
    echo ‘Testing…’
    }
    }
    stage(‘Deploy’) {
    steps {
    echo ‘Deploying…’
    }
    }
    }
    }

Jenkinsfile (Scripted Pipeline)
node {
stage(‘Build’) {
echo ‘Building…’
}
stage(‘Test’) {
echo ‘Building…’
}
stage(‘Deploy’) {
echo ‘Deploying…’
}
}
并非所有的Pipeline都具有相同的三个阶段,但是对于大多数项目来说,这是一个很好的起点。

以下部分将演示在Jenkins的测试安装中创建和执行简单的Jenkins。

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

该阶段的指令,和步骤的指令也需要一个有效的声明Pipeline,因为他们指示Jenkins如何执行并在哪个阶段应该执行。

要使用Scripted Pipeline进行更高级的使用,上面的示例中,node是为Pipeline分配执行程序和工作空间的关键第一步。在本质上,没有node的话, Pipeline不能做任何工作!在node上, 检出此项目的源代码。由于Jenkinsfile直接从源代码控制中抽取,所以Pipeline提供了一种快速简便的方式来访问源代码的正确版本
Jenkinsfile (Scripted Pipeline)
node {
checkout scm
/* … snip … */
}
:该checkout步骤将从源控制代码检出代码;。

通常,Pipeline的初始阶段将是下载源代码,进行组装,编译或打包,Jenkinsfile不能替代现有构建工具,如GNU/Make,Maven, Gradle,等,而是把项目的开发生命周期中的多个阶段(建设,测试,部署等)进行集成。

Jenkins有一些插件,可以用于调用几乎任何一般使用的构建工具,但是这个例子将只是make从shell步骤(sh)调用。该sh步骤假定系统是基于Unix / Linux的,因为bat可以使用基于Windows的系统。

Jenkinsfile (Declarative Pipeline)
pipeline {
agent any

stages {
    stage('Build') {
        steps {
            sh 'make' 
            archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true 
        }
    }
}

}
:该sh步骤调用该make命令,只有在命令返回零退出代码时才会继续。任何非零退出代码将失败Pipeline。

:archiveArtifacts捕获与include pattern(**/target/*.jar)匹配的文件,并将它们保存到Jenkins主文件以供以后检索。

存档工件不能替代使用诸如Artifactory或Nexus之类的外部工件存储库,只能用于基本报告和文件归档。
测试
运行自动化测试是任何持续部署的重要组成部分。因此,Jenkins有许多插件可用于记录测试结果、测试报告可视化 。有测试失败时,让Jenkins在Web UI中记录报告和可视化的故障是有用的。
下面的示例使用junit(由JUnit插件)提供的步骤。
在下面的示例中,如果测试失败,则Pipeline被标记为“不稳定”,如Web UI中的黄色球。根据记录的测试报告,Jenkins还可以提供历史趋势分析和可视化。

Jenkinsfile (Declarative Pipeline)
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' 
        }
    }
}

}


Jenkinsfile (Scripted Pipeline)
node {
/* … snip … /
stage(‘Test’) {
/
make check returns non-zero on test failures,
* using true to allow the Pipeline to continue nonetheless
/
sh ‘make check || true’
junit '**/target/
.xml’
}
/* … snip … */
}
:使用内联shell conditional(sh ‘make || true’)确保该 sh步骤始终看到零退出代码,从而使该junit步骤有机会捕获和处理测试报告。下面的“ 处理故障”部分将详细介绍其他方法。

:junit捕获并关联与包含pattern(**/target/*.xml)匹配的JUnit XML文件

《《部署》》
部署可能包含不同的步骤,具体取决于项目或组织的要求,并且可能是从构建的job发送到归档/发布服务器,将代码推送到生产系统等步骤。

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

Jenkinsfile (Declarative Pipeline)
pipeline {
agent any

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

}


Jenkinsfile (Scripted Pipeline)
node {
/* … snip … /
stage(‘Deploy’) {
if (currentBuild.result == null || currentBuild.result == ‘SUCCESS’) {
sh ‘make publish’
}
}
/
… snip … */
}

:测试失败,该currentBuild.result值将是 UNSTABLE。

假设Jenkins Pipeline 成功执行,Pipeline 将会触发存档构建部分,报告的测试结果和完整的控制台输出全部放在Jenkins中。

脚本Pipeline可以包括条件测试(如上所示),循环,try / catch / finally块甚至函数。

》》管道高级语法》》
字符串引用
Jenkins Pipeline使用与Groovy相同的规则 进行字符串插值。虽然Groovy支持使用单引号、双引号、三引号来声明一个字符串,例如:
def singlyQuoted = ‘Hello’
def doublyQuoted = “World”
其中三引号中的内容可以包含换行
只有doublyQuoted 字符串支持前面加dollar-sign($)来使用字符串的值

例如:
def username = ‘Jenkins’
echo ‘Hello Mr. ${username}’
echo “I said, Hello Mr. ${username}”
会导致:
Hello Mr. ${username}
I said, Hello Mr. Jenkins

《《job的环境变量》》
Jenkins Pipeline通过全局变量公开环境变量,该变量env可从任何地方获得Jenkinsfile。
假设Jenkins主机正在运行,在本地主机:8080 / pipeline-syntax / globals#env中记录了可从Jenkins Pipeline中访问的环境变量的完整列表 localhost:8080,其中包括:

BUILD_ID
当前版本ID,与Jenkins版本1.597+的 BUILD_NUMBER相同,

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

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

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

Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage(‘Example’) {
steps {
echo “Running ${env.BUILD_ID} on ${env.JENKINS_URL}”
}
}
}
}


Jenkinsfile (Scripted Pipeline)
node {
echo “Running ${env.BUILD_ID} on ${env.JENKINS_URL}”
}

设置环境变量
Declarative或Scripted Pipeline,在Jenkins Pipeline中设置环境变量是不同的。

声明式Pipeline中使用environment 指令来设置环境变量,而Scripted Pipeline使用withEnv设置环境变量。

Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
environment {
CC = ‘clang’
}
stages {
stage(‘Example’) {
environment {
DEBUG_FLAGS = ‘-g’
}
steps {
sh ‘printenv’
}
}
}
}


Scripted Pipeline (Advanced)

Jenkinsfile (Scripted Pipeline)
node {
/* … snip … */
withEnv([“PATH+MAVEN=${tool ‘M3’}/bin”]) {
sh ‘mvn -B verify’
}
}
: pipeline块中使用的指令将适用于Pipeline中的所有步骤。

:在一个environment意图中定义的一个指令stage将仅将给定的环境变量应用于该过程中的步骤stage。

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

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

假设一个名为“Greeting”的String参数已经在Jenkinsfile声明 ,它可以通过${params.Greeting}以下方式访问该参数:

Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
parameters {
string(name: ‘Greeting’, defaultValue: ‘Hello’, description: ‘How should I greet the world?’)
}
stages {
stage(‘Example’) {
steps {
echo “${params.Greeting} World!”
}
}
}
}


Jenkinsfile (Scripted Pipeline)
properties([parameters([string(defaultValue: ‘Hello’, description: ‘How should I greet the world?’, name: ‘Greeting’)])])

node {
echo “${params.Greeting} World!”
}

故障处理
声明性Pipeline默认支持在post 部分进行robust失败处理,并提供“post conditions”,例如:always,unstable,success,failure,和 changed。“ Pipeline语法”提供了一些tips。
Jenkinsfile (Declarative Pipeline)
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 ?’
}
}
}


Jenkinsfile (Scripted Pipeline)
node {
/* … snip … /
stage(‘Test’) {
try {
sh ‘make check’
}
finally {
junit '**/target/
.xml’
}
}
/* … snip … */
}
但是脚本Pipeline依赖于Groovy的内置try/ catch/ finally该Pipeline的执行过程中进行出错处理。

在上面的测试示例中,该sh步骤也可以修改为返回非零退出码(sh ‘make check || true’),这种方法虽然有效,但是意味着后面的阶段需要通过检查currentBuild.result以确定测试是否失败。

处理这种情况的另一种方法是使用一系列try/ finally块:保留Pipeline故障的退出行为,同时junit仍然有机会获取测试报告

《《使用多个agent》》
在所有以前的例子中,只使用了一个agent。这意味着Jenkins将分配一个可用的执行器,无论它是如何标记或配置的。

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

Jenkinsfile (Declarative Pipeline)
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’
}
}
}
}
}


Jenkinsfile (Scripted Pipeline)
stage(‘Build’) {
node {
checkout scm
sh ‘make’
stash includes: ‘**/target/*.jar’, name: ‘app’
}
}

stage(‘Test’) {
node(‘linux’) {
checkout scm
try {
unstash ‘app’
sh ‘make check’
}
finally {
junit '/target/*.xml’
}
}
node(‘windows’) {
checkout scm
try {
unstash ‘app’
bat ‘make check’
}
finally {
junit '
/target/.xml’
}
}
}
:此处,stash步骤允许捕获与模式(**/target/
.jar)匹配的文件,以在同一pipelien中重用。一旦Pipeline完成执行,stash文件将从Jenkins主站中删除。

:agent/中的参数node允许任何有效的Jenkins lable 。

:unstash 将从Jenkins主机中检索名为“藏书”的管道当前工作空间。
该bat脚本允许在基于Windows的平台上执行批处理脚本.

可选步骤参数
Pipeline遵循Groovy语言约定,允许在方法参数中省略括号。

许多Pipeline 使用命名参数创建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 */

《《高级脚本管道》》
脚本Pipeline是 基于Groovy 语言的,大多数Groovy语法可以在脚本Pipeline中使用而无需修改。

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

幸运的是,Pipeline具有内置功能,用于并行执行Scripted Pipeline,可以通过parallel实现。

重构上述示例以使用parallel步骤:

Jenkinsfile (Scripted Pipeline)
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环境允许情况下并行执行测试

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值