
策劃&編輯|雅純
上一講,我們詳細介紹了4種常見的分支模式及其優劣對比,本文我們將根據不同的團隊場景,分析如何選擇適合團隊的研發模式,
研發模式選擇看什么

研發模式的選擇與產品形態、發布方式、團隊規模、協作成熟度密切相關,比如團隊規模很小,協作成熟度很高,就直接用主干開發,類似于Web服務端的開發,可以做到持續部署,可以選擇GitHub—Flow,或者是TBD,
如果你的團隊規模比較大,需要開發的時候做相應的隔離,再看協作的成熟度,如果一般就用GitHub—Flow,成熟度很高就用TBD,
另外,有一些研發場景有固定的發布視窗,它是按版本的方式去發布,我們建議有相應的release分支去做隔離,實際程序中我們應該盡可能地根據自己實際的產品和團隊情況,來去制定合適的分支規則,

舉一個例子,這張圖的上半部分是需求價值流,可以看到他們開發的時候是一個需求一個需求地做,做完一個需求再做另外一個,因此可以看出這是一種持續交付需求的方式,針對一個需求會做相應的代碼變更,

與之相應的分支模式為GitHub—Flow,
在做特性開發的時候,只要做特性之間的隔離,但是可以做到持續發布,所以直接在Master上發布就好,因為是在Master上去發布,所以不會同時有兩個發布存在,
可以看到分支模式和發布流水線之間是強相關的,發布流水線會基于不同的分支來去做相應地事情,比如特性分支發生變化后,針對特性分支做相應的集成和驗證,通過后再合到Master上去做集成,完成集成后做相應的SIT(系統級別的驗證),然后再做部署,因此分支模式和發布流水線之間是強相關的,
這是持續發布的方式,

版本制發布模式常見于客戶端的發布,例如iOS或安卓,因為有一定的發布節奏,和上面的持續發布模式相比多了一個release分支,用來做版本發布用,從整體來看分支模式比較簡單,不建議用Git—Flow,可以對其適當進行裁剪,
研發模式的目的是減少代碼協作當中的沖突,減少等待,代碼之間的協作沖突有兩種,一是開發程序中的沖突和隔離,另一個是發布程序中的隔離,所以組合方式無非是:分支開發和主干發布、分支開發和分支發布、或是主干開發和分支發布等幾種,

這個例子初看和Git—Flow一樣,但是相對于Git—Flow,它有兩個變化,首先,它沒有release分支,它的發布表現為在主干上打Tag,第二,它的hotfix不合回主干,而是直接在hotfix上打Tag進行發布,這樣它就少了release分支,少了hotfix和master之間的同步,
整個分支模式有這樣一個特點,它有四種分支:feature分支、develop分支、master分支和hotfix分支,其中develop和master是長期分支,feature和hotfix是短期分支,開始開發的時候會拉一個feature分支,合并完成后消亡掉,如果是熱修復,會拉一個hotfix分支,hotfix分支永遠是從tag上創建的,之后創建tag,分支消亡,
所以長期分支就兩個,大部分的情況下hotfix就是feature分支,整個流程比Git—flow簡化很多,
分支模式實踐案例分析
分支模式是和產品的形態和團隊是強相關的,以下是幾個實踐案例,
1、P2P直播CDN產品

第一個案例是P2P直播CDN產品,左邊是它的架構圖,分為一個客戶端和一個服務端,客戶端是有多端的,比如手機、路由器、機頂盒等,每一種端的發布形式是不一樣的,終端,客戶端和服務端之間有兩條通信鏈路,一條是視頻資料的鏈路,另外一條是控制資料的鏈路,
服務端包括了三部分,控制面、用戶面,和資料、運營、監控等服務,每一塊都包含多個具體的應用,團隊成員物理上在一起,協作緊密,工程能力還可以,有單元測驗和功能自動化保證,基本上可以做到比較快的測驗反饋,
它有兩種應用:一個是服務端應用,一般golang、C++都是通過原始碼級構建依賴,運行時依賴配置中心,共30個左右應用,一次發布一個應用,每個應用是獨立發布,所以不存在發布的依賴性和編排問題,
另外一個是客戶端,一個代碼多端構建,無運行依賴,有的可以熱更新,有的需要通過應用市場發布,比如說iOS,所以發布頻率不太一樣,會導致長期有多個版本存在,那么,怎樣針對服務端和客戶端去做研發模式的設計?

首先看服務端,服務端是一個看上去比TBD還簡單的模式,因為人很少,服務拆得足夠小,幾乎每個服務同時只有1—2個人在修改,這樣的情況下就沒必要再用release分支,直接在主干上開發,基本上一個服務一個庫,而且這個服務拆得粒度很小,平均一個人大概是3、4個應用,這個服務是很小的,
這樣的情況下,它會有一些自己的紀律,比如因為要保證多端和客戶端多版本,代碼需要保證向前兼容,同時代碼是直接Push在Master分支上的,不存在合并等問題,在Master上一旦代碼提交會有對應的測驗,如果測驗失敗,提交者需要在一小時內修復,在Master上創建Tag即會視為一次發布,
如果出現問題,在最新代碼上修復,永遠發布最新的版本,這就是服務端的流水線,所以如果有類似的團隊建議可以嘗試一下,基本上來說如果做好紀律,可以做到很高效地發布,

客戶端基本上就是TBD的模式,平時還是主干開發,代碼在主干上集成,但是要發布的時候會拉一個release分支,因為客戶端的發布和升級比較困難,需要做足夠多的發布前驗證,這個情況下就需要release分支去保護,同時因為它會同時存在多個版本,所以需要在release分支上做bugfix,
但是,release分支還是要保持活躍數盡量地少,所以一般只關注最新的活躍的release分支,這樣TBD是一個非常合適的模式,針對發布它會做隔離,另外,因為一個版本需要保持一定時間的維護,所以需要一個相對長期的release分支,
2、基礎網路產品

它是在軟體層面做的虛擬化網路產品,很多外部做一些底層產品的公司會遇到這樣類似的產品,整個產品研發50人左右,分為5個團隊,每個團隊大概10個人,團隊間協作需求很高,一般都是一起發布、一起集成,但開發的時候是很多人一起開發的,
整個團隊工程能力中等,有單元測驗但是沒有其他測驗的保護,后面的測驗主要是靠具體的環境去測,開發的語言是C+和C++為主,部署到物理機或者虛擬機上,應用是一份代碼,多端構建,需要應對多種的硬體和作業系統,底層依賴Hypervisor和硬體,部署時可能需要停機,因為網路問題不是總能做到熱更新,一次部署一個應用,發布順序有要求,
如果有多個應用,應用間的發布有編排順序,它的發布周期很長,通常幾個月發布一次,同時會存在兩個都在發布的版本,比如一個版本發布了80%,另外一個版本發布了10%,

這個產品的release分支會更長,它的版本需要固定下來,要有明確的Tag,所以Master不能直接提交,永遠指向最后一個已發布的版本,但是整個開發其實是拉release去做,這個release可能會比較久,
在這邊做完以后,在release做完整的測驗和評審然后發布,完成后合進Master,這個類似于專案制,一個release相當于一個專案,從Master上創建出來以后,所有的開發和發布的作業都在這個release分支上,這個release分支就相當于專案的版本,發布完后release分支進入維護階段,Master在這里是作為一個穩定基線來管理的,
3、金融安全產品

這個產品一份代碼提供兩種交付形態,包括SaaS和私有化交付形態,整個應用架構比較簡單,包含一些后臺服務和API入口,以及一個管理和配置用的控制臺,后臺服務里面API會調很多其他的服務,比如設備指紋、指標計算、資料服務等,
這是典型的大資料場景,包括很多人工智能的產品都是類似的架構,整個團隊在150人左右,它的特點是前端、演算法、后端、測驗都有專門的職能團隊,但是沒有運維,
團隊之間通常需要協作才能完成一個要求,一般來說不會有一個需求落在某一個團隊,工程能力一般,沒有單元測驗和自動化功能測驗的守護,基本上是靠后續的人工測驗來去保證質量,
整個技術堆疊是以Java為主,K8s部署方式,另一個特點是二方包依賴較多,snapshot和release版本都有,運行時應用間有較強依賴,比如在API依賴了設備指紋,API依賴了指標計算,類似這樣的依賴其實很多,
整個應用數大概是20個,一個應用很多人協作,一次發布往往是一組應用或者是一個應用,SaaS版本落后私有化版本較多,

它和Git—Flow有點類似,區別是沒有Develop分支,release分支用來做了臨時的集成分支,Master是發布分支,永遠指向最新可發布版本,
作為私有化產品,有固定的版本節奏,一般一個月發布一個版本,于是每個月會拉一個release分支來做這個月的Feature分支的集成,集成完以后會合回Master去做發布,發布完打一個Tag,
所以在這里的release分支相當于一個迭代分支,整個測驗是比較長的周期,同時也要維護多個版本,因此會有多個并行的release分支存在,
通過這幾個例子可以發現,我們需要根據團隊和產品的特征來確定它的分支模式,在這些分支模式里面,我們都盡可能地減少分支,讓分支的維護成本低一點,因為每多一個分支意味著多一份維護成本,
除此以外,還有一些其他的場景,比如集成程序中,集成進去以后發現集成分支出現問題,需要把相應地代碼摘出來,很多的Feature分支合在一起,合并進去以后想再摘出來就很難,這種情況其實也可以用分支,比如臨時的集成分支解決,阿里內部的研發工具Aone,有一個分支模式叫Aoneflow,就可以解決相應的問題,
很多時候分支是可以很靈活地去使用的,但是靈活使用也會給程式員帶來特別多理解和維護成本,我們的建議是分支越簡單越好,另外盡可能地減少程式員的關注度,只關注在自己開發的分支上就好,這里給出幾點建議:
- 單主干:一個代碼倉庫應該保證有且僅有一個主干分支,像Gitflow里面Develop和Master就比較迷惑,
- 最少長期分支:避免沖突的前提下,盡量減少長期分支的數量
- Promotion(晉級):代碼的提交應該是逐級合并,如Feature–Develop-Master,是逐步地Promotion的程序,
- 發布不可變:發布的版本是不可變且可回溯的,可以根據Commit來追溯到你最早的源頭,
- 自動化事件觸發:分支的持續集成程序應該是自動化的,且通過代碼提交事件或制品變更事件自動觸發,
總結
- 團隊研發本質上是一個異步的、延遲協作的程序,隨著產品復雜度和團隊復雜度的增加,協作成本快速上升,
- 研發模式的本質是為高效交付需求,研發團隊圍繞代碼庫的一系列行為約束,
- 通過分支進行隔離,避免沖突;通過小批量頻繁提交,減少等待,
- 控制分支需要考慮最大化生產力及最小化風險,
- 分支的選擇需要綜合團隊規模、協作成熟度、產品交付形態幾個要素,
下一講,我們將進入可信發布篇,敬請期待,

點擊下方鏈接,免費體驗云效流水線Flow,
https://www.aliyun.com/product/yunxiao/flow?channel=yy_rccb_36

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/440445.html
標籤:其他
