摸索前端管理2年,這份研發(fā)流程幫到我不少

在現(xiàn)在的公司工作也有2年多了,時(shí)間過(guò)得真快!2年的時(shí)間里,前端從單兵作戰(zhàn)發(fā)展到現(xiàn)在的10人規(guī)模。如果要我說(shuō),這個(gè)過(guò)程里什么最重要?我想應(yīng)該是一份接地氣的研發(fā)流程。
說(shuō)到研發(fā)流程,大部分人肯定首推某某某大廠的研發(fā)流程。誠(chéng)然,大廠的研發(fā)流程的確完善并且細(xì)致,然而實(shí)際上并不一定適用于其他公司或團(tuán)隊(duì),比如QA、單元測(cè)試、自動(dòng)化測(cè)試這些環(huán)節(jié),我想很多公司都不會(huì)有。所以,盲目地套用別的公司或者團(tuán)隊(duì)的研發(fā)流程,是可能水土不服的,但是卻可以給我們提供一個(gè)參考意見(jiàn),去彌補(bǔ)自身的不足。
研發(fā)流程一定不是憑空出現(xiàn)的,它必須緊密貼合實(shí)際的項(xiàng)目過(guò)程。我很重視這塊,在我還是“光桿司令”的時(shí)候,我就在籌備著。我當(dāng)時(shí)的想法是,等我這個(gè)組進(jìn)人的時(shí)候,我一定不是手把手告訴他做項(xiàng)目的每一步該怎么做,而是用標(biāo)準(zhǔn)化的文檔把整個(gè)大致過(guò)程記錄下來(lái),另外也是想要告訴我未來(lái)的同事,我這個(gè)團(tuán)隊(duì)是有思考和沉淀的,值得大家一起成長(zhǎng)!
研發(fā)流程一定不是完美的,但它一定是與時(shí)俱進(jìn)的。我回顧了一下這份文檔,前前后后修改了不下100次。

接下來(lái)針對(duì)前端研發(fā)流程這塊分享一下我們的實(shí)踐,希望給有需要的朋友一點(diǎn)幫助!
整體流程
團(tuán)隊(duì)整體的一個(gè)研發(fā)流程大致如下:

這塊可能大部分公司都是大同小異,沒(méi)什么好細(xì)說(shuō)的。實(shí)際上,可能每個(gè)環(huán)節(jié)是否執(zhí)行到位也是需要打個(gè)問(wèn)號(hào)的。

前端研發(fā)流程
系統(tǒng)鏡像
為了方便新入職同事快速進(jìn)入狀態(tài),我們制作了統(tǒng)一的前端開(kāi)發(fā)系統(tǒng)鏡像,避免了出現(xiàn)電腦裝機(jī)和各種環(huán)境配置出現(xiàn)的問(wèn)題,產(chǎn)生一些不必要溝通而浪費(fèi)時(shí)間。
最早的時(shí)候,還是我出的一個(gè)簡(jiǎn)單的文檔,告訴新同事要裝什么什么軟件這樣子,但是發(fā)現(xiàn)問(wèn)題還是挺多,用了鏡像后,省心不少。
前端研發(fā)流程圖

這張圖描述了前端日常開(kāi)發(fā)的主要過(guò)程,可以花個(gè)1到2分鐘好好看看。
研發(fā)資源
原型設(shè)計(jì): axure視覺(jué)設(shè)計(jì):藍(lán)湖, iconfontapi文檔: swagger敏捷協(xié)作: TAPD,研發(fā)日常的任務(wù),需求,缺陷等工作都集中在TAPD[1]平臺(tái)上。源碼倉(cāng)庫(kù):自建 Gitlab團(tuán)隊(duì)文檔:語(yǔ)雀
處理IconFont圖標(biāo)
在圖標(biāo)管理這塊,我們使用的是 iconfont,包括字體圖標(biāo)和矢量圖標(biāo)都有用到,并且封裝了對(duì)應(yīng)的組件icon-font和icon-svg,目前主要以使用icon-svg為主,icon-font主要面向部分項(xiàng)目。

在 iconfont 上調(diào)整好圖標(biāo)后,需要重新生成鏈接;
對(duì)于字體圖標(biāo)組件 icon-font,生成在線的 font class 鏈接,替換掉項(xiàng)目中 index.html 中的對(duì)應(yīng)鏈接才會(huì)生效。

對(duì)于矢量圖標(biāo)組件 icon-svg,生成在線的 symbol 鏈接,替換掉 icon-svg 組件中引用的 js 鏈接才會(huì)生效。

issue驅(qū)動(dòng)
雖然git log已經(jīng)提供了記錄查詢(xún)的能力,但是還不夠便捷,直觀。
我們采用issue驅(qū)動(dòng)開(kāi)發(fā),所有的代碼改動(dòng)都應(yīng)該先在gitlab創(chuàng)建issue,包括但不限于需求,缺陷,自測(cè)試,優(yōu)化類(lèi)改動(dòng)。
commit是可以自動(dòng)關(guān)聯(lián)和關(guān)閉issue的,這樣一來(lái),我打開(kāi)每一個(gè)issue,就知道這個(gè)issue關(guān)聯(lián)了哪些代碼提交記錄,查問(wèn)題非常直觀!另外,這也是眾多開(kāi)源項(xiàng)目常見(jiàn)的協(xié)作方式。

對(duì)于需求、缺陷類(lèi)型的開(kāi)發(fā)任務(wù),應(yīng)在創(chuàng)建issue時(shí)附上TPAD相關(guān)鏈接,方便跳轉(zhuǎn)查詢(xún)。
issue應(yīng)該保證原子性,一個(gè)issue只做一件事。
開(kāi)發(fā)流程
VSCode擴(kuò)展
首先,安裝必要的 VSCode 擴(kuò)展,結(jié)合項(xiàng)目中配置的 Lint/Formatting 能力,達(dá)到一個(gè)高效開(kāi)發(fā)的狀態(tài)。




全局依賴(lài)
// 保證 yarn 的正常使用
npm install -g yarn
// 用于規(guī)范 commit 提交
npm install -g commitizen
npm install -g conventional-changelog-cli
npm/yarn代理
npm 自帶的源有時(shí)候速度太慢,或者有時(shí)候根本下載不了某個(gè)包,容易導(dǎo)致 install 失敗或停頓,請(qǐng)統(tǒng)一使用 taobao 代理。
npm config set registry https://registry.npm.taobao.org
// 部分項(xiàng)目使用yarn
yarn config set registry https://registry.npm.taobao.org
Nginx代理配置
我們?cè)陂_(kāi)發(fā)者本地使用 Nginx 作為中間代理,加一層本地 Nginx 代理的目的是:
統(tǒng)一項(xiàng)目訪問(wèn)的服務(wù)端口,防止誤提交項(xiàng)目配置文件,避免不必要的代碼沖突。 便于切換不同環(huán)境時(shí),實(shí)現(xiàn)秒級(jí)切換,不用重啟 devServer。后面這里可以?xún)?yōu)化下,據(jù)我觀察,ant-design-pro 實(shí)現(xiàn)了不重啟 devServer 更新 proxy,有空研究下! 如果比較反感,不強(qiáng)制增加本地 Nginx 這一層,可以自行指定后端 gateway 地址,但是注意不要提交 vue.config.js 文件,避免引起沖突!
下載windows穩(wěn)定版本Nginx,鏈接是http://nginx.org/en/download.html[2]

修改nginx/conf/nginx.conf
一個(gè)基本的代理配置如下:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#gzip on;
server {
listen 8090;
server_name 127.0.0.1;
location / {
proxy_pass http://xxx.xxx.tech;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
nginx 統(tǒng)一監(jiān)聽(tīng) 127.0.0.1:port,代理請(qǐng)求到后端 gateway。在需要切換環(huán)境時(shí)只需要修改 proxy_pass 這一項(xiàng)即可。
前端工程默認(rèn)配置 proxy 的 target 為
http://127.0.0.1:port,配合Nginx使用時(shí),不要修改此項(xiàng)。常見(jiàn)命令
#linux中
#開(kāi)機(jī)啟動(dòng)
systemctl enable nginx
#啟動(dòng)
systemctl start nginx
#重啟
nginx -s reload
#windows中
#啟動(dòng)
直接打開(kāi)nginx.exe
#重啟
修改配置文件后重啟,可以選擇cmd打開(kāi)根目錄,然后nginx.exe -s reload
#其他
如果重啟有問(wèn)題,一般是點(diǎn)擊了多次nginx.exe,這時(shí)候可能啟動(dòng)了多個(gè)nginx,算是個(gè)windows版本的bug吧,
可以直接打開(kāi)任務(wù)管理器找到所有nginx進(jìn)程,然后結(jié)束掉。最后直接打開(kāi)nginx.exe啟動(dòng)。
關(guān)于這一環(huán)節(jié),我之前還寫(xiě)過(guò)一篇「前端必看」這篇Nginx反向代理技巧,助你準(zhǔn)時(shí)下班陪女神,想要詳細(xì)了解的朋友可以打開(kāi)看看。
項(xiàng)目依賴(lài)安裝
目前有的項(xiàng)目使用npm管理依賴(lài),有的使用的是yarn。進(jìn)入項(xiàng)目時(shí),觀察lock文件,如果項(xiàng)目根目錄有yarn.lock,則說(shuō)明使用yarn;如果項(xiàng)目有package-lock.json,說(shuō)明使用npm。
安裝依賴(lài)時(shí)根據(jù)情況執(zhí)行以下命令:
npm
npm install
yarn
yarn
需求/缺陷分配
TL負(fù)責(zé)任務(wù)分配,將TPAD上的需求進(jìn)行分配,指定開(kāi)發(fā)責(zé)任人。
TAPD的需求分發(fā)到個(gè)人后,都要求開(kāi)發(fā)人員拆分出前端子需求(不限于1個(gè)),根據(jù)自身能力和需求復(fù)雜度評(píng)估出開(kāi)發(fā)時(shí)間規(guī)模,根據(jù)自己的排期填寫(xiě)預(yù)估起始時(shí)間和結(jié)束時(shí)間,項(xiàng)目經(jīng)理會(huì)追這個(gè)事情,責(zé)任到個(gè)人。如果有逾期風(fēng)險(xiǎn),提前向 TL 或者自己的導(dǎo)師反饋原因,不要拖到最后一天才暴露問(wèn)題。
按道理,開(kāi)發(fā)時(shí)間規(guī)模應(yīng)該是大家做需求評(píng)審時(shí)定下來(lái)的,但是考慮到團(tuán)隊(duì)的一個(gè)實(shí)際情況,這塊權(quán)限是下放到開(kāi)發(fā)者自行評(píng)估,但是 TL 需要起到一個(gè)監(jiān)督的作用。這里大家可以結(jié)合實(shí)際情況考量。
創(chuàng)建issue
原則上由開(kāi)發(fā)者自行創(chuàng)建,創(chuàng)建需求和 bug 類(lèi) issue 時(shí),應(yīng)附上 tapd 鏈接,方便查詢(xún)關(guān)聯(lián)事項(xiàng)!issue 也是分支命名的一個(gè)依據(jù)。下面我會(huì)接著說(shuō)。
有些時(shí)候,TL 或者項(xiàng)目 Owner 會(huì)安排一些非 TAPD 管理的組內(nèi)任務(wù),會(huì)直接以 issue 形式指給開(kāi)發(fā)人員,開(kāi)發(fā)人員接到 issue 后,不必再重復(fù)創(chuàng)建 issue,只要基于已創(chuàng)建的 issue 創(chuàng)建本地分支開(kāi)發(fā)就行。
分支權(quán)限控制
在我們團(tuán)隊(duì)中,約定了三個(gè)重要分支,分別是:
develop:開(kāi)發(fā)分支 release:測(cè)試分支 master:生產(chǎn)分支
這三個(gè)分支被設(shè)置為 Protected Branches,通常都關(guān)聯(lián)了對(duì)應(yīng)環(huán)境的 CI/CD 配置。在權(quán)限控制上一般設(shè)置為:Maintainer 擁有 Merge 權(quán)限,所有人都沒(méi)有 push 權(quán)限。
實(shí)際操作時(shí),一個(gè)基本的 Merge 方向是:

根據(jù)實(shí)際情況,也可以引入預(yù)發(fā)布分支之類(lèi)的分支。
如果對(duì)分支權(quán)限不做控制,大家可以隨意 push,就意味著潛在的災(zāi)難隨時(shí)可能發(fā)生。所以這一點(diǎn)是非常值得關(guān)注的!
創(chuàng)建分支
我之前也試過(guò)分支語(yǔ)義化命名,但是也發(fā)現(xiàn)了要用有限的單詞描繪出復(fù)雜的含義永遠(yuǎn)是個(gè)偽命題。我們可能會(huì)在做一個(gè)新功能時(shí),會(huì)把相關(guān)分支命名為feature/xxx,而后面有優(yōu)化類(lèi)需求時(shí),又會(huì)新建一個(gè)feature/xxx-optimization之類(lèi)的分支。然而,往往一個(gè)功能會(huì)有一次又一次的優(yōu)化、變更或 bug,采取這樣的命名策略永遠(yuǎn)會(huì)讓自己直面靈魂拷問(wèn)!
并且在追溯問(wèn)題時(shí),這種分支命名方式往往讓人心力交瘁!
那么如何命名能解決這樣的問(wèn)題呢?我采用了下面這種策略!
issue本身有一個(gè)編號(hào),或者叫ID,這種唯一標(biāo)識(shí)讓我們命名分支變得簡(jiǎn)單。假定一個(gè)issue的編號(hào)是1,那么我們?cè)诒镜貏?chuàng)建分支時(shí),只需要將分支命名為issue/1即可,根據(jù)這個(gè)編號(hào),我就能查到這個(gè)分支處理的是哪個(gè)issue,而打開(kāi) Gitlab 的issue界面,我就能知道這個(gè)issue與什么需求或缺陷有關(guān),而且也能直觀看到與這個(gè)issue關(guān)聯(lián)的代碼 commit 記錄。這不僅給開(kāi)發(fā)者帶來(lái)了方便,也讓管理者變得更輕松!
好,下面說(shuō)實(shí)際操作。以開(kāi)發(fā)新特性為例:
本地切換到 develop分支,拉取最新develop分支代碼
git checkout develop
git pull
基于 develop分支創(chuàng)建新的特性分支,用于開(kāi)發(fā)新特性,目前統(tǒng)一命名為issue/xxx,其中xxx是你在gitlab上創(chuàng)建的issue號(hào),如下所示:
git checkout -b issue/1
也就是說(shuō),issue/1分支用于解決gitlab上的issue 1提到的問(wèn)題。
有的項(xiàng)目比較簡(jiǎn)單,或者還在初期階段,這種情況下,不會(huì)設(shè)置 develop 分支,而是基于 master 分支快速開(kāi)發(fā)。如果是這種情況,在上面的操作中,可以直接把 master 理解為 develop,依葫蘆畫(huà)瓢即可。
提交代碼
特性/缺陷分支應(yīng)該保證原子性,一個(gè)分支只解決一個(gè)問(wèn)題(指的是一個(gè)issue提及的問(wèn)題),否則原則上不允許合入其他分支。這對(duì)敏捷迭代有關(guān)鍵意義!
開(kāi)發(fā)完畢后,應(yīng)提交到遠(yuǎn)程倉(cāng)庫(kù)同名分支。
git add .
git cz // 進(jìn)行cz交互式命名行提交
git push origin HEAD // 提交到遠(yuǎn)程倉(cāng)庫(kù)同名分支
提交部分代碼
如果一次commit希望提交部分文件(而不是全部修改的文件),不要用 git add .,可以結(jié)合 GUI 進(jìn)行選擇(比如VSCode自帶的Git面板),進(jìn)入staged狀態(tài)的文件,就是你希望提交的。
? 是進(jìn)入 staged,? 是移出 staged,Staged Changes 就是你希望在這次 commit 的內(nèi)容。
提交部分代碼時(shí),注意保管好自己未提交的代碼,未入庫(kù)就有丟失的可能,這一點(diǎn)要明確!

git cz流程
git cz是commitizen提供的能力,這塊我之前簡(jiǎn)單寫(xiě)過(guò)一段介紹,具體見(jiàn)規(guī)范commit message[3]。使用git cz的主要目的就是規(guī)范代碼提交。
選擇提交的類(lèi)型,
feat代表需求,fix代表修復(fù)缺陷,docs代表文檔類(lèi)變動(dòng),style是代碼風(fēng)格層面的(不是指樣式...),refactor指的是代碼重構(gòu),perf則是優(yōu)化相關(guān)的(包括性能/體驗(yàn)等),test是單元測(cè)試之類(lèi)的,build是構(gòu)建工具相關(guān)的,ci是持續(xù)集成相關(guān)的,chore的解釋各異,按commitizen的解釋就是非src或test的其他改動(dòng),revert代表代碼回退...請(qǐng)準(zhǔn)確選擇改動(dòng)類(lèi)型!

影響范圍
【按情況填寫(xiě)即可,如果不是過(guò)于摳細(xì)節(jié),大部分時(shí)候可以不填】
What is the scope of this change (e.g. component or file name): (press enter to skip)
改動(dòng)描述
【必填】本次代碼改動(dòng)的描述信息,可摘取issue的標(biāo)題,或者是tapd需求或缺陷的標(biāo)題,也可以自行總結(jié)。
Write a short, imperative tense description of the change (max 94 chars):
登錄功能開(kāi)發(fā)
詳細(xì)描述
【按情況填寫(xiě),如果不是過(guò)于摳細(xì)節(jié),大部分時(shí)候可以不填】提供詳細(xì)描述
Provide a longer description of the change: (press enter to skip)
是否有重大變更?
【一般是回車(chē)或者輸入N跳過(guò)】一般來(lái)說(shuō),只有架構(gòu)層面的變更才會(huì)填入y
Are there any breaking changes? (y/N)
是否影響issue?
【一般來(lái)說(shuō),一次commit都應(yīng)該有與之關(guān)聯(lián)的issue,輸入y,用來(lái)關(guān)閉issue,這個(gè)是很常見(jiàn)的】
Does this change affect any open issues? (y/N)
【一般可以跳過(guò)】如果關(guān)聯(lián)的issue已經(jīng)關(guān)閉,可以針對(duì)本次commit 做一個(gè)信息補(bǔ)充。
If issues are closed, the commit requires a body. Please enter a longer description of the commit itself:
(-)
關(guān)閉issue?
? Add issue references (e.g. "fix #123", "re #123".):
假設(shè)要關(guān)閉 issue#1,則輸入:
fix #1
如果要關(guān)閉多個(gè) issue,則輸入:
fix #1 #2 #3
提交至遠(yuǎn)程同名分支
git push origin HEAD // 提交到遠(yuǎn)程倉(cāng)庫(kù)同名分支commit 檢查
配合 husky 和 git hook 來(lái)實(shí)現(xiàn) commit 檢查。
防止提交不符合規(guī)范的代碼。 防止 commit message不規(guī)范。
這里需要借助以下依賴(lài):
husky commitlint commitizen conventional-changelog-cli lint-staged
發(fā)起Merge Request
git push到遠(yuǎn)程同名分支后,并不代表你的代碼進(jìn)入了主分支,你接著還需要走代碼合并流程。
由開(kāi)發(fā)者在gitlab自行發(fā)起Merge Request,請(qǐng)求將代碼合入develop分支。
TL或者有Merge權(quán)限的人負(fù)責(zé)進(jìn)行Code Review,審核通過(guò)后,方可合入代碼。
本地獲取最新develop分支
代碼合入后,就可以基于develop分支做其他的功能開(kāi)發(fā)了。
git checkout develop
git pull
// 進(jìn)行其他的特性開(kāi)發(fā),或bug修復(fù)
繼續(xù)未完成的需求
如果提交代碼并被Merge后,發(fā)現(xiàn)本需求并未開(kāi)發(fā)完畢,此時(shí)不可再另外創(chuàng)建 issue,應(yīng)該基于同一個(gè) issue 繼續(xù)修改;以 issue 號(hào)為 1 舉例說(shuō)明。
首先需要在 gitlab 上 reopen issue#1。然后本地進(jìn)行分支操作。
git checkout develop
git pull
git branch -d issue/1
git checkout -b issue/1
繼續(xù)開(kāi)發(fā)...
開(kāi)發(fā)到中途想拉別人代碼
如果自己正在 issue/1 分支開(kāi)發(fā),而其他同事提交了代碼,并且已經(jīng)合并到 develop 分支,此時(shí)你想用他這部分代碼。需要執(zhí)行以下步驟。
git checkout develop // 如果這一步如果無(wú)法執(zhí)行,見(jiàn)下一節(jié)
git pull
git checkout issue/1
git merge develop
想切出去合入別人提交的最新代碼卻發(fā)現(xiàn)git checkout develop報(bào)錯(cuò)
這種情況是因?yàn)槟愕?issue 分支代碼與最新的 develop 分支相比,已經(jīng)落后或者產(chǎn)生了沖突。
此時(shí)如果仍希望把別人提交的最新代碼合入到自己的 issue 分支繼續(xù)開(kāi)發(fā),需要執(zhí)行以下步驟,利用git stash做一個(gè)臨時(shí)儲(chǔ)存。
// 假設(shè)現(xiàn)在位于 issue/1 分支
git stash
git checkout develop
git pull
git checkout issue/1
git merge develop
git stash pop
此時(shí)一般會(huì)出現(xiàn)沖突,VSCode git 區(qū)域會(huì)有提示感嘆號(hào)或者 C(代表 conflict)。
需要解決掉沖突再繼續(xù)開(kāi)發(fā),開(kāi)發(fā)完畢后按正常流程提交代碼。
其他
以上是以新特性開(kāi)發(fā)為例進(jìn)行說(shuō)明。
其實(shí)對(duì)于修復(fù)缺陷而言,整個(gè)操作流程也基本相同。
如果是測(cè)試環(huán)境和生產(chǎn)環(huán)境都有的bug,通常先修復(fù)測(cè)試環(huán)境驗(yàn)證效果后,視情況通過(guò) cherry-pick 進(jìn)行生產(chǎn)環(huán)境緊急發(fā)版。緊急情況下,可優(yōu)先修復(fù)生產(chǎn)環(huán)境。
issue和merge request規(guī)范
issue規(guī)范
創(chuàng)建 issue 時(shí),應(yīng)清楚該 issue 用于處理什么事務(wù)。
如果明確 issue 處理的是 TAPD 上的需求或缺陷,必須在描述中插入 TAPD 鏈接,方便自己或同事查閱跟蹤。選擇的 Label 應(yīng)該是需求或 Bug。

如果不是來(lái)源于TAPD,則在標(biāo)題中簡(jiǎn)要說(shuō)明主題,在描述中說(shuō)明具體事項(xiàng)(可選),根據(jù)實(shí)際情況選擇合適的Label。

Merge Request 規(guī)范
提交 Merge Request 時(shí),應(yīng)明確目標(biāo)分支。比如需求類(lèi)的,我們是基于 develop 分支創(chuàng)建 issue/xxx 分支,所以提交到遠(yuǎn)程同名分支后,需要請(qǐng)求合入到 develop 分支。
對(duì)于 bug,首先明確 bug 發(fā)生的環(huán)境。而對(duì)于生產(chǎn)環(huán)境bug,我們是基于 master 分支創(chuàng)建 issue/xxx 分支,解決完之后,是請(qǐng)求合入到 master 分支;測(cè)試環(huán)境bug的處理方式可類(lèi)比;如果一個(gè)bug在開(kāi)發(fā)環(huán)境,測(cè)試環(huán)境和生產(chǎn)環(huán)境都有出現(xiàn),應(yīng)基于develop分支新建分支,bug 處理完畢后先發(fā)起 MR 合入到 develop 分支,再通過(guò) cherry-pick 等方式合入到 release 或者 master 分支。
可能有人會(huì)覺(jué)得生產(chǎn)環(huán)境 bug 相關(guān)的代碼直接合入到 master 分支不妥,這個(gè)我覺(jué)得可以看具體情況分析,如果團(tuán)隊(duì)的風(fēng)險(xiǎn)把控程度嚴(yán)一點(diǎn),可以考慮安排一個(gè)預(yù)發(fā)布分支,對(duì)應(yīng)一個(gè)預(yù)發(fā)布環(huán)境,盡可能模擬生產(chǎn)環(huán)境。
Assignee選擇審核人,一般是Mentor或其他同事(交叉評(píng)審)。

同時(shí)也附上Labels,表明你這次提交解決了哪些類(lèi)型的問(wèn)題。如同時(shí)涉及多類(lèi),則進(jìn)行多選。比如,我同時(shí)解決了 bug 和需求,那我就會(huì)勾選兩項(xiàng),但是不推薦這樣做,因?yàn)槲覀兘ㄗh一個(gè) issue 只做一件事,所以一次 Merge Request 也意味著只解決一個(gè)問(wèn)題。
如果涉及發(fā)版分支(比如release和master),建議勾選下環(huán)境選項(xiàng)(如測(cè)試環(huán)境,生產(chǎn)環(huán)境),給人一目了然的感覺(jué)。

Merge Request 不通過(guò)
有 Code Review 就可能存在審核不通過(guò)的情況,各種情況都有,比如業(yè)務(wù)組織方式不恰當(dāng),不符合規(guī)范,未完成功能,等等。
Code Review 不通過(guò)時(shí),我會(huì)以 Comment 的形式直接在問(wèn)題代碼附近進(jìn)行標(biāo)注。這些 Review 意見(jiàn)會(huì)以郵件的形式通知到責(zé)任人。

針對(duì) Code Review 不通過(guò)的情況,不用另外創(chuàng)建 issue,直接切到 issue 對(duì)應(yīng)的分支繼續(xù)修改代碼并 push 就可以了,push 到 remote 后會(huì)自動(dòng)反映到 MR 中,自己在 MR 的 Changes 中也能看得到你最終修改了哪些內(nèi)容。

當(dāng)所有 Review 意見(jiàn)都被 Resolved 后,這個(gè) Merge Request 才可以通過(guò)。
發(fā)版流程
由于我們團(tuán)隊(duì)采用了 CI/CD,所以發(fā)版流程與相關(guān)分支的代碼合并是緊密關(guān)聯(lián)的,項(xiàng)目 Owner 負(fù)責(zé)跟進(jìn)發(fā)版事宜。
按照我們目前的流程,發(fā)版的觸發(fā)動(dòng)作就是執(zhí)行 Merge Request,接著對(duì)應(yīng)的 Pipeline 就會(huì)自動(dòng)執(zhí)行,根據(jù) CI/CD 的環(huán)境配置,部署到對(duì)應(yīng)的服務(wù)器上。


正常情況下發(fā)版的一個(gè) Merge 方向是:
測(cè)試環(huán)境發(fā)版:develop -> release
生產(chǎn)環(huán)境發(fā)版:release -> master
正常發(fā)版
正常就是一個(gè)迭代進(jìn)行一次生產(chǎn)環(huán)境發(fā)版。生產(chǎn)環(huán)境發(fā)版當(dāng)天,要求相關(guān)責(zé)任人在場(chǎng)支撐!
測(cè)試環(huán)境的發(fā)版可能會(huì)頻繁一點(diǎn),一般來(lái)說(shuō),至少一天一個(gè)版本,方便快速進(jìn)行回歸測(cè)試。
非全量發(fā)版
有時(shí)候會(huì)遇到這么一個(gè)情況,生產(chǎn)環(huán)境準(zhǔn)備要發(fā)版了,但是突然發(fā)現(xiàn)測(cè)試環(huán)境某個(gè)功能存在缺陷,不能執(zhí)行全量發(fā)版。但是你不可能說(shuō)我就不發(fā)了吧,所以還是要把剩下的可用功能發(fā)上去。
那么此時(shí)我們就不能執(zhí)行 release -> master 這樣一個(gè) Merge 流程了,只能挑選出可以上線的代碼,這個(gè)時(shí)候就用到 cherry-pick 了。我們可以找到可用功能的代碼 Merge 到 develop 分支的記錄,通過(guò) cherry-pick 挑選合入到 master 分支,實(shí)現(xiàn)一個(gè)非全量上線的效果。
這也是我前面強(qiáng)調(diào)一個(gè) issue 只做一件事的原因,而且一次 commit 盡可能要做完一件事,方便我們進(jìn)行特殊情況下的 cherry-pick。如果很多代碼摻和到一起,一旦部分功能不可用,發(fā)版上線就成了一件非常痛苦的事情。
發(fā)版成功判定依據(jù)
目前已經(jīng)配置了 Pipeline 郵件提醒,發(fā)版成功后,會(huì)有郵件提醒到項(xiàng)目組全員!
注意分支和環(huán)境的對(duì)應(yīng)關(guān)系,就能知道哪個(gè)環(huán)境發(fā)布了新版本!
TAPD管理
代碼提交的流程已經(jīng)在上文中描述清楚了,另外還要做的事情是TAPD的狀態(tài)流轉(zhuǎn)。
開(kāi)發(fā)優(yōu)先級(jí)
首先遵從產(chǎn)品規(guī)劃層面的優(yōu)先級(jí)排序。
在此基礎(chǔ)上拆解出前端子需求,各個(gè)子需求的優(yōu)先級(jí)應(yīng)視實(shí)際情況(比如后端接口完成情況)調(diào)整。
按高中低三個(gè)等級(jí)來(lái)看,應(yīng)保證子需求分配到個(gè)人后,個(gè)人工作臺(tái)只有1-3個(gè)高優(yōu)先級(jí)任務(wù),也就是可能并行開(kāi)發(fā)的1-3個(gè)需求,其余需求視情況應(yīng)納入中或低優(yōu)先級(jí)。待高優(yōu)先級(jí)子需求開(kāi)發(fā)完畢轉(zhuǎn)測(cè)試后,應(yīng)通知項(xiàng)目 Owner,Owner 再根據(jù)實(shí)際情況調(diào)整其余任務(wù)的優(yōu)先級(jí),保證高優(yōu)先級(jí)的任務(wù)的最小規(guī)模,使得開(kāi)發(fā)人員專(zhuān)注于處理高優(yōu)先級(jí)任務(wù)。
開(kāi)發(fā)排期
迭代層面會(huì)有一個(gè)大致的排期出來(lái),但仍不足以作為開(kāi)發(fā)排期。
拆解子需求后,處理人應(yīng)第一時(shí)間評(píng)估出開(kāi)發(fā)預(yù)估耗時(shí),方便進(jìn)行迭代需求排期,按照優(yōu)先級(jí)、預(yù)估耗時(shí)以及自己的任務(wù)排期情況,排好每個(gè)需求的開(kāi)發(fā)起止時(shí)間。
如無(wú)團(tuán)隊(duì)協(xié)作的意外情況發(fā)生,應(yīng)保證在每個(gè)需求的開(kāi)發(fā)結(jié)束時(shí)間之前完成需求轉(zhuǎn)測(cè),否則應(yīng)回溯原因。
當(dāng)出現(xiàn)多個(gè)項(xiàng)目之間并行迭代發(fā)生優(yōu)先級(jí)沖突時(shí),應(yīng)由項(xiàng)目經(jīng)理組織協(xié)調(diào),根據(jù)實(shí)際情況調(diào)整排期和優(yōu)先級(jí)。
開(kāi)發(fā)中
準(zhǔn)備開(kāi)發(fā)需求前,應(yīng)先將TAPD上的相關(guān)需求的狀態(tài)改為開(kāi)發(fā)中
解決缺陷前,應(yīng)先將TAPD上的相關(guān)缺陷的狀態(tài)改為接受/處理
已完成
開(kāi)發(fā)完畢后,開(kāi)發(fā)者應(yīng)充分自測(cè),如果轉(zhuǎn)測(cè)試不通過(guò),需要承擔(dān)相應(yīng)責(zé)任。
CI/CD 自動(dòng)發(fā)版完成后,開(kāi)發(fā)者會(huì)收到郵件通知,此時(shí)方可在TPAD中進(jìn)行狀態(tài)流轉(zhuǎn):
相關(guān)需求的狀態(tài)改為轉(zhuǎn)測(cè)試 相關(guān)缺陷的狀態(tài)改為已解決
小結(jié)
以上就是我在前端研發(fā)流程上的一點(diǎn)親身實(shí)踐,希望能給有需要的朋友帶來(lái)一點(diǎn)幫助。總的來(lái)說(shuō),將流程形成文檔之后,還是節(jié)省了我很多時(shí)間,有些重復(fù)的問(wèn)題我就不必一一回答了。當(dāng)然,上述文檔也只是描述了研發(fā)過(guò)程中主要環(huán)節(jié)的過(guò)程,起到一個(gè)輔助的作用,還有很多細(xì)節(jié)也是需要在日常多做溝通交流的。
我始終認(rèn)為有效的溝通和反饋是一個(gè)團(tuán)隊(duì)的首要任務(wù),只有這一塊做好了,才能勁往一處使,高效出成果!
參考
TAPD: https://www.tapd.cn/my_worktable
[2]http://nginx.org/en/download.html: http://nginx.org/en/download.html
[3]規(guī)范commit message: https://juejin.cn/post/6844904056498946055#heading-6
END


“分享、點(diǎn)贊、在看” 支持一波
