我們是如何管理一個 1w+ stars 的開源倉庫的

飛冰發表於2019-04-02

對於每個開發者來講,git 倉庫是我們幾乎每天都要接觸的東西,但是實際上大多數的 git 倉庫管理都是非常隨性且不規範的,在某些情況下這樣做並沒有太大的問題,但是當協作成員逐漸增多、倉庫職責逐步擴充套件時,很多原本不規範的小問題會被逐漸放大乃至產生一些極為嚴重的問題。筆者所在的飛冰(ICE)團隊在 2018 年 2 月開源了 alibaba/ice 這個倉庫,經過不到一年的時間終於在 2018 年末達到了 1w+ stars 的里程碑,在管理這個倉庫以及運營社群的過程中我們積累了一些或大或小的最佳實踐,希望能分享出來幫助到其他開源或者沒開源的 git 倉庫管理者。注:對於 git 的操作,筆者自知還處於一個比較初級的階段,如有錯誤的地方還望指出。

合理的拆分倉庫

當我們說管理倉庫的時候,其實面向的不是一個單一的倉庫,而是一個產品、一個專案甚至一個業務,這背後可能會有多個倉庫也可能只有一個倉庫,因此在前期的規劃上要儘量梳理清楚,核心避免兩個誤區:

誤區 1:每個職責都建一個倉庫

這個方案可能是多數人的直覺反應,這種方式會讓產品對應的倉庫數快速增多,導致長期管理成本陡增:

  • 倉庫許可權管理成本高且容易混亂
  • 程式碼開發提交成本高
  • issue/PR 太過零散,難以統計管理
  • ……

實際上,飛冰(ICE)原先在內部的時候,我們開發了很多業務元件,每個業務元件都是一個單獨倉庫,然後最近在做統一升級(工具、規範或者其他變更導致)的時候給筆者個人帶來非常大的困擾:

  • 有的元件(倉庫)已經不再維護但沒有任何標記
  • group 許可權管理太過鬆散導致出現一些跟官方無關的元件
  • 升級過程中需要頻繁切換倉庫操作

因此,我們需要避免過於零散的管理方式,然後結合實際場景做適當的聚合。

誤區 2:所有的職責都用一個倉庫承載

在前端社群裡,隨著 lerna 這個批量釋出包工具的出現,這種方式越來越流行,一些非常熱門的專案比如 babel、React、jest 等都逐漸遷移到這個方案。先拋開 lerna 這個工具提供的能力,這種聚合式的管理方式給倉庫管理者節省了很多成本,比如:

  • 只需要管理一個倉庫
  • issue/PR/wiki 等都收斂到一個地方管理

但是在實踐這種方式的時候有可能會走偏,還是以筆者所在的 ICE 團隊做反面教材,踩了誤區 1 的坑之後,在做開源版本的時候我們過段把所有包都放到同一個倉庫,然後通過目錄結構來保證職責清晰,這個方式也同樣如上面所提到的給我們的管理帶來了諸多便利,但在經歷了一年的迭代之後目前也遇到了一些問題:

  • 職責多代表程式碼多,然後隨著歷史記錄的增長,倉庫 clone 速度一日不如一日,尤其在一些小公司的慢速網路環境下(即便加了 --depth)
  • 目錄結構相對複雜,對有心貢獻程式碼的社群同學不夠友好

因此我們推薦「在方案 2 的基礎上按照職責再做一層拆分」,結合 alibaba/ice 這個倉庫,我們後續會把 React 物料程式碼、Vue 物料程式碼、Angular 物料程式碼分別拆出去成為三個獨立倉庫,一方面降低主倉庫的體積,另一方面Vue 的貢獻者不需要關心其他對他沒有意義的檔案目錄。

建立團隊內的操作規範

筆者曾經有幸參與過淘寶前端團隊的程式碼規範制定以及相關工具落地,因此深知規範之於團隊的重要性,同時也有一些制定規範的原則:(1) 規範首先保證正確,其次提升質量;(2) 規範不能過多影響到效率(兩者的權衡需要結合實際場景)。以下就是我們目前在遵循的一些規範:

保護分支

我們是如何管理一個 1w+ stars 的開源倉庫的

根據倉庫情況設定保護分支,禁止直接往保護分支提交程式碼,在非常特殊的情況下 admin 賬戶可以繞過。

新建分支規則

我們是如何管理一個 1w+ stars 的開源倉庫的

  • 分支名稱需要有語義,比如 ice-scripts/fix-foo-bug
  • 如果需求比較簡單,時間週期比較短,那麼直接從 master 切一個分支,然後通過 PR 合併後到 master,合併之後釋出對應包的版本
  • 如果需求包含多個變更點,比如 Iceworks 釋出版本,往往涉及到多個功能點,開發週期一般會在一週左右,如果每個 PR 都往 master 上合併,很難把控整體的進度。因此我們有以下約定:
    1. 先從 master 切出 release 分支(如 release/iceworks-2.16.0),然後提一個基準 PR,PR 中需要補充當前版本包含的功能列表以及釋出先後順序等,該 PR 主要用於管理此次版本開發進度,程式碼無需 review,release 分支不允許直接推送程式碼
    2. 然後每個功能變更都從 release 分支切出新分支,同時 PR 也需要合併到對應 release 分支,切出的分支不需要包含版本資訊(比如 iceworks/fix-xxxx 即可)
    3. 等所有 PR Review 完成並且合併到 release 分支之後,在 release 分支進行釋出,釋出完成後再將 release -> master 的 PR 合併(此處不在 master 分支釋出的原因是擔心釋出時可能會出各種問題,需要再次做程式碼變更)

commit message 規範

我們是如何管理一個 1w+ stars 的開源倉庫的

好的 commit message 可以讓人快速瞭解程式碼意圖,加速 review 程式,未來對於整個程式碼倉庫的歷史追溯也會更加方便,關於這一點社群有足夠多的規範可以參考,此處不再一一贅述,有興趣可以參考末尾的參考連結。

PR 合併流程

我們是如何管理一個 1w+ stars 的開源倉庫的

github 預設提供了三種合併 PR 的方式,關於三種方式的區別可以參考文末的相關連結,我們認為大多數情況應該選擇 Squash and merge,因為 squash 會將當前 PR 的多個 commit 合併,讓整個提交歷史更加乾淨清晰,但是在將上文提到的 release 分支合併到 master 時,是否應該將每個功能點的 commit 合併成一個 release commit,目前我們還沒有思考清楚,希望能得到一些建議或者指導。同時在合併 PR 的時候 Reviewer 有責任重新編寫 commit message 以保證語義更加準確。

這裡簡單追溯一點歷史:在最早期的時候,github 還沒有提供 squash merge 的方式,當我們向開源倉庫提交一個 PR 時,在倉庫作者 review 完成之後一般會要求提交者將 commit 合併,因此很多人都有谷歌過「如何合併 commit」這樣的關鍵詞,而如今只需要點一下按鈕即可,這也是工具對效率提升的一個體現。

釋出流程

對於管理工具包的同學,都應該熟悉並且遵循 Semver 規範(語義化版本),這是原則,在此基礎上需要遵循以下規範:

  • 測試版本:版本號需要遵循 x.y.z-n 的規則,通過 npm publish --tag beta 釋出,很多同學包含筆者本人經常會忘記 --tag beta,不知道有沒有更加有效的方式約束?
  • 正式版直接通過 npm publish 釋出,釋出之後執行 tnpm sync 同步內部版本
  • 正式版本釋出之後,需要同時建立對應的 git tag,tag 命名規則:產品名/x.y.z,比如 ice-scripts/1.0.2

其他不重要的事情

如何保證規範落地

結合曾經在淘寶前端團隊推動的規範落地以及當下在 ICE 團隊制定的規範,兩點結論可供參考:

  • 規範需要保證多數人認可,然後由鬆到緊逐步迭代,人跟著規範逐步成長
  • 小團隊靠素養,大團隊靠工具:在小團隊內製定規範,需要做的就是反覆強調,逐漸讓每個人形成習慣;而在大團隊裡顯然是沒法關注到每個人的,此時需要藉助工具,比如 eslint,commit-check 以及像門神這種強流程的工具

如何迭代歷史版本

上文說的一些工具包的發版,假設我有一個工具包 ice-scripts 在 1.6.5 的基礎釋出了一個 break change 的版本 2.0.0,正常情況下我們肯定是在 master 分支(2.0.0 的程式碼)的基礎上逐步迭代,但 1.x 的版本可能還有使用者使用,當我們需要修復 1.x 的一個 bug 時如何去做?這裡推薦一個流程:

  • 首先基於 git tag ice-scripts/1.6.5 切出一個 stable/ice-scripts-1.x 的分支(幸虧之前打了 tag,否則要找到對應的 commit 還是有點工作量的)
  • stable/ice-scripts-1.x 設為保護分支,可以理解為 1.x 版本的 master 分支
  • stable/ice-scripts-1.x 切出新分支 ice-scripts-1.x/fix-bar,然後修改程式碼提交 PR 到 stable/ice-scripts-1.x 分支上
  • Review 完成後合併程式碼,然後在 stable/ice-scripts-1.x 分支上進行釋出

如何做好答疑

運營社群的過程一定需要頻繁面對使用者的疑問,如何在滿足使用者的同時又能保證自身投入不影響到正常工具顯得極為重要了,對於技術產品,根據面向使用者群體的不同目前兩種主流答疑方式:

  • github issue: 純非同步交流,保證所有問題討論都能沉澱下來,同時因為非同步溝通有成本,大家會努力一點表達清楚自己的意圖,相對來講溝通質量更高,但響應速度之類的無法保證
  • 類釘釘群:同步交流,響應速度快,但是對於維護者來說時間容易被打碎,降低工作效率

答疑這塊目前整體上還是佔用了太多時間,這塊也一直處於探索階段:

  • 做好產品以及文件的積累
  • 釘釘群答疑進行值班機制,每個人負責一天,每個人需要對產品的全貌正確瞭解更多:事實上會有點難
  • 釘釘機器人問題沉澱
  • 引入外包機制

如何管理 issue

ICE 目前整體的 issue 管理做的不好,筆者也是近期開始治理這塊,一些建議僅供參考:

  • 通過 issue 模板努力提升 issue 質量:ICE 倉庫裡早期的 issue 質量非常低,很多問題都無法復現
  • 基於產品分類建議對應的標籤分類,每個 issue 關聯標籤,然後由對應負責人統一處理
  • issue 不要求及時處理,但鼓勵能通過溝通或其他方式快速明確問題,防止時間長了不理解 issue 的描述然後又無法跟 issue 作者溝通

如何運營社群

ICE 團隊目前維護著 5 個釘釘答疑群(每個 1000 人)以及技術論壇的官方帳號,但整體活躍度都比較一般,目前無論是精力上的投入還是運營產品的經驗都比較缺失,希望能得到一些建議或者支援。

有趣的機器人

github 上有很多方便的機器人(or App?),這裡推薦個人覺得比較有用的兩個機器人:

其他有趣的機器人歡迎推薦。

相關連結

相關文章