jenkins2 pipeline里groovy的高级用法。翻译自:https://github.com/jenkinsci/pipeline-plugin/blob/master/TUTORIAL.md

文章来自:http://www.ciandcd.com
文中的代码来自可以从github下载: https://github.com/ciandcd

1. 在groovy里使用函数,条件控制,循环,异常捕获等

node('remote') {
git url: 'https://github.com/jglick/simple-maven-project-with-tests.git'
def v = version()
if (v) {
echo "Building version ${v}"
}
def mvnHome = tool 'M3'
sh "${mvnHome}/bin/mvn -B -Dmaven.test.failure.ignore verify"
step([$class: 'ArtifactArchiver', artifacts: '**/target/*.jar', fingerprint: true])
step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*.xml'])
}
def version() {
def matcher = readFile('pom.xml') =~ '<version>(.+)</version>'
matcher ? matcher[0][1] : null
}

上面的代码中:

def用来定义groovy变量或函数;

=~表示正则表达式的匹配;

master[0][1]表示取出匹配结果中第一个匹配项中的第一个group的值;

readFile为groovy的函数用来从workspace里读取文件返回文件的内容,同时还可以使用writeFile来保存内容到文件,fileExists用来判断文件是否存在;

注意 groovy脚本框下面的checkbox:use groovy sandbox,如果选中的话,groovy 脚本会在沙盒里运行有限的功能, 否则如果不是管理员运行的话会报错或者仍然运行就的脚本,需要管理员来approve groovy script。

如果遇到RejectedAccessException权限问题,需要jenkins管理员在Manage Jenkins » In-process Script Approval中approve 权限staticMethod org.codehaus.groovy.runtime.ScriptBytecodeAdapter findRegex java.lang.Object java.lang.Object。

2. 本地变量的序列化

如下的代码在运行时可能会遇到错误java.io.NotSerializableException: java.util.regex.Matcher,错误的原因是Matcher是不可序列化的类型。

node('remote') {
git url: 'https://github.com/jglick/simple-maven-project-with-tests.git'
def matcher = readFile('pom.xml') =~ '<version>(.+)</version>'
if (matcher) {
echo "Building version ${matcher[0][1]}"
}
def mvnHome = tool 'M3'
sh "${mvnHome}/bin/mvn -B -Dmaven.test.failure.ignore verify"
step([$class: 'ArtifactArchiver', artifacts: '**/target/*.jar', fingerprint: true])
step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*.xml'])
}

pipeline job为了支持能够在jenkins重启后恢复继续运行,jenkins在后台定期地将job的运行状态保存到硬盘。保存的动作一般在每个step结束后,或者在一些step的中间,例如sh step的中间。
jenkins保存的job的状态,包括整个控制流程,例如局部变量,循环所在的位置,等等。正因为如此,groovy里的任何变量必须是number,string或可序列化的类型,其他的例如网络连接等是不能够序列化的。
如果你临时地使用不可序列化的类型,则需要在使用完马上释放。如果局部变量在函数中,函数调用结束的时候局部变量也会被自动释放。我们也可以显示地释放局部变量。 如下

node('remote') {
git url: 'https://github.com/jglick/simple-maven-project-with-tests.git'
def matcher = readFile('pom.xml') =~ '<version>(.+)</version>'
if (matcher) {
echo "Building version ${matcher[0][1]}"
}
matcher = null
def mvnHome = tool 'M3'
sh "${mvnHome}/bin/mvn -B -Dmaven.test.failure.ignore verify"
step([$class: 'ArtifactArchiver', artifacts: '**/target/*.jar', fingerprint: true])
step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*.xml'])
}

然而最安全的方法是将不可序列化的语句隔离到函数中,且在函数的前面增加属性@NonCPS。通过这种方法pipeline将识别此函数为native且不保存对应的局部变量。另外使用了@NoCPS的函数中不能够调用其他的pipeline steps,例如必须将readFile放到函数外面:
node('remote') {
git url: 'https://github.com/jglick/simple-maven-project-with-tests.git'
def v = version(readFile('pom.xml'))
if (v) {
echo "Building version ${v}"
}
def mvnHome = tool 'M3'
sh "${mvnHome}/bin/mvn -B -Dmaven.test.failure.ignore verify"
step([$class: 'ArtifactArchiver', artifacts: '**/target/*.jar', fingerprint: true])
step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*.xml'])
}
@NonCPS
def version(text) {
def matcher = text =~ '<version>(.+)</version>'
matcher ? matcher[0][1] : null
}

上面的加了@NoCPS的version函数将被正常的groovy运行时执行,所以任何的局部变量都是允许的。

3. 创建多线程

pipeline能够使用parallel来同时执行多个任务。 parallel的调用需要传入map类型作为参数,map的key为名字,value为要执行的groovy脚本。
为了测试parallel的运行,可以安装parallel test executor插件。此插件可以将运行缓慢的测试分割splitTests。

用下面的脚本新建pipeline job:

node('remote') {
git url: 'https://github.com/jenkinsci/parallel-test-executor-plugin-sample.git'
archive 'pom.xml, src/'
}
def splits = splitTests([$class: 'CountDrivenParallelism', size: 2])
def branches = [:]
for (int i = 0; i < splits.size(); i++) {
def exclusions = splits.get(i);
branches["split${i}"] = {
node('remote') {
sh 'rm -rf *'
unarchive mapping: ['pom.xml' : '.', 'src/' : '.']
writeFile file: 'exclusions.txt', text: exclusions.join("\n")
sh "${tool 'M3'}/bin/mvn -B -Dmaven.test.failure.ignore test"
step([$class: 'JUnitResultArchiver', testResults: 'target/surefire-reports/*.xml'])
}
}
}
parallel branches

如果遇到RejectedAccessException错误,需要管理员approve权限staticMethod org.codehaus.groovy.runtime.ScriptBytecodeAdapter compareLessThan java.lang.Object java.lang.Object。

当第一次运行上面的pipeline job的时候,所有的测试顺序执行。当第二次或以后执行的时候,splitTests将会将所有的测试分割为大概等价的两份,然后两个task并行运行。如果两个task运行在不同的slave上,则可以看到job总的时间将会减半。

下面的等价语句用来打包pom.xml和源代码:
archive 'pom.xml, src/'
step([$class: 'ArtifactArchiver', artifacts: 'pom.xml, src/'])

我们可以看到prallel里的语句使用了node,这意味着并行执行的任务将会在新的node/slave上执行,且使用不同的workspace,为了确保所有的node和workspace使用相同的代码,所以才有了前面的打包archive和parallel里的解包unarchive。

上面的例子中我们可以看到同一个pipeline job里可以使用多个node,多个node会有不同的workspace,我们需要确保每个workspace的内容都是我们想要的内容。

另一个问题,如果在pipeline中使用env,环境变量的修改会在整个pipeline起作用,如果只修改parallel并行的线程的变量,可以使用withEnv。

在使用了parallel的console log里,并行的log都混在了一起,需要在job的pipeline steps页面查看按逻辑分割的更情况的log。

4. 创建stage

默认地,pipeline的多个job可以并行地运行。使用stage可以限制job里的某些阶段的并行数量。新的job用于更高的优先级,旧的job遇到stage的并行限制会直接退出。

并行性的限制有的时候很有用,例如部署到单个server,在同一时间只能有最新的一个job部署。

5. 从外部加载groovy脚本

jenkins2 pipeline高级相关推荐

  1. Jenkins Pipeline高级用法-ShareLibrary

    1.Github配置 1.1 上传jenkinsfile到github https://github.com/zeyangli/ShareLibrary-jenkins.git 2.Jenkins配置 ...

  2. jenkins2 pipeline实例

    比较完整的实例,使用了maven打包,git tag,发通知邮件,等待用户deploy,deploy到nexus. 文章来自:http://www.ciandcd.com 文中的代码来自可以从gith ...

  3. Jenkins pipeline 入门到精通系列文章

    Jenkins2 入门到精通系列文章. Jenkins2 下载与启动 jenkins2 插件安装 jenkins2 hellopipeline jenkins2 pipeline介绍 jenkins2 ...

  4. 品达物流TMS项目_第6章 数据聚合服务开发(pd-aggregation)

    品达物流TMS项目_第6章 数据聚合服务开发(pd-aggregation) 文章目录 品达物流TMS项目_第6章 数据聚合服务开发(pd-aggregation) 第6章 数据聚合服务开发(pd-a ...

  5. Java物流项目第五天 数据聚合服务开发(pd-aggregation)

    品达物流TMS项目 第6章 数据聚合服务开发(pd-aggregation) 1. Canal概述 canal译意为水道/管道,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费. ...

  6. 2020年精彩文章回顾

    今年共整理了200+篇文章,现整理在此,望对每位同学有所帮助.2021新年已到,定会整理更多更实用的文章.在此感谢大家的关注与支持!(转发一下吧) DevSecOps: CI/CD流水线中增加安全 实 ...

  7. 2020年精彩文章回顾,都发布了哪些文章呢?

    今年共整理了200+篇文章,现整理在此,望对每位同学有所帮助.2021新年已到,定会整理更多更实用的文章.在此感谢大家的关注与支持!(转发一下吧) DevSecOps: CI/CD流水线中增加安全 实 ...

  8. Pipeline As Code With Jenkins2.0

    Jenkins2.0 Pipeline导入 Pipeline as Code是Jenkins 2.0版本的精华所在,是帮助Jenkins实现从CI到CD华丽转身的关键工具. 所谓Pipeline,简单 ...

  9. redis高级特性学习(慢查询、Pipeline、事务、Lua)(上)

    Redis高级特性和应用(慢查询.Pipeline.事务.Lua) Redis的慢查询 许多存储系统(例如 MySQL)提供慢查询日志帮助开发和运维人员定位系统存在的慢操作.所谓慢查询日志就是系统在命 ...

  10. Jenkins高级篇之Pipeline技巧篇-1-小白搭建Pipeline项目开发环境

    之前,有人和我说,pipeline教程这里,关于如何创建pipeline的git项目和,如何在jenkins上做pipeline的测试这块,在前面文章交代不清楚.这里我补上一篇,通过这一篇,小白也能开 ...

最新文章

  1. LeetCode简单题之学生出勤记录 I
  2. Pycharm运行Scrapy报错:no active project Unknown command: crawl Use “scrapy“ to see available commands
  3. c类网络使用子网掩码有无实际意义_弄懂IP系列(2)(刘晶作品)|子网掩码到底是啥?...
  4. require.js基本用法
  5. python PyQt5.QtWidgets.QApplication().exec_()函数 QCoreApplication.exec_()(进入主事件循环并等待直到调用exit()为止)
  6. 科普文丨Java 单元测试相关概念理清
  7. Synchronize和ReentrantLock区别
  8. new 操作符干了什么?
  9. STOA-diary-20110312-抉择
  10. mysql —— 分表分区(1)
  11. 考验你的吉他入门了吗?
  12. Android如何实现汉字手写输入法(带中文自动识别提示)
  13. mac插网线不能上网_我的Macbook插上网线为什么不能上网? – 手机爱问
  14. 爬虫爬取知乎评论并利用flask框架做简单的可视化
  15. 三、大数据时代下的SQL Server第三方负载均衡方案----Moebius测试
  16. c 语言输出省份面积和高度,中国省份面积
  17. windows10启动项修复||an operating system wasn't found解决办法
  18. 亚马逊云科技荣获2021中国公有云平台用户满意度第一
  19. python pip安装numpy_【风马一族_Python】 安装pip与Numpy
  20. CSS3动画产生圆圈由小变大向外扩散的效果

热门文章

  1. mysql 中时间和日期函数应用
  2. 10 步让你成为更优秀的Coder
  3. 函数和存储过程的区别
  4. 面试题|集合ArrayList list = new ArrayList(20) 中的list扩充几次?
  5. vue要求更新3.0-》使用axios的时候出现错误
  6. vue移动端,点击微信授权登录
  7. Django 09-2 模型层 字段
  8. SpringMvc @PathVariable 工作原理
  9. groupadd命令详解(实例)
  10. 转载 关于git的常用命令总结