首頁

目前文章總數:157 篇

  

最後更新:2024年 12月 07日

0055. GitFlow分支策略開發 - 詳細實用範例

日期:2023年 11月 19日

標籤: C# Asp.net Core Web MVC Web Git GitHub

摘要:C# 學習筆記


使用軟體:TortoiseGit
範例檔案:範例Git
解決問題:遵循Git Flow分支策略時,會需要的操作
基本介紹:本篇分為五大部分。
     第一部分:架構切出
     第二-四部分:修復 / 開發 / 發布的實際操作流程
     第五部分:與Jenkins的持續部署流程
第一部分:基本GitFlow架構
第二部分:生產營運-緊急修復
第三部分:開發功能-開發階段
第四部分:開發功能-完成上版
第五部分:CICD部署






第一部分:基本GitFlow架構

Step 1:介紹 - 1

起源:2010年Vincent Driessen於Blog上發表的分支策略
優點如下:

優點 說明
1. 中心化 Git本身分散式,此策略由develop分支與master分支為主要分支,並且主要產品線為master
2. 版本管理 此策略有定義輔助分支包含:修復分支(hotfix)、上版分支(release)、開發分支(feature)
3. 支援同時多版本開發 該策略支援多個版本並行開發,只有開發完成的項目才從develop產生分支release,打上Tag,合併回Master與develop
4. 大型項目 適合大型產品,所有發版產品都有固定的Tag,只有開發完成的項目才會合併到master


缺點如下:

缺點 說明
1. 繁複的分支操作 分支操作複雜,需要遵守規範,知道各個分支的用途、何時刪除、合併時機。
2. 不適用於小型項目或敏捷開發 不適合持續異動的專案,尤其產品尚未發布前。
3. 不適合持續集成 因策略的關係,在輔助分支(feature、hotfix),因分支會刪除新增,CICD需增加維護成本
4. 可能導致長時間未合併的分支: feature同時開太多的情況下,會造成分支線混亂,使develop分支長時間未穩定



Step 2:介紹 - 2

GitFlow 最初的分支架構圖


Step 3:架構 - 準備1

可以自行註冊一個Github開始,建立一個Repository
※範例Repository name: Template


Step 4:架構 - 準備2

建立完成後,預設只有一個main,裡面是空的


Step 5:架構 - 準備3

為了更真實,建立一個Visual Studio Asp.net Core MVC WebSite 作範例


Step 6:架構 - 準備完成

完成後,預設資料已進入


Step 7:架構 - 切develop

這邊用工具TortoiseGit,優點是UI介面。
選擇Create Brach


Step 8:架構 - 切出完成

以main為head,讓develop與main平行


Step 9:架構 - 切換成develop

選擇Switch/Checkout


Step 10:架構 - 切換完成

選擇develop,切換完成


Step 11:架構 - 推送Push

將切出的分支推上到版控上(Github)



Step 11:架構 - develop完成

GitFlow的基本架構已完成,可從Github上看到最核心的分支master(main)與develop


Step 12:架構 - 切release

release為輔助分支,依照團隊的需要決定是否保留release分支
此範例多維護此分支,develop完成後,會先merge到release,
優點:可保留歷程,且CICD中有”預生產”環境時,可以使用此分支進行佈署。QA測試完成後,打上Tag,再進入master更新主產品線。
缺點:需維護此分支增加Merge的時間成本


Step 13:架構 - 完成release

此步驟與切出develop相似(Step7 -Step11),故省略,切出完成後可以看到3個分支


TortoiseGit 的圖形,可看到當前亦為3個分支


Step 14:建立初始版號 - 切換release

先切換到release版本


Step 15:建立初始版號 - 建立Tag-1

選擇Create Tag


Step 16:建立初始版號 - 建立Tag-2

建立Tag 1.0.0
GitFlow策略是從release建立Tag,表示測試完成可上生產的版本,才可合併至master


Step 17:建立初始版號 - 建立Tag-完成

推送至版控


Step 18:release合併回master - 1

切換到master分支,當Tag完成後,要接著將release合併回master


Step 19:release合併回master - 2

選擇merge


Step 20:release合併回master - 3

選擇tag 1.0.0 或者release 將會是相同的 (Hash值相同)

推送成功:


Step 21:release合併回master - 完成

最後將合併的結果進行推送,因為包含Tag所以需打勾 Include Tags

推送成功:




Step 22:架構完成

最後可以看Show Log可以確認第一版develop,release,master皆對齊Tag




第二部分:生產營運-緊急修復


Step 1:緊急修復 - 切換到master

GitFlow策略下,當master分支發生問題,需緊急修復的時候,才允許從master切出hotfix。
※緊急修復:問題小、且影響範圍不大,否則還是建議從develop切出release,完整驗證流程後才上master
切換到master分之下


Step 2:緊急修復 - 切出hotfix分支

切換到main後,建立hotfix分支,命名規則建議從main的最後Tag (版本來源)作為辨識

hotfix\{版本來源}




Step 3:緊急修復 - 切換到hotfix

切出hotfix後,要切換到hotfix上


Step 4:緊急修復 - 建立hotfix完成-1

切換後,Push到版控上,hotfix分支就建立完成了


Step 5:緊急修復 - 建立hotfix完成-2

可以從版控(Github))上確認,目前有4個分支


Step 6:緊急修復 - 模擬修復BUG

假設我們的Bug是welcome要改成歡迎光臨,進行調整


調整後簽入:

Push到hotfix上:


Step 7:緊急修復 - 修復完畢後

修復後,並且驗證正確,接著就要切換到master,準備進行合併(merge)


Step 8:緊急修復 - 合併到master

將hotfix代碼合併到master


Step 9:緊急修復 - 推送到master

合併完成後,推送到master上,master這便邊就處理完成



Step 10:緊急修復 - 推送到master

合併完成後,推送到master上,master這便邊就處理完成


Step 11:緊急修復 - 推送到develop

針對develop,也是依序以下步驟合併
1. 切換到develop分支
2. 將hotfix代碼合併到develop
3. 推送到develop上


Step 12:緊急修復 - 推送到release

針對release,也是依序以下步驟合併
1. 切換到release分支
2. 將hotfix代碼合併到release
3. 推送到release上


Step 13:修復完成 - 切換到master

修復完成後,並且3個分支 master、develop、release 都合併資料完成,接著需要在master上打上Tag版號
先切換到master


Step 14:修復完成 - 準備建立Tag

切換到master後,按下create tag


Step 15:修復完成 - Tag建立與說明

建立tag 1.0.1 ,因為我們是修復,所以在Patch 加1


補充說明版本號:

x.y.z <=> 1.0.0


對應變數說明:

變數 定義 說明
x 主版本號(Major) 代表著重大的更新或改變,通常是向後不相容的變更。當進行重大改進或者引入不相容的 API 變更時,應該提高主版本號。
y 次版本號(Minor) 代表著向後相容的新功能的添加。當引入了新功能,但這些新功能對現有功能不會造成破壞時,應該提高次版本號。
z 修訂號(Patch) 代表著向後相容的錯誤修正。通常,當進行錯誤修正時,應該提高修訂號。修訂號的升級表示引入了一些小的改進或者修復了一些錯誤,但不會對現有功能造成影響。




Step 16:修復完成 - Tag建立完成

建立完成後,再推送到版控(GitHub)即完成對master打上Tag的工作



Step 17:刪除hotfix分支 - 打開Show Log

已經打上Tag後,GitFlow策略中,輔助分支再不需要的時候應予以刪除,避免混淆主要分支。因此hotfix需刪除。


Step 18:刪除hotfix分支 - 執行刪除

依序選擇Develop -> remotes -> hotfix/1.0.0 -> Delete


Step 18:刪除hotfix分支 - 刪除完畢

可以看到提示訊息,真實刪除此分支

刪除後,如下所示:


Step 19:hotfix完成 - 最後確認

到Github上可以看到分支,已經沒有hotfix

檢視Tag,最新的是1.0.1:


第三部分:開發功能-開發階段

Step 1:開發新功能 - 切換到Develop

如果要展開新的功能開發(較大的內容,小的直接在develop分支改動是可以的),一律需從develop切出分支。
切換到develop分支


Step 2:開發新功能 - 準備建立feature分支

選擇create branch


Step 3:開發新功能 - 建立feature分支

建立feature分支,命名規則如下

feature\{建立功能的名稱}


此分支也是標記清除即可:


Step 4:開發新功能 - 切換到feature分支

建立完成後,同樣要先切換到該分支


Step 5:開發新功能 - 推送版控

Push到版控(Github),將此分支建立完成

Github的分支多了feature:


Step 6:開發功能 - 模擬開發

假設此feature是翻譯語言,我們做個調整。

然後提交:


Step 7:開發功能 - 開發完成

開發完成後,將代碼Push到feature分支上


Step 8:開發功能 - 切換到Develop

當feature所有功能都完成後,並且也自測完成,接著就可以Merge到develop
先切換到develop


Step 9:開發功能 - 進行merge

切換到develop後,選擇merge


Step 10:開發功能 - merge完成

將feature上的所有資料merge到develop (※如果要部份更新可以考慮cherry pick)


Step 11:開發功能 - 推送版控

merge完成後,推送到版控(Github)上的develop分支,開發週期就暫時告一段落了。

推送後,可以看到已更新develop內容:


Step 12:收尾 - 開發完成後將feature刪除

完成整個開發後,就可以將feature刪除

讓整個分支保持乾淨,只留下主要分支(master、develop、release),如下:


第四部分:開發功能-完成上版

Step 1:更新預生產 - 切換release

假設所有功能都告一段落,develop分支已驗證完成,那麼接著就可以合併到release


Step 2:更新預生產 - 合併代碼

切換到release後,需要將代碼從develop合併到release


Step 3:更新預生產 - 完成release

合併完成,推送到版控(Github),接著就可以透過CICD 建置這次的更新


Step 4:更新生產 - 切換master

預生產(release)驗證完成後,接著要推送生產,先切到master


Step 5:更新生產 - 合併代碼

release已經驗證完畢,所以代碼會是OK的,因此應該要從release合併代碼到master


Step 6:更新生產 - 完成master

合併完成,推送到版控(Github)

可以做個確認,release 與 master 一致


Step 7:更新生產 - 準備打上Tag

都完成後,為master打上Tag,確認這次穩定的版本可上生產


Step 8:更新生產 - 建立Tag

如果這個功能不是很大型,就可以考慮從 次版本號(Minor)加上1


Step 9:更新生產 - 完成Tag

最後進行推送版控(Github)到master分支上,記得要將Include Tag打勾,才會更新


Step 10:更新生產 - 發版生產

從Github上確認,Tag 1.1.0 已建立,這時就可以安心的發佈到生產環境


第五部分:CICD部署

Step 1:當前架構圖

從第一部分到第四部份,經歷過一系列操作後架構圖如下:


Step 2:Jenkins Job

這邊Jenkins 有建立好3個Job,分別對應develop、release、master


Step 3:develop開發環境 - 配置

在開發環境的develop分支,將分支設定為 */develop


Step 4:develop開發環境 - 建置

建置時,只有設定分支會自動建置該分支下最新版本的檔案


Step 5:release預生產 - 配置

在預生產環境的release分支,將分支設定為 */release


Step 6:release預生產 - 建置

建置時,只有設定分支會自動建置該分支下最新版本的檔案


Step 7:master生產 - 配置1

master需要透過Tag佈署,因此需要先參數化配置


Step 8:master生產 - 配置2

在生產環境的master分支,將分支設定為 refs/tags/${Tag}
表示只吃Tag值


Step 9:master生產 - 執行建置

建置時將版本號1.1.0帶入


Step 10:master生產 - 建置完成

可以看到有存在的Tag會進行建置

以下是示範執行不存在的Tag,9.9.9

將會出現錯誤