灣區日報·第857期
作為一名開源項目的維護者是一種什么樣的體驗
原文鏈接
by zzq
數百人站在你家門口,耐心地等你去解決他們地問題,抱怨,合并代碼請求,新功能請求。
你想去幫助他們所有人,但是你現在正在推遲??赡苣憬裉旃ぷ鞑豁樌?,或者你累了,或者你只是想和家人朋友享受一個周末。
如果你去看一眼github上的通知,它總會提醒你有多少人在等。
當你安排出一些空閑時間,開門迎接第一位等待的人。這些人都是很好心的,他們嘗試使用你的項目但對API有些困惑,他們已經把代碼帖在Github評論里,但他們忘了或者是不知道怎么去格式化代碼,所以他們的代碼真的是一團亂,難以閱讀。
幸運的是,你編輯他們的評論來添加一個代碼塊,代碼很好的格式化了,但仍然有一大堆代碼要去讀。
然而,他們對問題的描述難以理解??赡苓@個人的母語不是英語,或者他們不擅長通過文字進行交流,你也不確定是什么原因。無論如何,你艱難地去理解他們所寫的段落。
看到后面還有上百人在排隊等候,你有些不耐煩了。你可以花費半小時去理解這個人的代碼,或者你可以僅僅瀏覽以下然后給出一些教程和文檔的鏈接,這很可能無法解決他們的問題。你也可以興奮的告訴他們去嘗試以下StackOverflow或者Slack的Channel。
下一個人皺著眉頭。說出一大堆的抱怨話,他們覺得由于你的某個API沒有按照公布的方式工作而浪費了他們生命中的兩個小時。他們的風涼話讓你想你心里不爽。
你沒有在這個人身上浪費很多時間。你說:“這是一個開源項目,都是志愿者在維護。如果代碼里有bug,請提交一個可再現的測試用例或者一個pull request。
下一個人遇到了一個很常見的錯誤。你知道之前已經見過這種錯誤好幾次了,但是想不起來解決方法在哪里。StackOverflow?wiki?郵件列表?Google了一番之后,你貼出了個鏈接,關閉了這個問題。
下一位是一個普通的代碼貢獻者。你是通過各種社區論壇和兄弟項目認出他們的名字的。他們遇到了一個難解的問題,發送了一個代碼合并的請求來解決這個問題。不幸的是這個問題很復雜,他們的Pull Request用了不少篇幅來解釋這個問題。
你再一次瞄了一眼排隊等候的人。你知道這個人在他們的解決方法里做了很多工作,可能是一個合理的解決方案把。測試用例通過了,所以你冒險合并了這段代碼。
然而,你之前曾上過這樣的當。當時你沒有仔細評估就合并了一個Pull Request,最后由于一些你沒有考慮到的問題而引發一個小災難。通過了測試,但可能導致性能下降十分之一。或許它可能導致內存泄露??赡苓@個Pull Request使得API看起來更加復雜從而對新使用者造成很多困擾。
如果現在合并這個PR(Pull Request),明天可能會遇到更多的問題,因為你可能為了解決某一個人的問題而破壞了別人的工作流。把這個問題先擱置在這,以后有時間了再解決。
下一個排隊的人發現了一個新BUG,你知道這BUG在另一個兄弟項目中頁存在。他們說這個BUG阻止了他們發布APP。你知道這是個大問題,但只是其中的一個,所以你現在沒有時間解決它。
你回答說這開起來確實是一個問題,也許開辟一個新倉庫更合適。所以你關閉了這個問題并把它拷貝到另一個倉庫里,添加了一條評論告訴他們應該仔細檢查哪部分代碼來修復bug。你不確定他們是否真的會按照你說的做。然而,大部分都沒有這么做。
下一個人僅僅問了“現在是什么情況?”。你不知道他們到底在說什么,所以仔細看了以下上下文。他們在github上的一個項目中評論了一個長期存在的Bug,很多人不同意這個問題的解決方案,因此引發了很多討論。
在這個特殊的問題上有超過20條評論,看完所有評論會消耗很多時間,所以你僅僅回復了“對不起,這個問題存在有一段時間了,但還沒有人解決它。我們正在努力解決問題,要是有人解決了給我們發個代碼合并請求會是一個好的開始。
下一位的問題比較簡單。除了這個倉庫有一些古怪的測試數據。這些測試失敗的原因看起來很不真實,所以你必須重新運行來測試以下。你提醒自己等數據測試完成后再回過頭來仔細看看。
下一個人往那個很活躍的倉庫上提出了代碼合并請求,另一個維護者正在寫反饋,你大概瀏覽了一下,由于對另一位維護者比較信任,所以把這個問題設置為已讀,繼續往下看。
下一個人似乎遇到一個BUG,這個BUG你以前沒見過。不幸的是,他們提供的數據不充足:用的什么瀏覽器?Node的版本是哪個?用的項目的哪個版本?他們在開發中使用了哪些代碼?你要求他們明確以下這些信息并關閉了這個標簽頁。
** The constant stream **
過了一會兒,你大概瀏覽了一二十個這樣的人。后面仍然有超過一百人。但是現在你覺得累了,每個人要么是發抱怨,提問題,要么是要求完善該項目。
從某種意義上來說,Github的通知功能展示的永遠都是你項目的消極的一面。當他們對你的工作感到滿意的時候就不會新建一個issue或者request。他們只有在發現不足之處的時候才會這么做。即使你只花一點實踐來瀏覽這些通知,它也可能是你心理上和感情上感到疲憊。
你的伴侶注意到每當做完這些工作的時候都會變得脾氣暴躁。你可能發現自己毫無理由的沖她發火,僅僅是因為你自己心情不好?!叭绻鲞@些開源項目使你生氣,為什么還要做呢?”她問。這時候你無法回答。
你可以休息以下了。事實上這使你自找的。過去,你為了自己的身心健康會從Github銷聲匿跡一兩周。但是你知道那樣做的結果就是現在的狀況:好幾百人排隊等候。
如果你僅僅保留Github通知里的最上面那些通知,可能就會只有20-30個issue需要處理了。然而你卻讓他們積累了起來,導致現在已經有好幾百個了,你覺得很有愧疚感。
過去,出于這樣或那樣的原因,你從來不讓issue累積起來。可能偶爾會見到一個issue被放置了幾個月都沒處理。你再次去處理的時候提出issue的那個不再回復你了,或者他們說他們用其他項目替代了你的項目從而解決了問題。那種感覺讓你覺得很糟,但是你也理解他們的難處。
你從經驗中得知對付陳舊的issue最實用的方法是告訴他們“我把舊的issue關了,如果你還沒有解決這個問題請再開一個issue或者提供更詳細的信息”。通常他們不再回復。有時候會回復也只是很生氣的表達他們等了這么長時間。
所以現在你處理Github的通知更加勤奮了,數百人在排隊等候,你渴望有一天排隊的人減少到100以內,或者一打,甚至是神話般的0。所以你奮力前進。
吸引新的代碼貢獻者
就這樣處理了足夠多的issue,即使你真的到達了那個“零點”(即要處理的通知為零個),你仍然還有一堆Bug沒有解決,還有很多代碼合并請求。加標簽可以有些幫助,比如給issue加上“需要新的版本”、“有測試案例”或者“添加第一個補丁”?!疤砑拥谝粋€補丁”這個標簽很有用,因為它經常會吸引新的貢獻者。
然而,你注意到吸引新貢獻者的那些issue都是簡單的問題,處理這些問題并且解釋它耗費的時間比你自己去解決所花費的時間更多。你明知是這樣卻還添加那些標簽,因為當你聽到別人說這是他第一次為開源項目做貢獻時你的心里十分高興。
你知道他們很可能會提供反饋信息。一般這些人不會成為長期貢獻者或代碼維護者。你不知道這樣做是否正確,或許這樣做會吸引到一些真正的維護者來減輕你的負擔。
你有一個項目是可以自維護的。你已經好幾年沒碰它的,但仍然有一群維護者來處理issue和PR。你非常感謝那些代碼維護者。但你找不到方法在這個項目上吸引到代碼維護者, whereas other projects wind up as your responsibility and yours alone(怎么理解?)
向前看
你不愿意去創建新的項目了,因為你知道這只會增加你維護代碼的負擔。事實上,這里有一個有悖常情的現象,你越成功,就會受到github通知的更多懲罰。
你仍然可以回憶起創造的興奮,東拼西湊寫個項目并解決了之前沒有被解決的問題時的喜悅之情。但是現在你根據經驗知道任何一個新的項目都會偷走你維護舊項目的時間。你有時候頁考慮是否把某個舊項目正式標記為“不推薦使用”或者“不再維護”。
你不知道在自己崩潰之前還能撐多久。從跟那些以做開源項目為全職工作朋友聊天中,你知道把開源項目作為全職工作會允許你在某個項目上投入更多時間,你也考慮了這件事,但是這并不會給你很多幫助,因為你有幾十個開源項目競爭你的時間。
你最渴望的是有更多項目可以自維護。你盡量按照規范:詳細的配置說明,代碼風格,對那些提交優質PR的貢獻者更多的權限。為每個項目做這些事情是挺累人的,也許是我不夠勤奮吧。
你知道開源更多的被認為是特權白人的排他性俱樂部,你對這感到遺憾,擔心自己在解決這件問題上做的不夠。
更重要的是,你感到愧疚:你明知道自己可以幫助一些人解決問題,但是你卻讓問題擱置數月然后關閉了它。你知道有些人是第一次對開源項目做貢獻但是你卻沒有回復他,這樣你可能就會打擊了他對開源的熱情,這也讓你感到愧疚。你對自己做的事感到愧疚,沒做的事也感到愧疚,因為你沒有招募新人來分享你這愧疚的體驗。
** 總結以下吧 **
我以上所述都是基于我個人的真實經歷。我說的并不代表所有從事開源軟件事業的人的心聲,但代表了和我有相同感受的人。
我從事開源事業大概七年了,也不愿意這樣抱怨,因為我擔心這會被認為是夸張的抱怨。畢竟這些都是我自找的,我本可以隨時離開Github,我對別人沒有任何該履行的義務。
或許我還應該感到愉快呢?我在開源軟件方面的工作給了我現在在社區的地位。我獲得了在大會上發言的機會。Twitter上有數千粉絲,他們贊同并捍衛我的的觀點??梢哉f我之所以能在微軟公司有一份工作,都要歸功于我在開源方面的工作。我到底是在抱怨誰呢?
然而,我只要一些和我有相似感受的人都已經爆發了。之前他們都是熱心的合并代碼,解決問題,在博客上寫關于他們項目的文章,但是有一天他們突然消失了,你再也找不到他們了。對于這些人,我甚至懶得去在他們的代碼倉庫里新建一個issue,因為我知道他們肯定不會回復。我不是在指責他們,我只是擔心自己有天也會和他們一樣離開github。
我已經采取一些對我友好的措施了。我不使用Github通知的接口而是用郵件過濾器,所以能對這些通知根據項目(不維護的項目被忽略)或通知的類型(我曾發表過評論的具有較高的優先級)進行分類。郵件也能支持離線工作和把所有東西集中起來。
對那些我已經停止維護的項目的問題的郵件我都標記為藍色(但是一般我仍然會每一個查看一次),并且不予回復。我忽略博客的評論,StackOverflow的上回答的回復以及郵件列表里的問題。我甚至對那些我覺得其他人已經維護的不錯的項目取消關注。
讓我感到沮喪的一個原因是解決這些issue消耗了我維護項目的時間。換句話說,雖然我經常僅僅回復“對不起我現在沒時間處理這個問題”,但這些回復也消耗掉我放在開源項目上的時間。
issue模板,GreenKeeper, travis_retry, Sauce Labs, 有這么多針對開源項目的技術解決方案,我很感謝他們。如果沒有這些自動化工具我不能專心工作。從某種意義上來說你對一個issue提出反對,它造成的更多的是社交問題而不是技術問題。一個人這么做還不會怎么樣。我甚至還不是npm前100維護者就已經感覺到自己被壓榨。不能想象那些前100維護者的感受。
我甚至告訴我的妻子,等我們有了孩子,我從開源界退出。我不能想像自己如何能邊做開源邊撫養家庭。我猜測這最終會解決我的問題:唯一的選擇。我希望它能以一種正面的方式到來,就像開啟人生的新篇章,而不是以一種消極的方式,比如突然粗魯的爆發了。
** 結束語 **
如果你已經讀到這里了并且對困擾開源社區的問題和解決方案感興趣,你可能會更想讀一下Nadia Eghbal所寫的一篇文章Roads and Bridges。這可能是最這個問題最透徹的分析了。
我樂于接受大家的建議,雖然我知道我很不情愿在我的開源項目中把金錢和勞動力混為一談(可能是一些愚蠢的理想主義的原因)。但是我發現在其它項目中這方法很有用。
希望大家理解,雖然我上面表達了很多負面情緒,我仍然覺得開源是我人生中有價值的加分,我一點都不后悔。但我仍然希望這篇文章能讓大家知道成為自己成功的受害者的感受,以及被所有未完成工作拖累的感受。
如果我能從開源中學到一點東西的話,那就是:你做的工作越多,你得到的工作就越多。我覺得這個問題現在還沒有解決方案。
** 全文完(2017.3.16) **
不完善之處日后抽空修改,翻譯不得當的地方請指正并多多海涵