通过设计(前)、开发(中)、重构(后)三个阶段的把关提高整体代码质量。?好的设计能够提升代码可维护性和扩展性。
开发中的质量管控能够提升整体编码质量。代码上线后或者添加新的代码时适当的重构,不会让代码质量随着时间的推移而下降。本系列重点讨论红框部分。在开发过程中的从分支管理、代码提交和代码审查规范,三方面提高代码质量。主要参考Facebook研发效能和谷歌工程实践。
主要介绍下Facebook的主干无功能分支模式,也叫做Trunk-based。在这种方式中,用于开发的长期分支只有一个,而用于发布的分支可以有多个。Facebook 有几千名开发人员同时工作在一个大代码仓,每天会有一两千个代码提交入仓 ,但仍能顺利地进行开发,并发布高质量的产品。整体原则为开发人员原子并能够不被阻塞地尽快把代码提交到仓库。
开发分支
所有的开发人员基于 master 分支进行开发,提交也直接 push 到这个分支上,对于不需要上线或者未完成的功能使用功能开关进行屏蔽。
如果功能较大或者多人合作,Facebook 采用的是使用代码原子性、功能开关、API 版本等方法,让开发人员把功能拆小尽快合并到 master 分支。
发布分支
在需要发布的时候会从 master 拉出一条发布分支,进行测试、稳定。在发布分支发现问题后,先在 master 上修复,然后 cherry-pick 到发布分支上。分支上线之后,如果需要长期存在,比如产品线性质的产品,就保留。如果不需要长期存在,比如 SaaS 产品,就直接删除。Facebook 采用的方式是后者。
Facebook分支管理和发布策略
尽量提高master代码质量。Facebook 采用主干分支模式,最大的好处是可以把持续集成、持续交付做到极致。能够促进开发人员把代码频繁入主仓进行集成检验。而这正是持续集成的精髓。与之相对应的是,很多 20 名开发者的小团队,采用的也是共主干开发方式,但使用了功能分支,让大家在功能分支上进行开发,之后再 merge 回主仓。结果是,大家常常拖到产品上线前才把功能分支合并回主干,导致最后关头出现大量问题。线性的和原子的提交历史。必须尽早将代码合入 master 分支,否则就需要花费相当长的时间去解决合并冲突。所以每个开发人员,都会尽量把代码进行原子性拆分,写好一部分就赶快合并入库。这里描述的部署流程是 Facebook 持续部署的模式。非常多的公司还没有达到持续部署的成熟度,所以这种持续交付的方式,对我们更多的是参考价值。
传统的分支管理方式。
Git-flow 工作流有两个长期分支:一个是 master,包含可以部署到生产环境的代码;另一个是 develop,是一个用来集成代码的分支,开发新功能、新发布,都从 develop 里拉分支。此外,它还有 3 种短期分支,分别是新功能分支、发布分支、热修复分支,根据需要创建,当完成了自己的任务后就会被删除 GitHub-flow。
GitHub引入了一个分支模式叫GitHub—Flow,明显比Git—Flow简单很多。没有Develop,没有hotfix,也没有Release,当需要开发的时候拉一个Feature分支,开发完就合并Master做发布。Fork-merge?适用于众多贡献者的开源项目 Forking工作流。
适用于众多贡献者的开源项目。
Fork-merge 是在 GitHub、GitLab 流行之后产生的,具体做法是:每个开发人员在代码仓服务器上有一个“个人”代码仓。这个“个人”代码仓实际上就是主代码仓的一个 clone,开发者完成 Feature 开发后提交patch,由指定的几个核心项目管理者审核通过后入库。
阿里采用的分支管理方式。?
基于功能分支灵活产生发布分支的方式。这种方式的典型代表是阿里云效的“分支模式”。具体方法是大量使用工具对分支的管理进行自动化,开发人员在 web 界面上自助产生针对功能的分支。编码完成后,通过 web 界面对分支组合、验证,并上线,上线之后分支再自动合入主库。
我们目前采用GitHub-flow的方式进行分支管理。
Facebook的区别在于前者是分支上开发合并到主干发布,后者是主干上开发拉取分支发布。采用的GitHub-flow方式的优势在于线上代码与开发代码隔离,所有代码经过测试和审核后发布。缺点是合并到主分支的频率低,如果版本间的功能有相互依赖不好处理,不利于大团队共同维护一个代码仓库。Facebook采用的Trunk-based方式有利于提升持续集成研发模式的效率,但是对开发者个人能力和测试的要求很高。
目前分支管理方式符合当前小团队的情况,可以继续保持当前的流程。主要存在的问题是,在上线前做 codereview,重点审查的目标是发布是否有风险。对设计、规范等方面关注较少。因此更多的需要在代码提交和审查阶段进行改进。