Trunk Based Development(主干开发)介绍

主干开发是相对GitFlowGithub Flow更贴合CI/CD(持续集成/持续分发)的高效版本控制管理实践,也更贴合Devops团队。

背景

在软件开发的早年期间,GitFlow和GithubFlow被用来在软件开发中做版本控制管理。

  • GitFlow工作流中,分为主干分支(master)、开发分支(dev)、特性分支、分布分支、热修分支等,这些分支都是长期存在的,并在需求开发完成/bug修复完成/代码发布等特定时候执行代码的CR(Code Review)和合码工作。且在合并时,由仓库的核心成员或者管理员们把握代码质量。随着项目的扩大,冲突的几率提高,每次代码合码时候的工作量也大大提升,带来了额外的仓库维护成本。Github Flow便随着Github逐渐流行起来。
    GitFlow
  • Github Flow工作流中,只有一个主干分支(master),一些特性分支以及发布时会用到的分布分支。开发者可以自由从主干分支签出特性分支开发、调试,并在需求完成后合入主干分支。一定程度上减少了长期存在分支的维护成本,但同样的,CR依然是项目管理者进行,特性分支合码时代码量依然有可能很大,团队内规范不好的话,也容易导致合码后主干分支不可发布。
    Merge Conflict

主干开发(Trunk Based Development)是一种更敏捷的git工作流,所有的开发者都可以合码到主干分支,结合CI/CD流程,有助于团队快速迭代。

什么是主干开发

主干开发和CI/CD相互依赖相辅相成。

  • 进行主干开发才能保证CI/CD,即每天充分多次的集成乃至发布
  • CI/CD过程中的快速自动化测试可以保证主干分支的可发布性

在主干开发中每位或者每小组开发者将自己的工作分成小份,然后以每天至少一次的形式从自己的分支合并到主干,由于每次合并代码量不大,CR时间以及CI时间都会缩短。一个典型的主干开发时间轴如下:

主干开发时间轴

在主干开发中,某些情况下需要从主干分支中选出最佳的bug修复合并到对应版本中,但如果每天发布多次,则根本不需要发布分支,可直接从主干中部署。这样做的最大优势在于减少开发线,频繁执行小批量合并,将代码保持最新。从而降低团队的合码成本。

如何实现主干开发

在进行主干开发时,开发者需要了解如何拆解工作为小份,同时,还需要让构建流程保持通过,如果CI失败,开发者需要立即停止当前工作修复问题,无法短期修复时,也要还原相应更改。通常来讲,主干开发有下面这样的特征:

  • 仓库里的活跃分支不超过3个
  • 分支的合码频率不少于每天1次,即分支的生存周期不超过1天
  • 没有代码冻结期或集成期

在实践中,有下面一些tips:

  • 小commit,多合码:将每次合码改动限制在少量的commit和较少的代码改动上,保证合码时轻松;主干分支应该有频繁的小批量改动合码
  • 最少1天1合码:每天合并或关闭待合并分支,有效减少合码压力,提高增量发布敏捷度
  • 同步Code Review:主干分支的每次合码需要保证CR的及时响应,这可以借助一些代码分析工具的辅助
  • 全面的自动化测试覆盖:确保有全面的自动化单元测试套件,保证测试通过后再合并代码,这也是保证主干分支可发布的基础
  • 构建快速:降低CI成本,构建和测试需要在几分钟内完成

同时也带来两个新概念

  • 分支抽象:在主干开发中,合码频率很高,有些大需求可能没有办法在1天内就完成合码,对于未完成的需求,可以在代码中先埋下未使用的新特性,等待需求完成后,再使用埋好的新功能。这种在源代码中提前埋下“代码分支”的方式成为抽象分支(Branch by abstraction)
  • 特性开关:在分支抽象的基础上,有些合并到主干的改动不一定想让所有用户都看见,可以在代码中预先埋入分支语句,再从配置中读取当前是否使用特性。这样可以实现功能灵活切换、实现ab-test等效果

feature-flags

标准开发流

1
2
3
4
5
6
7
8
git checkout master && git pull --prune
git checkout -b <feat/branch>
# coding
git push -u origin <feat/branch>
# after any updates
git push
# or add --force if rebased during updates
git push -f
  1. 更新本地master分支
  2. 签出特性分支
  3. 编码
  4. 推送本地分支到远端
  5. 提MR,如果MR后有更新,继续push,当rebase master遇到冲突时,推送需要增加-f参数
  6. 合码

注:因为主干开发每次合码量不大,建议使用rebase解决冲突

主干开发的好处

主干开发的最大好处在于对CI的亲和度。可以想象开发者完成当日工作,当日合码,当日测试通过完成集成,达到可发布状态。很大程度减少了合码的痛苦。进而有:

  • 持续CI
  • 持续CR
  • 持续CD

总结

非常适用于敏捷开发中,对于团队成员能力过关(要懂得怎样拆分需求)、测试有着良好建设的团队来讲,是种提效的好方式,值得一试。相反如果成员拆分不够良好、代码review不够及时,测试不够自动化和系统,则不适用主干开发。

参考