夜天之书 #31 Make More Time Maintainer
这篇文章本来是在昨天的文章里一起发布的,但是有点写不过来,就给自己多留了一天。本文主要讲的是作为项目维护者,如何提高开源社区参与的时间利用率。
Choose your partner.
这是最重要的事,项目的维护者要有选择性的吸纳新的维护者。
毫无疑问,提升开源社区的创造力需要吸纳新的成员。作为项目的维护者,要想给自己留出时间思考,也需要吸纳新的维护者来分担事务性的工作。
首先得讲讲关于维护者头衔的认识。实际上,项目的维护很大程度上是个苦力活儿。一个比较健康的社区是这样的,头衔或权限是认可的一种形式。对贡献的感谢,不一定要跟头衔或权限挂钩,这只是其中一种形式。反正有人做了什么贡献,你大可以通过宣传渠道去讲,而不是必须有一个头衔。任何一个社区成员都可以做技术讨论,如果表现出来的技术强,方案好,就会被采纳。项目维护者的工作之一是在这个技术写作的过程当中,做一些合并 PR 和做出决策等协调工作。如果现有的维护者群体忙不过来了,再从社区当中吸纳合适的成员帮忙处理下事务。应该这么认识,而不是说维护者有特权或者高人一等。
有了这样的认识,就可以讲下一个观点了,即项目的维护者应当根据项目维护的需要吸纳新的维护者。这意味着你不应该为了自己从公司身份背负的不合理的“维护者人数”等指标提名一个不适合的人做维护者,也意味着你不需要刻意追求数量或者多样性,或者任何形式的政治正确。如果你降低或者违心地改变了维护者的标准,那么新的维护者不仅不会成为助力,还会产生摩擦成为新的负担。这并不少见,相当数量的开源社区就是这么变成政治斗争漩涡甚至分裂的。
选择维护者并没有一个普适的标准。Perl 社区最初是由 Larry Wall 一个人进行独裁,近年来他淡出主要开发人员圈子以后,社区逐渐形成了 28 人的 Core Team 治理群体。PostgreSQL 社区由 7 人的 Core Team 和 28 人的 Committers 群体处理所有工作。Apache 基金会的项目有一套比较固定的 PMC 和 Committers 的分层治理模型,具体到每一个项目,又会有各自选择 Committers 的倾向。例如 Apache Pulsar[1] 和 Apache Flink[2] 都公布了项目希望看到的 Committer 的品质。Spring 核心项目的维护者都是 Pivotal 公司或 VMWare 公司的员工,但是 Spring 核心项目显然也从海量的多样化的参与当中获益。
Linux 项目基本还是由 Linus 独裁,有若干个 Committers 能够协助 Review 补丁和处理项目事务。Linus 曾在一个视频当中提到,自己只以技术论高低,实际上只和大约 20 个人密切合作,大约 50 个人保持接触。所以,如果你的精力足够并且习惯处理所有事情,并不需要为了维护者的数字而刻意吸纳维护者。如果你像 Netty 项目的 Trustin Lee 那样从很早就和地球另一端的 Norman Maurer 紧密合作,这也是可行的。
如果说选择维护者有一个什么样的基础要求,我认为就是这个人在项目社区当中做出了与项目状况匹配的卓越的贡献,本人愿意成为维护者,并且现有的维护者愿意和这个人一起工作。
Write down your processes.
如果只提一个具体可行的减少项目维护负担的方法,那就是这一点。
每个开源社区都会有独特的做事的调性,这种调性往往是从最初的维护者群体的个人喜好生长出来,在与参与者的双向选择和磨合当中演进的。参与者的做事方式与社区的调性相符,维护者需要的沟通成本将会显著降低。
为了帮助参与者了解社区的调性,往往需要维护者出面重复解释,而减少重复解释负担的最好方式就是写下文档。不管是参与者自主阅读文档,还是在解释的过程中直接甩出一个文档链接,都能极大的节约维护者需要消耗的时间。
这些文档里首要的是项目的目标和设计,这是每个对项目感兴趣的人都会问的问题。真的,不是流程和怎么做,真诚想要为项目的发展做出贡献的人,首先会想知道这个问题。对于项目维护者来说,这也是帮助自己在漫长的开发和维护周期里不要忘记自己从何处来,要往哪里去的灯塔。
其次是一些约定俗成的文档,例如 README 和 CONTRIBUTING 等等。如果项目比较复杂,可以考虑准备一份 Dev Guide 分类介绍参与贡献所需要知道的知识。对于想要吸纳成维护者的成员,最好还要保证其对社区行为准则的知悉和理解。行为准则通常是一些基本的平等尊重原则,大部分开源社区很少遇到坏的案例,但是一旦出现,就要认真应对。否则可能陷入政治斗争的漩涡,甚至产生项目分裂或停摆的风险。
最后,不仅仅刻意写就的文档是文档,其实社区成员的交流就是现成的“文档”。我在加入一个社区之后会做的一件事就是入乡随俗,也即看看别人是怎么做的,模仿社区当中受欢迎的行为。模仿是人类的天性,如果你希望别人这么做来减少自己维护项目的摩擦,那么你最好自己也这么做。因此,社区成员交流的公开性就非常重要。The Apache Way[3] 当中强调 Open Communications 就是这个原因。交流的内容不仅仅是模仿的对象,本身也携带信息,减少项目维护者单点传播知识的负担。
Open Communications: as a virtual organization, the ASF requires all communications related to code and decision-making to be publicly accessible to ensure asynchronous collaboration, as necessitated by a globally-distributed community.
当然,ASF 选择了邮件列表,对于一个不在 ASF 当中的项目来说,可以自由选择喜欢的沟通渠道。但是切记避免私下讨论!
Automate workflows.
如果一个流程能够被自动化,那么就应该考虑自动化它。
显然,自动化是不言自明的降低维护负担的手段。但是请注意上面这句话的因果关系,首先要有一个流程,然后隐含着它是一个运行得很好的流程,可以通过自动化来减少重复劳动,那么就考虑自动化它。
我个人非常认同自动化的价值,但是也在最近看到了太多自动化的大跃进带来的问题。未经检验的复杂流程以全自动化的形式上线,把所有社区成员都折磨得不行,反而加重了维护者协调 bad case 的负担。某些流程有它的价值,但是有非常多的环节需要人的判断,强行拆解成类似审批流的东西,细分权限,逼迫更多的人牵扯到每一个可能非常简单的事务当中,这么做或许社区的事件数字会上涨,但是大部分却是无效冗余的操作,并且强化了等级和管控观念,其实跟开源社区基于对人的信任和合作的假设是格格不入的。
流程自动化做得好的社区包括 Kubernetes 社区[4]和 Rust 社区[5],我就不多介绍了,可以从前面两个链接里了解。这里需要强调的是,对于新兴社区,请关注这两个社区有多少人投入在自动化上,请关注它们什么引入了何种自动化,请关注它们的成员如何配合自动化,请关注两个社区在自动化上的异同,以及实施自动化过程中社区的争议。请勿船货崇拜,像素级拷贝,你会死得很惨。一句话,Rust 都不抄 Kubernetes 呢,你为啥未经调查就要抄?
流程自动化具体的方向可以是文档网页在有新的提交时自动发布,PR 数量上来以后利用 merge bot 协调等等。对于后者,请注意,Linux / PostgreSQL / Apache Hadoop / Apache Flink 等社区的开发活跃度,都不需要这类机制。请确保你真的理解 merge bot 如何改善社区协作流程的效率,并保留和时刻考虑回滚自动化逻辑的可能性。
另一个典型的 bad case 是 stale bot 的自动关闭功能。相信我,没人喜欢这东西。开发者来到社区是为了寻求人的连结,而不是为了被机器人支配,这是明显的赛博朋克倾向。对于 issue 或 PR 的积压,首先考虑如何快速关闭无效的内容,并不是所有内容都应该以 issue 或 PR 的形式存在。如果项目的维护者不足以处理飞涨的信息,那么是时候吸纳一名新的维护者了。
Users SHALL NOT log feature requests, ideas, suggestions, or any solutions to problems that are not explicitly documented and provable. The ZeroMQ Community[6]
Manage day-to-day events.
这个话题非常复杂,因为我们来到了真实的世界,即作为项目的维护者,你需要处理项目的日常事务。我只讲一个典型的场景。
这个典型的问题是如何管理开发工作的风险。通常,一个项目会有自己的版本发布周期,有时候你想在下个版本中带上某几个功能,这些功能的开发不止由你一个人完成,这个时候就需要你来管理开发工作当中的风险。这不是一个维护者才会遇到的问题,甚至不是在开源社区当中才会遇到的问题,不过开源项目的维护者确实经常被这个问题困扰,尤其是当他们还有公司员工的身份,承担了公司对项目期待的实现中介的时候。
回答这个问题也有很多角度。先从公司员工的身份来说,我曾经提到过开源项目和商业公司相互独立的运营模型,如果能保证商业上紧急的需求可以由 fork 承担,稍后 contribute back 的话,可以很大程度缓解冲突。另一方面,公司对 contributing back 也会有一个期待,我的建议是在力所能及的范围内保证由公司员工承担。你并不需要刻意去引入公司以外的开发者开发一个公司有明确期待的工作。
从开源协同的角度来说,基础是上面提到的文档和公开交流带来的信息流畅,确保跨越社区成员所属组织的边界合作不会有额外的信息差。另一点是平时保持和其他社区成员的联系,了解他们在社区当中寻求什么价值,有合适的内容找到合适的人一起开心的做事。大部分情况下,真诚的社区成员被激发出兴趣以后,能够爆发出极强的创造力。并且只要你在开发文档当中写清楚了发布周期,并且这是一个社区当中的共识,每个成员都乐于见到自己的工作成果随新版本发布被用户使用。你不必过度担心他们会错过时间,只需要关注他们遇到的困难和帮助他们管理好自己的时间。注意,这也适用于自己,如果自己遇到了困难,应当及时提出,如果自己管理不好时间,可以阅读这两天的文章。如果你参与的社区当中的成员没有这种品质,那可得好好想想是为什么了。
对于这些日常的事务,项目维护者处理的时候需要秉承一个理念,项目要发展新成员,重点不在于尽可能完成更多开发或组织更多活动,而在于时刻思考社区成员的诉求是什么,找到共同利益一起努力。关于这一点,我在 COSCon'21 的演讲《Why Contributors Stay and Grow》[7]有详细的展开。
Have fun.
最后,时不时回想你为什么要维护这个项目,看看这个项目已经达成的成就。你已经做得很好了。
保持自己心情愉快是提高效率最有效的方式。当你发现一件事情不想做的时候,可以说“不”。当你发现一个人不想理会的时候,也可以说“不”。不要让人群无形的压力危害你的健康。
如果你找到了新的乐趣,可以把项目交给其他的维护者或者转入归档状态。这不是你的错,并且你已经创造了非常可观的价值。
References
[1]
Apache Pulsar: https://pulsar.apache.org/en/contributing/#becoming-a-committer[2]
Apache Flink: https://flink.apache.org/contributing/how-to-contribute.html[3]
The Apache Way: https://www.apache.org/theapacheway/index.html[4]
Kubernetes 社区: https://github.com/kubernetes/test-infra/tree/master/prow[5]
Rust 社区: https://github.com/rust-lang/homu[6]
The ZeroMQ Community: https://zguide.zeromq.org/docs/chapter6/[7]
《Why Contributors Stay and Grow》: https://www.bilibili.com/video/BV1Tg411K7KS/