节点深耕

Fork 开源项目:决策模型与工程代价

本文从 issue、发布、构建、测试四个环节拆解 Fork 开源项目的真实成本,帮助团队在“等社区、买支持、自己维护”之间做出可量化决策。

2024-06-01约 5 分钟阅读
#node #docker #automation

使用开源软件时,团队经常会遇到两类问题:业务侧新增需求,或社区版本中的缺陷。常规做法是提 issue、提 PR,但现实是需求不一定会被及时处理,发布节奏也不受你控制。

团队管理者会有几种选择:

购买开源软件的商业支持

  • 一些开源软件的维护者(组织、公司)会提供商业支持,这样你可以获得更快的响应和解决方案。
  • 他们会根据客户的级别来调整服务的优先级,从而影响Issue和PR的处理速度以及Release的发布时间。
  • 他们会根据客户的规模(用户数、收入等)来调整服务的价格。
  • 当团队规模持续增长时,商业支持的价格可能会超出预算。

积极参与开源社区

  • 可以发动团队成员参与开源社区,培养团队的技术能力
  • 可以通过参与开源社区,获得更多的技术资源和人脉
  • 提升影响力,从而影响开源软件的发展方向
    • 虽然听起来有些不公正,但开源本身也是一种共创式制定标准的手段
    • 参与开源就要对社区负责,即使是 PMC 也并不意味着可以随意修改 Roadmap
  • 需要平衡开源贡献的成本和收益
    • 需要花费多少时间在 PR 上
    • 需要等待多久才能 Release
    • 需要多少人兼职、全职的参与

Fork 一个开源项目

  • 自己维护一个分支
  • 可以自由的发布自己的版本
  • 可以自有的添加自己的功能
  • 可以自由的选择优先合并的 PR
  • ...

因此,不少规模化团队都会评估 Fork。问题不在“能不能 Fork”,而在“Fork 之后能否长期维护”。

挑战

最大的挑战是如何保持自己的 Fork 版本与原始版本的同步。

Issue / PR 阶段

挑战一:你的 issue 可能不会被处理

你提交了一个 issue,但是维护者并没有立即处理,或是直接拒绝了你的提议。

你是否还需要这个功能?

  • No,关掉这个 issue,寻找替代方案
  • Yes,fork 这个项目,自己实现这个功能 ... 除此之外你还需要 ...

你的 commits 可能会很快过期,当上游的新版本发布时,你需要将你的 commits rebase 到最新的版本。例如,你基于 v1.10 fork 了一个项目,现在你想升级到 v1.11。

每一次上游版本的升级,你的团队都需要疲惫地处理冲突 💀,特别是当你有很多这样的 commits 时。

mermaid
%%{init: { 'gitGraph': {'rotateCommitLabel': true}} }%%
gitGraph
    commit
    branch release-v1.10
    commit tag: "v1.10"

    branch your-v1.10
    checkout your-v1.10
    commit id: "feature-1"

    checkout release-v1.10
    commit tag: "v1.10.1"

    branch your-v1.10.1
    checkout your-v1.10.1
    cherry-pick id: "feature-1"

    checkout main
    commit
    commit
    branch release-v1.11
    checkout release-v1.11
    commit tag: "v1.11"

    branch your-v1.11
    checkout your-v1.11
    cherry-pick id: "feature-1"

Tips:

  • 保持你的 commits 小而简单
  • 避免删除原有代码,通过 feature-toggle 的方式来跳过
  • 创建新的文件、函数来实现你的功能,在原有文件中只是调用
  • 通过配置文件、环境变量、流水线在编译和运行时注入代码

以上小技巧能帮助你减少 rebase/cherry-pick 时的冲突

挑战二:你的 PR 短期内无法发布

即使你的 PR 被合并,社区通常有自己的发布计划,可能需要很长时间才能发布。以我参与的 ingress-nginx 为例:

  • Issue raised Apr 10
  • PR created Apr 13
  • PR merged May 27
  • Tagged Release 1.11 (probably in Sep)
    • 1.10.0 at Feb, 2024
    • 1.9.0 at Sep, 2023

可以看到,社区对于 minor 版本的发布计划是 6 个月,也就意味着我的 PR 可能会在今年九月才会发布 ... 距离 issue 提交已经是半年过去了。

你是否还需要这个功能,现在?

  • No,关掉这个 issue,寻找替代方案
  • Yes,fork 这个项目,自己实现这个功能 ... 除此之外你还需要 ...

你仍然需要 rebase 你的 commits,但是相对于挑战一,这个过程会简单很多。

虽然会等待一段时间,但你的代码已经存在于下一个版本。一旦新版本发布,抛弃 Fork,按照官方的升级指南升级即可。

mermaid
%%{init: { 'gitGraph': {'rotateCommitLabel': true}} }%%
gitGraph
    commit
    branch release-v1.10
    commit tag: "v1.10"

    checkout main
    commit id: "feature-1"

    checkout release-v1.10
    branch your-v1.10
    cherry-pick id: "feature-1"

    checkout main
    commit
    branch release-v1.11
    commit tag: "v1.11"

Build / Release 阶段

挑战一:你的构建可能会失败

很多开源项目都会依赖 Github / Gitlab 等平台的 CI/CD 服务,进行自动化构建和发布。当你 fork 一个项目时,原有的 pipeline 你是无法直接使用的,需要自己配置 CI 服务,包括:

  • 你的 Fork 是否在私有仓库
  • 你的 CI 能否访问你的 Fork 仓库
  • 你的 CI 是否有构建代码的环境和依赖
  • ...

挑战二:如何发布你的 Fork 版本

同挑战一,开源项目会链接到官方的发布渠道,例如 Docker Hub、Github Release 等。在构建好你的 Fork 版本后,你还需要将他们发布到你的私有仓库中。

当然,你也可以选择发布到公共仓库,但是你需要注意命名冲突的问题。我在发布一个 python 包时,为了避免和上游版本的包冲突,重命名了整个 src 文件夹。

https://github.com/Anddd7/diagrams-ext

挑战三:如何测试你的 Fork 版本

现在,你可能是唯一一个使用你的 Fork 版本的人,当你遇到 Bug 可能也无法从社区获得有效的帮助。你需要做额外的测试,确保你的 Fork 版本没有问题 —— 除非你对自己的代码有 100% 的信任。

结论

业界确实有很多公司维护自己的 Fork,但通常它们同时具备两项前提:持续的定制需求和稳定的维护资源。

  • 云服务提供商:希望将自己的服务集成到开源项目中,例如负载均衡团队也会负责 Ingress 相关的内容。
  • 金融行业:稳定性高于一切 ... 他们不需要那些新的功能,Fork 一个过期但稳定运行的版本,只添加安全相关的功能,是一个不错的选择。

当然,“性价比”才是决定因素,团队管理者需要算好手里的账:

  • 经济账:购买商业支持 vs hire团队来维护分支
  • 时间账:fork 项目 vs 等待社区发布
  • 技术账:自己实现 vs 依赖社区