作为一个开源软件的作者是一种什么样的感受?

根号三
根号三
2017-03-15

你的门外有几百人在排队。他们耐心地等待着你回答他们的问题、抱怨、pull requests 和 功能请求。

你想帮助他们,但是现在你要关闭它们。或许你已经辛苦工作了一整天,或者你累了,或者你只是想和你的家人、朋友享受一个周末。

但是如果你访问 github.com/notifications,它会持续地提醒你有多少人正在等着你:

screenshot showing 403 unread GitHub notifications

当你设法找到一些空闲时间后,你打开门并接待了第一个人。他们非常善意。他们尝试使用你的项目,但是在 API 上遇到了一些困惑。他们将自己的代码粘贴到了 GitHub 评论区中,但是他们忘记或不知道怎样格式化它,所以他们的代码非常混乱,难以阅读。

你热心地将他们的代码放到一个代码块中,因此它们有一个很友好的格式。但是你仍然需要阅读很多代码。

并且他们对于问题的描述也很难理解。或许这个人不以英文为母语,或者他们有残疾使得他们很难通过写作进行沟通。你不确定。总之,你很难理解他们发布的这一段话。

你很疲劳。你看了看排在他后面的数百个其他人。你可以花费半个小时来理解这个人的代码,或者你可以选择跳过他,只是给他一些教程和文档的链接,这些有助于帮助解决他们的问题。你也可以善意的建议他们尝试 Stack Overflow 或 Slack channel instead。

队伍里的下一个人脸上皱起了眉头。他们抱怨你的项目浪费了他们两个小时,因为某个明确的 API 并没有像宣传的那样如期工作。他们刻薄的言辞让你感觉很不舒服。

你不想在这个人上浪费太多的时间。你简单地回复了:“这是一个开源项目,并由志愿者志愿维护”。如果代码中有一些 bug,请提交一个可复现的测试代码或者一个 PR。

接下来的一个人遇到了一个非常普遍的错误,但是有一个很容易的解决方案。你知道你之前见过这个错误,但是就是想不起来解决方法写在了哪里了。Stack Overflow? wiki? 邮件?Google 了几分钟以后,你粘贴了一个链接并关闭了这个问题。

下一个人是一个长期贡献者。你从各种社区论坛和兄弟项目中认出他们的名字。他们遇到了一个非常深奥的问题,并且提出了一个 pull request 来解决它。不幸地是,这个问题太复杂了,以至于他们的 PR 包含了好几段文字来解释它。

你的眼睛再一次瞥了外面仍然在排队的几百人。你知道这个人在他们的解决方案上做了大量的工作。并且这可能是一个合理的方案。Travis 的测试已经通过了。所以你想回复一个 "LGTM" (译者注:Looks Good To Me.) 然后合并它。

然而,在之前你曾吃过这样的亏。你曾经合并过一个 PR 但是并没有完整的评估它。最后它让你很头痛因为你没有预料到它带来的问题。或许通过了测试,但是性能下降了十分之一。或者造成了内存泄漏。又或者因为导致了这个项目的 API 过于复杂以至于对新用户来说容易困惑。

如果你现在合并了这个 PR,明天你可能会遇到更多的问题,因为你通过解决了这个人的(非常边缘的)问题打破了别人的工作流。因此你决定先将它滞后,稍后当你有更多时间时你会再处理它。

下一个人发现了一个新 bug,但是你知道它实际上是一个兄弟项目中的 bug。他们说这个问题阻止他们运行应用。你知道这是一个大问题,但是只是许多问题中的一个。你现在没有时间来马上修复它。

你回复到看起来这真的是一个问题,但是在另一个 repo 里报告这个问题更合适。因此你关闭了这个问题,并把它复制到另一个 repo 里面。然后添加一个评论建议应该从代码中的哪个地方开始修复它。虽然你怀疑他们是否会这样做。(很少啦)。

接下来的一个人只是说了一句“这是什么状态?”。你不确定他们到底在讨论什么,因此你查看上下文。他们关于一个项目中的长期 bug 的评论导致 GitHub 评论板很冗长。许多人不同意这个问题原本的解决方案,所以它产生了很多讨论。

在这个问题上有 20 多条评论,你需要花费很长的时间才能阅读并理解所有的内容。所以你只是回复了一句:“对不起,这个问题已经打开了有一段时间了,但是到现在还没有人解决它。我们仍在试着理解问题的范围。一个 pull request 或许是一个好的开始。”

下一个人仅仅是一个 GreenKeeper bot。这个处理起来很轻松。除了这个特定的仓库有着相当脆弱的测试,并且因为一个看起来并不真实的原因而测试失败了,因此你为了能够通过测试必须重新启动它。你重启了测试并尝试提醒自己在稍后 Travis 能运行它时检查一下。

接下来的那个人打开了一个 pull request,但是是在一个相当活跃的仓库上,因此另一个维护者已经提出了反馈。你瞥了一眼大致过程,你相信这个维护者能够处理这个问题。因此你将它标记为已读并继续下一步。

下一个人在运行时出现了一个你之前从未见过的大问题。但不幸的是他们没有提供一丁点关于问题实际发生时的细节。用了什么浏览器?Node 的哪一个版本?项目的哪一个版本?使用哪些代码能重现它?你要求他们重新提供一些细节并关闭了这个页面。

The constant stream

过了一段时间后,你已经处理了一二十个这样的情况。但是仍然还有几百个人在等待着。但是现在你已经感到精疲力尽了。每一个人都有他自己的抱怨、问题、或者是新需求。

从某种意义上来说,这些 GitHub 通知就是一个关于你的项目的的不间断消极流。没有人会因为对你的所作所为感到满意时打开一个 issue 或者是 pull request。他们只会在发现缺少一些东西时才这样做。尽管你只花费很少的时间来阅读他们的这些通知,但是仍然能让你在精神上和情绪上感到疲惫不堪。

你的伴侣观察到你在做完这些事情之后总是脾气很坏。或许你发现自己在毫无原因的嘲笑她,仅仅是因为你的心情很糟糕。“如果从事开源工作会让你如此生气,为什么你还要做呢?”她问道。你也没有一个很好的答案。

你可以休息一下。事实上你可以已经尝试过了。之前有一次,你远离 GitHub 给自己放了一两周的假期,仅仅是为了自己的心理健康。但是你知道你结束这种情况的原因是因为有数以百计的人们在耐心地等着你。

如果你保持关注并处理你的 GitHub 通知。或许每天只有 20-30 消息,更容易处理一点。然而你让它们在那里堆积,所以现在堆积了上百个。你感到内疚。

之前,由于某种原因,你真的让这些问题堆积在那了。你或许已经看到有一个问题已经几个月没有回复了。通常,当你回过头处理这样的问题时,打开这个问题的人一直没有给你回复。或者他们回复到:“我放弃了你的项目用了另外一个,所以问题已经解决啦。”这让你感觉很糟糕。但是你理解他们的失望。

从以往的经验中你学到了:对于这种陈旧的问题,更实际的回复是仅仅说一句:“我关闭这个旧问题啦,如果这个问题还存在或者你能提供更多细节的话请再重新打开。”通常情况下都没人回复。有时有人回复了一下,然而只是很生气的抱怨你让他们等待了这么长时间。

现在你尝试更频繁的关注你的通知。数百人的等待队伍实在是太长了。你渴望这个队伍的人数能够降到一百,或十几,甚至有一个 空收件箱 的神话。所以你继续。

招募一个新的贡献者

像上面这样处理了很多问题之后,即使你最终清空了收件箱,仍然会以积压了大量的 bug 和 pull request 而收尾。标签可以对你有所帮助 —— 例如,你可以将一个问题标记为“需要再现”、“存在测试用例”或者 “good first patch”。“good first patch” 尤其有帮助,因为他们常常吸引新的贡献者。

然而,你已经注意到了,通常吸引新贡献者的那些问题都是非常容易的问题 —— 对那些问题而言努力记录并且解释如何修复它比你只是自己修复它还重要。你创建了一些这样的问题,因为你知道让新人参与到开源项目中是值得的,当 pull request 的作者告诉你“这是我第一次向开源项目做出贡献”时,你会感到很开心。

但你知道他们不太可能会回来。通常这些人不会成为长期贡献者或维护者。你想知道你是否做错了,是否有更多你力所能及的可以引领新贡献者并且帮助减轻你的负担的事情。

在你的项目中就有一个几乎是自我维持的。你已经好几年没有碰过它了,但是有一个维护小组在答复每一个问题和 PR,因此你不用关注它。你极其感激这些维护者。但是你并不知道是因为做了什么事情才有如此多的维护者参与这个项目中,而其他的项目则以你独自负责而收尾。

展望未来

你不愿意创建新项目了,因为你知道它只会增加你的维护负担。事实上,有一个对立的现象是:你越成功,你从 GitHub 通知那里得到的“惩罚”就越多。

你仍然可以回忆起创作的激情,从头开始写一个新项目解决之前未解决的问题时的那种喜悦。但是现在你不喜欢这种喜悦,因为任何新项目都会从旧项目中窃取时间。你想知道是否到了正式放弃你的一些旧项目或者 标记它们为不再维护 的时候了。

你想知道在你崩溃之前你还能坚持多久。你之前考虑将开源作为你的日常工作。但是和一些真正将开源作为生活的人聊过之后,你知道这通常意味着可以将一个具体的开源项目作为你的日常工作。但是对你来说并没有什么帮助,因为你有横跨多个领域的 几十个项目,这些都在争夺你的时间。

你最想要的是有更多的项目可以自我维护。你尝试按照所有的 最佳实践:你有一个 CONTRIBUTING.md 和一个行为准则,你热情地向所有提交高质量的 PR 的人发出所有者权限。为每一个项目都做这些事情是非常辛苦的,所以,你并没有对自己想象中的那样勤奋。

自从你知道开源经常被视为一个为享有特权的白人(就像你一样)开设的高档俱乐部后,你也因为这个而感到内疚。所以你因为没有付出足够的努力来修复这些问题而焦虑。

无论如何,你感到内疚:你知道你可以帮助某人解决他们的问题但是反而让他们的问题腐烂了几个月然后关闭它而内疚,或者因为知道某个人在你的仓库发起了他们的第一个 pull request 但是你并没有时间去回复它而内疚,并且你可能还因此致使他们对开源长期感到气馁。你因自己的所作所为而感到内疚,因没能做到的事情感到内疚,并且不想招募更多的人来分担你不幸的内疚经历。

Putting it all together

我上面所说的都是基于我自己的经验。我不能声称代表了所有从事开源软件事业的人,但是这确实是我的感受。

我已经从事开源很长一段时间了(大概 7 年吧),我一直很讨厌抱怨这些事情,因为我担心这会被理解为应当更明白事理的人的夸张的牢骚。毕竟,这种情况不是我自己导致的么?只要我愿意我可以随时离开 GitHub,我对任何人都没有义务。

还有,我不应该感激么?我在开源方面的工帮助我在社区获得了名声。我被邀请在一些会议上演讲。我在推特有成千上万的粉丝在听我说的话并且高度尊重我的意见。可以说我之所以得到了微软的工作就是因为我在开源方面的经历。我该抱怨谁?

并且,我知道已经有很多跟我类似的人放弃了。那些人在无影无踪地消失之前曾积极地合并 pull request、修复问题,在博客上写一些关于他们项目的文章。对于其中一些人,我甚至都不会在他们的 repo 上打开 issue,因为我知道他们不会回复。我不会抱怨这些事情,但是我担心我也会走他们的老路。

我已经采取了很多自我保护措施。我不再使用 GitHub 的通知界面了,我使用邮件进行过滤。因此我可以基于项目(不维护的会被忽略掉)或通知类型(提到我的和我评论过的通常优先级更高)分类我的通知。由于通知是邮件,这也有助于我离线工作并且在一个地方处理所有的事情。

我经常会收到蓝色级别的邮件让我支持一个我已经停止维护的项目(例如,我每月至少收到一封关于这一个项目,通常情况下我不会回复他们。我也倾向于忽略我博客文章里面的评论、Stack Overflow 答案的回复和邮件里的问题。我基本上也不再关注那些我觉得别的维护者已经做得很好的 repo。

这种情况如此令人沮丧的原因之一是,我越来越觉得处理问题远比实际维护一个项目要花费时间。换句话说,我经常只有时间阅读一个问题然后说:“对不起,我现在没时间看这个。”仅仅是这样的回复就已经占用了我原本为开源预留的大部分时间。

Issue templates, GreenKeeper, Travis, travis_retry, Coveralls, Sauce Labs… 针对开源维护的问题,有这么多的技术解决方案。我非常感激它们。如果没有这么多自动化工具,我将不能保持专注。但在某些时候,相比技术问题,你遇到的更多的是社交问题。一个人成不了规模。我甚至不在 前 100 个 npm 贡献者 之列,就已经感觉到了压力。简直不敢想象那一百个人的感觉是什么样的。

我已经告诉我的伴侣,当我们决定开始拥有一个孩子时,可能我还是退出开源比较好。我不知道我怎样才能在撑起一个家庭和从事开源之间平衡时间。我预计最终这个将解决我的问题:核选择。我只是希望它能以一个积极的形式到来,像是开启了我的生活新篇章一样,而不是一个消极的形式。

结尾词

如果你已经阅读到这里,并且对开源社区的问题和潜在的解决方案感兴趣,或许你会想看看 Nadia Eghbal 写的 “Roads and Bridges”,这可能是对问题最清晰和最彻底的分析。

我也乐于接受建议,但是请记住,我非常不愿意在我的开源项目中将钱和劳动成果混在一起(由于傻傻的理想主义的原因)。但是我曾在 其他项目 中看到它处理的很好。

注意,尽管上边这些都是消极的,但是我仍然感觉开源已经成为了对我的生活很有价值的补充。但我希望这是一个有用的窗口,它可以感受到如何成为你自己的成功的受害者,并且没有完成就放下工作而感到压力。

如果说我在开源中学到了一件事,那就是:你做的工作越多,你就越需要工作。我知道这个问题无解。

本文根据 Nolan Lawson 的《What it feels like to be an open-source maintainer》所译,整个译文带有自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:nolanlawson.com/2017/03/05/what-it-feels-like-to-be-an-open-source-maintainer