本文來自:
萬金 極狐(GitLab)解決方案專家
楊周 極狐(GitLab) 高級解決方案架構師
極狐(GitLab) 市場部內容團隊
我們提到的 Workflow 是指什麼?
我們在日常開發工作中提到的 Workflow 通常是指通過 Git(版本控制工具)實現的分佈式版本控制(distributed revision control),它允許多名軟件開發者,在不同的網絡環境下,參與同一個軟件開發項目。
這種工作模式,比集中式版本控制具有分佈式的特性與增量版本的明顯優勢,已經成為行業內主流版本管理方法。
Git 除了最基本的推拉代碼,還包括分支、tag、commit,其背後有很多最佳實踐,例如:
- 基於哪個分支派生出新分支?合併到哪裏去?
- 如何進行代碼評審?
- 使用快進、壓縮還是直接合並?
- 什麼階段,在哪個分支上創建 tag?
- 怎樣設置 Git commit 的格式規範?
這些最佳實踐的集合被稱為工作流(Workflow)。
Git 在 2005 年誕生,最初目的是為了更好地管理 Linux 內核開發而設計。Git 最初只是作為一個可以被其他前端包裝的後端應用而開發的,但後來 Git 內核已經成熟到可以獨立地進行版本控制。
僅有版本控制功能還不足以勝任代碼託管工作,隨後一款基於 Git 的在線源代碼託管服務平台 GitHub 於 2008 年 2 月上線。
隨着 2007 年持續集成(Continuous Integration)和 2009 年 DevOps 概念的流行,一站式 DevOps 研發平台 GitLab 於 2011 年誕生。
主流 Workflow 有哪些?
近年來,Workflow 基於各類平台快速發展。
用於 Linux 的內核版本管理工具 Git 推薦的工作流是 Git flow,源代碼託管平台 GitHub 推薦的是 GitHub flow,而 DevOps 研發平台 GitLab 的,則是 GitLab flow。
以上 3 個工作流並不存在好壞之分,只要可以幫助有效管理並行開發的軟件版本、實現團隊高效協同的,就是好的 Workflow。每個團隊都應該基於不同類型的應用開發場景,選擇最適合自己的。
點擊👉獲取一對一諮詢服務,選擇合適的workflow,讓研發工作事半功倍~
Git flow
Git flow 面向多版本長期維護和多版本同時發的開發模式,比如框架(Spring 2 和 3 共存)、編程語言(Node.js 18 LTS 和 19 共存)、開放 API(v1 和 v2 共存)、多客户定製版。
Git flow 並行開發模式非常複雜,作者本人也在 2020 年宣佈其「不適合持續交付」。
並行開發模式如下圖:
圖 1:Git flow 並行開發分支模型
圖中每個分支都有不同的使用場景和用途:
功能分支(Feature):開發人員以功能名稱命名一個分支,獨立於其他分支進行開發工作,完成開發後合併入共享開發分支。
共享開發分支(Develop):用於集成多個功能分支,一個版本全部功能開發完成後,可以拉出發佈分支進行發佈,而共享開發分支可以繼續進行下一個版本的開發工作。
發佈分支(Release):用於保存發佈過程中產生的代碼修改,發佈後會將代碼合併到共享開發分支和主分支。
熱修復分支(Hotfix):當某個正式版本出現緊急 bug 需要修復時,從主分支的對應版本拉出 Hotfix 分支,進行緊急修復,發佈後,合併回主分支。
主分支(Master):用於保存所有發佈的版本。
GitHub flow
做為一個代碼託管平台的分佈式版本管理模型,GitHub flow 相對簡單很多。
其經歷過多個版本更迭,V1.0:主幹開發、主幹發佈,V2.0:分支開發、主幹發佈。作為託管平台,GitHub Flow 對團隊約束性較低,難以在團隊內形成規範,適合人數較少的開源項目。
圖2:GitHub flow 分支模型(上圖為 V1.0,下圖為 V2.0)
GitLab flow
作為一站式 DevOps 平台,GitLab 在分佈式版本管理的能力與CI/CD 能力,已有較多完善功能,且在並行開發模型和研發治理方面的能力都相對比較成熟。
圖3:GitLab 與 GitHub 功能成熟度比較
在持續集成方面,GitLab 推出了一系列功能保障主幹分支的代碼質量:
- 對受保護分支的修改必須通過審批才能完成代碼合併;
- 通過代碼掃碼和自動化測試保證代碼質量的同時引入代碼評審,保證發佈的每一行代碼都是有質量保證的;
- 通過二進制倉庫作為 CI 與 CD 的銜接點,確保生產環境版本可追溯到對應源代碼。
圖 4:GitLab CI/CD 模式
GitLab flow 有三種推薦的 flow 模式:
- 環境分支 Environment branches with GitLab flow;
- 產品分支 Production branch with GitLab flow ;
-
發佈分支 Release branches with GitLab flow。
以環境分支為例:
圖 5:環境分支模型
每個分支使用場景如下:
- 主分支 Master:用於功能開發,每次代碼合併主分支都有流水線進行質量看護,保證主分支隨時可以發佈到準生產環境;
- 準生產環境 Pre-Production:用於進行功能與部署方法的測試,只有達到一定質量標準才能發佈到生產環境;
- 生產環境 Production:用於保存發佈的軟件版本。
似乎缺點什麼不是嗎?
對應以上三種主流 flow,基本可以覆蓋各類不同複雜度的項目。
- 複雜度 4,同時支持多個並行版本的成熟項目(Git flow):其作者文森特·德里森(Vincent Driessen)表示其過於複雜,不適合持續交付場景下使用;
- 複雜度 3,支持 DevOps 實踐與方法的多環境持續交付項目(GitLab flow):具備成熟的質量管控功能與持續交付能力;
- 複雜度 1,開源軟件的代碼託管(GitHub flow):基於代碼託管,模型比較簡單,可以快速交付,但難以形成研發規範。
圖 6:主流工作流複雜度對比
但,這全面了嗎?
如果我的企業,既需要敏捷快速迭代(如 GitHub Flow),也需要一定的研發規範、確保安全可控(如 GitLab Flow)呢?
極狐 flow
極狐 GitLab 研發團隊根據多年實踐經驗,推出了「極狐 flow」(JiHu flow),既簡單易上手(對應上圖,複雜度為 2),又兼具團隊研發規範性,非常適合在規範保障基礎上、強調敏捷創新、快速迭代的項目。
分支模型如下圖:
- 共享開發分支(Develop):用於集成功能分支的代碼,由於設置了保護分支,所以應根據需求創建特性分支,通過自動化流水線進行質量看護,經代碼評審後合入共享開發分支,同時默認刪除特性分支;
- 主分支(Master):用於正式版本和熱修復版本發佈。
圖 7:極狐 flow 分支模型
極狐 flow 全景圖
- 項目計劃:通過敏捷方式進行項目迭代;
- 代碼編寫:提交規則進行需求與代碼的關聯,從 Develop 分支創建特性分支保存功能編碼,代碼更新後觸發持續集成,符合質量要求的代碼進入代碼評審,減少質量風險,代碼負責人可以保證關鍵代碼修改的質量;
- 開發環境部署:將代碼合併到 Develop 分支,自動刪除需求分支,通過容器方式進行構建,鏡像存入二進制倉庫,完成部署後進行集成測試;
- 測試環境部署:將功能代碼從 Develop 分支合併至 Master 分支,自動化測試保證功能完整,通過動態安全檢查模擬安全演練,最後進行驗收測試;
- 生產環境發佈:通過評審觸發正式發佈過程,所有軟件發佈的過程,環境配置都存儲在代碼倉庫中,這是 GitLab 特有的 GitOps 實踐。
圖 8:JiHu flow 全景圖
極狐 flow 最佳實踐
分支命名規範
正則表達式(如果是小型項目,可省略 develop 分支):
main|develop|(\d+-(feature|bugfix|hotfix)-[A-Za-z0-9]+)分支示例:
master:主分支
develop:共享開發分支
1-feature-sms-deng-lu:需求分支
2-bugfix-sms-repeat:缺陷分支
3-hotfix-register-failed:熱修分支
其中數字為需求/缺陷的 ID,所以應當先創建需求/缺陷,再寫代碼,杜絕「口頭加需求」、「口頭報 bug」的情況。通過需求分支和合並請求草稿功能,可以方便地為需求人員創建需求分支,暫存代碼修改。
使用極狐 GitLab 創建需求/缺陷應使用「feature|bugfix|hotfix」開頭,可以一鍵創建符合規範的分支,開發人員再也不用為分支命名發愁。另外中文需求(issue)可自動轉化為拼音分支名,例如:Feature:SMS 登錄變為 1-feature-sms-deng-lu。
分支來源與合併
feature 和 bugfix 分支來自 develop,完成開發後應合併到 develop,且在合入後自動刪除 feature 和 bugfix 分支,減少過多的分支數量。
hotfix 分支來自 main,完成開發後應合併到 main,且在合入後自動刪除 hotfix 分支。
發佈時,將功能代碼從 develop 合併到 main,合併後不會刪除分支。
如果是小型項目,無 develop 分支,則 feature、bugfix 和 hotfix 分支都來自 main,也會合入到 main,合併後自動刪除多餘分支。
推薦使用快進式(Fast-forward)合併,而不推薦使用常規合併(產生一條冗餘 commit)。
如果 commit 有多條調試記錄,則應壓縮為一條,不得強制使用壓縮。
可通過極狐 GitLab「設置 → 合併請求」進行設置:
保護分支
所有的公共分支都必須被保護,包括公共開發分支 develop。
常見錯誤:保護了 master,而未保護 develop,大家隨意提交 develop,最後 develop 合併到 master,導致未經審核的代碼進入生產環境。
可通過極狐 GitLab「設置 → 倉庫 → 受保護分支」進行限制:
代碼評審
禁止將修改代碼直接合入分支,必須通過合併請求,由至少另一位開發者進行代碼評審,同意後才可合併。
評審必須在合併之前,合併後、上線後的評審只能稱為「技術分享」,而非「代碼評審」。
只在臨時分支(feature、bugfix、hotfix)合併到公共分支時進行評審,而不評審公共分支的互相合並(比如 develop 合併到 main,單向合併減少評審工作量)。
可通過極狐 GitLab「設置 → 合併請求 → 合併請求批准」實現代碼管控:
業務代碼中應使用規範掃描工具和配置文件,必須配置本地鈎子 .Git/hooks/pre-commit 執行掃描,進行強制檢查代碼規範。
如果項目配置了持續集成流水線,則應該用和本地一致的代碼規範進行檢查,持續集成流水線必須成功,才可以合併,這也是安燈實踐的要求。
代碼評審提出的評審建議,需要全部解決,才可以合併。
提交信息規範
Git commit 採用 Angular 規範,正則表達式:
(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert): #\d+ .+正確示例:
feat: #1 sms 登錄
fix: #2 sms repeat
fix: #3 register failed
英文前綴固定,後半部分可以寫漢字等多種語言的文字。
其中數字為需求/缺陷的 ID,所以必須先創建需求/缺陷,再寫代碼,杜絕「口頭加需求」、「口頭報 bug」的情況。
可通過極狐 GitLab「設置 → 倉庫 → 推送規則」中,設置正則表達式進行限制:
提交人員身份檢查
Git commit 時讀取了 Git config user.name 與 user.email,推送到服務器時必須至少校驗 email,杜絕「個人郵箱推送到公司項目」的情況。
可通過極狐 GitLab「設置 → 倉庫 → 推送規則」進行驗證:
禁止提交垃圾文件
禁止提交第三方包(比如 jar、node_modules、vendor)、編譯打包結果(比如 apk、exe、zip),以及任何大於 4MB 的文件。
建議使用 .Gitignore 進行配置,或者可通過極狐 GitLab「設置 → 倉庫 → 推送規則」進行限制:
tag 與版本號規範
採用 npm 和語義化規範,版本號不使用 v 前綴,而 Git tag 使用 v 前綴,避免純數字導致的問題,正則表達式:
v(\d+.){1,2}\d+示例:
v0.1
v1.2.0
v2.0.0
當提取 Git tag 用作 Docker、maven、npm 等版本號時,應在使用時去除 v 前綴,比如:
https://Github.com/nodejs/nod...
docker pull node:19.1.0
maven se.bjurr.violations:violations-maven-plugin:1.50.4
部署
推薦使用 GitOps 進行部署,即:
- 遵循「基礎設施即代碼」的理念,將 K8s yaml、微服務編排配置文件、Terraform 等文件保存於 Git 中,與業務代碼分開;
- 優先使用拉取式部署(無需公網 IP,更安全)而不是推送式部署;
- 藉助 Git 的合併請求進行上線審批,記錄可追溯。
功能開關
多個需求的代碼合併之後,在上線之前可能會遇到一個需求代碼有嚴重問題,來不及修復的情況,或者尚未到達業務部門的發佈時間(發佈會、節日促銷等)。此問題不應該從 git 角度解決,因為無論是剔除代碼,還是需求分支遲遲不合並,兩者的成本都比較高。此時推薦使用功能開關(Feature Flags)。
功能開關可以實現「AB 測試」和「先部署,後發佈」。研發人員提前部署,將產品功能發佈的權力,交給業務部門,提高了協作效率。
通過以上 10 個實踐,希望幫助所有創新類型的產品進行快速迭代,而又不必犧牲規範性與質量。如果是內部使用產品也可以進一步簡化分支模型,只使用 master 分支進行功能開發和版本發佈即可。
參考文檔
https://docs.Gitlab.cn/
https://about.Gitlab.com/why-...
https://forge.etsi.org/rep/he...