Gitflow 在 CI / CD 实践中存在的问题
一、在传统的 Gitflow 规范中,长期分支有 master 和 develop,为了完成特定需求的开发的分支又有 feature branch,hotfix branch 和 release branch。将这么一套复杂的 workflow 规范应用到团队中,不仅需要每个人都能正确地理解和选择正确的分支进行工作,还对整个团队的纪律性提出了很高的要求。毕竟规范越复杂,应用起来就越难。
二、在 Gitflow 规范中,新功能建议在 feature branch 上进行开发,当功能开发完成之后,featrue branch 才会被 merge 到 develop branch。如果这样管理分支的话,那我们如何做持续集成呢?毕竟持续集成不是自己在本地把所有测试跑一遍,持续集成是把来自不同 developer,甚至不同 team 的代码集成在一起,确保能构建成功通过所有的测试。按照持续集成的纪律,本地代码必须每日进行集成,如果基于 Gitflow 实践持续集成,有以下几种方案可选:
- 每个 feature branch 在一天内完成,然后集成回 develop branch。首先,大多数的功能都不可能在一天内完成开发。其次,如果一天内就可以完成一个功能的开发,我们为什么还要专门开一个分支呢?
- 每个分支有自己独立的持续集成环境,在分支内进行持续集成。然而为每个环境准备单独的持续集成环境是需要额外的硬件资源和虚拟化能力的。假设这点没有问题,不同分支间如果不进行集成,仍然不算真正意义上的持续集成,到最后 merge 的时候,big bang conflict 还是无法避免。
- 每个分支有自己独立的持续集成环境,在分支内进行持续集成,同时每日将不同分支 merge回 develop 分支进行集成。听起来很完美,不同分支间的代码也可以持续集成了。可是如果发生了冲突,CI 挂掉了谁来维护呢?也就是说我们还是得关心其他 developer 的开发情况。不是说好了用 feature branch 就可以不管他们自己玩吗,那我们要 feature branch 还有什么用呢?难道就是为了废弃掉未完成的功能时删除一个 branch 比较方便?
所以在实践 CI / CD 的过程中,你会发现 feature branch 是一件非常矛盾的事情。持续集成在鼓励更加频繁的代码集成和交互,让冲突越早解决越好。feature branch的代码隔离策略却在尽可能推迟代码的集成。延迟集成所带来的恶果在软件开发的历史上已经出现过很多次了,每个团队自己写自己的代码是挺 high,到最后不同团队进行联调集成的时候就傻眼了,经常出现写两个月代码,花一个月时间集成的情况,质量还无法保证。
更适合 CI / CD 实践的 Git workflow
除了 Gitflow 和 Github flow 之外,市面上主流的 Git workflow 还有 Gitlab flow。在 Gitlab flow 规范中,有 master,pre-production 和 production 三个长期分支,能够很好地对应上 CI / CD 中的开发环境、测试环境和生产环境。而且代码合并遵循 upstream first 原则,也就是确保代码被充分测试过,才会从上游分支合并到下游分支。
Developer 将代码提交到 master branch 上进行持续集成,如果 master branch 通过自动测试,则将新增代码 merge 到下游分支,逐层递进。这就可以保证 production branch 上的代码总是处于可用状态。使用 production branch 上的代码对外发布,并且打上 tag,当我们线上发生故障的时候,就可以利用 production branch 上的代码进行回滚。