My First Contribution to Nginx

nginx conf

因為工作上的需要,所以其實我還蠻常會編輯 nginx configuration file 的,理所當然的編輯器是用 vim,然後就會對 nginx 設定檔的支援有意見,一般人用的 nginx 設定檔的 vim script 其實是 nginx repository 的 contrib 目錄裡面的那份,這份 vim script 其實本來也是獨立的,不過原作者好像把他捐進去 nginx 裡面,之後就一直都在裡面了,也因此之後更新就很不頻繁。

然後因為檔案都放在 nginx repository 裡面,Vim 要使用其實不太方便,所以 Github 上還看的到不少人單獨抽出來,我一開始也是 fork mosky 的來用,後來就直接在自己的 repository 上面修改了,改一陣子之後就開始想要推回 upstream,也就是 nginx 的程式庫,然後就開始了這段協工旅程(?)。

要發修改上 upstream,第一步自然是看一下如何貢獻,節錄這邊幾個重點:

  1. nginx-devel 這個 mailing list 做討論
  2. 發 patch 前有一些注意事項,不過我改 vim script 比較沒關係
  3. Patch 也是用 email 發到 nginx-devel,有範例
  4. 推薦用 patchbomb
  5. 要先簽 CLA(不過目前這條已經不見了,改成最後說發 patch 等於同意用他們專案的 LCIENSE)

總之我就照這份,先去訂閱了 nginx-devel 觀察一陣子,然後就直接把我的修改整個丟上去了,一開始是直接用 Gmail 發,把 patch 檔內容直接複製貼過去,產生 patch 檔的方法是:

hg export > something.patch

hg export會直接輸出最後一個 commit 的 patch 內容到 STDOUT,然後就直接用 Gmail 發過去,結果 review 的 Maxim Dounin 說他沒辦法 apply patch,可能是因為我的 mail client 的關係,建議我用 patchbomb 發,所以就研究搜尋了一下,發現他是直接發 email 的機制,所以要把帳號密碼都寫到設定內,找了一篇 Gmail 的設定範例,搭配 Google account 的應用程式密碼,設定範例如下:

[extensions]
hgext.patchbomb =

[email]
from=othree <othree@gmail.com>
to=nginx-devel@nginx.org
cc=othree@gmail.com
method=smtp

[smtp]
host=smtp.gmail.com
port=587
username=othree@gmail.com
password=[gmail_password]
tls=True

把這些資訊填入.hg/hgrc這個檔案內,然後就可以用hg email -o --test來測試看看,這個指令會把完整的原始信件內容,包括 header 等都顯示出來(丟到 STDOUT),如果正式要發就把--test拿掉就好了。

確認一切沒問題後,我就改用 patchbomb 發 patch 到 nginx-devel 了,結果還是被拒絕了,問題主要是這個 patch 一次修改太多,理想上應該是不同目的的修改放到不同 patch 內,當然這和我一開始的預想不一樣就是了,我一開始的想法是因為 contrib 這邊的東西,相對於 nginx 本體的原始碼來說比較次要,所以盡量減少 commit 數,其實如果我有先去問過應該是可以少繞這段路,總之,為了一個一個修改送出,我又開了一個 github repository,叫做 nginx-contrib-vim-patch,想要慢慢把我的 nginx-contrib-vim 內的更動搬過去,接著開始的,就是漫長的 review 和溝通了。

其實我完全沒想到 Maxim Dounin 會這麼認真的 review,不止會看我這樣改是要達到什麼目的,還有認真測試,結果被抓出一堆問題,雖然都是奇妙的 conf 寫法,合語法,但是應該不會有人這樣寫的 case,這些 case 我也開始慢慢收集到 github 上的 nginx-conf-test,方便之後測試用,總之來回許久,終於有一部分比較簡單的東西先進去 nginx repository 了,然後我發現外部貢獻者都會在 change log 那邊被感謝,我貢獻進去的目前應該都在 1.11.11 那版,其實只有把新的 directive 補上(core modules, 3rd party modules)和幾個 protocol 參數的 highlight,至於其他的修改還進不去,目前看起來會是一場長期抗戰,主要是因為 reviewer 對於期望的目標和我不一樣,目前大概會維持兩個版本吧,一邊弄自己希望的,一邊抽東西送回去 upstream,不得不說主事者控制太緊會讓貢獻者動力被削減不少。

貢獻 nginx 的過程讓我體會到以前的開源協做的模式(應該是吧?),用 mailing list 溝通,發 Patch、code review、做討論,這些點來看,nginx 的流程其實是非常老派,和現在用 Github 做溝通、協做 的流程差很大,門檻也高不少,當然這不一定是壞事,還是要看專案性質,在 Github 這類平台上做這些協做流程的話,門檻降低了,其實可能隨之而來的問題就是太多人進來造成貢獻品質落差很大,反而會吃掉主力人員的時間,剛好今天也看到知乎上有一篇「維護一個大型開源專案是怎樣的體驗?」,裡面就有提到 VSCode 的狀況,變成還需要排人專門處理 issue 和 PR,感覺就很可怕。

順帶一題,nginx 的固定貢獻者當中不少中國人啊。