如何管理一个大型开源仓库?淘系带你一探究竟

 

稿件来源:阿里云开发者社区

 

合理的拆分仓库

当我们说管理仓库的时候,其实面向的不是一个单一的仓库,而是一个产品、一个项目甚至一个业务,这背后可能会有多个仓库也可能只有一个仓库,因此在前期的规划上要尽量梳理清楚,核心避免两个误区:

误区 1:每个职责都建一个仓库

这个方案可能是多数人的直觉反应,但是这种方式会让产品对应的仓库数快速增多,导致长期管理成本陡增:

  • 仓库权限管理成本高且容易混乱
  • 代码开发提交成本高
  • issue/PR 太过零散,难以统计管理
  • ……

实际上,飞冰(ICE)原先在内部的时候,我们开发了很多业务组件,每个业务组件都是一个单独仓库,然后最近在做统一升级(工具、规范或者其他变更导致)的时候给我带来非常大的困扰:

  • 有的组件(仓库)已经不再维护但没有任何标记
  • group 权限管理太过松散导致出现一些跟官方无关的组件
  • 升级过程中需要频繁切换仓库操作

因此,我们需要避免过于零散的管理方式,结合实际场景做适当的聚合。

误区 2:所有的职责都用一个仓库承载

在前端社区里,随着 lerna 这个批量发布包工具的出现,这种方式越来越流行,一些非常热门的项目比如 babelReactjest 等都逐渐迁移到这个方案。先抛开 lerna 这个工具提供的能力,这种聚合式的管理方式给仓库管理者节省了很多成本,比如:

  • 只需要管理一个仓库
  • issue/PR/wiki 等都收敛到一个地方管理

但是在实践这种方式的时候有可能会走偏,还是以我所在的 ICE 团队做反面教材,踩了误区 1 的坑之后,在做开源版本的时候我们果断把所有包都放到同一个仓库,然后通过目录结构来保证职责清晰,这个方式也同样如上面所提到的给我们的管理带来了诸多便利,但在经历了一年的迭代之后目前也遇到了一些问题:

  • 职责多代表代码多,然后随着历史记录的增长,仓库 clone 速度一日不如一日,尤其在一些小公司的慢速网路环境下(即便加了 --depth
  • 目录结构较为复杂,对有心贡献代码的社区同学不够友好

因此我们推荐「在方案 2 的基础上按照职责再做一层拆分」,结合 alibaba/ice 这个仓库,我们已经通过职责将 ice-devtools/ice-scripts/react-materials 等拆为独立仓库,这些仓库职责上足够清晰同时相关依赖聚合在一起不至于太过分散。

建立团队内的操作规范

笔者曾经有幸参与过淘宝前端团队的代码规范制定以及相关工具落地,因此深知规范之于团队的重要性,同时也有一些制定规范的原则:

(1) 规范首先保证正确,其次提升质量;

(2) 规范不能过多影响到效率(两者的权衡需要结合实际场景)。

以下就是我们目前在遵循的一些规范:

保护分支!

https://ucc.alicdn.com/pic/developer-ecology/28c9bdc4437f420681bda43393652d8f.png

根据仓库情况设定保护分支,禁止直接往保护分支提交代码,在非常特殊的情况下 admin 账户可以绕过。

新建分支规则

https://ucc.alicdn.com/pic/developer-ecology/8b973f007e884cceaec965abbf116ac3.png

  • 分支名称需要有语义,比如 ice-scripts/fix-foo-bug
  • 如果需求比较简单,时间周期比较短,那么直接从 master 切一个分支,然后通过 PR 合并后到 master,合并之后发布对应包的版本
  • 如果需求包含多个变更点,比如 iceworks 发布版本,往往涉及到多个功能点,开发周期一般会在一周左右,如果每个 PR 都往 master 上合并,很难把控整体的进度。因此我们有以下约定:

a.先从 master 切出 release 分支(如 release/iceworks-2.16.0),然后提一个基准 PRPR 中需要补充当前版本包含的功能列表以及发布先后顺序等,该 PR 主要用于管理此次版本开发进度,release 分支不允许直接推送代码,同时合并到 master 时也无需 Review

b.然后每个功能变更都从 release 分支切出新分支,同时 PR 也需要合并到对应 release 分支,切出的分支不需要包含版本信息(比如 iceworks/fix-xxxx 即可)

c.等所有 PR Review 完成并且合并到 release 分支之后,在 release 分支进行发布,发布完成后再将 release -> master PR 合并(此处不在 master 分支发布的原因是担心发布时可能会出各种问题,需要再次做代码变更)

commit message 规范

https://ucc.alicdn.com/pic/developer-ecology/93e3f99727284a8191faa7a8e985cf28.png

好的 commit message 可以让人快速了解代码意图,加速 review 进程,未来对于整个代码仓库的历史追溯也会更加方便,关于这一点社区有足够多的规范可以参考,此处不再一一赘述,有兴趣可以参考末尾的参考链接。

PR 合并流程

https://ucc.alicdn.com/pic/developer-ecology/ee74c03a8dd74f8bbd65268da63781d1.png

github 默认提供了三种合并 PR 的方式,关于三种方式的区别可以参考文末的相关链接,我们认为大多数情况应该选择 Squash and merge,因为 squash 会将当前 PR 的多个 commit 合并,让整个提交历史更加干净清晰。但是在将上文提到的 release 分支合并到 master 时建议使用普通 Merge,因此此时我们需要保留那些有效的 commit 记录。同时在合并 PR 的时候 Reviewer 有责任重新编写 commit message 以保证语义更加准确。

这里简单追溯一点历史:在最早期的时候,github 还没有提供 squash merge 的方式,当我们向开源仓库提交一个 PR 时,在仓库作者 review 完成之后一般会要求提交者将 commit 合并,因此很多人都有谷歌过「如何合并 commit」这样的关键词,而如今只需要点一下按钮即可,这也是工具对效率提升的一个体现。

发布流程

对于管理工具包的同学,都应该熟悉并且遵循 Semver 规范(语义化版本),这是原则,在此基础上需要遵循以下规范:

测试版本:版本号需要遵循 x.y.z-n 的规则,通过 npm publish --tag beta 发布,很多同学包含笔者本人经常会忘记 --tag beta,不知道有没有更加有效的方式约束?

正式版直接通过 npm publish 发布

正式版本发布之后,需要同时创建对应的 git tagtag 命名规则:产品名/x.y.z,比如 ice-scripts/1.0.2,然后在 GitHub 上填写 Release 信息

 

稿件来源:阿里云开发者社区

猜你喜欢

转载自blog.csdn.net/weixin_40050195/article/details/97646120