分支模式
1.TrunkBased模式
工作方式
TrunkBased 模式是持續(xù)集成思想所崇尚的工作方式,它由單個(gè)主干分支和許多發(fā)布分支組成,每個(gè)發(fā)布分支在特定版本的提交點(diǎn)上從主干創(chuàng)建出來(lái),用來(lái)進(jìn)行上線部署和 Hotfix(補(bǔ)?。?。
缺點(diǎn)
它的缺點(diǎn)比較明顯,太多的團(tuán)隊(duì)同時(shí)工作在主干上,到發(fā)布的時(shí)候就可能出現(xiàn)災(zāi)難(尤其是多版本并行開(kāi)發(fā)的情況)。
應(yīng)對(duì)措施
彌補(bǔ)的措施是 FeatureToggle(特性切換) 以及頻繁的集成和足夠的測(cè)試覆蓋。
應(yīng)用場(chǎng)景
目前 TrunkBased 模式主要用在不需要同時(shí)維護(hù)多個(gè)歷史版本的 SaaS 型項(xiàng)目,特別是經(jīng)過(guò)微服務(wù)改造的各種小型服務(wù)上。
2.GitFlow模式
工作方式
GitFlow 模式是若干模式的集大成者,包含一個(gè)主干分支、一個(gè)開(kāi)發(fā)分支、許多的特性分支、許多的發(fā)布分支和 Hotfix 分支,以及許多繁瑣的合并規(guī)則。
缺點(diǎn)
但它使用起來(lái)并不是很容易,大量的合并沖突和對(duì)集成測(cè)試不友好也是它被詬病最多的地方。
與TrunkBased的異同
在 TrunkBased 的基礎(chǔ)上,增加了個(gè)人倉(cāng)庫(kù)和 Pull Request 合并代碼的操作,與在同一個(gè)倉(cāng)庫(kù)里增加個(gè)人分支的做法類(lèi)似。GithubFlow 也有演進(jìn)版本,例如強(qiáng)調(diào)了多環(huán)境部署和將倉(cāng)庫(kù)或分支與環(huán)境關(guān)聯(lián)的 GitlabFlow 模式。
應(yīng)用場(chǎng)景
從實(shí)用的意義來(lái)說(shuō),它更合適分布式團(tuán)隊(duì)。
要么簡(jiǎn)單粗暴如 TrunkBased,要么繁瑣復(fù)雜如 GitFlow。難到真沒(méi)有其他選擇了嗎?
3.AoneFlow模式
在 AoneFlow 上你能看到許多其他分支模式的影子。它基本上兼顧了 TrunkBased 的“易于持續(xù)集成”和 GitFlow 的“易于管理需求”特點(diǎn),同時(shí)規(guī)避掉 GitFlow 的那些繁文縟節(jié)。
簡(jiǎn)介
AoneFlow 只使用三種分支類(lèi)型:主干分支、特性分支、發(fā)布分支,以及三條基本規(guī)則。
規(guī)則一(開(kāi)始工作前,從主干創(chuàng)建特性分支)
規(guī)則:AoneFlow 的特性分支基本借鑒 GitFlow,沒(méi)有什么特別之處。每當(dāng)開(kāi)始一件新的工作項(xiàng)(比如新的功能或是待解決的問(wèn)題)的時(shí)候,從代表最新已發(fā)布版本的主干上創(chuàng)建一個(gè)通常以feature/前綴命名的特性分支,然后在這個(gè)分支上提交代碼修改。也就是說(shuō),每個(gè)工作項(xiàng)(可以是一個(gè)人完成,或是多個(gè)人協(xié)作完成)對(duì)應(yīng)一個(gè)特性分支,所有的修改都不允許直接提交到主干。

規(guī)則二(通過(guò)合并特性分支,形成發(fā)布分支)
規(guī)則:AoneFlow 的發(fā)布分支設(shè)計(jì)十分巧妙,可謂整個(gè)體系的精髓。GitFlow 先將已經(jīng)完成的特性分支合并回公共主線(即開(kāi)發(fā)分支),然后從公共主線拉出發(fā)布分支。TrunkBased 同樣是等所有需要的特性都在主干分支上開(kāi)發(fā)完成,然后從主干分支的特定位置拉出發(fā)布分支。而 AoneFlow 的思路是,從主干上拉出一條新分支,將所有本次要集成或發(fā)布的特性分支依次合并過(guò)去,從而得到發(fā)布分支。發(fā)布分支通常以release/前綴命名。

基礎(chǔ)使用:基礎(chǔ)玩法是將每條發(fā)布分支與具體的環(huán)境相對(duì)應(yīng),比如release/test分支對(duì)應(yīng)部署測(cè)試環(huán)境,release/prod分支對(duì)應(yīng)線上正式環(huán)境等等,并與流水線工具相結(jié)合,串聯(lián)各個(gè)環(huán)境上的代碼質(zhì)量掃描和自動(dòng)化測(cè)試關(guān)卡,將產(chǎn)出的部署包直接發(fā)布到相應(yīng)環(huán)境上。
進(jìn)階使用:進(jìn)階點(diǎn)的玩法是將一個(gè)發(fā)布分支對(duì)應(yīng)多個(gè)環(huán)境,比如把灰度發(fā)布和正式發(fā)布串在一起,中間加上人工驗(yàn)收的步驟。
高級(jí)使用:高級(jí)的玩法呢,要是按迭代計(jì)劃來(lái)關(guān)聯(lián)特性分支,創(chuàng)建出以迭代演進(jìn)的固定發(fā)布分支,再把一系列環(huán)境都串在這個(gè)發(fā)布分支的流水線上,就有點(diǎn)經(jīng)典持續(xù)集成流水線的味道了。再或者做一個(gè)將所有特性分支都關(guān)聯(lián)在一起的發(fā)布分支,專門(mén)用于對(duì)所有提交做集成測(cè)試,就玩出了 TrunkBased 的效果。
優(yōu)勢(shì):
- 發(fā)布分支的特性組成是動(dòng)態(tài)的,調(diào)整起來(lái)特別容易。在一些市場(chǎng)瞬息萬(wàn)變的互聯(lián)網(wǎng)企業(yè),以及采用“敏捷運(yùn)作”的乙方企業(yè)經(jīng)常會(huì)遇到這種情況,已經(jīng)完成就等待上線的需求,隨時(shí)可能由于市場(chǎng)策略調(diào)整或者甲方的一個(gè)臨時(shí)決定,其中某個(gè)功能忽然要求延遲發(fā)布或者干脆不要了。再或者是某個(gè)特性在上線前發(fā)現(xiàn)存在嚴(yán)重的開(kāi)發(fā)問(wèn)題,需要排除。按往常的做法,這時(shí)候就要來(lái)手工“剔代碼”了,將已經(jīng)合并到開(kāi)發(fā)分支或者主干分支的相關(guān)提交一個(gè)個(gè)剔除出去,做過(guò)的同學(xué)都知道很麻煩。在 AoneFlow 的模式下,重建發(fā)布分支只是分分鐘的事,將原本的發(fā)布分支刪掉,從主干拉出新的同名發(fā)布分支,再把需要保留的各特性分支合并過(guò)來(lái)就搞定。這一系列動(dòng)作能夠在很大程度上實(shí)現(xiàn)自動(dòng)化,而且不會(huì)在倉(cāng)庫(kù)留下一堆剔除代碼的記錄,干凈無(wú)污染。
- 發(fā)布分支之間是松耦合的,這樣就可以有多個(gè)集成環(huán)境分別進(jìn)行不同的特性組合的集成測(cè)試,也能方便的管理各個(gè)特性進(jìn)入到不同環(huán)境上部署的時(shí)機(jī)。松耦合并不代表沒(méi)有相關(guān)性,由于測(cè)試環(huán)境、集成環(huán)境、預(yù)發(fā)布環(huán)境、灰度環(huán)境和線上正式環(huán)境等發(fā)布流程通常是順序進(jìn)行的,在流程上可以要求只有通過(guò)前一環(huán)境驗(yàn)證的特性,才能傳遞到下一個(gè)環(huán)境做部署,形成漏斗形的特性發(fā)布流。
規(guī)則三(發(fā)布到線上正式環(huán)境后,合并相應(yīng)的發(fā)布分支到主干,在主干添加標(biāo)簽,同時(shí)刪除該發(fā)布分支關(guān)聯(lián)的特性分支)
當(dāng)一條發(fā)布分支上的流水線完成了一次線上正式環(huán)境的部署,就意味著相應(yīng)的功能真正的發(fā)布了,此時(shí)應(yīng)該將這條發(fā)布分支合并到主干。為了避免在代碼倉(cāng)庫(kù)里堆積大量歷史上的特性分支,還應(yīng)該清理掉已經(jīng)上線部分特性分支。與 GitFlow 相似,主干分支上的最新版本始終與線上版本一致,如果要回溯歷史版本,只需在主干分支上找到相應(yīng)的版本標(biāo)簽即可。

不成文技巧
上線后的 Hotfix,正常的處理方法應(yīng)該是,創(chuàng)建一條新的發(fā)布分支,對(duì)應(yīng)線上環(huán)境(相當(dāng)于 Hotfix 分支),同時(shí)為這個(gè)分支創(chuàng)建臨時(shí)流水線,以保障必要的發(fā)布前檢查和冒煙測(cè)試能夠自動(dòng)執(zhí)行。但其實(shí)還有一種簡(jiǎn)便方法是,將線上正式環(huán)境對(duì)應(yīng)的發(fā)布分支上關(guān)聯(lián)的特性分支全部清退掉,在這個(gè)發(fā)布分支上直接進(jìn)行修改,改完利用現(xiàn)成的流水線自動(dòng)發(fā)布。如果非得修一個(gè)歷史版本的 Bug 怎么辦呢?那就老老實(shí)實(shí)的在主干分支找到版本標(biāo)簽位置,然后從那個(gè)位置創(chuàng)建 Hotfix 分支。
AoneFlow 中每一個(gè)看似簡(jiǎn)單的步驟都并非憑空臆造,而是經(jīng)歷大量產(chǎn)品團(tuán)隊(duì)反復(fù)磨礪后積累下來(lái)的經(jīng)驗(yàn)。接下來(lái),我會(huì)說(shuō)說(shuō) AoneFlow 的技術(shù)門(mén)檻以及阿里內(nèi)部的應(yīng)對(duì)之道。
原文鏈接:https://yq.aliyun.com/articles/573549?spm=5176.10695662.1996646101.searchclickresult.487037c2mlR4QM