ShareLibrary 共享库


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


文章作者: Da
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Da !
  目录