ShareLibrary 共享库扩展
一、什么是 ShareLibrary?
ShareLibrary 共享库,顾名思义是用来存放一些用来共享的仓库,共享什么呢?答案是:“重复代码定义”
我们可以将一些在多个 pipeline 都会频繁使用的 “代码片段”,抽离到一个独立的代码控制仓库中,让其他的 Jenkins pipeline 直接加载使用,不必在重复定义
二、使用 ShareLibrary
2.1 初体验
2.1.1 创建目录结构
创建目录
$ mkdir -p shareLibraryDemo/{src/org/devops,vars}
$ touch shareLibraryDemo/src/org/devops/utils.groovy
$ touch shareLibraryDemo/vars/hello.groovy
执行效果
$ tree shareLibraryDemo
shareLibraryDemo
├── src
│ └── org
│ └── devops
│ └── utils.groovy
└── vars
└── hello.groovy
4 directories, 2 files
2.1.2 编写共享函数
编写 vars/hello.groovy
// 当 pipeline 调用 hello() 时,自动调用 call 方法
def call(){
println("你好,我是来自 vars/hello 中的 call 函数!")
}
编写 src/org/devops/utils.groovy
package org.devops
def PrintMsg(msg){
println("你好,我是来自 src/org/develop/util 中的 PrintMsg 函数,你传递的参数为:${msg}")
}
2.1.3 创建远程仓库
WebUI 操作下就行了,初始化本地仓库
$ git config --global user.name "USERNAME"
$ git config --global user.email "USERNAME@example.com"
# 初始化 git 仓库
$ git init
Initialized empty Git repository in /prodata/scripts/jenkinsLearn/shareLibraryDemo/.git/
# 添加变更到暂存区
$ git add *
# 提交变更
$ git commit -m "推送 shareLivrary 共享库 groovy 代码."
[master (root-commit) fbb7894] 推送 shareLivrary 共享库 groovy 代码.
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 src/org/devops/utils.groovy
create mode 100644 vars/hello.groovy
$ git remote add origin git@gitee.com:l0tusch1ng/shareLibraryDemo.git
# 推送本地提交到远程仓库
$ git push -u origin master
Counting objects: 7, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (7/7), 479 bytes | 0 bytes/s, done.
Total 7 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.2]
To git@gitee.com:l0tusch1ng/shareLibraryDemo.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
2.1.4 添加远程共享库
首先,确保 Jenkins 可以访问远程 Git Server,如果访问远程 Git 服务器的 SSH 凭证没有添加,可以按照下图添加下,HTTP 方式的就不在赘述了
参考文档:https://gist.github.com/Plasmoxy/0069f6eac31e44209691bc79a5c725ae
配置添加远程共享库,操作路径:Manage Jenkins → Configure System → Global Pipeline Libraries
这里会用到此前创建的 远程仓库 及 SSH 凭证
2.1.5 流水线引用共享库
OK,现在我们在 pipeline 中使用共享库
@Library('shareLibraryDemo')
// 基于 utils 实例化一个 util_tools 对象
def util_tools = new org.devops.utils()
pipeline {
agent any
stages {
stage('PrintMsg') {
steps {
script {
print("【org.devops.utils.PrintMsg】")
// 调用 util_tools 对象中的 PrintMsg 方法
util_tools.PrintMsg("呦吼,共享库测试!")
}
}
}
stage('hello') {
steps {
script {
print("【vars.hello.call】")
// 默认会自动调用 vars/hello.groovy 中 call() 方法
hello()
}
}
}
}
}
执行效果
2.2 日志颜色输出
接下来,我们基于 ShareLibrary 共享库做个有些用途的案例,格式化日志颜色输出,先按照一个插件 ansiColor
编写 src/org/devops/utils.groovy
package org.devops
// 格式化输出
def PrintColorMsg(content, color){
colors = ['red' : "\033[40;31m >>>>>>>>>>> ${content} <<<<<<<<<<< \033[0m",
'blue' : "\033[47;34m >>>>>>>>>>> ${content} <<<<<<<<<<< \033[0m",
'green' : "\033[40;32m >>>>>>>>>>>${content}<<<<<<<<<<< \033[0m", ]
ansiColor('xterm') {
println(colors[color])
}
}
编写 pipeline
@Library('shareLibraryDemo')
// 基于 utils 实例化一个 util_tools 对象
def util_tools = new org.devops.utils()
pipeline {
agent any
options {
timestamps()
}
stages {
stage('代码拉取') {
steps {
script {
util_tools.PrintColorMsg("拉取最新代码.", "green")
}
}
}
stage('编译打包') {
agent {
label "built-in"
}
steps {
script {
util_tools.PrintColorMsg("【Parallel-A】我在编译打包最新代码.", "blue")
}
}
}
stage('代码扫描') {
agent {
label "build-server-aliyun-ecs-01"
}
steps {
script {
util_tools.PrintColorMsg("【Parallel-B】我在扫描最新代码.", "blue")
}
}
}
stage('集成测试') {
agent {
label "build-server-aliyun-ecs-01"
}
steps {
script {
util_tools.PrintColorMsg("【Parallel-C】我在测试最新代码.", "blue")
}
}
}
stage('应用部署') {
steps {
script {
util_tools.PrintColorMsg("部署更新应用.", "red")
}
}
}
}
}
执行效果
实验时遇到了一个问题,当我使用 parallel 运行 “编译、扫描、测试” stages 时,PrintColorMsg
函数会输出同样的内容,如下图所示
@Library('shareLibraryDemo')
// 基于 utils 实例化一个 util_tools 对象
def util_tools = new org.devops.utils()
pipeline {
agent any
options {
timestamps()
}
stages {
stage('代码拉取') {
steps {
script {
util_tools.PrintColorMsg("拉取最新代码.", "green")
}
}
}
stage('代码集成') {
parallel {
stage('编译打包') {
agent {
label "built-in"
}
steps {
script {
util_tools.PrintColorMsg("【Parallel-A】我在编译打包最新代码.", "blue")
}
}
}
stage('代码扫描') {
agent {
label "build-server-aliyun-ecs-01"
}
steps {
script {
util_tools.PrintColorMsg("【Parallel-B】我在扫描最新代码.", "blue")
}
}
}
stage('集成测试') {
agent {
label "build-server-aliyun-ecs-01"
}
steps {
script {
util_tools.PrintColorMsg("【Parallel-C】我在测试最新代码.", "blue")
}
}
}
}
}
stage('应用部署') {
steps {
script {
util_tools.PrintColorMsg("部署更新应用.", "red")
}
}
}
}
}
很奇怪,目前也没有找到解决办法,难道是 ShareLibrary 共享库定义的函数在 parallel 的支持上有问题?后续有时间再研究研究~
喔,找到解决办法了,需要在 PrintColorMsg 函数定义前加上 @NonCPS
package org.devops
// 格式化输出
@NonCPS
def PrintColorMsg(content, color){
colors = ['red' : "\033[40;31m >>>>>>>>>>> ${content} <<<<<<<<<<< \033[0m",
'blue' : "\033[47;34m >>>>>>>>>>> ${content} <<<<<<<<<<< \033[0m",
'green' : "\033[40;32m >>>>>>>>>>>${content}<<<<<<<<<<< \033[0m", ]
ansiColor('xterm') {
println(colors[color])
}
}
执行效果
2.3 构建工具封装
todo