一個簡單CI/CD流程的思考


  因為公司有兩地研發團隊,在統一CI/CD上難度不亞於兩家公司合並后的新流程建立,並非不可攻克,簡單描述下心得。

  首先,代碼管理使用gerrit -> 因其強大的 codereview 功能被選中為 codebase 的選型,而且,我們依賴於 gerrit event 觸發流程,取代溝通基本靠喊的簡單粗暴的方式。

  關於 gerrit event 介紹,請參考

  https://gerrit-review.googlesource.com/Documentation/cmd-stream-events.html

  原本,CI/CD 流程是重度依賴 jenkins 及其插件。但因 jenkins 的排隊處理,及其插件 gerrit-trigger 的 miss 率達到將近 10%(針對本公司 gerrit 提交情況),導致 CI/CD 流程無法獲得期望中的推廣效果,故拋棄 jenkins 插件,降低 jenkins 使用權重,降低替代 jenkins 的成本 

  使用 python 開發 gerrit client, 監聽 gerrit event 事件(目前只處理 PatchSet Create & ChangeMerged ) 

監聽 gerrit event:

def run(self):
host = self.config.get("gerrit_host", "example.net")
user = self.config.get("gerrit_user", "engineer")
port = int(self.config.get("gerrit_ssh_port", "29418"))
fkey = self.config.get("gerrit_key_file", None)
etyp = self.config.get("gerrit_event_types", "").split(",")
events = queue.Queue()
listener = StreamEventListener(events, user, host, port, fkey)
listener.set_event_types(etyp)
listener.set_logger(self.logger)
listener.start()
while True:
e = events.get()
handler = GerritStreamEventHandler(e, self.logger, self.config)
handler.start()

 

  eg:

if "patchset-created" == etype:
taskQueues[project][cs].put(self.event)
taskQueues[project][ut].put(self.event)
elif "change-merged" == etype:
#change-merged,啟動ci構建job

url = 'http://127.0.0.1:9091/citrigger'
param = {"event":event}
header = {"Content-Type": "application/json"}
response = requests.post("http://127.0.0.1:3200/", json=param, headers = header)
log_trigger_fmt = "Trigger ci job on [{}], ref: {}, event created {}, responses :{}"
self.logger.info(log_trigger_fmt(project, ref, etime, response))

此處,通過使用自行開發的EventListner 及 handler,替代 jenkins 中 gerrit trigger的功能,解決了 miss 的問題!

另外,發布系統作為前端展示及任務調度的部分,可以完成數據統計,針對某個提交進行重復構建,記錄發布歷史,統一公司項目結構進行的技術限制,保證高度統一。

 

  通過 trigger 的轉發及過濾,可以確保每一次開發的提交在經過submit后得到構建,構建使用的工具還是采用了 jenkins (天坑jenkins,以后會丟掉的),通過參數化構建的方式,並依賴於公司內同一類型的項目的構建方式統一 (nodejs, maven, gradle),消息處理,更新模板,創建job, 更新job, 這個部分由一個獨立的服務來維護, 服務與 jenkins 通信,維護 jenkins 中 job的配置信息。

 

設計思路

  1. 啟用端口監聽 發布系統 發來的請求:
  • 請求包含4個部分 type Income struct { AppId string json:"app_id" Project string json:"project" TaskId string json:"task_id" Ref string json:"ref" }
  1. 進行以下處理:
  • 根據 AppId, 搜索該項目是否有特殊配置(構建前/后的命令執行),如果有,不執行刷新 job template 的操作,如果沒有, 根據項目類型刷新對應的 job template
  • 根據 AppId, 獲取該項目的 job url,並執行構建操作
  • Job Build 需要的參數 type Param struct { Ref string json:"Ref" TaskId string json:"TaskId" AppId string json:"AppId" Project string json:"project" Module string json:"Module" }
  1. 新增創建job端口,進行以下處理:
  • 接收發布系統的請求: type CreateIncome struct { AppId string json:"app_id" Project string json:"project" Type string json:"type"Module string json:"module" SzOrSh string json:"SzOrSh" }
  • 收到請求后,在 t_app_job 插入記錄即可

 

 


免責聲明!

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



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