zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    坚持的力量 第十五篇
    <QT障碍之路>qt中使用串口类接收数据不完整
    《开发板 — ping得通本地,但是不能上网。route设置默认网关》
    《海思3531D 搭建环境出现的一些问题》
    《应用编程 — 进程通信 — 命名管道FIFO》
    <QT学习>QT中串口QSerialport类学习与使用
    网络视频工具/网站
    [恢]hdu 1701
    [恢]hdu 1425
    [恢]hdu 2523
  • 原文地址:https://www.cnblogs.com/qingfengfumian/p/14539706.html
Copyright © 2011-2022 走看看