做開源專案的維護者,是怎樣一種體驗?

Nolan Lawson發表於2017-05-20

做開源專案的維護者,是怎樣一種體驗?

熱門開源專案的維護者都很不容易,素不相識的伸手黨會因為你沒有及時回答問題、沒有及時幫他們搜尋出他們想要的答案而開罵,開源專案維護者們往往會憋出心理疾病來的。如果你有開源專案,或許已有體會了。

Nolan Lawson 是微軟 Edge 瀏覽器 Web 平臺的 PM。參與了多個開源專案,比如:PouchDB、optimize-js 等。做開源專案的維護者,是怎樣一種體驗?請看他這 7 年的切身體會。

幾百個人排成一個隊伍,候在你家門外。他們耐心等待你去解答問題、聽他們的抱怨、回覆 Pull Request 和 Feature Request 。

你想去幫他們所有人,但你一直拖到現在。也許你辛苦工作了一整天,或者你累了,再或者你只是想跟家人和朋友享受週末。

但你如果登陸 github.com/notifications,Notification 會不斷提醒有多少人在等著你:

screenshot showing 403 unread GitHub notifications

當你設法找到一些空閒時間,你開門迎接第一個人(即處理第一個問題,其中可能包含不止一個人,下同)。他們足夠善意;他們想使用你的專案,但在 API 上陷入一些困惑。他們把程式碼貼上到 GitHub 評論上,但是忘記了或者不知道怎麼格式化程式碼,結果程式碼一團糟。

還好,你編輯了他們的評論以新增程式碼塊,把程式碼格式化了。但仍有許多程式碼需要讀。

另外,他們對問題的描述有些讓人難以理解。也許英語不是他們的母語,或者他們在書面表達上能力不足。不管怎樣,你努力去理解他們提交的文字段落。

你疲倦地看了一眼,排在隊伍後面等待的另外幾百個人。你可以花半個小時去理解這第一個人的程式碼,或者你可以只是瀏覽一遍然後給出一些教程或者文件的連結,說不定可以幫助他們解決問題。你還愉快地建議他們嘗試 Stack Overflow 或者 Slack 。

第二個人皺著眉頭,臉上露出不悅的神情。他們不斷抱怨你的專案如何浪費了他們生命中的兩小時,因為某個 API 沒有宣傳中的效果。他說的話很刻薄,讓你很不舒服。

你沒有在這個人身上浪費太多時間。你簡單地說道,“這是一個開源專案,且由志願者維護。如果程式碼中有 Bug,請提交一個可復現的測試案例或者 PR 。”

第三個人遇到的是一個很常見的錯誤,解決方法很簡單。你之前看到過幾次這個錯誤,但是一時想不起解決方法在哪。Stack Overflow?維基?郵件列表?在谷歌搜尋了幾分鐘後,你貼上上了一個連結然後關閉了這個 Issue 。

第四個人是一個定期的貢獻者。你從多個社群討論會和兄弟專案sibling project 中識出了他們的名字。他們陷在一個十分晦澀的 Issue ,並提交了一個 Pull Request 來解決它。很不幸這個 Issue 很複雜,所以他們的 PR 中包含許多枯燥的段落,來解釋問題。

再一次地,你瞥了一眼還在排隊等待的幾百號人,你知道這第四個人在他們的解決方案上花了很多工夫,並且可能這個解決方案是合理的。Travis 測試透過,所以你打算只評論句“LGTM”,然後合併掉這個 Pull Request 。

然而,你之前被這類情況傷過。在過去,你合併了一個 PR 但沒有經過充分的評價,最終因為一些你沒有預見到的問題,它導致了新的麻煩。也許是測試透過了,但效能下降了 10% 。或者它引發了一個記憶體洩漏。或者可能這個 PR 讓新使用者對專案感到困惑,因為它使得 API 看起來過於複雜。

如果現在你合併了這個 PR,以後可能會有更多的問題,因為你為解決這個人的問題而打斷了另一個人的工作流程。所以你把它放在次要位置,等有了更多時間再去處理它。

第五個人發現了一個新 Bug,但你知道實際上它是兄弟專案中的一個 Bug 。他們說這阻礙了他們啟動 App 。你知道這是個大問題,但只是眾多問題中的一個,所以你此刻沒有時間去修復它。

你回應道,這看起來是一個真實的問題,但是它更適合在另一個 Repo 中開啟。所以你關閉了他們的 Issue,把它複製到了另一個 Repo,然後你新增一個評論提示,在程式碼中從哪裡開始修復它。儘管你懷疑他們實際上會這個做。很少人會。

第六個人只說道“現在是什麼情況/狀態?”你不知道他們在談論什麼,所以你看一下上下文。關於專案中的一個長期存在的 Bug,他們在冗長的 GitHub 執行緒上進行了評論。許多人不同意這個問題目前的解決方案,所以產生了許多討論。

在這個特定 Issue 下有超過 20 條評論,要讀完並記住,需要花費你很長的時間。所以你僅僅回應道,“對不起,這個 Issue 開放了一段時間了,但還沒有人解決它。我們仍試著去理解問題的範圍,最好是開一個 Pull Request !”

第七個人只是個 GreenKeeper 網站機器人。他們的問題很簡單,除了這個特殊的 Repo 中有相當碎片化的測試,且這個測試由於看起來像是謬誤的原因失敗了,所以你不得不重新測試看是否透過。你重啟了這個測試,並試圖讓自己記住在 Travis 有機會執行後再去觀察一下。

第八個人開了一個 Pull Request,但所在的 Repo 相當活躍,另一個維護者已經做出反饋。你看了一眼執行緒,你相信其他維護者會處理好,所以你標記它為已讀,然後走開繼續。

第九個人遇到的似乎是個 Bug,而你之前也沒見過。但不幸的是,他們對“這個問題實際是如何發生的”沒有提供足夠的細節。是什麼瀏覽器下出現的?哪個 Node 版本?哪個版本的專案?他們用什麼程式碼來複現它?你讓他們做出澄清,然後關掉這個標籤。

問題不斷湧進

不一會兒,你接待了 10 到 20 個這樣的人。仍有 100 多個在排隊等待。但此刻你感到精疲力盡;每個人不是抱怨,就是有問題要解答或者是有增強的請求。

在某種程度上,這些 GitHub 通知就是不斷湧出你專案中差的一面。當他們滿意你的工作時,就不會有人建立一個 Issue 或 Pull Request。只有當他們發現有所缺失,才會如此。即使你只花了一點時間閱讀這些通知,在精神和情感上都是消耗。

你妻子觀察到在例行完這些公事之後你總是暴躁易怒。也許你發現自己總是沒緣由地對她厲聲呵斥,僅僅是心情不好。她問你:“如果開源工作這麼讓你憤怒,為什麼你還要做它?”你找不到一個好的答案。

你可以暫停;事實上目前你可能已經有所體會了。在過去,你曾從 GitHub 休假過一兩個星期,只為了精神健康。但最後因為有幾百個人在耐心等待(你去處理問題),不得不停止休假。

如果你過去持續跟進 GitHub 通知,你可能每天要處理 20-30 條。相反,你讓它們堆積,所以現在攢了幾百條。你感到內疚。

在過去,由於這樣或那樣的原因,你確實讓這些 Issue 堆積。你或許看到一條數個月都沒人應答的 Issue 。通常,當你返回找到那個 Issue,提出這個 Issue 的人從不回應。或者他們這麼回應,“我們放棄了你的專案而用了另一個,這樣我的問題就解決了。” 這讓你感覺很糟,但你明白他們的挫敗感。

你從經驗中得知,對於這些陳舊的 Issue,最實用的回應往往是隻說句,“我要關閉這些舊的 Issue,如果這對你仍是個問題,或者你能提供更多的細節,請重新開一個 Issue 。”通常沒有人回應。有時候有,也僅是一個憤怒的評論,抱怨怎麼讓他們等這麼久。

所以現在你想更勤快地處理你的通知收件箱。幾百條太多。你渴望這個數字縮減到一百,幾十,或者甚至是神話般地清空。所以你奮力前行。

吸引新的貢獻者

在處理完足夠多這樣的 Issue 後,即使你的收件箱最終被清空,最後可能仍會積壓大量的 Bug 和 Pull Request 。標籤可以起到作用——例如,你可以把 Issue 標記為“需要復現”或“有測試用例”或者“很讚的首個補丁”。“很讚的首個補丁”尤其有幫助,因為他們常常可以吸引到新的貢獻者。

然而,你傳送能吸引到新貢獻者的那一類 Issue ,往往是處理起來非常簡單的那一類,這一類 Issue 由新的志願者去記錄,比你親自去做更有價值。你建立了一些這類的 Issue,因為你知道它的價值所在,讓新人參與到開源,當這條 Pull Request 的作者告訴你“這是我在開源社群做的第一個貢獻。” 你感覺很棒。

但你知道他們回來的希望很渺茫;通常這些朋友不會成為定期貢獻者或維護者。你懷疑是不是你哪裡做錯了,你在哪方面改進,才能吸引住新的貢獻者來幫你減輕負擔。

你有一個專案幾乎就是靠自身維持的。你多年沒碰了,但有一幫維護者會回應每一個 Issue 和 PR ,所以你不必親自去。你非常感激這些維護者。但你不知道你做了什麼才使得這麼多貢獻者投入這個專案,而其他專案最後都是你,且只有你自己負責。

向前看吧

你不願去建立新專案,因為你知道它只會增加你的維護負擔。事實上,這裡有一種反效應,你做得越成功,在 GitHub 通知上得到的“懲罰”就越多。

你仍能回想起這種建立的快感,從零開始寫一個新專案以及解決一個之前未解決問題的喜悅。但是現在你開始衡量這種喜悅,因為任何新專案必定會從舊專案中奪走時間。你不知道是否是時候該正式摒棄你的一箇舊 Repo,或者把它標記為 Unmaintained

你不知道在你倦怠之前,這樣的情況還要持續多久。你曾考慮將開源工作作為你的白天工作,但是自從你和真正從事開源為生的朋友交流後,你知道這通常意味著,讓一個特定的開源專案作為你的白天工作。這對你無益,因為你有幾十個跨越多個領域的專案,這些都在爭奪你的時間。

你最想要的是更多的專案可以自身獨立維持,你嘗試去遵守所有的最佳實踐:你有 CONTRIBUTING.md 和行為指導,你熱情地交出擁有的特權,給任何提交高質量 PR 的人。然而每個專案都這麼做,也很耗費精力,所有你沒有你期望的那樣勤奮。

你也為此感到內疚,因為你知道開源常常被看做是有特權的白人男性(比如你自己)的專屬俱樂部。所以你擔心你做的還不夠,去解決那樣的問題。

更重要的是,你感到內疚:內疚來自於你知道你本可以幫助有些人解決他們的問題,但你讓他們的 Issue 在關閉前被無視了好幾個月,或者有人在你的 Repo 開了他們第一條 Pull Request,但你沒有時間去回應,這可能因此讓他們沮喪到永遠不想再參與開源。你的內疚是因為你已做的事情,也是因為你沒做過的事情,以及因為你沒能招募到更多的人分享你的不幸而有負罪感的經歷。

集中到一起

以上我說的一切都是基於我自己的經驗。我不能聲稱自己代表所有開源軟體工作者,這是我自己的感覺。

我從事開源工作已經有很長一段時間了(大約 7 年),我一直不願去抱怨任何這些牢騷,因為我擔心會被理解為是本應瞭解更多的前輩在這裡誇張地發牢騷。畢竟,這種處境不是我自己造成的嗎?我可以隨時離開 GitHub;我沒有跟任何人籤合約。

還有,我不該感激嗎?我從事的開源工作幫助我在社群樹立了地位。我獲得了在會議做演講的邀請。在 Twitter 上我有幾千號粉絲,他們傾聽我的想法,並對我的意見給予很高的評價。可以說,我得到微軟的工作是因為我的開源經歷。我還有什麼可抱怨的?

然而,我知道許多其他處在與我同樣位置的人都已倦怠。夥伴們也都曾熱情地合併 Pull Request ,處理 Issue,寫部落格展示他們的專案,之後就消失得無影無蹤。對於其中有些人,我甚至不願在他們的 Repo 中開 Issue 。因為我知道他們不會回應,我不反對他們,但我擔心自己會變成他們一樣。

我已經採取了大量的自我保護措施。我不再使用 Github 通知介面——我使用電子郵件過濾器,這樣我可以基於項(Unmaintained 這一類可以忽略)或者通知的類別(提到過的或者我評論過的執行緒通常會有優先權)來分類通知。因為是電子郵件,這也有助於我離線工作和在同一處管理事務。

我常常會出乎意料地收到在專案上請求支援的郵件,而這個專案我停止維護已經很久了(例如這個專案,我仍至少每月會收到一封),而通常我都是不回應。我還選擇忽視我博文下的評論,不回應 Stack Overflow 的回答和郵件列表下的問題。我還積極地取消關注了那些我認為其他人維護得足夠好的 Repo 。

這種情況如此令人沮喪的另一個原因是,你越來越發現處理 Issue 從專案實際維護中奪去太多時間,換句話說,我通常只有足夠讀取Issue,然後說“對不起,我此刻沒有時間看”的時間。僅僅是回應的行為,就會佔據我為開源預留的大部分時間。

Issue templatesGreenKeeperTravistravis_retryCoverallsSauce Labs … 有太多技術工具可以處理開源維護問題,我很感激有這些工具。如果沒有這些自動化工具,我就不可能保持頭腦清醒。但在某些時候,你會遇到很多 Issue,它們裡面涉及的社會性問題比技術性問題更多。一個人不足以說明。我甚至沒有進到前100位 npm 維護者榜單,我就已經累覺不愛了;我無法想象那 100 個人是什麼體會。

我已經告訴我妻子,如果當我們打算開始要孩子,我還是放棄開源工作為好,我覺得自己沒有能力兼顧撫養家庭和維護開源專案,我預料到,放棄開源才是我核心問題的解決方案。我只希望它會以一種積極的形式到來,就如開始我人生新的篇章,而不是以一種消極的形式,比如毫不客氣地倦怠。

最後的一點思考

如果讀到這裡,你對困擾開源社群的問題和潛在的解決方案感興趣,你可能會想研究下 Nadia Eghbal 的《Roads and Bridges》。它可能是對該問題最清晰最深入的分析。

我也樂於接受建議,儘管我在心中牢記我不願在開源專案中把金錢和勞動混在一起(也許是出於天真的理想主義)。但我曾在其他專案中看到它是有效的。

請注意,儘管上文表達了開源消極的一面,但我仍覺得它是我生活裡一個有價值的補充,我沒有任何後悔。但我希望這篇文章對大家有幫助,讓你們看到成為自身成功的犧牲者是什麼感受,以及你會因為未完成的工作而感到沉重。

我從參與開源的經歷中學到的一點就是:你參與越多,對你的要求就越多。我意識到這樣的問題,並沒有解決方法。

相關文章