共享库其实就是将pipeline里面的函数,进行封装,从而简化pipeline。 后面流水线就是不断的补充这个库了,补充和Jenkins和相关平台集成的函数,比如gitlab,nexus,sonqrqube这些,将和这些平台集成的代码封装到共享库里面供pipeline调用。

你的项目不是很多,你可以使用函数这种方式,这里有个问题,当你存在两个Jenkinsfile的时候,这个时候函数就是两份,你设法将其导入进来。

什么时候会产生多个Jenkinsfile呢?比如公司的项目类型太复杂了,技术栈太多了,有安卓的,有ios的,有Java等等不同类型的,那么Jenkins发布的类型都不太一样,甚至每个项目里面都不太一样,所以还是用共享库,将函数都放在共享库当中,哪个项目用到了哪些直接使用导入的方式去使用就可以了,就不需要在每个Jenkinsfile里面去放置这些函数了。

所以总体来说,以前在做Jenkins改进的时候,从自由风格到若干个Jenkinsfile,再到统一的Jenkinsfile,最好所有的功能函数放到library里面,然后一个Jenkinsfile来支持整个集团的项目发布。 

其实也就是流水线在执行的时候所需要使用到的功能函数,也就是将所有的逻辑放在共享库里面。

共享库一般放在git上面,在git上面创建项目。然后按照共享库的结构去创建仓库,共享库这里是公用的仓库。

Jenkins共享库实践


共享库这并不是一个全新的概念,其实在编程语言Python中,我们可以将Python代码写到一个文件中,当代码数量增加,我们可以将代码打包成模块然后再以import的方式使用此模块中的方法。

在Jenkins中使用Groovy语法,共享库中存储的每个文件都是一个groovy的类,每个文件(类)中包含一个或多个方法。每个方法包含groovy语句块。

创建共享库,共享库的目的就是将一些反复使用的模块进行封装,比如拉取代码模块,邮件通知模块这样使得你的Jenkinsfile看起来更加简洁,减少代码量。

可以在Git等版本控制系统中创建一个项目用于存储共享库。共享流水线有助于减少冗余并保持代码整洁。

总结就是将所有的工具以共享库的方式封装起来 

属性:

  • 共享库名称
  • 共享库版本
  • 共享库地址
├── src
│   └── org
│       └── devops
│           └── tools.groovy
├── vars
│   └── GetHosts.groovy
│   └── GetCommitId.groovy
│           
└── resources
│   └── org
│       └── devops
│           └── config.json

在java里面src都是存放着源码的,在这个地方存放流水线的功能和方法,这里会有类似于域名的结构,比如src.com.devops  src.org.devops。

vars里面是可以定义流水线模板的,ci cd流水线都可以在vars里面去定义。

gitlab上面创建共享仓库(封装常用的函数代码块)


package定义属于哪个包,每个groovy文件都需要定义这个包,都需要去定义这个package。

共享库内容分析 


builds.groovy 存放构件相关的代码配置

  • 这里面定义了一个 Build 函数, 接受两个参数 buildToolsbuildType , 前者定义的是一个构建工具的位置map,后者是定义的构建类型例如 maven/ant/gradle/web/golang
  • 代码主体是根据不同的构建类型执行不同的构建命令,默认打印信息。 

package org.devops

// 构建函数
def Build(buildTools,buildType){
    switch(buildType){
        case "maven":
            sh "${buildTools["maven"]}/bin/mvn clean package"
            break
        case "gradle":
            sh "${buildTools["gradle"]}/bin/gradle build -x test"
            break
        
        case "golang":
            sh "${buildTools["golang"]}/bin/go build demo.go"
            break
        
        case "web":
            sh """ ${buildTools["web"]}/bin/npm install  && ${buildTools["web"]}/bin/npm run build """
            break
        
        default :
            println("buildType ==> [maven|gralde|golang|web]")
            break
    }
}

 mytools.groovy用于存放一些小工具, 这里定义了 GetCode 函数用于下载代码,接受三个参数:

  • srcType 代码库类型(git/svn)
  • branchName 代码库的分支名称
  • gitHttpURL 代码库的地址
  • credentialsId 存放凭据ID

EmailUser 函数用于发送邮件通知, 接受两个参数:

  • userEmail  邮件接收人(多个使用逗号分隔)
  • status 作业状态(成功、失败)

创建mytools.groovy

以后把所有的工具都放在这里面

mytools.groovy里面内容,封装的拉取代码和邮件通知

package org.devops

def GetCode(srcType,branchName,gitHttpURL,credentialsId){

    if (srcType == "git"){
        println("下载代码 --> 分支: ${branchName}")
        checkout([$class: 'GitSCM', branches: [[name: "${branchName}"]],
                    extensions: [], 
                    userRemoteConfigs: [[credentialsId: "${credentialsId}", 
                                        url: "${gitHttpURL}"]]])
    }

}

def EmailUser(userEmail,status){
  emailext body: """
            <!DOCTYPE html> 
            <html> 
            <head> 
            <meta charset="UTF-8"> 
            </head> 
            <body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0"> 
                <img src="http://192.168.1.200:8080/static/0eef74bf/images/headshot.png">
                <table width="95%" cellpadding="0" cellspacing="0" style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">   
                    <tr> 
                        <td><br /> 
                            <b><font color="#0B610B">构建信息</font></b> 
                        </td> 
                    </tr> 
                    <tr> 
                        <td> 
                            <ul> 
                                <li>项目名称:${JOB_NAME}</li>         
                                <li>构建编号:${BUILD_ID}</li> 
                                <li>构建状态: ${status} </li>                         
                                <li>项目地址:<a href="${BUILD_URL}">${BUILD_URL}</a></li>    
                                <li>构建日志:<a href="${BUILD_URL}console">${BUILD_URL}console</a></li> 
                            </ul> 
                        </td> 
                    </tr> 
                    <tr>  
                </table> 
            </body> 
            </html>  """,
            subject: "Jenkins-${JOB_NAME}项目构建信息 ",
            to: userEmail

}

最近共享库目录结构如下

 

 

配置共享库到Jenkins


如果没有发现共享库选项的,那么可以安装这个插件。 

Jenkins系统配置 -> Global Pipeline Libraries

首先,我们为共享库设置一个名称 devopslib自定义,无需与github仓库一致),注意这个名称后续在Jenkinsfile中引用。 再设置一个默认的版本,这里的版本是分支的名称。我默认配置的是main版本。(github默认版本必须是main)

这里可以定义若干个共享库,pipeline里面也可以导入若干个共享库。

主要配置有两块,一块是取别名,然后定义好它的版本,这里的版本最好按照分支来做,最后就是git的url和认证信息。(注意这里要提前在Linux上面安装好git) 

 进入Jenkins 设置, 定义共享库名称 devopslib  默认的版本 master

接下来我们配置共享库的仓库地址,我的仓库在github中,所以这里我填写的是github的方式。(如果你用的是gitlab可以使用gitlab方式或者git方式)。如果仓库是私有的方式,需要在jenkins的凭据中添加一个账号用于下载共享库。 

设置共享库的Git地址 , 设置共享库的凭据。(如果没有提前创建好凭据,需要先去创建好然后再重新配置这个页面。)

保存设置,共享库就配置好了。

测试共享库 


在Jenkinsfile中使用@Library("mylib") _ 加载共享库,注意后面符号_用于加载

类的实例化:   def mytools = new org.devops.jenkinstest()

使用类中的方法:  mytools.PrintMsg(msg)

其实可以看到也会去gitlab上面加载共享库,之后去下载共享库。 

Jenkinsfile内容如下所示 

// 加载名称为devopslib的共享库的master版本
@Library("devopslib@master") _

//导入共享库中的方法类
def mytools = new org.devops.mytools()
def builds  = new org.devops.builds()

//定义构建工具类型与路径map
def buildTools = [  "maven": "/usr/local/apache-maven-3.8.1",
          "gradle": "/usr/local/gradle-6.8.3/",
          "golang": "/usr/local/go",
          "web" : "/usr/local/node-v14.16.1-linux-x64/"]

//定义UI上面的参数(用户去选择构建那个项目的那个分支的构建类型)
String branchName = "${env.branchName}"
String gitHttpURL = "${env.gitHttpURL}"
String buildType  = "${env.buildType}"
String credentialsId = "${env.credentialsId}"


// 以下是流水线阶段
pipeline {
  agent { label  "build" }  
  options {
    skipDefaultCheckout true
  }

  stages {
    stage("GetCode"){
      steps{
        script{
        
          // 调用GetCode方法进行代码下载 
          mytools.GetCode("git",branchName,gitHttpURL,credentialsId)
        }
      }
      
    }

    stage("Build"){
      steps {
        script {
          // 调用Build方法进行代码构建
          builds.Build(buildTools, buildType)
        }
      }
    }

  }

  post {
    always {
      script{
        echo "always......"

      }
    }

    success {
      script {
        echo "success....."
      }
    }
  }

}

最后构建如下

我这里用的是docker注意git的版本,docker jenkins容器里面自带的git的版本是1.18版本,先宿主机升级然后挂载到容器目录下使用

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐