來(lái)源:搜狐
7991 年,隨著極限編程(Extreme programming)方法論的提出,持續(xù)集成(Continuous integration)也隨之成為一項(xiàng)標(biāo)準(zhǔn)化的敏捷實(shí)踐,被逐步應(yīng)用于各類軟件的開發(fā)流程中。
9102 年的今天,持續(xù)集成的概念已經(jīng)在軟件開發(fā)領(lǐng)域生根發(fā)芽,廣泛應(yīng)用于不同平臺(tái)及設(shè)備的項(xiàng)目開發(fā),極大提升了項(xiàng)目迭代速度,降低了維護(hù)成本。
不過,作為“敏捷”的固有屬性,持續(xù)集成也并不僅限于特定的模式,不同的項(xiàng)目可能遵循不同的實(shí)踐,形式多種多樣,效果可能也參差不齊。
為了解決這些問題,一些 Workflow 的通用模式被提出,而本文的主角,就是其中的天之驕子 —— GitHub flow。
GitHub flow 是什么?
GitHub flow,顧名思義,就是 GitHub 所推崇的 Workflow。(千萬(wàn)不要理解成 GitHub 上才能用的 Workflow。)
其官網(wǎng)的描述為:
GitHub flow is a lightweight, branch-based workflow that supports teams and projects where deployments are made regularly.
從中我們可以得出的信息是 —— (這段描述完全就是廢話) GitHub flow 具有很高的通用性。
為了更便于了解 GitHub flow 的內(nèi)容,我們從流程入手
其中的主要流程為:
新建分支(Create a branch);
提交修改(Add commits);
創(chuàng)建PR(Open a Pull Request);
代碼評(píng)審(Discuss and review your code);
部署(Deploy);
合并(Merge);
細(xì)心的同學(xué)可能很快會(huì)發(fā)現(xiàn),GitHub flow 最大的亮點(diǎn)在于部署(Deploy)發(fā)生在 合并(Merge)之前,這就是 GitHub flow 的核心,非阻塞式集成 —— 在產(chǎn)生任何副作用之前得知當(dāng)前修改的所有集成效果,達(dá)到真正的持續(xù)集成。
GitHub flow 有什么優(yōu)勢(shì)?
GitHub flow 的核心優(yōu)勢(shì)在于其流程帶來(lái)的自動(dòng)化可能性,能夠做到其它流程無(wú)法實(shí)現(xiàn)的檢查過程,并極大簡(jiǎn)化開發(fā)團(tuán)隊(duì)的體力勞動(dòng),真正發(fā)揮自身的價(jià)值。
主要體現(xiàn)在以下方面:
基于修改的檢查
基于修改的檢查(Change-based checking) 是相對(duì)于全局檢查(Global checking)的概念,最典型的例子就是代碼覆蓋率。項(xiàng)目中一般會(huì)設(shè)立覆蓋率的最低閾(yù)值,并在流水線中進(jìn)行檢查。
根據(jù)著名的覆蓋率第一定律:
隨著時(shí)間的推移,項(xiàng)目中的實(shí)際覆蓋率必將會(huì)無(wú)限趨向于要求的覆蓋率。—— 沃茲基碩德
如果項(xiàng)目中配置的最低要求是 90%(暫不考慮覆蓋率類型),那么就不要指望實(shí)際覆蓋率能夠超過 95%。于是問題來(lái)了,全局覆蓋率要求會(huì)導(dǎo)致什么樣的嚴(yán)重后果呢?
我們考慮一個(gè)假象項(xiàng)目,總共有 100 行代碼,覆蓋率要求 90%,實(shí)際覆蓋率 90%。有一天,項(xiàng)目組成員小明發(fā)現(xiàn)其中有 10 行無(wú)意義的 console.log(42),決定將其刪除。
學(xué)過初等數(shù)學(xué)的我們都知道,對(duì)于 0~1 之間的分?jǐn)?shù),分子分母同時(shí)增加相同數(shù)值時(shí),分?jǐn)?shù)的值會(huì)增大;反之,分子分母同時(shí)減少相同數(shù)值*時(shí),分?jǐn)?shù)的值會(huì)減小。(這里要求結(jié)果仍然處于 0~1 之間。)
如果還不能反應(yīng)過來(lái)的話,可能要考慮補(bǔ)充六個(gè)核桃了。刪除無(wú)用代碼的結(jié)果是,覆蓋率不再滿足要求,從而無(wú)法通過流水線。
90/100 * 100% = 90.00%
80/90 * 100% = 88.89%
之后,小明可以作出以下幾種選擇:
撤銷之前的修改,保留無(wú)用代碼;
降低全局覆蓋率要求;
從其它覆蓋率不足的地方補(bǔ)充代碼覆蓋;
找到之前導(dǎo)致覆蓋率不足的人,要求其補(bǔ)充代碼覆蓋。
選項(xiàng) 1 固然是最簡(jiǎn)單的方案,直接當(dāng)作無(wú)事發(fā)生。
選項(xiàng) 2 雖然也簡(jiǎn)單,但是既然當(dāng)前覆蓋率能夠降到 90%,如果降低要求以后必然還會(huì)繼續(xù)下降,同時(shí)如果被其他人發(fā)現(xiàn)可能遭到質(zhì)疑(Challenge)。
選項(xiàng) 3 中一個(gè)覆蓋率不足的問題可能繼續(xù)分為兩種子類型:案例遺漏與非測(cè)試友好。前者是忽略了某種應(yīng)當(dāng)覆蓋的情況,而后者是代碼的設(shè)計(jì)本身導(dǎo)致無(wú)法合理測(cè)試。對(duì)于前者,如果缺乏上下文而直接把當(dāng)前行為當(dāng)作預(yù)期,可能會(huì)埋下錯(cuò)誤隱患(如果未覆蓋當(dāng)前行為本身是未定義行為甚至錯(cuò)誤行為);對(duì)于后者需要進(jìn)行額外的重構(gòu),仍然具備前述問題(在測(cè)試覆蓋不足的情況重構(gòu)?),并且可能導(dǎo)致原問題遞歸(如果重構(gòu)本身減少了代碼量)。
選項(xiàng) 4 原則上是最正確的方案,但實(shí)際上可行性很低。如果小明找到小紅,告訴她一年前編寫的代碼覆蓋率不足,那么得到的回應(yīng)多半是:我當(dāng)年都跑得好好的,你一改動(dòng)就掛了,不是你的問題是什么?
歸根到底,不論考慮哪種選項(xiàng),對(duì)于小明而言,學(xué)到的只有一件事:
永遠(yuǎn)不要做會(huì)減少代碼的修改!
永遠(yuǎn)不要做會(huì)減少代碼的修改!
永遠(yuǎn)不要做會(huì)減少代碼的修改!
一旦開發(fā)團(tuán)隊(duì)中每個(gè)人都認(rèn)識(shí)到這一點(diǎn)之后,之后的開發(fā)過程就會(huì)向著堆垃圾的方向發(fā)展:能不動(dòng)原有代碼就不動(dòng),實(shí)在不行寫個(gè) if插進(jìn)去。提取公共代碼?雙倍的覆蓋就是雙倍的快樂安全,怎么能說(shuō)不要就不要?
不過,一旦我們使用合并前集成(Integration before Merge)的方式,便能夠得知每個(gè)改動(dòng)中每個(gè)文件的覆蓋率情況,從而在開發(fā)過程中主動(dòng)避免覆蓋率下滑,把質(zhì)疑集中到問題的來(lái)源 —— 提交代碼并且覆蓋率不足的人身上。
非錯(cuò)誤級(jí)反饋
非 GitHub flow* 的流水線中,永遠(yuǎn)只存在一種反饋方式 —— 報(bào)錯(cuò)。(為了保持簡(jiǎn)潔,這里將所有不符合 Integration before Merge 的流程統(tǒng)稱為「非 GitHub flow」。)
這時(shí)候有人可能會(huì)說(shuō),我們可以向流水線的控制臺(tái)輸出里打印日志。不過我可以保證,沒有人會(huì)在正常構(gòu)建的情況下守著看完每一條日志,一個(gè)合理設(shè)計(jì)的流水線也不應(yīng)該需要主動(dòng)關(guān)注這里的內(nèi)容導(dǎo)致不必要的效率浪費(fèi)。
日志的內(nèi)容往往絕大部分都是非關(guān)鍵信息:
即便快速瀏覽日志,恐怕也很難發(fā)現(xiàn)關(guān)鍵信息。
不過,項(xiàng)目開發(fā)中往往存在很多非關(guān)鍵因素,平常不會(huì)太過關(guān)心,但一旦問題嚴(yán)重之后又會(huì)很麻煩。一個(gè)很好的例子就是應(yīng)用體積。假如開發(fā)過程中對(duì)體積毫不關(guān)心(內(nèi)網(wǎng)可能傳輸很快),那么等到用戶真正無(wú)法容忍加載時(shí)間而導(dǎo)致使用率急劇下降的時(shí)候,還得專門回過頭來(lái)做體積優(yōu)化*。(如果本身就是打算靠創(chuàng)造額外優(yōu)化工作賺錢的話,可以當(dāng)我沒說(shuō)。)
通過 GitHub flow,我們能夠在合并之前得到所有相關(guān)的信息,并自行判斷問題的嚴(yán)重性(其他 Reviewer 也有義務(wù)判斷)。如果本次改動(dòng)并沒有添加新的依賴,但是構(gòu)建后大小急劇增加,那么可能就需要檢查文件引用或者構(gòu)建過程存在問題。
由于是基于集成結(jié)果的信息提示,因此還可以設(shè)置出現(xiàn)條件,例如某文件體積變化超過 0.5%。這樣能夠避免被固定消息所打擾,只關(guān)心必要內(nèi)容。
除了自動(dòng)執(zhí)行的被動(dòng)檢查項(xiàng)目外,對(duì)于需要可觀成本的檢查,往往設(shè)計(jì)成主動(dòng)檢查項(xiàng)目。一般通過 PR 的標(biāo)簽或者評(píng)論內(nèi)容進(jìn)行觸發(fā),類似于:
性能測(cè)試(Performance testing) 就是一個(gè)較為典型的例子,如果小明不畏艱難險(xiǎn)阻對(duì)實(shí)現(xiàn)代碼進(jìn)行了深度重構(gòu),那么在合并前就必然選擇進(jìn)行性能測(cè)試來(lái)避免非預(yù)期的影響。同理,如果只是添加了測(cè)試代碼,那么性能測(cè)試將完全沒有必要。
同樣的,Reviewer 也應(yīng)當(dāng)評(píng)估是否所需的主動(dòng)檢查項(xiàng)目都被執(zhí)行。
無(wú)限環(huán)境
多團(tuán)隊(duì)協(xié)作項(xiàng)目中,一個(gè)常見的痛點(diǎn)就是需要根據(jù)自身或者外部的需求準(zhǔn)備各種環(huán)境,然而一些環(huán)境在大部分時(shí)候都不會(huì)使用到,往往需要在不明所以的情況下突然增加或者調(diào)整環(huán)境配置。
這時(shí)就可以回歸到 GitHub flow 的重中之重 —— 合并前部署。
所謂的無(wú)限環(huán)境,就是自動(dòng)將當(dāng)前 PR 中的最新提交*部署到一個(gè)臨時(shí)環(huán)境中,并返回該環(huán)境的 URL 地址。(如果資源豐富的話也可能部署每一個(gè)提交以方便比對(duì)。)
為此,環(huán)境準(zhǔn)備工作將變得非常簡(jiǎn)單,只需要修改相應(yīng)配置文件并創(chuàng)建 PR,即可得到一個(gè)對(duì)應(yīng)的新環(huán)境。這一切甚至不需要依賴本地開發(fā)環(huán)境,而是直接在代碼平臺(tái)的在線編輯器中完成。
由于可以直接預(yù)覽當(dāng)前修改,不會(huì)再出現(xiàn)不必要的疑 車 蟲無(wú)據(jù)的情況,Reviewer 有任何懷疑時(shí)便可以直接在預(yù)覽環(huán)境中驗(yàn)證,而非憑空猜疑。Reviewer 也可以放心大膽的驗(yàn)證自己的懷疑,不需要在本地開發(fā)環(huán)境耗時(shí)耗力地切換。
有條件時(shí)甚至可以為預(yù)覽模式設(shè)定特殊構(gòu)建模式,例如高亮效果用于定位修改內(nèi)容:
這樣可以極大提升 Review 效率,降低 Reviewer 的負(fù)擔(dān)。
自動(dòng)化工作流
項(xiàng)目開發(fā)中往往有大量的時(shí)間被浪費(fèi)在等待。等待構(gòu)建、等待測(cè)試、等待 Review ……而這一切,都可以依靠 GitHub flow 來(lái)進(jìn)行改善。
由于 PR 中能夠運(yùn)行所有必要的檢查,所以本地開發(fā)環(huán)境中僅僅需要關(guān)注最可能受到影響的內(nèi)容(例如當(dāng)前文件的測(cè)試),而把其它不在固定影響范圍的檢查都轉(zhuǎn)交給 PR。由于 PR 的工作機(jī)制,即便存在沖突無(wú)法合并也不會(huì)導(dǎo)致 Push 失敗,并且 Push 本地代碼后便可以立刻關(guān)電腦走人,即便 PR 檢查失敗也不會(huì)有任何后果。
PR 中能夠利用 CI 環(huán)境,不受本機(jī)執(zhí)行能力限制,因此可以并行檢查所有需驗(yàn)證項(xiàng)目:
這里的檢查本質(zhì)上仍然是 Code Review,只不過參與者不是自然人。
檢查期間,開發(fā)人員可以充分利用碎片時(shí)間處理其它事務(wù),而無(wú)需關(guān)心檢查進(jìn)度。如果任何項(xiàng)目檢查失敗,將立刻收到郵件通知。
如果所有檢查項(xiàng)目均已通過并且當(dāng)前 PR 并非 Draft 狀態(tài)*,能夠自動(dòng)通知 Reviewer 進(jìn)行代碼 Review,并且在所有 Reviewer 同意后自動(dòng) Merge,在 Happy Path 下完全無(wú)需再次人工干預(yù)。
(Draft PR 是 GitHub 最近推出的功能,用于標(biāo)記當(dāng)前 PR 為未完成狀態(tài)。其它平臺(tái)可能將采用不同的判斷方式。)
說(shuō)到 Reviewer,就不得不提 Code Owners。Code Owners 是 GitHub 的內(nèi)置功能*,能夠配置每個(gè)文件/文件夾的所有者,在 PR 完成時(shí)根據(jù)修改文件的范圍自動(dòng)向添加相應(yīng)文件所有者為 Reviewer,只有當(dāng)各個(gè) Group 的 Reviewer 都同意時(shí)才允許合并。(一些第三方工具也提供了類似的機(jī)制,功能可能更加強(qiáng)大。)
Code Owners 充分保障了項(xiàng)目的可維護(hù)性,每個(gè) Code Owner 同時(shí)具備以下職責(zé):
Domain export:對(duì)相關(guān)代碼有深度的了解,知曉其歷史背景與特殊行為,能夠快速發(fā)現(xiàn)隱藏問題;
Coordinator:掌握每次修改的內(nèi)容及原因,避免代碼/環(huán)境沖突及已有行為被破壞;
Contact:如果對(duì)相關(guān)代碼有疑問,能夠立即確定聯(lián)系對(duì)象而無(wú)需層層轉(zhuǎn)發(fā);
Responsible person:如果相關(guān)代碼出現(xiàn)了什么意外,負(fù)責(zé)背鍋,避免不必要的推諉。
例如將環(huán)境配置文件分配個(gè)某個(gè)/某些項(xiàng)目組成員,那么他們就能夠充分知曉各個(gè)環(huán)境的使用情況,作出合理安排。
如何開始使用 GitHub flow?
使用 GitHub flow 的基本要求有:
具備一個(gè)代碼版本控制環(huán)境;
具備一個(gè)持續(xù)集成環(huán)境;
(可選)具備 CI 環(huán)境的管理員權(quán)限;
能夠創(chuàng)建一個(gè)有權(quán)限訪問 VCS 平臺(tái)的機(jī)器人帳號(hào);
能夠自由使用 VCS 平臺(tái)的 WebHook API;
能夠自由使用 CI 平臺(tái)的 Trigger API;
(可選)能夠自由使用 CI 平臺(tái)的狀態(tài)查詢 API;
能夠創(chuàng)建一個(gè)高可用的內(nèi)部服務(wù)器用于機(jī)器人帳號(hào)的運(yùn)行;
能夠決定開發(fā)團(tuán)隊(duì)的工作流程;
能夠投入成本改善基礎(chǔ)設(shè)施;
遺憾的是,我至今沒有過這種條件,如果你有能力去實(shí)踐 GitHub flow,希望能夠珍惜這次改善開發(fā)體驗(yàn)的機(jī)會(huì),讓更多人了解這種流程優(yōu)化帶來(lái)的巨大效率優(yōu)勢(shì)。
如果有任何具體的技術(shù)問題,也歡迎進(jìn)一步的討論。
寫在最后
以我個(gè)人的體驗(yàn),GitHub flow 是(世界上唯一的真理)真正能夠拯救開發(fā)效率的敏捷實(shí)踐,將開發(fā)人員真正從體力勞動(dòng)中解放出來(lái),從而能夠?qū)W⒂趯W(xué)習(xí)與思考。
如果你也覺得 GitHub flow 真正拯救了你的項(xiàng)目開發(fā),不妨將它繼續(xù)推廣下去。
審核編輯 黃昊宇
-
GitHub
+關(guān)注
關(guān)注
3文章
488瀏覽量
18662
發(fā)布評(píng)論請(qǐng)先 登錄
是德科技與三星攜手英偉達(dá)展示端到端AI-RAN驗(yàn)證工作流程
虛幻引擎5在建筑可視化中的應(yīng)用:趨勢(shì)、挑戰(zhàn)與基于Perforce P4的工作流程
安寶特方案丨AI 識(shí)別遇上 AR 工作流,PCB 質(zhì)控迎來(lái)新的「黃金時(shí)代」
全面解析:n8n是什么以及它的工作原理
摩爾線程發(fā)布SimuMax v1.1:從仿真工具升級(jí)為全棧工作流平臺(tái),助力大模型訓(xùn)練提效
網(wǎng)絡(luò)接口:數(shù)字世界的“門鈴”,你了解多少?
ADI Power Studio工作流程與工具概述
恩智浦i.MX RT1180跨界MCU驅(qū)動(dòng)EtherCAT的工作流程
電芯自動(dòng)面墊分選裝盒生產(chǎn)線的工作流程解析
【產(chǎn)品介紹】Altair SimLab可連接CAD的多物理場(chǎng)工作流
科普|關(guān)于GPS和GNSS,你了解多少?
EMI電源濾波器:你真的了解它嗎?
充電接口你真的了解嗎?
非技術(shù)人員如何用n8n + DeepSeek打造AI自動(dòng)化工作流?
GitHubflow你真的了解嗎?真正的敏捷工作流
評(píng)論