Primary jenkins-pipeline shared library use

Using jenkins pipelineshared libraries, applications of the same framework can basically use the same jenkinsfile template, and changing the shared library can be applied to all jenkins-jobs that use this library. The vars directory is not used at present, but it can fully meet our daily needs, and the usage is relatively low. The defined functions are listed below for reference only.

Shared library directory structure:

jenkins-pipeline-libraries git:(master) ✗ tree .
.
├── jenkins-ci
│   └── jenkinsfile-java
├── out
│   └── production
├── src
│   ├── ops
│   │   └── jk
│   │       ├── appDetail.groovy
│   │       └── tools.groovy
│   └── pipeline.gdsl
└── vars
    └── pipelineCfg.groovy

7 directories, 6 files

appDetail.groovySome functions in the file are as follows:

// 获取时间 格式:20201208200419
def getTime() {
    return new Date().format('yyyyMMddHHmmss')
}

//格式化输出,需安装ansiColor插件
def printMes(value,level){
    colors = ['warning' : "\033[43;30m ==> ${value} \033[0m",
              'info'    : "\033[42;30m ==> ${value} \033[0m",
              'error'   : "\033[41;37m ==> ${value} \033[0m",
    ]
    ansiColor('xterm') {
        println(colors[level])
    }
}

// 远程主机上通过ssh执行命令
def runCmd(ip, user, pass, command, sshArgs = '') {
    return sh(returnStdout: true,
            script: "sshpass -p ${pass} ssh ${sshArgs} -oStrictHostKeyChecking=no -l ${user} ${ip} \"${command}\"")
}

// 格式化输出当前构建分支用于镜像tag
def getBranch() {
    def formatBranch = "${env.GIT_BRANCH}".replaceAll('origin/', '').replaceAll('/', '_')
    assert formatBranch != 'null' || formatBranch.trim() != ''
    return formatBranch
}

// 获取分支commitId
def getSHA() {
    def commitsha = "${env.GIT_COMMIT}".toString().substring(0, 6)
    assert commitsha != 'null' || commitsha.trim() != ''
    return commitsha
}

// 获取commit时间
def getCommitTime() {
    out = sh(returnStdout: true, script: "git show -s --format=%ct ${env.GIT_COMMIT}")
    def commitTime = out.toString().trim()
    assert commitTime != 'null' || commitTime.trim() != ''
    return commitTime
}

//获取git commit变更集
def getChangeString() {
    def result = []
    def changeString = []
    def authors = []
    def MAX_MSG_LEN = 20
    def changeLogSets = currentBuild.changeSets
    for (int i = 0; i < changeLogSets.size(); i++) {
        def entries = changeLogSets[i].items
        for (int j = 0; j < entries.length; j++) {
            def entry = entries[j]
            truncatedMsg = entry.msg.take(MAX_MSG_LEN)
            commitTime = new Date(entry.timestamp).format("yyyy-MM-dd HH:mm:ss")
            changeString << "${truncatedMsg} [${entry.author} ${commitTime}]\n"
//            changeString += ">- ${truncatedMsg} [${entry.author} ${commitTime}]\n"
            authors << "${entry.author} "
        }
    }
    if (!changeString) {
        changeString = ">- No new changes"
        authors = "No new changes, No authors"
        result << changeString << authors
        return result
    } else {
        if (changeString.size() >5) {
            changeString = changeString[0,4]
            changeString.add("......")
        }
        changeString = ">-" + changeString.join(">-")
        authors.join(", ")
        result << changeString << authors.unique()
        return result
    }
}

// java项目sonar扫描
def sonarScanner() {
    def sonarDir = tool name: 'scanner-docker', type: 'hudson.plugins.sonar.SonarRunnerInstallation'
    printMes("sonarqube scanner started. sonarHomeDir: ${sonarDir}", "info")
    withSonarQubeEnv(credentialsId: 'comp-sonar') {
        sh "${sonarDir}/bin/sonar-scanner \
           -Dsonar.projectKey=${projectName} \
           -Dsonar.projectName=${projectName} \
           -Dsonar.ws.timeout=60 \
           -Dsonar.sources=. \
           -Dsonar.sourceEncoding=UTF-8 \
           -Dsonar.java.binaries=. \
           -Dsonar.language=java \
           -Dsonar.java.source=1.8"
    }
    printMes("${projectName} scan success!", "info")
}

// 发送钉钉消息,按需自定义,需要安装httpRequest插件
def dingMes(){
    def user = ''
    def description = ''
    def specificCause = currentBuild.getBuildCauses('hudson.model.Cause$UserIdCause')
    if (specificCause) {
        user = "$specificCause.userName"
        description = "$specificCause.shortDescription"
    }
    def DingTalkHook = "https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxx"
    def ChangeStrings = getChangeString()[0]
    def ChangeAuthors = getChangeString()[1]
    def ReqBody = """{
            "msgtype": "markdown",
            "markdown": {
                "title": "项目构建信息",
                "text": "### [${JOB_NAME}](${BUILD_URL})\\n---\\n>- 分支:**${env.GIT_BRANCH}**\\n> - 执行人: **${user}**\\n>- 描述: ${description}\\n>#### 作者:\\n>- **${ChangeAuthors}**\\n>#### 更新记录: \\n${ChangeStrings}"
            },
            "at": {
                "atMobiles": [], 
                "isAtAll": false
                }
            }"""
    httpRequest acceptType: 'APPLICATION_JSON_UTF8',
            consoleLogResponseBody: true,
            contentType: 'APPLICATION_JSON_UTF8',
            httpMode: 'POST',
            ignoreSslErrors: true,
            requestBody: ReqBody,
            responseHandle: 'NONE',
            url: "${DingTalkHook}",
            timeout: 5,
            quiet: true
}

//邮件通知
def emailSuccess(){
    emailext(
        subject: "✅${env.JOB_NAME} - 更新成功",
        body: '${SCRIPT, template="email-html.template"}',
        recipientProviders: [requestor(), developers()]
    )
}

def emailFailure(){
    emailext(
        subject: "❌${env.JOB_NAME} - 更新失败",
        body: '${SCRIPT, template="email-html.template"}',
        recipientProviders: [requestor(), developers()]
    )
}

We jenkinsare jobnameall in accordance with 环境-项目名the format of the name of, e.g. dev-potato, appDetail.groovya function dependent on this section belowjobname

// 通过jenkins-jobname获取项目名称
def getProjectName() {
    String projectName
    String jobName = "${env.JOB_NAME}"
    if ("${env.JOB_NAME}".contains('front-end')) {
        jobName = "${env.JOB_NAME}".replaceAll('front-end/', '')
    }
    projectName = jobName.substring(jobName.indexOf('-') + 1)
    assert projectName != 'null' || projectName.trim() != ''
    return projectName
}

// 通过jobname获取环境名称
def getNameSpace() {
    String namespace
    if ("${env.JOB_NAME}".contains('front-end')) {
        def realJobName = "${env.JOB_NAME}".replaceAll('front-end/', '')
        namespace = realJobName.split('-')[0]
    }else {
        namespace = "${env.JOB_NAME}".split('-')[0]
    }
    assert namespace != 'null' || namespace.trim() != ''
    return namespace
}

// 定义镜像tag,输出格式 xxx.yy.com/comp/bnu:o_hotfix_update_publish_wwefan_0808_78ffds_10
def getImgTag() {
    String regUrl
    def imageTag = ''
    def namespace = getNameSpace()

    if ("${namespace}" != 'pre' && "${namespace}" != 'online') {
        regUrl = 'xxx.yy.net'
    }else {
        regUrl = 'xxx.yy.com'
    }

    def rollTag = "${params.ROLLTAG}"  // jenkins通过参数构建过程传进来的镜像回滚tag
    def gitProjectName = "${env.GIT_URL}".substring("${env.GIT_URL}".lastIndexOf('/') + 1, "${env.GIT_URL}".lastIndexOf('.git'))
    def projectNamespace = "${env.GIT_URL}".substring("${env.GIT_URL}".lastIndexOf(':') + 1, "${env.GIT_URL}".lastIndexOf('/'))
    def jkProjectName = getProjectName()
    if (jkProjectName != gitProjectName) {
        printMes('the jobname of Jenkins does not match the project name of Gitlab', 'warn')
//        error('the jobname of Jenkins does not match the project name of Gitlab')
    }

    if (rollTag) {
        imageTag = "${regUrl}/${projectNamespace}/${gitProjectName}:${rollTag}"
    } else {
        def commitShortSha = getSHA()
        // def COMMIT_TIME = getCommitTime()
        def formatBranch = getBranch()
        imageTag = "${regUrl}/${projectNamespace}/${gitProjectName}:${namespace}_${formatBranch}_${commitShortSha}_${env.BUILD_NUMBER}"
    }
    printMes(imageTag, 'info')
    return imageTag
}

// 构建docker容器镜像推送到仓库
def dockerBuild() {
    printMes("开始构建docker镜像", 'info')
    def namespace = getNameSpace()
    def projectName = getProjectName()
    String regUrl
    if ("${namespace}" != 'pre' && "${namespace}" != 'online') {
        regUrl = 'https://xxx.yy.net'
    }else {
        regUrl = 'https://xxx.oo.com'
    }
    if (!params.ROLLTAG) {
        def core = getCore()
        def dockerimg = ''
        docker.withRegistry("${regUrl}", "comp-image") {
            dockerimg = docker.build(getImgTag(), "-f Dockerfile ./${projectName}-${core}/target/")
            dockerimg.push()
        }
        printMes("镜像已推送到 ${regUrl}", 'info')
    }

}

The java project is jenkinsfileas follows:

#!groovy
@Library('jenkinslib') _

def mytool = new ops.jk.tools()
def app = new ops.jk.appDetail()
def appMap = app.getAppMap()
def projectName = app.getProjectName()
def namespace = app.getNameSpace()

pipeline {
    environment {
        CI_PROJECT_NAME = app.getProjectName()
        IMG_TAG = app.getImgTag()
        NAMESPACE = app.getNameSpace()
        APPTYPE = app.getAppType()
    }

    options {
        timestamps()
        timeout(time: 20, unit: 'MINUTES')
    }

    agent {
        docker {
            image 'xxx.yy.com/library/maven:3.6-git-kube16'
            registryUrl 'https://xxx.yy.com'
            registryCredentialsId 'comp-image'
            label app.getAppLabel()
            args '-v /var/run/docker.sock:/var/run/docker.sock -v /home/admin/:/home/admin/'
        }
    }

    parameters {
        string(name: 'ROLLTAG', defaultValue: '', description: '是否回滚到之前的版本,输入镜像tag进行回滚')
        choice(name: 'SONAR_SCANNER', choices: ['不执行', '执行'], description: '是否执行代码扫描')
    }

    stages {
        stage('mvnPackage'){
            when { expression { return ! params.ROLLTAG } }
            steps {
                script {
                    app.mvnPackage()
                }
            }
        }
        stage('sonar-scanner'){
            when { expression { return params.SONAR_SCANNER == '执行' } }
            steps {
                script {
                    app.sonarScanner()
                }
            }
        }
        stage("Quality Gate") {
            when { expression { return params.SONAR_SCANNER == '执行' } }
            steps {
                timeout(time: 5, unit: 'MINUTES') {
                    waitForQualityGate abortPipeline: true
                }
            }
        }
        stage('dockerBuild') {
            steps {
                script {
                    app.dockerBuild()
                }
            }
        }
        stage('publish') {
            steps {
                script {
                    app.publish()
                }
            }
        }
    }

    post {
        success {
            script{
                mytool.emailSuccess()
            }
        }
        failure {
            script{
                mytool.emailFailure()
            }
        }
    }
}

Dingding notification message example:

Primary jenkins-pipeline shared library use

Email notification example:

Primary jenkins-pipeline shared library use

Guess you like

Origin blog.51cto.com/weifan/2588576