自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

開源端到端流水線實踐-需求與代碼管理

開發(fā) 前端
業(yè)務的簡稱為demo,微服務架構(gòu)。N多個微服務。服務命名:業(yè)務簡稱-應用名稱-類型(demo-hello-service)。特性分支開發(fā),版本分支發(fā)布。每個需求(任務/故事)對應一個特性分支。每個發(fā)布(release)對應一個版本分支。

 [[348244]]

業(yè)務的簡稱為demo,微服務架構(gòu)。N多個微服務。服務命名:業(yè)務簡稱-應用名稱-類型(demo-hello-service)。特性分支開發(fā),版本分支發(fā)布。每個需求(任務/故事)對應一個特性分支。每個發(fā)布(release)對應一個版本分支。

1.需求與代碼管理
Jira作為需求和缺陷管理,采用Scrum開發(fā)方法,jira中的項目名稱與業(yè)務簡稱一致(demo)。Gitlab作為版本控制系統(tǒng),每個Group對應一個業(yè)務,每個微服務對應一個代碼庫。

需求與代碼關聯(lián):在jira中創(chuàng)建一個任務/故事,關聯(lián)模塊后自動在該模塊創(chuàng)建一個以ISSUE(任務/故事)ID的特性分支。此時的模塊等同于每個微服務的項目(代碼庫)名稱。以下面圖中為例:我們在demo項目中創(chuàng)建了一個模塊demo-hello-service,其實對應的就是Gitlab代碼庫中demo組的demo-hello-service服務。

特性分支:創(chuàng)建好每個模塊后,就可以實現(xiàn)需求與代碼關聯(lián)。例如:我們在Jira項目demo中創(chuàng)建一個問題,類型為故事(不受限制可為其他),重點是需要將改故事關聯(lián)到模塊(只有關聯(lián)到模塊,我們才能通過接口得知哪個問題關聯(lián)的哪個代碼庫)。

版本分支:當特性分支開發(fā)完成以及測試驗證完成后,基于主干分支創(chuàng)建一個版本分支,然后將所有的特性分支合并到版本分支。此時可以通過Jira中創(chuàng)建一個發(fā)布版本,然后問題關聯(lián)發(fā)布版本(此動作表示該特性分支已經(jīng)通過驗證,可以合并)。自動完成版本分支的創(chuàng)建和特性分支到版本分支的合并請求。

2. 配置過程
需求與代碼庫關聯(lián),主要用到的工具鏈為: Jira + GitLab + Jenkins。Jira負責創(chuàng)建需求,配置webhook。Jenkins負責接收Jira webhook請求,然后通過接口實現(xiàn)GitLab項目分支創(chuàng)建。

特性分支自動化:當我們在jira上面創(chuàng)建了問題,此時會通過Jira的webhook觸發(fā)對應的Jenkins作業(yè),該Jenkins作業(yè)通過解析Jira webhook傳遞的數(shù)據(jù),找到問題名稱和模塊名稱。調(diào)用GitlabAPI 項目查詢接口,根據(jù)模塊名稱找到代碼庫。調(diào)用GitLabAPI 分支創(chuàng)建接口,根據(jù)問題名稱基于主干分支創(chuàng)建一個特性分支。任務結(jié)束。

版本分支自動化:Jira創(chuàng)建發(fā)布版本,Issue關聯(lián)版本。自動在gitlab代碼庫基于master創(chuàng)建版本分支,并開啟特性分支到版本分支的合并請求。

2.1 準備工作
在Jenkins, 創(chuàng)建一個Pipeline 作業(yè)并配置GenericTrigger 觸發(fā)器,接收JiraWebhook數(shù)據(jù)。projectKey 參數(shù)表示Jira項目名稱,webHookData 參數(shù)為Jira webhook的所有數(shù)據(jù)。token 是觸發(fā)器的觸發(fā)token,這里默認采用的作業(yè)名稱(作業(yè)名稱要唯一)。

  1. triggers { 
  2.         GenericTrigger( causeString: 'Trigger By Jira Server -->>>>> Generic Cause',  
  3.                         genericRequestVariables: [[key'projectKey', regexpFilter: '']],  
  4.                         genericVariables: [[defaultValue: ''key'webHookData', regexpFilter: '', value: '$']],  
  5.                         printContributedVariables: true,  
  6.                         printPostContent: true,  
  7.                         regexpFilterExpression: '',  
  8.                         regexpFilterText: '',  
  9.                         silentResponse: true,  
  10.                         token: "${JOB_NAME}" 
  11.         ) 

在Jira項目中配置Webhook,勾選觸發(fā)事件填寫觸發(fā)URL。http://jenkins.idevops.site/generic-webhook-trigger/invoke?token=demo-jira-service&projectKey=${project.key} (這個地址是jenkins Generictrigger生成的,這里不做過多的介紹)

Jira webhook數(shù)據(jù)參考, 這些參數(shù)可以在Jenkinsfile中通過readJSON格式化,然后獲取值。

  1. response = readJSON text: """${webHookData}""" 
  2. println(response) 
  3.  
  4. //獲取webhook的事件類型 
  5. env.eventType = response["webhookEvent"
  1.     "timestamp":1603087582648, 
  2.     "webhookEvent":"jira:issue_created"
  3.     "issue_event_type_name":"issue_created"
  4.     "user":Object{...}, 
  5.     "issue":{ 
  6.         "id":"10500"
  7.         "self":"http://192.168.1.200:8050/rest/api/2/issue/10500"
  8.         "key":"DEMO-2"
  9.         "fields":{ 
  10.             "issuetype":{ 
  11.                 "self":"http://192.168.1.200:8050/rest/api/2/issuetype/10001"
  12.                 "id":"10001"
  13.                 "description":""
  14.                 "iconUrl":"http://192.168.1.200:8050/images/icons/issuetypes/story.svg"
  15.                 "name":"故事"
  16.                 "subtask":false 
  17.             }, 
  18.             "components":[ 
  19.                 { 
  20.                     "self":"http://192.168.1.200:8050/rest/api/2/component/10200"
  21.                     "id":"10200"
  22.                     "name":"demo-hello-service"
  23.                     "description":"demo-hello-service應用" 
  24.                 } 
  25.             ], 
  26.             "timespent":null
  27.             "timeoriginalestimate":null
  28.             "description":null
  29.             ... 
  30.             ... 
  31.             ... 

2.2 封裝GitLab接口
Gitlab接口文檔:https://docs.gitlab.com/ce/api/README.html

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

  1. package org.devops 
  2.  
  3. //封裝HTTP請求 
  4. def HttpReq(reqType,reqUrl,reqBody){ 
  5.     def gitServer = "http://gitlab.idevops.site/api/v4" 
  6.     withCredentials([string(credentialsId: 'gitlab-token', variable: 'gitlabToken')]) { 
  7.       result = httpRequest customHeaders: [[maskValue: truename'PRIVATE-TOKEN', value: "${gitlabToken}"]],  
  8.                 httpMode: reqType,  
  9.                 contentType: "APPLICATION_JSON"
  10.                 consoleLogResponseBody: true
  11.                 ignoreSslErrors: true,  
  12.                 requestBody: reqBody, 
  13.                 url: "${gitServer}/${reqUrl}" 
  14.                 //quiet: true 
  15.     } 
  16.     return result 
  17.  
  18.  
  19. //更新文件內(nèi)容 
  20. def UpdateRepoFile(projectId,filePath,fileContent){ 
  21.     apiUrl = "projects/${projectId}/repository/files/${filePath}" 
  22.     reqBody = """{"branch": "master","encoding":"base64", "content": "${fileContent}", "commit_message": "update a new file"}""" 
  23.     response = HttpReq('PUT',apiUrl,reqBody) 
  24.     println(response) 
  25.  
  26.  
  27. //獲取文件內(nèi)容 
  28. def GetRepoFile(projectId,filePath){ 
  29.     apiUrl = "projects/${projectId}/repository/files/${filePath}/raw?ref=master" 
  30.     response = HttpReq('GET',apiUrl,''
  31.     return response.content 
  32.  
  33. //創(chuàng)建倉庫文件 
  34. def CreateRepoFile(projectId,filePath,fileContent){ 
  35.     apiUrl = "projects/${projectId}/repository/files/${filePath}" 
  36.     reqBody = """{"branch": "master","encoding":"base64", "content": "${fileContent}", "commit_message": "create a new file"}""" 
  37.     response = HttpReq('POST',apiUrl,reqBody) 
  38.     println(response) 
  39.  
  40.  
  41. //更改提交狀態(tài) 
  42. def ChangeCommitStatus(projectId,commitSha,status){ 
  43.     commitApi = "projects/${projectId}/statuses/${commitSha}?state=${status}" 
  44.     response = HttpReq('POST',commitApi,''
  45.     println(response) 
  46.     return response 
  47.  
  48. //獲取項目ID 
  49. def GetProjectID(repoName='',projectName){ 
  50.     projectApi = "projects?search=${projectName}" 
  51.     response = HttpReq('GET',projectApi,''
  52.     def result = readJSON text: """${response.content}""" 
  53.      
  54.     for (repo in result){ 
  55.        // println(repo['path_with_namespace']) 
  56.         if (repo['path'] == "${projectName}"){ 
  57.              
  58.             repoId = repo['id'
  59.             println(repoId) 
  60.         } 
  61.     } 
  62.     return repoId 
  63.  
  64. //刪除分支 
  65. def DeleteBranch(projectId,branchName){ 
  66.     apiUrl = "/projects/${projectId}/repository/branches/${branchName}" 
  67.     response = HttpReq("DELETE",apiUrl,'').content 
  68.     println(response) 
  69.  
  70. //創(chuàng)建分支 
  71. def CreateBranch(projectId,refBranch,newBranch){ 
  72.     try { 
  73.         branchApi = "projects/${projectId}/repository/branches?branch=${newBranch}&ref=${refBranch}" 
  74.         response = HttpReq("POST",branchApi,'').content 
  75.         branchInfo = readJSON text: """${response}""" 
  76.     } catch(e){ 
  77.         println(e) 
  78.     }  //println(branchInfo) 
  79.  
  80. //創(chuàng)建合并請求 
  81. def CreateMr(projectId,sourceBranch,targetBranch,title,assigneeUser=""){ 
  82.     try { 
  83.         def mrUrl = "projects/${projectId}/merge_requests" 
  84.         def reqBody = """{"source_branch":"${sourceBranch}", "target_branch": "${targetBranch}","title":"${title}","assignee_id":"${assigneeUser}"}""" 
  85.         response = HttpReq("POST",mrUrl,reqBody).content 
  86.         return response 
  87.     } catch(e){ 
  88.         println(e) 
  89.     } 
  90.  
  91. //搜索分支 
  92. def SearchProjectBranches(projectId,searchKey){ 
  93.     def branchUrl =  "projects/${projectId}/repository/branches?search=${searchKey}" 
  94.     response = HttpReq("GET",branchUrl,'').content 
  95.     def branchInfo = readJSON text: """${response}""" 
  96.      
  97.     def branches = [:] 
  98.     branches[projectId] = [] 
  99.     if(branchInfo.size() ==0){ 
  100.         return branches 
  101.     } else { 
  102.         for (branch in branchInfo){ 
  103.             //println(branch) 
  104.             branches[projectId] += ["branchName":branch["name"], 
  105.                                     "commitMes":branch["commit"]["message"], 
  106.                                     "commitId":branch["commit"]["id"], 
  107.                                     "merged": branch["merged"], 
  108.                                     "createTime": branch["commit"]["created_at"]] 
  109.         } 
  110.         return branches 
  111.     } 
  112.  
  113. //允許合并 
  114. def AcceptMr(projectId,mergeId){ 
  115.     def apiUrl = "projects/${projectId}/merge_requests/${mergeId}/merge" 
  116.     HttpReq('PUT',apiUrl,''

2.3 共享庫配置

演示效果:上傳了兩個小視頻,可以掃描進入視頻號查看。

 

 

責任編輯:姜華 來源: DevOps云學堂
相關推薦

2021-04-29 08:55:54

GitLabDevOps項目

2017-03-02 14:12:13

流水線代碼Clojure

2022-07-18 06:05:28

Gitlab流水線

2024-01-07 12:47:35

Golang流水線設計模式

2023-12-11 18:35:37

測試流水線自動化

2021-12-24 08:02:48

GitLabCI模板庫流水線優(yōu)化

2021-04-13 06:15:37

開源部署流水線Jenkins

2019-11-07 09:00:39

Jenkins流水線開源

2017-02-28 16:00:45

DevOpsMarkdownreST

2023-05-10 15:08:00

Pipeline設計模式

2023-05-26 08:31:09

2013-06-06 09:31:52

2017-02-28 15:40:30

Docker流水線Azure

2021-11-08 07:41:16

Go流水線編程

2021-06-26 14:22:34

Tekton流水線Kubernetes

2022-01-26 08:12:42

Jenkins開源流水線

2023-08-18 10:24:52

GitLabCI 流水線

2021-10-12 08:47:01

Nexus存儲庫管理器DevOps

2019-11-07 10:02:33

開源開源工具DevOps

2025-02-20 08:00:00

點贊
收藏

51CTO技術棧公眾號