jenkins集成gitlab實現自動合並


背景

  • 公司目前使用環境和分支綁定的分支管理策略,不同環境有對應分支,代碼由功能特性分支合並到測試環境,然后根據環境等級逐級往上合並,為提高效率,需要實現功能特性分支自動合並到測試環境對應分支。

實現思路

  • 整體思路gitlab配置合並請求,自動觸發merge request鈎子推送相關信息至jenkins的webhook觸發jenkins的合並的job,該job通過調用gitlab api實現自動合並,並且將合並的結果郵件通知到請求人員。

實施過程

  1. gitlab創建jenkins賬號,給予管理員權限(如果對權限管理比較嚴格,可以在指定的項目,給予主程權限),配置服務調用token,給jenkins使用。
    image
  2. jenkins配置憑據,將gitlab token 添加到全局憑據中.
    image
  3. 配置郵件通知,詳細教程可以參考<<jenkins配置郵件擴展插件,實現郵件發送通知>>
    imageimage
  4. 編寫共享庫,實現獲取對git api的常見操作。

src/com/devops/gitlab.groovy

package com.devops

// 此處參考zeyang的jenkins封裝的源碼,也可以去gitlab的api文檔中獲取當前版本的api接口,根據實際需求進行編寫。https://your-gitlab-url/help/api/README.md下有所有的api接口說明文檔

//封裝HTTP請求
def HttpReq(reqType,reqUrl,reqBody){
	// 定義gitlab的接口地址
    def gitServer = "https://gitlab.url.com/api/v4"
	// 此處使用之前在jenkins中創建的gitlab token的憑據的id名稱
    withCredentials([string(credentialsId: 'jenkins-gitlab-token-text', variable: 'gitlabToken')]) {
      result = httpRequest customHeaders: [[maskValue: true, name: 'PRIVATE-TOKEN', value: "${gitlabToken}"]], 
                httpMode: reqType, 
                contentType: "APPLICATION_JSON",
                consoleLogResponseBody: true,
                ignoreSslErrors: true, 
                requestBody: reqBody,
                url: "${gitServer}/${reqUrl}"
                //quiet: true
    }
    return result
}

//允許合並
def AcceptMr(projectId,mergeId){
    def apiUrl = "projects/${projectId}/merge_requests/${mergeId}/merge"
    HttpReq('PUT',apiUrl,'')
}

  1. 共享庫內編寫郵件模板

src/com/devops/email.groovy

package com.devops

//定義郵件內容
def mergeEmail(username, source_branch, target_branch, status, merge_url, emailUser){
    emailext body: """
            <!DOCTYPE html> 
            <html> 
            <head> 
            <meta charset="UTF-8"> 
            </head> 
            <body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4" offset="0"> 
                <img height="100" width="100" src="https://about.gitlab.com/images/devops-tools/gitlab-logo.svg">
                <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>提交人: ${username}</li>
                                <li>源分支: ${source_branch}</li>         
                                <li>目標分支: ${target_branch}</li> 
                                <li>合並結果: ${status} </li>                         
                                <li>合並URL: <a href="${merge_url}">${merge_url}</a></li>                                    
                            </ul> 
                        </td> 
                    </tr> 
                    <tr>  
                </table> 
            </body> 
            </html>  """,
            subject: "gitlab分支合並結果通知",
            to: emailUser
        
}
  1. 創建jenkins item, 編寫pipeline
@Library("jenkinslib@master") _

def gitlabapi = new com.devops.gitlab()
def toemail = new com.devops.email()



def sourceBranch = source_branch - "refs/heads/"
def targetBranch = target_branch - "refs/heads/"
List branch_list = ["fat", 'fat1', 'fat2', 'uat']

currentBuild.description = "Trigger by ${username} ${sourceBranch} merge to ${targetBranch}"

if (!branch_list.contains(target_branch)) {
    error "目標分支不在${branch_list}中"
}


pipeline {
    agent any
    
    options { 
        buildDiscarder(logRotator(numToKeepStr: '60')) // 保留構建記錄為60次
        disableConcurrentBuilds() // 關閉同時執行流水線
        timeout(time: 1, unit: 'HOURS')  // 設置流水線超時時間
        timestamps() //日志打印時間戳
    }
    
    triggers {
        // 參考鏈接1: https://www.jianshu.com/p/7873d2f0dd3e
        // 參考鏈接2: https://plugins.jenkins.io/generic-webhook-trigger/
        GenericTrigger(
            genericVariables: [
                [key: 'username', value: '$.user.username'],
                [key: 'user_email', value: '$.user.email', ],
                [key: 'source_branch', value: '$.object_attributes.source_branch', ],
                [key: 'target_branch', value: '$.object_attributes.target_branch', ],
                [key: 'project_id', value: '$.project.id', ],
                [key: 'megre_id', value: '$.object_attributes.iid', ],
                [key: 'megre_state', value: '$.object_attributes.state',],
                [key: 'merge_url', value: '$.object_attributes.url']
            ],
            token: 'jenkins-gitlab-mr' ,
            causeString: ' Triggered on $branch' ,
            silentResponse: true,
            printContributedVariables: true,
            printPostContent: true,    
            )
    }
    

  
    stages {
        stage('merge') {
            when {
                equals expected: 'opened', actual: megre_state
            }
            steps {
                script {
                    try {
                        gitlabapi.AcceptMr(project_id, megre_id)
                        toemail.mergeEmail(username, source_branch, target_branch, '合並成功', merge_url, user_email)
                        
                    } catch(Exception ex) {
                        toemail.mergeEmail(username, source_branch, target_branch, '合並失敗', merge_url, user_email)
                        error ex
                    }
                    
                }
            }
        }
        
        stage('do not merge') {
            when {
                not {
                    equals expected: 'opened', actual: megre_state
                }
            }
            steps {
                script {
                    println("mergeState is not opened, nothing to do.")
                }
            }
        }
    }
}
  1. 測試結果
    image
    image
    image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM