DevOps提倡的主干开发,真的适合我所在的团队吗?(作者: 程序员Aike)
上次我们提到分支策略 — 软件协作开发的灵魂,今天我们主要聊一聊常见的分支策略,以及如何选择的话题。
分支策略大致可以分为主干开发和特性分支开发,主干开发包括分支发布和主干发布两种,而我们熟知的Git Flow 、GitHub Flow以及GitLab Flow都是属于特性分支开发。如下图所示:
01 主干开发
在主干开发模式中,团队将所有的工作直接在主分支(通常命名为 master 或 trunk)上完成。主干发布的核心理念是快速、频繁地将代码变更合并至主分支,确保主分支始终处于可随时发布的状态。这种模式尤其适用于那些采用持续集成与持续部署(CI/CD)实践的敏捷团队,通过自动化测试和部署流水线,实现高效且低风险的版本迭代。
在主干发布的场景下,当线上出现紧急问题时,开发者可以直接在主分支上进行热修复,修复完成后立即部署上线。但这也要求团队具备较高的自动化测试覆盖率和高效的代码审查机制,以保证主分支代码的质量和稳定性。
主干开发又可分为分支发布和主干发布两种。
主干开发、分支发布
采用主干开发,一般在发布时会拉取发布分支,问题修复先提交到 trunk 分支,之后再合并到release。如下图所示[1]:
主干开发、主干发布
更彻底的做法是,直接在 trunk 分支发布,这通常需要完善的流程、工具链和高质量的自动化测试保障质量。GitHub、Etsy、Netflix等公司都是采用这种方式。
02 特性分支开发
Git Flow
从Develop分支拉取一条Feature分支,开发团队在Feature分支上进行新功能开发;开发完成后,将Feature分支合入到Develop分支,并进行开发环境的验证;开发环境验证完成,从Develop分支拉取一条Release分支,到测试环境进行SIT/UAT 测试;测试无问题后,可将Develop分支合入Master分支,待发版时,直接将Master分支代码部署到生产环境。如下图所示[2]:
Git Flow的优点是每个分支都有明确的定义,严格按照GitFlow管理项目代码的话,很难出现代码混乱;其缺点是:如果特性分支过多的话很容易造成代码冲突,从而提高了合入的成本;由于每次提交都涉及多个分支,所以Git Flow也不太适合提交频率较高的项目。
GitHub Flow
GitHub Flow 来源于GitHub团队的工作实践,这个模型中,通常只有一个Master分支是固定的,而且GitHubFlow中的Master分支通常是受保护的,只有特定权限的人才可以向Master分支合入代码。
在GitHub Flow中,新功能开发或修复Bug需要从Master分支拉取一个新分支,在这个新分支上进行代码提交;功能开发完成,开发者创建Pull Request(简称PR),通知源仓库开发者进行代码修改review,确认无误后,将由源仓库开发人员将代码合入Master分支。
很多人可能会问,提交代码通常是commit 或者push,拉取代码才是pull,为什么GitHubFlow中提交代码提出的是“Pull Request”。因为在GitHubFlow中,PR是通知其他人员到你的代码库去拉取代码至本地,然后由他们进行最终的提交,所以用“pull”而非“push”[5]。大致流程如如下图所示[4]:
GitHubFlow优点是相对于GitFlow来说比较简单,其缺点是因为只有一条Master分支,万一代码合入后,由于某些因素Master分支不能立刻发布,就可能会影响发布。另外,每个特性都Fork代码仓库对于企业来说也过于繁琐,这种方式更适合开源项目。
GitLab Flow
GitLabFlow出现的最晚,GitLabFlow是开源工具 GitLab推荐的做法[6]。GitLabFlow支持GitFlow的分支策略,也支持GitHubFlow的“Pull Request”(在GitLabFlow中被称为“Merge Request”)。
相比于GitHub Flow,GitLabFlow增加了对预生产环境和生产环境的管理,即Master分支对应为开发环境的分支,预生产和生产环境由其他分支(如Pre-Production、Production)进行管理。在这种情况下,Master分支是Pre-Production分支的上游,Pre-Production是Production分支的上游;GitLabFlow规定代码必须从上游向下游发展,即新功能或修复Bug时,特性分支的代码测试无误后,必须先合入Master分支,然后才能由Master分支向Pre-Production环境合入,最后由Pre-Production合入到Production。具体如下图所示[4]:
GitLab Flow中的Merge Request是将一个分支合入到另一个分支的请求,通过Merge Request可以对比合入分支和被合入分支的差异,也可以做代码的Review。
需要发布版本时,GitLab Flow提倡先创建一个stable分支,之后修复bug先合并到Master分支,之后再合入到stable分支。如下图所示[6]:
特性分支组合发布
阿里云效的分支模式如下图所示[7]。基于 master 分支最新版本创建 feature 分支。然后在 feature 分支上开发、测试,直到这个 feature 功能完成,质量 OK,准备好去集成和发布。release 分支用于集成和发布。基于 master 分支最新版本创建一条 release 分支,然后把想要集成的各条feature分支合并到这条release分支,进行部署和测试工作。当 release 分支上的质量足够好,本次想上线的功能也都具备之后,就要考虑发布上线的问题啦。如前面讲的,发布上线前,会确保它基于基础分支(常见的如 master )最新。而发布后会把 release 分支合并回 master,让 master 代表最新发布版本。
结语
DevOps倡导主干开发[8],然后主干开发也对开发人员提出了很高的要求,个人觉得真正落地还是比较难的。在此也对比下各个分支模式的优缺点,根据优缺点,大家可自行根据团队情况选取,也可结合不同分支模式使用。
下篇,我们将介绍分支开发+主干发布的组合具体如何操作,敬请期待!
参考:
[1] https://paulhammant.com/2013/12/04/what_is_your_branching_model/
[2] https://bbs.huaweicloud.com/blogs/281789
[3] https://docs.github.com/en/get-started/using-github/github-flow
[4] https://www.ruanyifeng.com/blog/2015/12/git-workflow.html?bsh_bid=2219775734
[5] https://bbs.huaweicloud.com/blogs/281789
[6] https://docs.gitlab.cn/jh/topics/gitlab_flow.html
[7] https://help.aliyun.com/document_detail/224587.html
[8] https://dora.dev/devops-capabilities/technical/trunk-based-development/
原文作者:程序员Aike