个人亲自录制全套DevOps系列实战教程 :
手把手教你玩转DevOps全栈技术
随着jenkins pipeline项目越来越多,冗余代码也越来越多,所以share library诞生。
流水线支持在外部仓库中创建【共享库】,然后加载到现有流水线中使用,以达到复用的功能。
共享库目录结构
- src目录:源代码,可以定义类、变量、方法等;当执行jenkins pipeline时,该目录内容会被加载到pipeline项目的classes目录
- vars目录:以.groovy定义的文件,文件名被加载成环境变量名,可通过变量名获取文件中定义的变量或方法(通过def定义变量或方法);
.txt文件将会作为.groovy同名文件的说明文档,可以在jenkins的全局变量页面查看到此文档,用来说明对应的.groovy中有哪些变量或方法,
尽管是.txt结尾,但可以是html、markdown等内容。- resources目录:该目录的内容允许Jenkinsfile中的step步骤指令“libraryResource”来加载该目录的非.groovy文件,只能从外部共享库加载文件,而jenkinsfile所在的项目中的内容不能通过libraryResource来加载。通俗点说存放资源文件,如配置文件,方便我们在Jenkinsfile中读取。
src目录定义的源码:2种方式
①class类文件:不能直接使用sh或git等Jenkinsfile中的命令// 文件名src/org/devops/ClassTest.groovy package org.devops /* 在class类中定义的方法中,是不能执行我们Jenkinsfile中要执行的sh或git等命令的,只能使用groovy原生语法 如果需要使用sh等命令,可以将变量和方法定义到class外部,即删除class定义即可 */ class ClassTest implements Serializable { def steps; ClassTest(steps) { this.steps = steps; } def hello(args) { // 这种情况如果想使用sh或git等Jenkinsfile中使用的命令,可以通过Jenkinsfile中调用该方法时传递过来再执行 // 此处就是执行sh命令,只不过我们将pipeline的this传递过来了 this.steps.echo args } }
②非class类文件:可以直接使用Jenkinsfile中的命令
// 文件名src/org/devops/NoClassTest.groovy package org.devops def hello(args) { // 可以直接使用 echo "NoClassTest is $args" }
var目录创建变量文件:
该目录创建的文件和src中非class类似,只不过该文件会作为jenkins全局变量存在,而src中的文件会加载到classes目录可以被Jenkinsfile调用。// 文件名var/abc.groovy def info(message) { echo "INFO: ${message}" } def warning(message) { echo "WARNING: ${message}" } // 如果要定义字段作为全局变量需要使用注解@groovy.transform.Field @groovy.transform.Field def ABC_F = "字段变量"
无需指定package,所以比较简单
集成共享库到Jenkins
共享库配置到jenkins:在scm中创建完仓库后,还需要告诉jenkins,通过jenkins和scm配置好关联后,我们的pipeline项目(Jenkinsfile文件)才能使用@Library引用共享库。
路径:Manage Jenkins » Configure System » Global Pipeline Libraries
注意:如果Default version写错了,jenkins会有错误提醒的。
在Jenkins中使用共享库
注意:
导入只有src类库的共享库,可以通过注解@Library(‘mylib@master’) import packageName+className,这样groovy编译器会自动将类库加载到jenkins方便直接使用;
而如果只有var的共享库,则可以使用注解@Library(‘mylib@master’) _ ,这样更整洁,不必增加多个import语句,而_
符号是可以被解析的。
// 引入共享库,指定名称和版本
@Library('mylib@master') _
// 定义变量
def classTest = new org.devops.ClassTest(this)
// 虽然没有class但可以通过文件名直接创建
def noClassTest = new org.devops.NoClassTest()
pipeline {
agent any
stages {
stage('Hello') {
steps {
// 声明式语法需要script指令来执行脚本
script {
// 此处我们传递的是this参数
echo "$classTest.steps"
classTest.hello('测试打印参数')
// noclass的测试
noClassTest.hello("NoClassTestArgs")
// 文件名自动加载为环境变量
abc.info 'Starting'
abc.warning 'Nothing to do!'
}
}
}
}
}
动态加载:[了解]
- 只有var的共享库可以直接:
library 'mylib@master'
该语句后,就可以直接使用var中定义的变量- 只有src的共享库可以直接:def lib = library(‘mylib@master’).org.devops,可以直接导入package包,使用lib.NoClassTest.new().hello(“动态调用参数”)
在共享库中定制Jenkinsfile的step步骤:[了解]
就是说我们在Jenkinsfile中常用的步骤sh或git,像这种step步骤,我们可以在共享库中通过var中定义变量来实现,比如我们要定义一个step叫做:sayHello
使用的时候就可以像使用sh或git那样:sayHello ‘abc’
定义方法:创建文件var/sayHello.groovy// vars/sayHello.groovy // 通过定义一个特殊的方法call来实现,参数name默认值我这里指定为human def call(String name = 'human') { // Any valid steps can be called from this code, just like in other // Scripted Pipeline echo "Hello, ${name}." }
那么我们执行:
sayHello ‘abc’ => 输出 “Hello, abc”
Sayhello => 输出 “Hello human”
实际使用,使用src还是var,其实都可以,看大家习惯,但var会作为全局变量,这个注意一下不要重名或冲突即可。