(轉)在阿里,我們如何管理代碼分支?

阿里妹導讀:代碼分支模式的選擇并沒有絕對的正確和錯誤之分,關鍵是與項目的規模和發布節奏相匹配。阿里協同研發平臺在經過眾多實踐歷練后,總結出了一套獨創的分支管理方法:AoneFlow,通過兼備靈活高效與簡單實用的流程,保障阿里旗下眾多產品的交付。下面讓我們一起來深入了解。

引言

在阿里內部,流行著許多有意思的工程實踐。有些實踐通過工具和流程嵌在集團的大環境里,外界不容易復制,有些實踐則是流露在大家的日常習慣里,被默默的遵守。比如分支管理這件事,其實屬于工具和習慣各占一半,并且頗有阿里特色的成分,適合作為一個例子。阿里有很多的研發團隊,不同事業部使用的發布流程、分支策略并非整齊劃一,但總體上看是比較規整的。其中有一種主流的發布模式以及對應的分支使用方式,稱為“AoneFlow”。這套工作模式思路獨特,在阿里以外的地方并不多見。本文圍繞這些實踐,聊一聊分支管理的話題。

細數分支模式

說到分支管理模式,我們最耳熟能詳的莫過于 TrunkBased 和 GitFlow。

TrunkBased 模式是持續集成思想所崇尚的工作方式,它由單個主干分支和許多發布分支組成,每個發布分支在特定版本的提交點上從主干創建出來,用來進行上線部署和 Hotfix。在 TrunkBased 模式中,沒有顯性的特性分支。當然實際上 Git 的分布式特征天生允許每個人有本地分支,TrunkBased 也并非排斥短期的特性分支存在,只不過在說這種模式的時候,大家通常都不會明確強調它罷了。

雖然近年來有許多不錯的案例,但 TrunkBased 模式并沒有一統天下。太多的團隊同時工作在主干上,到發布的時候就可能出現災難(尤其是多版本并行開發的情況)。彌補的措施是 FeatureToggle 以及頻繁的集成和足夠的測試覆蓋,這對開發團隊的能力提出了比較高的要求。目前 TrunkBased 模式主要用在不需要同時維護多個歷史版本的 SaaS 型項目,特別是經過微服務改造的各種小型服務上。

TrunkBased 模式有兩種常見演進版本。OneFlow 模式參考了 TrunkBased 的許多思想,對操作流程做了更嚴格的定義,增加了 Hotfix 分支等內容。多主干模式(通常是雙主干,固定的開發分支和固定的發布分支),算是 TrunkBased 采用固定發布分支的特例。

GitFlow 模式是若干模式的集大成者,包含一個主干分支、一個開發分支、許多的特性分支、許多的發布分支和 Hotfix 分支,以及許多繁瑣的合并規則。它有一個 Git 插件,不過早就沒人維護了。由于對每個階段的每項操作定義十分明確,它曾經是很多重視流程的企業眼里的香饃饃。但它使用起來并不是很容易,大量的合并沖突和對集成測試不友好也是它被詬病最多的地方。

對,還有 GithubFlow 模式,不過這種策略無非是在 TrunkBased 的基礎上,增加了個人倉庫和 Pull Request 合并代碼的操作,與在同一個倉庫里增加個人分支的做法類似,從實用的意義來說,它更合適分布式團隊。GithubFlow 也有演進版本,例如強調了多環境部署和將倉庫或分支與環境關聯的 GitlabFlow 模式。

當然,代碼分支模式的選擇并沒有絕對的正確和錯誤之分,關鍵是與項目的規模和發布節奏相匹配。

另辟蹊徑的 AoneFlow

在 AoneFlow 上你能看到許多其他分支模式的影子。它基本上兼顧了 TrunkBased 的“易于持續集成”和 GitFlow 的“易于管理需求”特點,同時規避掉 GitFlow 的那些繁文縟節。

看一下具體套路。AoneFlow 只使用三種分支類型:主干分支、特性分支、發布分支,以及三條基本規則。

規則一,開始工作前,從主干創建特性分支。

AoneFlow 的特性分支基本借鑒 GitFlow,沒有什么特別之處。每當開始一件新的工作項(比如新的功能或是待解決的問題)的時候,從代表最新已發布版本的主干上創建一個通常以feature/前綴命名的特性分支,然后在這個分支上提交代碼修改。也就是說,每個工作項(可以是一個人完成,或是多個人協作完成)對應一個特性分支,所有的修改都不允許直接提交到主干。

img_84a9a0f87712850d7c278f6bd8a241f8.jpe
image

規則二,通過合并特性分支,形成發布分支。

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

img_1c708e4f162f49c1ccc45d25b2ff137a.jpe
image

這條規則很簡單,不過實際的玩法就相當豐富了。

首先,發布分支的用途可以很靈活。基礎玩法是將每條發布分支與具體的環境相對應,比如release/test分支對應部署測試環境,release/prod分支對應線上正式環境等等,并與流水線工具相結合,串聯各個環境上的代碼質量掃描和自動化測試關卡,將產出的部署包直接發布到相應環境上。進階點的玩法是將一個發布分支對應多個環境,比如把灰度發布和正式發布串在一起,中間加上人工驗收的步驟。高級的玩法呢,要是按迭代計劃來關聯特性分支,創建出以迭代演進的固定發布分支,再把一系列環境都串在這個發布分支的流水線上,就有點經典持續集成流水線的味道了。再或者做一個將所有特性分支都關聯在一起的發布分支,專門用于對所有提交做集成測試,就玩出了 TrunkBased 的效果。當然,這些花哨的高級玩法是我臆想的,阿里的發布分支一般都還是比較中規中矩。

其次,發布分支的特性組成是動態的,調整起來特別容易。在一些市場瞬息萬變的互聯網企業,以及采用“敏捷運作”的乙方企業經常會遇到這種情況,已經完成就等待上線的需求,隨時可能由于市場策略調整或者甲方的一個臨時決定,其中某個功能忽然要求延遲發布或者干脆不要了。再或者是某個特性在上線前發現存在嚴重的開發問題,需要排除。按往常的做法,這時候就要來手工“剔代碼”了,將已經合并到開發分支或者主干分支的相關提交一個個剔除出去,做過的同學都知道很麻煩。在 AoneFlow 的模式下,重建發布分支只是分分鐘的事,將原本的發布分支刪掉,從主干拉出新的同名發布分支,再把需要保留的各特性分支合并過來就搞定。這一系列動作能夠在很大程度上實現自動化,而且不會在倉庫留下一堆剔除代碼的記錄,干凈無污染。

此外,發布分支之間是松耦合的,這樣就可以有多個集成環境分別進行不同的特性組合的集成測試,也能方便地管理各個特性進入到不同環境上部署的時機。松耦合并不代表沒有相關性,由于測試環境、集成環境、預發布環境、灰度環境和線上正式環境等發布流程通常是順序進行的,在流程上可以要求只有通過前一環境驗證的特性,才能傳遞到下一個環境做部署,形成漏斗形的特性發布流。阿里有統一平臺來自動化完成特性組合在發布分支間的遷移,在下面講工具的部分里會再介紹。

規則三,發布到線上正式環境后,合并相應的發布分支到主干,在主干添加標簽,同時刪除該發布分支關聯的特性分支。

當一條發布分支上的流水線完成了一次線上正式環境的部署,就意味著相應的功能真正地發布了,此時應該將這條發布分支合并到主干。為了避免在代碼倉庫里堆積大量歷史上的特性分支,還應該清理掉已經上線部分特性分支。與 GitFlow 相似,主干分支上的最新版本始終與線上版本一致,如果要回溯歷史版本,只需在主干分支上找到相應的版本標簽即可。

img_18f1264409c7affc32bdf95d404dd3db.jpe
image

除了基本規則,還有一些實際操作中不成文的技巧。比如上線后的 Hotfix,正常的處理方法應該是,創建一條新的發布分支,對應線上環境(相當于 Hotfix 分支),同時為這個分支創建臨時流水線,以保障必要的發布前檢查和冒煙測試能夠自動執行。但其實還有一種簡便方法是,將線上正式環境對應的發布分支上關聯的特性分支全部清退掉,在這個發布分支上直接進行修改,改完利用現成的流水線自動發布。如果非得修一個歷史版本的 Bug 怎么辦呢?那就老老實實地在主干分支找到版本標簽位置,然后從那個位置創建 Hotfix 分支吧,不過由于阿里的產品大多是線上 SaaS 業務,這樣的場景并不多見。

正是這些簡單的規則,組成了 AoneFlow 獨樹一幟的核心套路。

AoneFlow 中每一個看似簡單的步驟都并非憑空臆造,而是經歷大量產品團隊反復磨礪后積累下來的經驗。接下來,我會說說 AoneFlow 的技術門檻以及阿里內部的應對之道。

AoneFlow 的體驗優化

諳熟武俠之道的人都懂得,掌握一個門派的看家武藝,除了要會招式,還得有深厚的內功和趁手的兵器。否則拿了辟邪劍譜,也只能望譜興嘆。

阿里團隊的內功和兵器,實際上是良好的代碼習慣和齊全的配套工具。

這里說的習慣,除了開發流程和代碼分支的管理方式以外,還包括日常開發中的一些約定俗成的規約。阿里的許多開發規約是有“文獻”記載的,主要收錄在 《阿里巴巴 Java 開發手冊》 里面。它的內容現在已經公開了,所以早就不算是秘密。

(注:在阿里技術公眾號回復“手冊”,即可免費下載《阿里巴巴 Java 開發手冊》)

舉一個具體的例子。在 AoneFlow 的流程中,每次重建發布分支的時候都會重新合并然后編譯代碼,產生新的部署包。然而,即使代碼的內容是一樣的,如果工程中依賴了一些會改變的第三方軟件包,依然可能導致打包出的產品行為不完全一致。因此,在阿里的代碼規約中就明確地指出了,用于線上發布的代碼,不可以使用包含“SNAPSHOT 版本”(即未正式發布版本)的依賴包,從而確保每次構建出的產物都是一致的。類似這樣的細節還有很多,好的開發習慣是確保軟件質量的必要前提。

工具可以使得團隊協作更加平滑。雖然只要弄懂原理,AoneFlow 中每個分支創建、合并、更改步驟使用單純的 Git 命令就能玩轉。但其中的一些操作(比如為每個發布分支選出恰當的特性分支組合進行合并)手工執行極易出錯,而且讓團隊的個人重復這些日常瑣事的命令操作,并不是令人愉悅的事情。

在阿里內部,使用 AoneFlow 流程的團隊基本上不用自己運行 Git 來處理分支的事情,而是由阿里巴巴集團內部名叫 Aone 的協同研發平臺(以下簡稱平臺)接管。這個承擔集團 80% 產品從需求和用戶故事提出到部署上線完整研發流程的平臺,內置了許多以服務組件的形式嵌入的研發提效工具,其中的發布組件為 AoneFlow 的用戶體驗添色不少。比較顯著的輔助“功效”包括以下幾個方面。

首先是整體流程的自動化。

由于是內部工具,平臺的功能高度內聚。對于項目而言,從提出原始需求,將需求拆分為任務,然后根據任務在線創建特性分支,再聚合生成發布分支,同時根據模板自動創建測試環境,直到后期的運維保障都可以一站式地搞定。

這個流程已經遠遠超出了代碼分支管理的范疇。但正是因為如此,平臺對于 AoneFlow,向前做到了將特性分支和需求項關聯起來,確保了特性分支的命名規范性;向后做到了將發布分支與部署行為關聯起來,確保了各環境版本來源的可靠性。打通了端到端交付的任督二脈。

其次是發布分支的流水線。

作為一種流程自動化的手段,CI/CD 流水線是許多現代交付團隊中常見的標配實踐。在 AoneFlow 的代碼生命周期里涉及許多分支,當這些分支被創建或更新時,往往需要伴隨其他的一系列行為。流水線能夠將這些日常開發過程中的代碼分支與其所表達的深層意圖(比如提交代碼即進行集成測試)聯系起來。特別是發布分支,AoneFlow 的每個發布分支通常關聯具體的部署環境,當有新代碼合并進分支時,就應該及時對代碼進行檢查和部署。

理想情況下,每條不同的分支都應該有與其作用相匹配的一條流水線來為它服務。AoneFlow 的發布分支是相對固定的,因此相比 GitFlow 更易于進行持續集成。理論上任何流水線工具都能夠配合 AoneFlow 使用,不過,阿里的統一平臺提供流水線對代碼評審、安全檢查、在線部署等功能的整合,還是為 AoneFlow 在內部團隊的使用優化增色不少。

還有一項很有用的輔助是分支關聯的管理。

特性分支與發布分支的關聯關系維護是一個 AoneFlow 特有的問題。記住每個發布分支分別來自哪些特性分支對于需要基于現有特性組合進行改變的時候十分有意義。比如當需要將某個特性從特定發布分支退出時,通常會將除了該特性以外的其他特性所在分支進行一次合并,以替換原有的發布分支。人為地記錄這些信息并不輕松,要是通過平臺進行展示和輔助就會方便許多。

當某些功能組合在一個低級別的發布環境(如集成測試環境)驗證完成后,我們希望將它的內容直接遷移到高級別的環境(如預發布環境)對應的發布分支上。這樣可以確保線上的版本一定是經過預發驗證的,預發的版本一定是經過集成驗證的,以此類推,使得各個發布分支形成串聯。同樣的,使用普通的 Git 命令就能實現這個操作,只不過用可視化工具會讓流程更加直觀。

除此以外,平臺提供代碼倉庫各個分支狀況的統一展示,包括分支所對應部署環境的機器信息、操作記錄等全都一覽無余。正是這些“高附加值”的輔助,使得 AoneFlow 得以揚長避短,成為阿里團隊支撐復雜項目首選的利器。

寫在最后

代碼分支模式的選擇并沒有絕對的正確和錯誤之分,關鍵是與項目的規模和發布節奏相匹配。阿里協同研發平臺在經過眾多實踐歷練后,總結出了一套獨創的分支管理方法,通過兼備靈活高效與簡單實用的流程,保障阿里旗下眾多產品的交付。當你還在猶豫于琳瑯滿目的分支模式,既舍不得 GitFlow 的并行特性開發,又放不下 TrunkBased 的持續集成友好時,AoneFlow 也許是一個值得考慮的選擇。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/390399.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/390399.shtml
英文地址,請注明出處:http://en.pswp.cn/news/390399.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

WIN10系統 截圖或者某些程序時屏幕會自動放大怎么辦

右擊這個應用程序,兼容性,以兼容模式運行,同時勾選高DPI設置時禁止顯示縮放即可

css背景圖片添加url_CSS背景圖片–如何向您的Div添加圖片URL

css背景圖片添加urlSay you want to put an image or two on a webpage. One way is to use the background-image CSS property. 假設您要在網頁上放置一兩個圖片。 一種方法是使用background-image CSS屬性。 This property applies one or more background images to an el…

golang基礎01

1.環境變量:go env//代碼目錄和第三方庫文件set GOPATHC:\Users\hanxiaodong\go//go安裝目錄set GOROOTC:\Gopath里要配置:goroot/bin;和gopath/bin; gopath目錄下三個文件夾:pkg:編譯好的庫文件 .a 文件bin:可執行文件…

hugo 能做web開發嗎_如何自托管Hugo Web應用

hugo 能做web開發嗎After hosting with Netlify for a few years, I decided to head back to self hosting. There are a few reasons for that, but the main reasoning was that I had more control over how things worked. 在Netlify托管了幾年之后,我決定回到…

資源 | 深度學習課程入門與介紹

【1】Andrew NG Deep Learning.ai http://deeplearning.ai/網易云課堂(中文字幕):http://mooc.study.163.com/smartSpec/detail/1001319001.htm推薦理由:Andrew Ng老師是講課的能手,很多人認識他是從Stanford的經典《機…

PostCSS 以及 cssnext語法

本文是對近兩天學習postcss的總結,在這里分享給大家。 如有錯誤,還請指正! 什么是postcss postcss 一種對css編譯的工具,類似babel對js的處理,常見的功能如: 1 . 使用下一代css語法 2 . 自動補全瀏覽器前綴…

5187. 收集足夠蘋果的最小花園周長

給你一個用無限二維網格表示的花園,每一個 整數坐標處都有一棵蘋果樹。整數坐標 (i, j) 處的蘋果樹有 |i| |j| 個蘋果。 你將會買下正中心坐標是 (0, 0) 的一塊 正方形土地 ,且每條邊都與兩條坐標軸之一平行。 給你一個整數 neededApples &#xff0c…

虛擬機 VMware Workstation12 安裝OS X 系統

Windows下虛擬機安裝Mac OS X —– VMware Workstation12安裝Mac OS X 10.11本文即將介紹WIN虛擬MAC的教程。完整詳細教程(包含安裝中的一些問題)【并且適用其他mac os x版本】Windows下 VM12虛擬機安裝OS X 10.11(詳細教程) 工具/原料 Mac OS X 10.11 鏡…

aws dynamodb_DynamoDB備忘單–您需要了解的有關2020 AWS認證開發人員助理認證的Amazon Dynamo DB的所有信息

aws dynamodbThe emergence of cloud services has changed the way we build web-applications. This in turn has changed the responsibilities of a Web Developer. 云服務的出現改變了我們構建Web應用程序的方式。 反過來,這改變了Web開發人員的職責。 We use…

北大CIO走進龍泉寺交流研討會圓滿舉行

緣起 2016年4月16日,北京大學信息化與信息管理研究中心秘書長姚樂博士與國家非物質文化遺產蔚縣剪紙傳承人周淑英女士一起在龍泉寺拜見了中國佛教協會會長、龍泉寺主持學誠法師。在拜見學誠法師時,姚樂博士與學誠法師聊到了“賢二機器僧”和人工智能。姚…

負載均衡種類

http://blog.csdn.net/zhoudaxia/article/details/23672319DNS DNS輪詢是最簡單的負載均衡方式。以域名作為訪問入口,通過配置多條DNS A記錄使得請求可以分配到不同的服務器。DNS輪詢沒有快速的健康檢查機制,而且只支持WRR的調度策略導致負載很難“均衡”…

代碼流星雨是什么形式_為什么要在2020年與流星合作

代碼流星雨是什么形式Meteor, an allegedly dead development platform, is still alive and can bring massive value to your everyday coding experience.Meteor,據稱已失效的開發平臺,仍然有效,可以為您的日常編碼體驗帶來巨大的價值。 …

Centos7 Docker私有倉庫搭建

Centos7 Docker私有倉庫搭建 倉庫:集中存放鏡像的地方,可分為公共倉庫和私有倉庫(公共倉庫"http://hub.docker.com"或國內的"http://www.daocloud.io") Registry:注冊服務器才是存放倉庫具體的服務…

MySQL觸發器使用詳解

MySQL包含對觸發器的支持。觸發器是一種與表操作有關的數據庫對象,當觸發器所在表上出現指定事件時,將調用該對象,即表的操作事件觸發表上的觸發器的執行。 創建觸發器在MySQL中,創建觸發器語法如下: 代碼如下: CREATE…

java中訪問修飾符_Java中的訪問修飾符介紹

java中訪問修飾符什么是訪問修飾符? (What are Access Modifiers?) Have you ever wanted to define how people would access some of your properties? You would not want anyone using your underwear. However, your close friends and relatives can use yo…

VIM 編輯器

2019獨角獸企業重金招聘Python工程師標準>>> VIM 相對于VI 的提升 VIM 支持多級撤銷VIM 可以跨平臺運行VIM 支持語法高亮VIM 支持圖形界面VIM 編輯器的操作模式 Command Mode -命令模式Insert Mode -輸入模式Last Lin Mode -底行模式#使用yum 命令安裝vim 軟件&…

/etc/profile、/etc/bashrc、~/.bash_profile、~/.bashrc 文件的作用

轉載自:http://blog.csdn.net/u013968345/article/details/21262033 /etc/profile:此文件為系統的每個用戶設置環境信息,當用戶第一次登錄時,該文件被執行. 并從/etc/profile.d目錄的配置文件中搜集shell的設置. /etc/bashrc:為每一個運行bash shell的用戶執行此文件…

python初學者_終極Python初學者手冊

python初學者Python has become one of the fastest-growing programming languages over the past few years. 在過去的幾年中,Python已成為增長最快的編程語言之一。 Not only it is widely used, it is also an awesome language to tackle if you want to get …

z-index

z-index 這個東西非常簡單,它有四大特性,每個特性你記住了,頁面布局就不會出現找不到盒子的情況。 z-index 值表示誰壓著誰,數值大的壓蓋住數值小的,只有定位了的元素,才能有z-index,也就是說,不…

大型運輸行業實戰_day12_1_權限管理實現

1.業務分析 權限說的是不同的用戶對同一個系統有不同訪問權限,其設計的本質是:給先給用戶分配好URL,然后在訪問的時候判斷該用戶是否有當前訪問的URL. 2.實現 2.1數據庫設計標準5表權限結構 2.2.sql語句實現,根據用戶id查詢該用戶所有的資源 sql語句: SELECT ur.user_id, r.u…