热门开源项目的维护者都很不容易,素不相识的伸手党会因为你没有及时回答问题、没有及时帮他们搜索出他们想要的答案而开骂,开源项目维护者们往往会憋出心理疾病来的。如果你有开源项目,或许已有体会了。
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 。
第四个人是一个定期的贡献者。你从多个社区讨论会和兄弟项目中识出了他们的名字。他们陷在一个十分晦涩的 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 templates、GreenKeeper、Travis、travis_retry、Coveralls、Sauce Labs … 有太多技术工具可以处理开源维护问题,我很感激有这些工具。如果没有这些自动化工具,我就不可能保持头脑清醒。但在某些时候,你会遇到很多 Issue,它们里面涉及的社会性问题比技术性问题更多。一个人不足以说明。我甚至没有进到前100位 npm 维护者榜单,我就已经累觉不爱了;我无法想象那 100 个人是什么体会。
我已经告诉我妻子,如果当我们打算开始要孩子,我还是放弃开源工作为好,我觉得自己没有能力兼顾抚养家庭和维护开源项目,我预料到,放弃开源才是我核心问题的解决方案。我只希望它会以一种积极的形式到来,就如开始我人生新的篇章,而不是以一种消极的形式,比如毫不客气地倦怠。
最后的一点思考
如果读到这里,你对困扰开源社区的问题和潜在的解决方案感兴趣,你可能会想研究下 Nadia Eghbal 的《Roads and Bridges》。它可能是对该问题最清晰最深入的分析。
我也乐于接受建议,尽管我在心中牢记我不愿在开源项目中把金钱和劳动混在一起(也许是出于天真的理想主义)。但我曾在其他项目中看到它是有效的。
请注意,尽管上文表达了开源消极的一面,但我仍觉得它是我生活里一个有价值的补充,我没有任何后悔。但我希望这篇文章对大家有帮助,让你们看到成为自身成功的牺牲者是什么感受,以及你会因为未完成的工作而感到沉重。
我从参与开源的经历中学到的一点就是:你参与越多,对你的要求就越多。我意识到这样的问题,并没有解决方法。
转载请注明:开发者关系 »