DevOps实战系列【第十二章】:详解Shared Libraries共享库

时间:2023-01-08 14:59:24

个人亲自录制全套DevOps系列实战教程 :​​手把手教你玩转DevOps全栈技术​

随着jenkins pipeline项目越来越多,冗余代码也越来越多,所以share library诞生。

流水线支持在外部仓库中创建【共享库】,然后加载到现有流水线中使用,以达到复用的功能。


共享库目录结构

DevOps实战系列【第十二章】:详解Shared Libraries共享库

  • 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

DevOps实战系列【第十二章】:详解Shared Libraries共享库

​​​注意:如果Default version写错了,jenkins会有错误提醒的。​

DevOps实战系列【第十二章】:详解Shared Libraries共享库


在Jenkins中使用共享库

DevOps实战系列【第十二章】:详解Shared Libraries共享库


​​​注意:​​导入只有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!'
}
}
}
}
}

DevOps实战系列【第十二章】:详解Shared Libraries共享库

​动态加载:[了解]​

  • 只有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会作为全局变量,这个注意一下不要重名或冲突即可。