Published on

一个开源项目的迭代流程

Authors

典型的开源项目迭代过程

传统瀑布式 vs 典型开源项目迭代

development-waterfall
development-open-source

http://aaaea.org/Al-muhandes/2008/February/open_src_dev_model.htm

和传统软件开发过程相比,开源软件的开发迭代有一些独特的特性。流程上开源软件的“特性开发、发布和测试”这三步往往会是一个循环过程。“尽早发布,经常发布”,开源软件的特性和版本往往会有很多的“小增量”迭代,开发好一个特性之后即时发布,然后多由社区测试,在 bug 被社区提出之后,尽快再走一次“开发、发布、测试”的过程。开源软件主要的独特特点如下:

  • 自下而上驱动的开发:讨论设计和实施决策的过程中,项目参与最多的成员最有发言权,开发者关系维护很重要
  • 尽早发布,经常发布:不要等到一个完整的生产版本所有功能完备的情况下再发布,而更鼓励易于理解和测试的小增量的更改,鼓励尽早发布版本供社区用户使用,然后再快速修改快速更新版本。开源社区认为,正因为存在可以为项目做同行评审、使用和测试软件、访问代码、报告 bug 和提供修复方案的大量用户,所以才能迭代出更高质量的软件
  • 同行评审:项目成员会评审代码,提供评论和反馈以改进软件的质量和功能,并在开发周期尽早进行早期测试或者提交功能增强的方案,这样的结果是项目质量会越来越好
  • 小而增量的更新:PR 一般范围较小并且通常没有侵入性,原因如下:
    • 相对于大的更新或者重构而言,小补丁或小的代码变更更易于理解和评审
    • 小的变更有利于做持续测试和集成
    • 小的变更产生意想不到的后果的可能性更小
  • 关注安全:通常正式版本的发布都会把过程中所有标记的安全问题都修复后才会发布
  • 持续的质量改进:CR、PR 和 bugfix 版本
  • 项目测试方式:大项目一般都会有测试套件或者持续集成平台做自动化测试,同时会结合社区使用的测试
  • 终端用户参与全流程:典型的开源项目用户可以参与到项目迭代的全流程,通常这也是常态

开源的开发模式已经被证明是成功的模式。基于开源软件迭代的特点,有一些值得鼓励的做法可以更好地发挥开源开发模式的优势:

  • 增强团队沟通:使用尽可能多的渠道促进项目成员和社区的沟通,邮件列表、即时通信软件、官网/wiki 等
  • 获取最终用户的反馈:在开发过程中就尽可能获取用户反馈
  • 同行评审:建立一个鼓励同行评审,欢迎反馈建议的环境
  • 尽早发布、经常发布:采用这种开发实践可以带来很多好处,要为此建立持续集成和自动化测试的环境
  • 透明度:在整个社区采用公开的代码库、bug 跟踪系统、邮件列表等实现公开透明
  • 好的代码设计:保持代码库最小化,把功能特性都尽可能设计成单独的模块,以鼓励复用并可以轻松进行测试

OSSDP 典型开源项目迭代流程综述

存在CI系统
不存在CI系统
获取需求
开发者邮件列表(开发者)
官网/wiki/roadmap/讨论组(用户)
bug报告系统(BUGDB、GNATS)
bug跟踪系统(Bugzilla、RedMine、Trac)
开发
没有多个方案
存在多个方案
定位现存问题
选择或者分配问题
确定解决方案
项目成员讨论反馈
开发代码
提交代码
测试
测试未通过或未被认可
测试通过并被认可
确定要进行的测试
确定测试形态和用例
执行所有测试
结果发布到bug报告系统/邮件列表
下一步
实行CR
pre_review
review
post_review
持续集成
未符合预期
符合预期
为开发者提供反馈结果
触发CI任务/构建并测试代码
代码变更
下一步
发布
存在预发布流程
不存在预发布流程
反馈通过
反馈问题
存在文档系统
不存在文档系统
执行预发布
冻结项目
在冻结版本中测试
用户体验/反馈
发布准备就绪
正式发布
报告issue
完善用户文档

Open Source Software Development Process: A Systematic Review (PrePrint . August 2020)

Open Source Software Development Process: A Systematic Review

其中,CR 的部分可以细看这篇论文(他们讨论的是 Mozilla 和 Python 项目,相对比较陈旧但有一定代表性):

Comparative case studies of open source software peer review practices

这篇论文里描述的 CR(patch peer review)有两种形式:RTC 和 CTR,分别是先 review 后 commit 和先 commit 后 review,当然新的基于中心化版本控制平台(github)的 OSS 通常是 CTR 形式的。

而 CR 会有三个阶段:前 review、review 和 后 review。

  • 前 review 主要由 patch 作者和提交人进行,会对 patch 本身做一些初步的审查,通常是“这个 PR 是否符合格式,符合准入条件”
  • review 由三种角色进行:代码审阅者、feature/bug 验证者、批准人
  • 后 review 通常由 submitter 以上的角色承担,代表正式进入合并流程

真实案例(AntV)

获取需求

年度规划

时间:每财年初

形式:线下开发者 meetup / 规划会议 + 线上文档

产出物:roadmap / PRD + 视觉稿 等

yuque

antv-iteration-plan

issues

时间:每周轮值,每天响应

形式:核心开发者每周轮流值班 + github 机器人

产出物:每个 issue 会被标记归类、assign 负责人、指定完成时间 / 发布版本等

https://github.com/antvis/G2/issues

用户社群

时间:每周轮值,每天响应

形式:在钉钉群、文档体系的评论回复里收集归类需求、答疑

产出物:由值班同学建立 issue,准备复现问题的 test case 等

内部需求透传

时间:不定期

形式:和公司内部业务线达成合作,在通用能力层面支持业务需求

产出物:在 roadmap 中插入相关 feature 规划(譬如语雀里需要的脑图、DeepInsignt 需要的 react 图表库等),因为 AntV 是蚂蚁主导的开源项目,roadmap 里大多数 feature list 都来自于蚂蚁真实业务场景的可视化需求

开发

和通用流程基本一致。不过因为组建团队的时候是按照领域储备相关的人才,所以更偏向于“需求固定分配给某个开发者”,而不是“开发任务出来后由社区开发者认领”。相对地,方案评审、迭代规划的讨论也趋向于中心化,而不是分布式。由于这样的壁垒,蚂蚁外部的开发者是很难获得某个方向的迭代主导权的,三方开发者的参与也很有限。有例外,譬如 AntD 这样更通用场景的迭代,会有比较强势的体系外贡献者,这些人要么最终被引进到 AntD 的研发团队了,要么就解决完自己的场景问题就不再贡献代码了。

测试

所有测试用例直接集成到代码库中。所有的测试场景都和代码库耦合绑定,包括单元测试、真实场景的 bug cases、性能测试等,所有的数据准备、场景构建也都在项目代码库内部。所有现存的 test case 都必须在每一次 CR 之前由持续集成平台自动执行通过。

测试用例列表

https://github.com/antvis/G2/tree/master/tests

CI 系统

https://github.com/antvis/G2/runs/6123489290?check_suite_focus=true

从某种意义上讲,这个测试用例库就是一个 duck test,它从系统层面最准确地描述了这个项目的所有行为特征。同时也是开发者上手入门的一个很好的途径,很多开发者在贡献代码或者投入项目使用的时候,就是从项目的测试用例库入手了解的。github 最早期是 ruby 社区带起来的,我工作的第一家公司就是一家严重依赖 ruby 社区技术的公司。公司技术团队的前辈在指导新人的时候最常见的做法就是“看测试用例”。从技术角度看,深入理解一个项目最直接也最全面的方式一定是看这个项目的测试用例库,这也是 ruby 社区的开发者快速了解和加入一个开源项目最常见的路径。

CR

做得比 mozilla、python 这些项目稍轻一点,只是区分了 CR 和 合并的角色(CR 需要由一线开发者进行,代码审阅和功能验证往往是同一个人,而批准、合并会由版本负责人承担,通常是 AntV 的首架)。

持续集成

之前是三方的 travis,现在直接采用 github action。

https://github.com/antvis/G2/blob/master/.github/workflows/ci.yml

发布

大版本(x.y.z 里的 x 版本)会经历相当长的流程,daily 版本、alpha 版本、beta 版本、preview 版本,最后再发布正式版本。相应的站点、文档都会提前准备好,和当前 current 版本并存相当一段时间。最终的大 x 版本通常会在年度发布会之前发布正式版(每年的 11 月 22 日)。在正式版发布之前,也会预留相当一段时间集中更新官网、文档、在具体业务场景中落地验证。x 大版本的规划、开发和发布往往是一年以上的周期。

而 y 版本的发布会相对轻量很多,一般在 PR 合并之后就会有 daily 版本发布,补充收集足够完善的测试用例和相应特性文档之后,就会发布正式版(git tag)了。y 版本的迭代周期一般在两周到一个月之间。

z 版本更轻量,通常在针对性的 bugfix 用例通过、修正关联文档后,就会把构建的版本号回复相关 issue 通知验证关闭了。z 版本随修随发,反馈比较饱和的时候几乎每两三天就会有一个 z 版本。

https://github.com/antvis/G2/releases

下一步做什么?

多看一些活跃开源社区的迭代全貌,加一些用户群组、开发者群组感受一下节奏和氛围,这是和在公司里按部就班的迭代存在非常大差异的开发模式。举个例子,值班的开发同学一半时间基本都在答疑、建 issue 整理 issue 处理 issue、改文档等等。

开始习惯用英文写 Commit 信息和 release notes。习惯非瀑布式的迭代流程,习惯小的 patching 和 release 等。

针对每一个主要流程建立我们自己的 SOP,譬如我们的需求流程,早期肯定是有点非主流的“客户主导流程”,主要由业务同学和 PD 牵头做版本规划和需求输入的;但慢慢地社区反馈的需求流程得建立起来。譬如具体以 github 为主的开发迭代,怎么和现有的 DevOps 平台结合。相关的测试、CR、CI 的流程也得去适配 github 的环境。版本发布最好也能遵从“尽早发布、经常发布”的原则,给出我们自己的发布 SOP。

另外要提前做好参与者分层和账号权限管理。github 的项目演进流程会天然涉及几个角色:

  • Group Owner(github.com/aloudata 群组的管理权限,包括创建分组、分配角色等)
  • Repo Owner(可以在 main 分支发版本,可以删除分支管理分支)
  • Repo Team Dev Member(开发组,可以新建分支,但对 main 分支没有管理和发布权限)
  • Repo Team Reporter(非开发者的项目成员,提供测试或设计建议,报告缺陷等)
  • Committer(三方贡献者,通过 fork 项目提 PR 给项目贡献代码的人)
  • User(单纯下载使用的人)

原则上 Dev Team 及以上成员需要开启 2FA(two-factor authentication),并且成员变动要及时同步变更和回收权限。

再之后就是官网、教程、视频、文档、开发者/用户群等渠道和内容的建立和筹备,还需要有一定的值班机制支持。