前端小微團隊的Gitlab實踐

疫情期間我感受整我的懶散了很多,慢慢有意識要振做起來了,恢復到正常的節奏。最近團隊代碼庫從Gerrit遷移到了Gitlab,爲了讓前端團隊平常開發工做有條不紊高效運轉,開發歷史可追溯,我也查閱和學習了很多資料。參考業界主流的Git工做流,結合公司業務特質,我也梳理了一套適合本身團隊的Git工做流,在這裏作下分享。前端

分支管理

首先要說的是分支管理,分支管理是git工做流的基礎,好的分支設計有助於規範開發流程,也是CI/CD的基礎。git

分支策略

業界主流的git工做流,通常會分爲develop, release, master, hotfix/xxx, feature/xxx等分支。各個分支各司其職,貫穿了整個開發,測試,部署流程。我這裏也基於主流的分支策略作了一些定製,下面用一張表格簡單歸納下:shell

分支名 分支定位 描述 權限控制
develop 開發分支 不能夠在develop分支push代碼,應新建feature/xxx進行需求開發。迭代功能開發完成後的代碼都會merge到develop分支。 Develper不可直接push,可發起merge request
feature/xxx 特性分支 針對每一項需求,新建feature分支,如feature/user_login,用於開發用戶登陸功能。 Develper可直接push
release 提測分支 由develop分支合入release分支。ps: 應配置此分支觸發CI/CD,部署至測試環境。 Maintainer可發起merge request
bug/xxx 缺陷分支 提測後發現的bug,應基於develop分支建立bug/xxx分支修復缺陷,修改完畢後應合入develop分支等待迴歸測試。
master 發佈分支 master應處於隨時可發佈的狀態,用於對外發布正式版本。ps: 應配置此分支觸發CI/CD,部署至生產環境。 Maintainer可發起merge request
hotfix/xxx 熱修復分支 處理線上最新版本出現的bug Develper可直接push
fix/xxx 舊版本修復分支 處理線上舊版本的bug Develper可直接push

通常來講,develop, release, master分支是必備的。而feature/xxx, bug/xxx, hotfix/xxx, fix/xxx等分支純屬一種語義化的分支命名,若是要簡單粗暴一點,這些分支能夠不分類,都命名爲issue/issue號,好比issue/1,可是要在issue中說明具體問題和待辦事項,保證開發工做可追溯。npm

保護分支

利用Protected Branches,咱們能夠防止開發人員錯誤地將代碼push到某些分支。對於普通開發人員,咱們僅對develop分支提供merge權限。json

保護分支

具體操做案例請前往下面的實戰案例一節查看。bash

issue驅動工做

咱們團隊採用的敏捷開發協做平臺是騰訊的TAPD,平常迭代需求,缺陷等都會在TAPD上記錄。爲了讓Gitlab代碼庫能與迭代平常事務關聯上,我決定用Gitlab issues來作記錄,方便追溯問題。併發

里程碑

里程碑Milestone能夠認爲是一個階段性的目標,好比是一輪迭代計劃。里程碑能夠設定時間範圍,用來約束和提醒開發人員。ide

milestones

里程碑能夠拆解爲N個issue,新建issue時能夠關聯里程碑。好比這輪迭代一共5個需求,那麼就能夠新建5個issue。在約定的時間範圍內,若是一個里程碑關聯的全部issueClosed掉了,就意味着目標順利達成。gitlab

建立issue

標籤

Gitlab提供了label來標識和分類issue,我以爲這是一個很是好的功能。我這裏列舉了幾種label,用來標識issue分類緊急程度post

標籤管理

issue分類

全部的開發工做應該經過issue記錄,包括但不限於需求缺陷開發自測試用戶體驗等範疇。

需求&缺陷

這裏大概又分爲兩種狀況,一種是TAPD記錄在案的需求和缺陷,另外一種是與產品或測試人員口頭溝通時傳達的簡單需求或缺陷(小公司會有這種狀況...)。

對於TAPD記錄的需求和缺陷,建立issue時應附上連接,方便查閱(上文中已有提到)。

對於口頭溝通的需求和缺陷,我定了個規則,要求提出人本人在Gitlab上建立issue,並將需求或缺陷簡單描述清楚,不然口頭溝通的開發工做我不接(也是爲了不過後扯皮)。

ps:其實要求產品或者測試提issue,還不如上Tapd記錄。我定這麼個規則,其實就是借Gitlab找個說辭,杜絕口頭類需求或缺陷,哈哈。

開發自測試

開發者本身發現了系統缺陷或問題,此時應該經過issue記錄問題,並建立相應分支修改代碼。

自測試issue

實戰案例

我前面也說了,個人原則是issue驅動開發工做。

下面用幾個例子來簡單說明基本的開發流程。小公司裏整個流程比較簡單,沒有複雜的集成測試,多輪驗收測試,灰度測試等。我甚至連單元測試都沒作(捂臉...)。

公共庫和公共組件實際上是頗有必要作單元測試的,這裏立個flag,後面必定補上單元測試。

需求開發

feature/1,一個特性分支,對應issue 1

建立需求

正常的需求固然來源於產品經理等需求提出方,因爲是經過示例說明,這裏我本身在TAPD上模擬着寫一個需求。

TAPD建立需求

建立issue

建立Gitlab issue,連接到TAPD中的相關需求。

建立issue

一個issue

建立分支&功能開發

基於develop分支建立feature分支進行功能開發(要保證本地git倉庫當前處於develop分支,且與遠程倉庫develop分支同步)。

git checkout -b feature/1
複製代碼

或者直接以遠程倉庫的develop分支爲基礎建立分支。

git checkout -b feature/1 origin/develop
複製代碼

ps:我這裏用的feature/1做爲分支名,其實這裏的1是用的issue號,並無用諸如feature/login_verify之類的名字,是由於我以爲用issue號能夠更方便地找到對應的issue,更容易追蹤代碼。

接着咱們開始開發新功能......

快樂地擼代碼

commit & push

完成功能開發後,咱們須要提交代碼並同步到遠程倉庫。

PS D:\projects\gitlab\project_xxx> git add .
PS D:\projects\gitlab\project_xxx> git cz
cz-cli@4.0.3, cz-conventional-changelog@3.1.0

? Select the type of change that you're committing: feat: A new feature ? What is the scope of this change (e.g. component or file name): (press enter to skip) ? Write a short, imperative tense description of the change (max 94 chars): (9) 登陸校驗功能 ? Provide a longer description of the change: (press enter to skip) ? Are there any breaking changes? No ? Does this change affect any open issues? Yes ? If issues are closed, the commit requires a body. Please enter a longer description of the commit itself: - ? Add issue references (e.g. "fix #123", "re #123".): fix #1 git push origin HEAD 複製代碼

git cz是利用了commitizen來替代git commit。詳情請點擊前端自動化部署的深度實踐深刻了解。

fix #1用於關閉issue 1

git push origin HEAD則表明推送到遠程倉庫同名分支。

建立Merge Request

開發人員發起Merge Request,請求將本身開發的功能特性合入develop分支。

建立Merge Request

接着Maintainer須要Review代碼,確認無誤後贊成Merge。而後這部分代碼就在遠程Git倉庫入庫了,其餘開發同窗拉取develop分支就能看到了。

版本提測

issue/2,處理更新日誌,版本號等內容,對應issue 2

每一個團隊的開發節奏都不一樣,有的團隊會每日持續集成發版本提測,有的可能兩天一次,這個就不深刻討論了......

那麼當咱們準備提測時,應該怎麼作呢?

經過上節的瞭解,咱們已經知道,迭代內的功能需求都會經過feature/xxx分支合入到develop分支。

提測前,通常來講,仍是要更新下CHANGELOG.mdpackage.json的版本號,能夠由Maintainer或其餘負責該項事務的同窗執行。

主要是執行npm version major/minor/patch -m 'something done',具體操做能夠參考前端自動化部署的深度實踐一文。

git checkout -b issue/2 origin/develop
npm version minor -m '迭代1第一次提測'
git push origin HEAD
而後發起merge request合入develop分支
複製代碼

此時,應以最新的develop分支代碼在開發環境跑一遍功能,保證版本自測經過。

提測時,由Maintainer發起Merge Request,將develop分支代碼合入release分支,此時自動觸發Gitlab CI/CD,自動構建併發布至測試環境

版本提測後,各責任人應在TAPD上將相關需求和缺陷的狀態變動爲**「測試中」**。

修復測試環境bug

bug/3,一個bug分支,對應issue 3

這裏說的是在迭代週期內由測試工程師發現的測試環境中的系統bug,這些bug會被記錄在敏捷開發協做平臺TAPD上。修復測試環境bug的步驟與開發需求相似,這裏簡單說下步驟:

  1. 在Gitlab上建立issue

    建立issue,並附上TAPD上的缺陷連接,方便追溯

  2. 建立分支&修復缺陷

    基於develop分支建立分支:

    // 3是issue號
    git checkout -b bug/3 origin/develop
    複製代碼

    接着改代碼......

  3. commit & push

    PS D:\projects\gitlab\project_xxx> git cz
    cz-cli@4.0.3, cz-conventional-changelog@3.1.0
    
    ? Select the type of change that you're committing: fix: A bug fix ? What is the scope of this change (e.g. component or file name): (press enter to skip) ? Write a short, imperative tense description of the change (max 95 chars): (11) 修復一個測試環境bug ? Provide a longer description of the change: (press enter to skip) ? Are there any breaking changes? No ? Does this change affect any open issues? Yes ? If issues are closed, the commit requires a body. Please enter a longer description of the commit itself: - ? Add issue references (e.g. "fix #123", "re #123".): fix #3 git push origin HEAD 複製代碼
  4. 發起Merge Request

    開發人員發起Merge Request,請求將本身修復缺陷引入的代碼合入develop分支。

    而後Maintainer須要Review代碼,贊成本次Merge Request

  5. 等待迴歸測試

    bug將在下一次CI/CD後,進入迴歸測試流程。

  6. 級別高的測試環境Bug

    若是是級別很高的bug,好比影響了系統運行,致使測試人員沒法正常測試的,應以release分支爲基礎建立bug分支,修改完畢後合入release分支,再發起cherry pick合入develop分支。

發佈至生產環境

通過幾輪持續集成和迴歸測試後,一個迭代版本也慢慢趨於穩定,此時也迎來了激動人心的上線時間。咱們要作的就是把經過了測試的release分支合入master分支。

release合入master

這一步相對簡單,可是要特別注意權限控制(防止生產環境事故),具體權限控制能夠回頭看第一章節分支管理

release分支相似,master分支自動觸發Gitlab CI/CD,自動構建併發布至生產環境

線上回滾

revert/4,一個回滾分支,對應issue 4

代碼升級到線上,可是發現報錯,系統沒法正常運行。此時若是不能及時排查出問題,那麼只能先進行版本回退操做。

先說說慣性思惟下,個人版本回退作法。

首先仍是建立issue記錄下:

建立記錄回滾的issue

基於master分支建立revert/4分支

git checkout -b revert/4 origin/master
複製代碼

假設當前版本是1.1.0,咱們想回退到上個版本1.0.3。那麼咱們須要先查看下1.0.3版本的信息。

PS D:\tusi\projects\gitlab\projectname> git show 1.0.3
commit 90c9170a499c2c5f8f8cf4e97fc49a91d714be50 (tag: 1.0.3, fix/1.0.2_has_bug)
Author: tusi <tusi@xxx.com.cn>
Date:   Thu Feb 20 13:29:31 2020 +0800

    fix:1.0.2

diff --git a/README.md b/README.md
index ac831d0..2ee623b 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,8 @@

 只想修改舊版本的bug,不改最新的master

+1.0.2版本仍是有個版本,再修復下
+
 特性2提交

 特性3提交
複製代碼

主要是取到1.0.3版本對應的commit id,其值爲90c9170a499c2c5f8f8cf4e97fc49a91d714be50

接着,咱們根據commit id進行reset操做,再推送到遠程同名分支。

git reset --hard 90c9170a499c2c5f8f8cf4e97fc49a91d714be50
git push origin HEAD
複製代碼

接着發起Merge Requestrevert/4分支合入master分支。

回滾分支合入master

通常來講,這波操做沒什麼問題,能解決常規的回滾問題。

臨時變通

因爲master分支是保護分支,設置了不可push。若是不想經過merge的方式回滾,因此只能先臨時設置Maintainer擁有push權限,而後由Maintainer進行回滾操做。

git checkout master
git pull
git show 1.0.3
git reset --hard 90c9170a499c2c5f8f8cf4e97fc49a91d714be50
git push origin HEAD
複製代碼

完過後,還須要記得把master設置爲不可push

Q: 爲何不讓Maintainer一直擁有masterpush權限?

A: 主要仍是爲了防止出現生產環境事故,給予臨時性權限更穩妥!

git reset --hard存在什麼問題?

如題,git reset --hard確實是存在問題的。git reset --hard屬於霸道玩法,直接移動HEAD指針,會丟棄以後的提交記錄,若是不慎誤操做了也別慌,仍是能夠經過查詢git reflog找到commitId搶救回來的;git reset後還存在一個隱性的問題,若是與舊的branch進行merge操做時,會把git reset回滾的代碼從新引入。那麼怎麼解決這些問題呢?

束手無策

別慌,這個時候你必須掏出git revert了。

Q: git revert的優點在哪?

A: 首先,git revert是經過一次新的commit來進行回滾操做的,HEAD指針向前移動,這樣就不會丟失記錄;另外,git revert也不會引發merge舊分支時誤引入回滾的代碼。最重要的是,git revert在回滾的細節控制上更加優秀,可解決部分回滾的需求。

舉個栗子,本輪迭代團隊共完成需求2項,而上線後發現其中1項需求有致命性缺陷,須要回滾這個需求相關的代碼,同時要保留另外一個需求的代碼。

我太難了

首先咱們查看下日誌,找下這兩個需求的commitId

PS D:\tusi\projects\test\git_test> git log --oneline
86252da (HEAD -> master, origin/master, origin/HEAD) 解決衝突
e3cef4e (origin/release, release) Merge branch 'develop' into 'release'
f247f38 (origin/develop, develop) 需求2
89502c2 需求1
複製代碼

咱們利用git revert回滾需求1相關的代碼

git revert -n 89502c2
複製代碼

這時可能要解決衝突,解決完衝突後就能夠push到遠程master分支了。

git add .
git commit -m '回滾需求1的相關代碼,並解決衝突'
git push origin master
複製代碼

感受仍是菜菜的,若是大佬們有更優雅的解決方案,求指導啊!

修復線上bug

hotfix/5,一個線上熱修復分支,對應issue 5

好比線上出現了系統沒法登陸的bug,測試工程師也在TAPD提交了缺陷記錄。那麼修復線上bug的步驟是什麼呢?

  1. 建立issue,標題能夠從TAPD中的Bug單中copy過來,而描述就貼上Bug單的連接便可。

  2. 基於master分支建立分支hotfix/5

    git checkout -b hotfix/5 origin/master
    複製代碼
  3. 擼代碼,修復此bug......

  4. 修復完此bug後,提交該分支代碼到遠程倉庫同名分支

    git push origin HEAD
    複製代碼
  5. 而後發起cherry pick合入到masterdevelop分支,並在master分支打上新的版本tag(假設當前最大的tag1.0.0,那麼新的版本tag應爲1.0.1)。

修復線上舊版本bug

fix/6,一個線上舊版本修復分支,對應issue 6

某些項目產品可能會有多個線上版本同時在運行,那麼不可避免要解決舊版本的bug。針對線上舊版本出現的bug,修復步驟與上節相似。

  1. 建立issue,描述清楚問題

  2. 假設當前版本是1.0.0,而0.9.0版本出了一個bug,應基於tag 0.9.0建立fix分支。

    git checkout -b fix/6 0.9.0
    複製代碼
  3. 修復缺陷後,應打上新的tag 0.9.1,並推送到遠程。

    git tag 0.9.1
    git push origin tag 0.9.1
    複製代碼
  4. 若是此bug也存在於最新的master分支,則須要git push origin HEAD提交該fix分支代碼到遠程倉庫同名分支,而後發起cherry pick合入到master,此時很大可能存在衝突,須要解決衝突。

    cherry pick

cherry pick

在瞭解到cherry pick以前,我一直認爲只有git merge能夠合併代碼,也好幾回遇到合入了不想要的代碼的問題。有了cherry pick,咱們就能夠合併單次提交記錄,解決git merge時合併太多不想要的內容的煩惱,在解決bug時特別有用。

git rebase

通過這段時間的使用,我發現使用git merge合併分支時,會讓git logGraph圖看起來有點吃力。

PS D:\tusi\projects\gitlab\projectname> git log --pretty --oneline --graph
*   7f513b0 (HEAD -> develop) Merge branch 'issue/55' into 'release'
|\
| * 1c94437 (origin/issue/55, issue/55) fix: 【bug】XXX1
| *   c84edd6 Merge branch 'release' of host:project_repository into release
| |\
| |/
|/|
* |   115a26c Merge branch 'develop' into 'release'
|\ \
| * \   60d7de6 Merge branch 'issue/30' into 'develop'
| |\ \
| | * | 27c59e8 (origin/issue/30, issue/30) fix: 【bug】XXX2
| | | *   ea17250 Merge branch 'release' of host:project_repository into release
| | | |\
| |_|_|/
|/| | |
* | | |   9fd704b Merge branch 'develop' into 'release'
|\ \ \ \
| |/ / /
| * | |   a774d26 Merge branch 'issue/30' into 'develop'
| |\ \ \
| | |/ /
複製代碼

接着我就瞭解到了git rebase,變基,哈哈哈。因爲對rebase瞭解不深,目前也不敢輕易改用rebase,畢竟rebase仍是有不少隱藏的坑的,使用起來要慎重!在這裏先挖個坑吧,後面搞懂了再填坑......

注意事項

  1. 通常而言,本身發起的Merge Request必須由別的同事Review並贊成合入,這樣更有利於發現代碼問題。
  2. 對了,TAPD還支持與Gitlab協同的。詳情見源碼關聯指引

結語

實踐證實,這套Git工做流目前能覆蓋我項目開發過程當中的絕大部分場景。不過要注意的是,適合本身的纔是最好的,盲目採用別人的方案有時候是會水土不服的。

以上所述純屬前端小微團隊內部的Gitlab實踐,必然存在着不少不足之處,若有錯誤之處還請指正,歡迎交流。

歡迎關注&交流
相關文章
相關標籤/搜索