官方文档 - Extending with Shared Libraries
CloudBees - getting-started-with-shared-libraries-in-jenkins
CloudBees - github - pipeline-library
CloudBees - github - global-library-课程范例
How To Use Shared Libraries In A Jenkins Pipeline?
一、Shared Libraries 简介
1、Directory structure
Shared Library repository 的结构
(root)
+- src # Groovy source files
| +- org
| +- foo
| +- Bar.groovy # for org.foo.Bar class
+- vars
| +- foo.groovy # for global 'foo' variable
| +- foo.txt # help for 'foo' variable
+- resources # resource files (external libraries only)
| +- org
| +- foo
| +- bar.json # static helper data for org.foo.Bar
-
src
目录类似标准的Java源目录。在执行Pipeline的时候会被添加到classpath
。 -
vars
目录存放脚本文件,这些文件在Pipelines中作为变量。文件的名称就是Pipeline中变量的名称。比如存在文件vars/log.groovy
,文件下存在函数def info(message)…
,那么在Pipeline以log.info "hello world"
的方式访问。 -
resources
目录允许扩展库使用libraryResource
step 加载非Groovy文件。目前内部库不支持此功能。参考Loading resources。
2、Global Shared Libraries
- 推荐方式
- 通过
Manage Jenkins » System » Global Pipeline Libraries
进行配置,然后在pipeline
调用。详情参见下文 使用 libraries
3、Folder-level Shared Libraries
https://stackoverflow.com/questions/37800195/how-do-you-load-a-groovy-file-and-execute-it
或许有其他使用方法,如下范例是文件级别,并非目录级别的共享库。
范例
- 创建测试groovy文件
/opt/jenkins_library_test/Tools.groovy
public class Demo {
String message;
Demo(String message) {
this.message = message;
}
public void print(def script) {
script.sh "echo " + message
}
}
Demo createDemo(String message) {
new Demo(message)
}
return this
- 编辑pipeline script
声明式 pipeline 如下
pipeline {
agent any
stages {
stage('Hello') {
steps {
echo 'Hello World'
}
}
stage('Demo stage') {
steps {
script {
Object lib = load '/opt/jenkins_library_test/Tools.groovy'
Object demo = lib.createDemo('a demo')
demo.print(this)
}
}
}
}
}
脚本式pipeline 如下
node {
stage('Hello') {
echo 'Hello World'
}
stage('Demo stage') {
script {
Object lib = load '/opt/jenkins_library_test/Tools.groovy'
Object demo = lib.createDemo('a demo')
demo.print(this)
}
}
}
-
执行结果如下
image.png
4、Automatic Shared Libraries
其他插件有更多动态定义库的方法。如 Pipeline: GitHub Groovy Libraries 插件,允许无需配置即可使用不可信任的库,比如github.com/someorg/somerepo
。指定库会以匿名 checkout 的方式 从 master
分支加载。
二、使用 libraries
1、常规调用
Jenkinsfile
使用 @Library
标识符,加 library 的名字,来进行调用。示例如下:
@Library('my-shared-library') _
/* Using a version specifier, such as branch, tag, etc */
@Library('my-shared-library@1.0') _
/* Accessing multiple libraries with one statement */
@Library(['my-shared-library', 'otherlib@abc1234']) _
@Library('somelib')
import com.mycorp.pipeline.somelib.UsefulClass
当引用
class library
(src/
目录)时,@注释需要在import
语句上面
annotation 帮助文档
对于只定义了全局变量 Global Variables (vars/
) 的 Shared Libraries,或只需要全局变量的 Jenkinsfile
, @Library('my-shared-library') _
的注释格式有助于保持代码简洁。本质上,是注释 _
,而非不必要的 import
。
不建议 import
全局变量/函数,即便是实例,这也会强迫编译器将字段和方法解释为 static
,这种情况下 Groovy compiler 会报错。
Libraries 在脚本执行前的编译过程被解析、加载。这就允许 Groovy compiler 在静态类型检查时理解所使用符号的含义,并允许它们在脚本中的类型声明中使用,例如:
这允许Groovy编译器理解静态类型检查中使用的符号的含义,并允许它们在脚本中的类型声明中使用,例如:
@Library('somelib')
import com.mycorp.pipeline.somelib.Helper
int useSomeLib(Helper helper) {
helper.prepare()
return helper.count()
}
echo useSomeLib(new Helper('some text'))
Global Variables 在 runtime 中被解析。
2、动态加载 Loading libraries dynamically
自插件 Pipeline: Shared Groovy Libraries
2.7 版本后,有一种动态加载library的方法(library
step )。
官方描述不严谨。
Pipeline: Shared Groovy Libraries
已退役,代替以 Pipeline: Groovy Libraries。
参见说明文档:https://plugins.jenkins.io/workflow-cps-global-lib/
library 'my-shared-library'
然后,脚本就可以访问该 library 中的任何全局变量了。
访问 src/
目录下的 class 也可以,略麻烦。@Library
在编译前已经设定好了 classpath
,到library step
的时候脚本已经编译完毕了。因此,不能import
或static
类型引用。
但是,您可以动态地使用 library classes(不进行类型检查),通过 library step
返回值中的完全限定名称
来访问。静态方法可以通过类似Java的语法调用:
library('my-shared-library').com.mycorp.pipeline.Utils.someStaticMethod()
当使用 new
的静态方法时,也是可以访问静态字段,并调用构造函数的:
def useSomeLib(helper) { // dynamic: cannot declare as Helper
helper.prepare()
return helper.count()
}
def lib = library('my-shared-library').com.mycorp.pipeline // preselect the package
echo useSomeLib(lib.Helper.new(lib.Constants.SOME_TEXT))
3、版本设定 Library versions
@Library('my-shared-library') _
@Library('my-shared-library@master') _
library 'my-shared-library@master'
library "my-shared-library@$BRANCH_NAME"
# 根据传递的参数设定版本
properties([parameters([string(name: 'LIB_VERSION', defaultValue: 'master')])])
library "my-shared-library@${params.LIB_VERSION}"
4、获取库的方法 Retrieval Method
- 使用 Modern SCM ,仅当老版本不支持Shared Libraries的新特性时使用 Legacy SCM 。
Jenkins -- 系统管理 -- 系统配置 -- Global Pipeline Libraries
Sharable libraries available to any Pipeline jobs running on this system. These libraries will be trusted, meaning they run without “sandbox” restrictions and may use @Grab.
范例:
Name: cloudbee-sample-library
项目仓库: https://github.com/darinpope/github-api-global-lib
如果library step
指定了library名称,Jenkins将查找该名称的预配置库。
也可以指定动态检索方法,无需在Jenkins中预先配置。
如下范例:
library identifier: 'custom-lib@master', retriever: modernSCM(
[$class: 'GitSCMSource',
remote: 'git@git.mycorp.com:my-jenkins-utils.git',
credentialsId: 'my-private-key'])
该方式必须指定版本
更多关于SCM的语法,参考 Pipeline Syntax
5、范例
配置 Global Share Libraries
如下:
Name: cloudbee-sample-library
项目仓库: https://github.com/darinpope/github-api-global-lib
pipeline script
library 'cloudbee-sample-library'
node {
stage('test') {
helloWorld(name:"Darin", dayOfWeek:"Tuesday")
}
}
![](https://img.haomeiwen.com/i18908711/ead594848ccb94f9.png)
修改如下
library 'cloudbee-sample-library@main'
这边的分支是 main , 不是 master。继续执行,如图。
![](https://img.haomeiwen.com/i18908711/2f63051f9bf9ba3b.png)
三、编写 libraries
略
网友评论