字節研發設施下的 Git 工做流

Git 提供了豐富的分支策略和工做流方式,咱們在深刻學習業界 Git 工做流時,每種工做流都設計的很是好,彷佛都能運用到團隊實踐。但在引入 Git 工做流規範開發時要留意:Git 工做流僅僅是整個研發流程中的一環。上游項目管理/缺陷追蹤系統虎視眈眈,下游 CD (Continuous Delivery) 嗷嗷待哺,還得考慮團隊規模、產品形態、發版方式等等因素。所以,在團隊中落地 Git 工做流規範並非一件能輕鬆決定的事。

html

字節跳動 Git 倉庫有效的 CR (Code Review) 覆蓋率 70%,仍有提高空間,經過調研,團隊中又以 GitHub Flow 模式居多。隨着字節研發效能建設愈發完善,GitHub Flow 已沒法充分利用研發設施進行提效並保障工程質量,不少團隊均意識到這點並着手建設流程規範。

本文經過介紹業界 Git 工做流和公司研發設施現狀,力求從倉庫形態、部署流程等多角度進行分析,給出一些制定工做流規範的建議。前端

業界 Git 工做流介紹

Git Flow

圖片來源:https://nvie.com/posts/a-successful-git-branching-model/

初級 Git 開發者,面對這滿圖的分支和 merge 指向,簡直想手撕做者。高級 Git 開發者要將這個流程運用實踐也大感頭疼。git

Git Flow 有很多優勢:github

  • 分支各司其職,覆蓋大部分開發場景。
  • 預期 master 分支中任何 commit 都是可部署的。
  • 嚴格按照流程執行,出現重大事故的情形會大大下降。

缺點也很多:後端

  • 過於繁瑣,沒法要求全部團隊成員按照這個流程嚴格執行。
  • 違反 git 提倡的 short-lived 分支原則。
  • master 分支歷史記錄並不乾淨,只能經過打 Tag 標記哪些是 master 真正要部署的。
  • 對持續部署和 monorepo 倉庫不友好。

GitHub Flow

GitHub Flow 是一個基於分支的輕量級工做流。它突出了 CR 的重要性,有助於咱們掌握 CR 的開發模式,但它沒有解答部署、環境、發佈、集成等問題。安全

圖片來源:https://guides.github.com/introduction/flow/index.html

GitLab Flow

GitLab Flow 並不像 Git Flow, GitHub Flow 同樣具備明顯的規範,它更可能是在 GitHub Flow 基礎上,綜合考慮環境部署、項目管理等問題而得出的一種實踐。markdown

基於環境:ide

圖片來源:https://docs.gitlab.com/ee/topics/gitlab_flow.html

基於發佈計劃:微服務

圖片來源:https://docs.gitlab.com/ee/topics/gitlab_flow.html

Trunk-based Flow

和「基於發佈計劃」的 GitLab Flow 相似,有一個主幹分支接受全部開發者的 commit,併爲後續 CI/CD 提供關鍵助力。oop

按照官方文檔描述:「你能夠選擇直接向主幹分支提交代碼的方式(適用於小團隊)或者採用 Pull-Request 的方式,只要保證特性分支不能長期存在,而且產品是獨立存在的。(the product of a single person.)」,trunk 分支提交是比較隨意的(不必定可部署),但也須要走 CR,能夠採用 Fast-forward 形式的 merge 保證主幹是一條線,到了合適的時間點,checkout release-* 分支,執行正式上線操做。

一旦發現 release 分支有 hotfix 需求,則先在 trunk 分支上進行 fix 開發,測試完成後,cherry-pick 到 release-* 分支,確保修復代碼即在 release-* 中上線,又能被下一個 release 週期包含。

圖片來源:https://paulhammant.com/2013/04/05/what-is-trunk-based-development/

Aone Flow

按阿里雲開發者社區描述:Aone Flow「基礎玩法是將每條發佈分支與具體的環境相對應,好比 release/test 分支對應部署測試環境,release/prod 分支對應線上正式環境」,這種發佈方式可保證每一個feature 都被測試,但不能保證 release/test CI 經過的 feature,能在 release/prod 環境也經過(feature pick 組合不一樣)。

「進階點的玩法是將一個發佈分支對應多個環境,好比把灰度發佈和正式發佈串在一塊兒,中間加上人工驗收的步驟」。實質是將基礎玩法中的「release/test」,「release/prod」 改爲 「release/combine-feature」,固定了 feature pick 組合,保證 features 在各個環境測試的一致性。

Aone Flow 的 pick 模式,適合複雜倉庫大團隊持續上線,避免了 Trunk-based Flow 引入未完成 feature 的問題。但彷佛不適合週期發版的要求。一個發版週期內會建立多個 feature ,上一個發版週期可能遺留若干 feature,隨着時間推移,feature 數愈來愈多,最終發版人在 pick feature 過程當中瘋掉。

圖片來源:https://developer.aliyun.com/article/573549

公司實踐

字節跳動的 Web 服務都跑在私有云 CE (Compute Engine) 中,部署產物則由統一的代碼編譯發佈和版本管理平臺分發,每一個構建產物都有一個 AR (Artifact Repository) 管理。

多環境部署現狀

服務端視角

服務端微服務跑在 CE 上,代碼編譯由 AR 完成,CE 和 AR 是 1:N 的關係,一個應用的運行依賴多個 AR,在進行環境管理時,須要以 CE 爲緯度來區分。

從 CE 視角來看,公司有 5 類環境(以國內產品爲例):

經過 headers -H 'x-env-tag:{env}' 將流量導向不一樣環境,知足「開發測試」、「QA測試」、「預發測試」、「小流量測試」、「全量上線」 各階段的測試需求。

CE 測試環境服務示例:

前端視角

前端和服務端有差別,一個 URL path 訪問的資源一般由一個 AR 產出,URL paths 和 AR 是 N:1 關係,因此前端部署以 AR 版原本區分環境:

前端部署可爲測試環境和產品預覽環境生成獨立的域名進行測試,也可經過設定 headers -H 'x-env-tag:{env}' 進行環境導流。

團隊實踐的 Git 工做流

結合先後端的環境現狀,可整理三類研發流程:

  1. 功能測試流程(測試環境)

  2. QA 提測流程(測試環境)

  3. 上線發佈流程(測試、預發、灰度、線上環境)

公司內目前有三種 Git 工做流與之對應:

  • 小步快跑:單主幹

  • 週期發版:雙主幹

  • 週期發版:三主幹

對比」雙主幹「和」單主幹「,

有聯繫:

  1. 處於 MR 狀態的迭代分支 ≈≈ 研發主幹 Dev

  2. 單主幹 Master ≈≈ 發佈主幹 Master

也有區別:

  1. 單主幹的「研發分支」不存在一個固定的測試環境(相較於雙主幹 dev 分支)
  2. 多個 feature 同時發測試環境時須要組合成新分支,管理不便
  3. 單主幹迭代分支在 MR /非 MR 狀態下的 CI 流水線有差別

單主幹實踐

前端微服務管理平臺

字節前端微服務平臺屬於成熟業務,只需作少許 feature/fix 開發,在工做流上採用單主幹模式。

本地測試後,再也不通過功能測試環境測試。發起 Merge Request,CR 經過合碼後,上測試基準環境進行測試,如發現問題,回滾,進入下一輪 CR。

雖然小修小改影響風險小,但流程缺少進入功能測試環境的流程,仍是存在隱患,有可能影響測試環境的業務方使用,不是很好的實踐。

單主幹只適應於業務規模小,成熟度高無大改動的項目。但不管業務規模如何,執行上線發佈流程前,都必須先通過線下環境驗證。

雙主幹實踐

私有云平臺

雲平臺的 Git 工做流是由繁入簡的過程。最開始爲每一個部署環境設定了一個部署分支。feature 分支的 commit 點須要和三個環境的部署分支發生 merge,起不到串聯測試的目的。

通過改進後,採用標準的 Trunk-based Flow,仍能知足 online/sandbox/boe 三個環境的部署要求。

雲平臺參與業務方有上百個(相似阿里雲平臺),雖然圖中僅展現了三個環境,但實際上5大環境的使用都融入了平常開發中。

某業務中臺

某業務中臺的 Git 工做流重點闡述了同一個項目多人協做開發時會遇到的問題:

  1. 多個 feature 各自獨立提測, 臨近上線合碼時有較多衝突, 可能致使線上 bug
  2. 提測前和提測中, 若是 master 更新了, 可能沒有及時同步下來, 上線前合入 master 可能會致使衝突或 bug
  3. 在流程設計上,master 做爲發佈分支,release-* 爲提測分支,結合了單主幹的便捷(hotfix 直接和 master 交互)和雙主幹對 feature 的管理
  4. 和 Trunk-based Flow 恰好相反,主分支是發佈分支,提測分支是短時間的
  5. 另外一個比較有特色的是,在 release 測試過程當中,發現某個 feature 的 bug, 直接從 release 分支 checkout 出來進行修復,並再次合入 release

Jupiter 工做流規範

Jupiter 是字節 Web 開發引擎,覆蓋 Web、組件庫、BFF、SSR 等前端開發領域。Jupiter 推薦 Trunk-based Flow 相似的 Flow,並從 CI/CD 角度出發,在開發新需求、hotfix 等時機給出 Git 操做建議。

  1. 有重疊人員參與的各項目之間有一致的流程和模式,避免增長認知負擔,避免同一我的在不一樣項目之間切換時混淆和迷惑,也能集中力量作實踐和改進,共享經驗和基礎建設。
  2. 上線節奏要靈活。既照顧早期的項目,也照顧規模化落地的項目,考慮到項目在追求不一樣里程碑時,上線頻率會有變化。因此每週上線一次、天天上線一次(適合人多、穩定性要求高的項目)、一天內分屢次上線多個 feature,都有可能,不能限定一個固定的節奏。任何人,在任什麼時候候均可以發起上線。
  3. 支持 monorepo。不一樣方向不一樣人蔘與的項目,可能會共用一個倉庫,方便複用代碼和基礎設施。因此倉庫中不一樣項目可能有不同的上線節奏和上線需求。
  4. 鼓勵持續集成(CI),集成不等同於部署,發 MR 集成代碼的時候不用有壓力,不會在不知情的狀況下被上線。也鼓勵持續部署(CD),部署不等於發佈,不能發佈的代碼,在正式上線前有機會關掉。
  5. 上線過程必須是固定、重複、能統一改進,能逐步增長自動化的,不能每次上線時從新、臨時規劃或修改上線方法,增長負擔和成本。
  6. CI 是 CD 的前提,沒通過 CI 的修改不能進入 CD 環節。
  7. 不能有任何修改不通過 staging(預發佈,儘量跟線上一致)測試,直接上線。
  8. CI 和 CD 的歷史記錄要絕對可靠、可追溯,只能增長,不能減小和修改。
  9. 儘量減小手動操做環節,避免在特定的我的機器上作上線操做。

三主幹實踐

億級 App

App 發版應該是目前爲止最爲複雜的分支管理場景了。客戶端安裝包一旦下發到渠道被用戶下載,若是沒法經過熱更新修復,將嚴重影響 App 用戶留存。

App 發版具備更規範的發版規律,Feature Toggle 必不可少,當咱們以爲 CR,CI/CD 麻煩時,對比開發上線一個影響上億用戶的 App feature,是否是感受作 Web 的 CI/CD 簡單多了?

總結

本文儘量從多角度闡述 Git 工做流的使用姿式,但願對你們有幫助。Git 工做流是爲了上線有保障,上線過程當中充分測試必不可少,良好的 Git 工做流能保障測試是漸進且可靠的。環境管理和 Git 工做流結合在頭條內部也造成了不少規範,包括「環境部署」、「流量調度」、「連通性測試」等使用規範;「限定場景容許」、「暫時場景容許」、「限定流程容許」等環境約束規範。再結合 CI/CD,咱們就能夠全鏈路保障業務的快速迭代、安全上線。

參考資料

  1. Trunk-based Development vs. Git Flow

  2. Please stop recommending Git Flow!

  3. Understanding the GitHub flow

  4. Introduction to GitLab Flow

  5. cn.trunkbaseddevelopment.com

  6. 在阿里,咱們如何管理代碼分支?

  7. 谷歌的代碼管理

歡迎關注「字節前端」

簡歷投遞聯繫郵箱「tech@bytedance.com

相關文章
相關標籤/搜索