pipeline,java pipeline框架
从演示中学习
为了便于解释,我暂时贴了一个简单的管道。如上面效果图所示(必须安装一个名为蓝海的插件)。准备也很简单。安装jenkins 2.x,在插件管理中下载管道相关的插件。创建管道作业并粘贴以下代码:
库质量保证-管道-库
管道{
代理{
标签“devops”
}
}
阶段{
阶段(“环境部署”){
步骤{
回显“部署”
}
}
Stage()提取测试代码)))。
步骤{
Checkout(($class:(gitscm))、branches:([name:(*/release/3 . 8 . 2)]、dogeneratesubmoduleconfigining的本地分支:“sage-SDK-test”、submoduleCfg: []、useremoteconfigs 3360[[凭据id : ] gaofeigitlab
}
}
Sage(sageSDK测试))。
步骤{
“嘘”
3 PIPIP INSTALL-I 3358 pypi . 4 paradigm.com/4范式/DEV//-Trusted-HostPYPI.4范式. com sage-SDK [building]
pip3 install -r requirement.txt
测试光盘
python3 -m pytest -n 5
}
}
阶段(“生成测试报告”)。
步骤{
allure命令行:“allure2。13.1 ,includeProperties: false,jdk:,结果:[ [路径3: test/]
}
}
}
帖子{
总是{
发邮件(孙高菲@4paradigm.com))。
}
}
}
管道语法分别是命令式和脚本式的。以上是命令式演示,非常适合进入詹金斯管道。我觉得命令式,就像我们测试领域的关键词驱动,提前实现了很多有用的命令。所以对初学者很好,学习成本低。缺点是不能灵活地将groovy语言应用到脚本中,也就是说,对脚本使用groovy是有限制的。脚本表达式正好相反,它的优点是groovy代码可以随意插入到脚本中。没关系。然而,学习groovy语言是昂贵的,它不能只是声明性的和易于使用的指令。所以声明性是大多数人的优先考虑。
生产过程说明
我不会像官方那样每点一道菜。太占地方了,真没精神。所以我要用另一种方式来解释。命令管道很容易上手。因为几乎所有的指令都可以在UI中找到,所以可以说和流程框架中的UI大致相同。比如上面的demo,在pipeline { 0 }的基本估计下。来几次。
第一个代理“devo PS”安装任务在哪个节点上运行?在UI上,响应如下。
最后一个岗位{}实际上是支持UI上的建后操作,负责发送邮件、生成报表等任务完成后的后期处理。Post{}后跟其他命令,如always、success和failed,以支持UI操作。意思是继续触发这些善后处理。果然只有成功或失败才会有触发器。中间阶段命令执行真正的任务。阶段下有很多小阶段,负责每个阶段的运作。因此,命令式管道的简单流程如下。
管道
代理{}
阶段{
舞台{}
}
邮箱{}
}
这样分阶段,像上面的演示,就可以开始一个一个的用命令执行任务了。在stage下分步运行checkout命令。如下图。
=中心
这是使用checkout指令从gitlab中提取代码。例如,下面执行的allure指令是为了生成allure的测试报告。如下所示:
因此,通过这种方式,我们实现詹金斯流水线实际上非常简单。在这个流程框架中,我们可以通过使用一个又一个指令来完成我们的流水线。当然还有一些控制工艺发散等参数的指令,也很重要,这里就不一一描述了。你可以移动到官方文件:https://jenkins.io/doc/book/pipeline/shared-libraries/
当然,jenkins上有那么多函数和插件,每个插件对应一个指令。学这么多指令太麻烦了。所以詹金斯也为我们开发了一个自动生成指令的工具。如下所示:
如上,詹金斯将帮助我们生成相应的指令代码。
共享库
基础部分我就不说了,因为我真的精力不够。接下来,我们来谈谈如何编写共享库。随着管道技术的成熟,使用管道脚本的作业数量迅速增加。虽然我们可以做一个尽可能通用的管道脚本样本,让构建者只需要修改几个赋值参数就可以在自己的项目中应用。初衷是让大家都能了解pipeline中的流程,但是也发现了一些比较麻烦的问题。比如有的人对具体剧本不熟悉,随意删除,导致各种错误。更有甚者,当我们在管道脚本中增加一些新功能时,需要通知所有管道维护人员进行修改,过程非常纠结。这意味着我们需要使用pipline的共享库,在各个项目之间共享管道核心实现,以减少冗余,确保所有作业在构建时都会调用最新的共享库代码。
目录结构
共享库由三个元素定义:库名、代码检索方法(比如SCM)和代码版本。库名尽可能简洁,因为它将在脚本中被调用。编写共享库时,我们需要遵循固定的代码目录结构。
共享代码目录结构如下:
src目录是标准的Java源代码目录结构。执行管道时,目录将被添加到类路径中。
vars目录托管定义从管道访问的全局脚本(通常,我们可以在这里编写标准化的脚本)。我们在pipeline中调用的指令就是在这里定义的,这是我们最重要的目录。
resources目录允许libraryResource使用外部库的步骤加载相关的非Groovy文件。也就是说,我们的管道脚本可以通过代码加载资源目录中的文件。
定义全局库
这里只介绍全局共享库的方式。您可以通过管理Jenkins来配置系统全局管道库,从而添加一个或多个共享库。
这些库将是全球可用的,系统中的任何管道都可以利用这些库中实现的功能。并且通过配置SCM,你可以在每次构建时获得指定共享库的最新代码。
动态加载库
从2.7版本开始,Pipeline: Shared Groovy Libraries插件的插件提供了一个新的参数“library”,用于在脚本中加载(非隐式)库。
如果只需要加载全局变量/函数(从vars/directory),语法非常简单:
之后,可以在脚本中访问库中的任何全局变量。
库质量保证-管道-库
共享库演示
让我们从一个演示开始。注意,这里的方法名必须是call。这涉及到groovy语言的委托机制,所以名字一定是call。
然后在我们的管道中,我们可以调用下面的。
只要我们在管道上使用库‘QA-pipeline-library’,就可以在下面的步骤中直接调用demo方法。
如果你想加载一个文件,你可以使用
库资源 k8s/template/java.yaml
上面的例子是从共享库中的resource目录中加载一个k8s yaml文件,然后使用它供下面的代理动态创建slave pod来执行管道任务。我会把詹金斯和k8s融合的细节放到下一个教程里。这里只是演示了如何在共享库中加载文件。
实战中的共享库
先来看看我之前开发的用来发邮件的共享库。它会判断作业本身的执行状态来发送不同的邮件内容。并将自动获取allure报告中的测试结果信息。如下所示:
/**
*由孙高飞于19/2/8创作。
*/
@ Grab(group= org . code Haus . groovy . modules . http-builder ,module=http-builder ,version=0.7 )
导入groovyx.net.http.HTTPBuilder
导入静态groovyx.net.http.ContentType.*
导入静态groovyx.net.http.Method.*
导入groovy.transform.Field
//全局变量
@ Field Jenkins URL= http://auto . 4 paradigm . com
@Field failed=FAILED
@Field success=SUCCESS
@Field inProgress=IN_PROGRESS
@Field abort=ABORTED
@非警察
极好的字符串checkJobStatus() {
def URL=/view/API/JOB/$ { JOB _ NAME }/$ { BUILD _ NUMBER }/wfapi/describe
HTTPBuilder http=新的HTTPBuilder(jenkinsURL)
字符串状态=成功
http.get(路径:url) { resp,json -
if (resp.status!=200) {
抛出新的RuntimeException(请求${url}返回${resp.status} )
}
List stages=json.stages
for(int I=0;一.阶段。size();i ) {
def stageStatus=json.stages[i].状态
if (stageStatus==failed) {
状态=失败
破裂
}
if (stageStatus==abort) {
状态=中止
破裂
}
}
}
退货状态;
}
@非警察
定义调用(字符串到){
println(邮件列表:$ {收件人} )
极好的发送成功={
def报告URL= $ { Jenkins URL }/view/API/JOB/$ { JOB _ NAME }/$ { BUILD _ NUMBER }/allure/
def blue ocean URL= $ { Jenkins URL }/blue/organizations/Jenkins/$ { JOB _ NAME }/detail/$ { JOB _ NAME }/$ { BUILD _ NUMBER }/pipeline
极好的文件内容=
传递的定义=
极好的失败=
跳过的定义=
def broken=
def unknown=
def total=
http builder http=new http builder( http://auto。4范式。com’)
//根据responsedata中的内容类型标题,调用数据解析器处理responsedata
http.get(路径:/view/API/JOB/$ { JOB _ NAME }/$ { BUILD _ NUMBER }/allure/widgets/summary。JSON ){ resp,json -
打印责任状态
passed=json.statistic.passed
failed=json.statistic.failed
skipped=json.statistic.skipped
broken=json.statistic.broken
unknown=json.statistic.unknown
total=json.statistic.total
}
println(通过)
电子邮件正文:""
詹金斯构建作业摘要地址:${BUILD_URL}测试报告地址:$ { reportURL }管道流程地址:$ { blueOCeanURL }测试结果汇总用例总数:${ total }次通过数量:${已通过}失败数量:$ {失败}跳过数量:$ {已跳过}已损坏数量:${broken} " ",mime类型:“text/html”,主题:" ${JOB_NAME}测试结束,至:至
}
def send={ String subject -
电子邮件正文:""
詹金斯建立工作地址:${BUILD_URL}
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。