分支模型
We firmly believe that long-lived version-control branches harm valuable engineering practices such as continuous integration, and this belief underlies our dislike for Gitflow.
—— ThoughtWorks Technology Radar 2015 Nov
Gitflow 是由 Vincent Driessen 在2010年提出的基于 Git 的軟件開發(fā)工作流,但與持續(xù)集成(Continuous Integration,CI)的實(shí)踐有不少沖突的地方,在團(tuán)隊(duì)開發(fā)中不推薦采用,具體分析可以參見 Gitflow有害論 。

我們采用單主干開發(fā)的 Git 分支模型(Trunk Based Development),所有的開發(fā)工作均在 master 分支上進(jìn)行,同時(shí)利用 CI 流水線進(jìn)行持續(xù)集成,保證 master 中的代碼隨時(shí)都可以發(fā)布到生產(chǎn)。除了利用 master 進(jìn)行開發(fā),我們利用 release 分支進(jìn)行發(fā)布的跟蹤。

持續(xù)發(fā)布流水線
除了持續(xù)集成(CI),項(xiàng)目還涉及自動化測試與持續(xù)部署(Continuous Deployment,CD) 因此,我們會有開發(fā)環(huán)境與測試環(huán)境,而測試環(huán)境又可以分為 SIT 測試、UAT 測試與壓力測試等等。那么代碼應(yīng)該在什么時(shí)候發(fā)布,發(fā)布什么樣的版本,這些版本又如何追蹤,發(fā)現(xiàn) bug 之后如何處理呢?

我們的流水線模型如上圖所示,采用單主干開發(fā)策略。
所有的開發(fā)人員都在 master 分支提交代碼,每次提交都觸發(fā) CI 構(gòu)建,并在 CI 環(huán)境執(zhí)行自動化測試,測試通過之后可以由測試人員發(fā)布到 SIT 環(huán)境并進(jìn)行測試。
發(fā)布人員根據(jù)項(xiàng)目進(jìn)度,選取合適并通過 SIT 測試的 commit 節(jié)點(diǎn),打上 tag 作為 SNAPSHOT 版本,并合并到 release 分支,在release分支中采用 RC (Release Candidate) 標(biāo)記版本。
-
將 RC 版本發(fā)布到 UAT 環(huán)境進(jìn)行測試,如果測試通過則發(fā)布到生產(chǎn)環(huán)境并將該版本標(biāo)記為 release 版本,如果測試發(fā)現(xiàn) bug:
- 將該 RC 版本標(biāo)記為不可靠。
- 回滾到上一個(gè)可靠版本。
- 在 master 分支進(jìn)行修復(fù),并 cherry pick 到 release 分支,并標(biāo)記新的 RC 版本號。
- 如果 master 分支有新的 commit 提交而不能重現(xiàn) bug,則從原始 commit 節(jié)點(diǎn)拉取 hot-fix 分支,bug 修復(fù)完成后,cherry pick 到 release 分支,標(biāo)記新的 RC 版本號,并將 hot-fix 上的修改 merge 到 master。
在 release 分支選擇 RC 標(biāo)記版本,主要理由如下:
- 假如在 release 分支采用 SNAPSHOT 版本并部署到 UAT 環(huán)境,由于 SNAPSHOT 可以不斷被覆蓋,我們無法回滾到前幾次 hot fix 產(chǎn)生的 SNAPSHOT 版本。
- 加入使用 release 版本:由于每次 hot fix 產(chǎn)生一個(gè)新的 release 版本,但這個(gè)版本并沒有通過 UAT 測試驗(yàn)證,如果驗(yàn)證失敗,就屬于不可靠版本,與 release 版本的原始語義相違背。
- 選用 RC 版本,每次 hot fix 都產(chǎn)生一個(gè)新的 RC 版本,部署到 UAT 發(fā)現(xiàn)問題之后,可以快速回滾到上個(gè) RC 版本或者 release 版本;如果驗(yàn)證該 RC 版本不可靠,可以立即對其做不可靠標(biāo)記。我們只對可靠的 RC 版本標(biāo)記為 release 并部署到生產(chǎn)環(huán)境。
在 master 修復(fù) bug 之后,選擇 cherry-pick 而非 merge 的理由如下:
對于團(tuán)隊(duì)而言,發(fā)布人員在合并 master 到 release 之后,開發(fā)人員可以繼續(xù)開發(fā)新的feature,這個(gè)時(shí)候 release 和 master 是有區(qū)別的。bug 修復(fù)完成之后,直接 merge 到 release 分支有可能在發(fā)布版本引入還沒有測試的新的 feature,甚至是還沒有完成的 feature,這是我們不想看到的。因此,我們只需要 cherry pick 修復(fù) bug 的有關(guān) commit 到 release 分支。