Utilisation principale de la bibliothèque partagée jenkins-pipeline

En utilisant jenkins pipelinedes bibliothèques partagées, les applications du même framework peuvent essentiellement utiliser le même modèle de fichier jenkins, et la modification de la bibliothèque partagée peut être appliquée à tous les jobs jenkins qui utilisent cette bibliothèque. Le répertoire vars n'est pas utilisé pour le moment, mais il peut répondre pleinement à nos besoins quotidiens et son utilisation est relativement faible. Les fonctions définies sont listées ci-dessous à titre indicatif uniquement.

Structure de répertoire de bibliothèque partagée:

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.groovyCertaines fonctions du fichier sont les suivantes:

// 获取时间 格式: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()]
    )
}

Nous jenkinssommes jobnametous en conformité avec 环境-项目名le format du nom, par exemple dev-potato, appDetail.groovyune fonction dépendant de cette section ci - dessousjobname

// 通过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')
    }

}

Le projet java est jenkinsfilele suivant:

#!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()
            }
        }
    }
}

Exemple de message de notification de sonnerie:

Utilisation principale de la bibliothèque partagée jenkins-pipeline

Exemple de notification par e-mail:

Utilisation principale de la bibliothèque partagée jenkins-pipeline

Je suppose que tu aimes

Origine blog.51cto.com/weifan/2588576
conseillé
Classement