ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

开源端到端流水线实践-需求与代码管理

2020-10-26 17:02:14  阅读:259  来源: 互联网

标签:Jira projectId 开源 branch 流水线 分支 response def 端到


业务的简称为demo,微服务架构。N多个微服务。服务命名:业务简称-应用名称-类型(demo-hello-service)。特性分支开发,版本分支发布。 每个需求(任务/故事)对应一个特性分支。每个发布(release)对应一个版本分支。

1.需求与代码管理

Jira作为需求和缺陷管理,采用Scrum开发方法,jira中的项目名称与业务简称一致(demo)。 Gitlab作为版本控制系统,每个Group对应一个业务,每个微服务对应一个代码库。

开源端到端流水线实践-需求与代码管理
需求与代码关联:在jira中创建一个任务/故事,关联模块后自动在该模块创建一个以ISSUE(任务/故事)ID的特性分支。此时的模块等同于每个微服务的项目(代码库)名称。 以下面图中为例:我们在demo项目中创建了一个模块demo-hello-service,其实对应的就是Gitlab代码库中demo组的demo-hello-service服务。

开源端到端流水线实践-需求与代码管理

特性分支: 创建好每个模块后,就可以实现需求与代码关联。例如:我们在Jira项目demo中创建一个问题,类型为故事(不受限制可为其他),重点是需要将改故事关联到模块(只有关联到模块,我们才能通过接口得知哪个问题关联的哪个代码库)。

开源端到端流水线实践-需求与代码管理

版本分支: 当特性分支开发完成以及测试验证完成后,基于主干分支创建一个版本分支,然后将所有的特性分支合并到版本分支。此时可以通过Jira中创建一个发布版本,然后问题关联发布版本(此动作表示该特性分支已经通过验证,可以合并)。自动完成版本分支的创建和特性分支到版本分支的合并请求。

开源端到端流水线实践-需求与代码管理

2. 配置过程

需求与代码库关联,主要用到的工具链为: Jira + GitLab + Jenkins。 Jira负责创建需求,配置webhook。Jenkins负责接收Jira webhook请求,然后通过接口实现GitLab项目分支创建。

特性分支自动化:当我们在jira上面创建了问题,此时会通过Jira的webhook触发对应的Jenkins作业,该Jenkins作业通过解析Jira webhook传递的数据,找到问题名称和模块名称。 调用GitlabAPI 项目查询接口,根据模块名称找到代码库。调用GitLabAPI 分支创建接口,根据问题名称基于主干分支创建一个特性分支。任务结束。

版本分支自动化:Jira创建发布版本,Issue关联版本。自动在gitlab代码库基于master创建版本分支,并开启特性分支到版本分支的合并请求。

2.1 准备工作

在Jenkins, 创建一个Pipeline 作业并配置GenericTrigger 触发器,接收JiraWebhook数据。projectKey 参数表示Jira项目名称,webHookData 参数为Jira webhook的所有数据。 token 是触发器的触发token,这里默认采用的作业名称(作业名称要唯一)。

triggers {
        GenericTrigger( causeString: 'Trigger By Jira Server -->>>>> Generic Cause', 
                        genericRequestVariables: [[key: 'projectKey', regexpFilter: '']], 
                        genericVariables: [[defaultValue: '', key: 'webHookData', regexpFilter: '', value: '$']], 
                        printContributedVariables: true, 
                        printPostContent: true, 
                        regexpFilterExpression: '', 
                        regexpFilterText: '', 
                        silentResponse: true, 
                        token: "${JOB_NAME}"
        )
    }

在Jira项目中配置Webhook,勾选触发事件填写触发URL。http://jenkins.idevops.site/generic-webhook-trigger/invoke?token=demo-jira-service&projectKey=${project.key} (这个地址是jenkins Generictrigger生成的,这里不做过多的介绍)

开源端到端流水线实践-需求与代码管理

Jira webhook数据参考, 这些参数可以在Jenkinsfile中通过readJSON格式化,然后获取值。

response = readJSON text: """${webHookData}"""
println(response)

//获取webhook的事件类型
env.eventType = response["webhookEvent"]
{
    "timestamp":1603087582648,
    "webhookEvent":"jira:issue_created",
    "issue_event_type_name":"issue_created",
    "user":Object{...},
    "issue":{
        "id":"10500",
        "self":"http://192.168.1.200:8050/rest/api/2/issue/10500",
        "key":"DEMO-2",
        "fields":{
            "issuetype":{
                "self":"http://192.168.1.200:8050/rest/api/2/issuetype/10001",
                "id":"10001",
                "description":"",
                "iconUrl":"http://192.168.1.200:8050/images/icons/issuetypes/story.svg",
                "name":"故事",
                "subtask":false
            },
            "components":[
                {
                    "self":"http://192.168.1.200:8050/rest/api/2/component/10200",
                    "id":"10200",
                    "name":"demo-hello-service",
                    "description":"demo-hello-service应用"
                }
            ],
            "timespent":null,
            "timeoriginalestimate":null,
            "description":null,
            ...
            ...
            ...

2.2 封装GitLab接口

Gitlab接口文档: https://docs.gitlab.com/ce/api/README.html

共享库:src/org/devops/gitlab.groovy

package org.devops

//封装HTTP请求
def HttpReq(reqType,reqUrl,reqBody){
    def gitServer = "http://gitlab.idevops.site/api/v4"
    withCredentials([string(credentialsId: 'gitlab-token', 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 UpdateRepoFile(projectId,filePath,fileContent){
    apiUrl = "projects/${projectId}/repository/files/${filePath}"
    reqBody = """{"branch": "master","encoding":"base64", "content": "${fileContent}", "commit_message": "update a new file"}"""
    response = HttpReq('PUT',apiUrl,reqBody)
    println(response)

}

//获取文件内容
def GetRepoFile(projectId,filePath){
    apiUrl = "projects/${projectId}/repository/files/${filePath}/raw?ref=master"
    response = HttpReq('GET',apiUrl,'')
    return response.content
}

//创建仓库文件
def CreateRepoFile(projectId,filePath,fileContent){
    apiUrl = "projects/${projectId}/repository/files/${filePath}"
    reqBody = """{"branch": "master","encoding":"base64", "content": "${fileContent}", "commit_message": "create a new file"}"""
    response = HttpReq('POST',apiUrl,reqBody)
    println(response)
}

//更改提交状态
def ChangeCommitStatus(projectId,commitSha,status){
    commitApi = "projects/${projectId}/statuses/${commitSha}?state=${status}"
    response = HttpReq('POST',commitApi,'')
    println(response)
    return response
}

//获取项目ID
def GetProjectID(repoName='',projectName){
    projectApi = "projects?search=${projectName}"
    response = HttpReq('GET',projectApi,'')
    def result = readJSON text: """${response.content}"""

    for (repo in result){
       // println(repo['path_with_namespace'])
        if (repo['path'] == "${projectName}"){

            repoId = repo['id']
            println(repoId)
        }
    }
    return repoId
}

//删除分支
def DeleteBranch(projectId,branchName){
    apiUrl = "/projects/${projectId}/repository/branches/${branchName}"
    response = HttpReq("DELETE",apiUrl,'').content
    println(response)
}

//创建分支
def CreateBranch(projectId,refBranch,newBranch){
    try {
        branchApi = "projects/${projectId}/repository/branches?branch=${newBranch}&ref=${refBranch}"
        response = HttpReq("POST",branchApi,'').content
        branchInfo = readJSON text: """${response}"""
    } catch(e){
        println(e)
    }  //println(branchInfo)
}

//创建合并请求
def CreateMr(projectId,sourceBranch,targetBranch,title,assigneeUser=""){
    try {
        def mrUrl = "projects/${projectId}/merge_requests"
        def reqBody = """{"source_branch":"${sourceBranch}", "target_branch": "${targetBranch}","title":"${title}","assignee_id":"${assigneeUser}"}"""
        response = HttpReq("POST",mrUrl,reqBody).content
        return response
    } catch(e){
        println(e)
    }
}

//搜索分支
def SearchProjectBranches(projectId,searchKey){
    def branchUrl =  "projects/${projectId}/repository/branches?search=${searchKey}"
    response = HttpReq("GET",branchUrl,'').content
    def branchInfo = readJSON text: """${response}"""

    def branches = [:]
    branches[projectId] = []
    if(branchInfo.size() ==0){
        return branches
    } else {
        for (branch in branchInfo){
            //println(branch)
            branches[projectId] += ["branchName":branch["name"],
                                    "commitMes":branch["commit"]["message"],
                                    "commitId":branch["commit"]["id"],
                                    "merged": branch["merged"],
                                    "createTime": branch["commit"]["created_at"]]
        }
        return branches
    }
}

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

2.3 共享库配置

开源端到端流水线实践-需求与代码管理

 

标签:Jira,projectId,开源,branch,流水线,分支,response,def,端到
来源: https://www.cnblogs.com/dcv218/p/13879360.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有