《持续交付 发布可靠软件的系统方法》读书笔记
版本控制系统(也叫源文件控制或修订控制系统)用于维护应用程序每次修改的完整历史,包括源代码、文档、数据库定义、构建脚本和测试,等等。 然而,它也有另一个重要的用途,让团队一起开发应用程序的不同部分,同时维护系统记录。
分支与合并
团队使用分支的几个原因:
- 物理上:因系统物理配置而分支,即为了文件、组件和子系统而分支。
- 功能上:因系统功能配置而分支,即为特性、逻辑修改、缺陷修复和功能增加,以及其他可交付的功能(比如补丁、发布或产品等)而分支。
- 环境上:因系统运行环境而分支,即由于构建和运行时平台的不同而分支或为整个平台而分支。
- 组织上:因团队的工作量而分支,即为活动/任务、子项目、角色和群组而分支。
- 流程上:因团队的工作行为而分支,即为支持不同的规章政策、流程和状态而分支。
不用分支也可以做复杂的修改
当你想对代码基进行某种非常复杂的修改时,通常会创建一个分支,然后在该分支上进行修改,从而避免打断其他开发人员的工作,这么做看起来是最简单的方式。然而,事实上,这种方法会导致多个长生命周期的分支,与主干产生很多的代码分歧。每到发布时,分支合并几乎总是最复杂的过程,无法预期会花费多长时间。书中这里的建议并不是一个技术上的解决方案,而是一种实践:一直向主干提交代码,并且至少每天一次。假如你认为,对代码做重大修改时不适合这么做的话,那我们有理由认为,你也许根本没有努力尝试过。根据我们的经验,虽然使用一系列小的增量步骤来实现某个功能,又要保持软件一直处于可用状态的这种做法有时需要花更长的时间,但其收益也是巨大的。让代码一直处于可工作状态是非常基本的要求,要想持续交付有价值、可工作的软件,怎么强调这个实践都不过分。针对这个观点,个人感觉值得讨论,欢迎评论区讨论。
按发布创建分支
“按发布创建分支”的场景是这样的。开发团队需要开始做新功能,而当前发布版本正在测试或准备部署当中,同时测试团队希望能够在当前发布中修复缺陷,但不要影响正在进行当中的新功能开发。在这种情况下,在逻辑上将新功能的开发与分支上的缺陷修复分开是可以的。但要记住的是,缺陷修复必须被合并回主干。一般来说,当把缺陷修复提交到分支上之后,最好立即就合并回主干。在这种模式中,要遵循如下规则:
- 一直在主干上开发新功能。
- 当待发布版本的所有功能都完成了,且希望继续开发新功能时才创建一个分支。
- 在分支上只允许提交那些修复严重缺陷的代码,并且这些修改必须立即合并回主干。
- 当执行实际的发布时,这个分支可以选择性地打一个标签。
按功能特性分支
这种模式是为了让开发团队更容易在“特性”层次上并行工作,并保持主干的可发布状态。每个用户故事或特性在不同的分支上开发完成。一个故事只有通过测试人员验证无问题后,才会被合并到主干,以确保主干一直是可发布的。
- 每天都要把主干上的所有变更合并到每个分支上。
- 每个特性分支都应该是短生命周期的,理想情况下应该只有几天,绝对不能超过一个迭代周期。
- 活跃分支的数量在任意时刻都应该少于或等于正在开发当中的用户故事的数量。
- 在合并回主干之前,该用户故事应该已经由测试人员验收通过了。只有验收通过的用户故事才能合并回主干。
- 重构必须即时合并,从而将合并冲突最小化。这个约束非常重要,但也可能非常痛苦,进而限制了这种模式的使用。
- 技术负责人的一部分职责就是保证主干的可发布状态。他应该检查所有的合并(可以通过查看补丁的方式进行检查)。他有权拒绝可能破坏主干代码的补丁。
按团队分支
在一个大型团队里,有很多开发人员同时工作在多个工作单元流上,并且还要维持主干总是处于可发布状态。为每个团队创建一个分支,并且只有当该分支稳定后才将其合并回主干。每次合并后,其他分支都要立即将这次变更与自己合并在一起。
- 创建多个小团队,每个团队自己都有对应的分支。
- 一旦某个特性或用户故事完成了,就让该分支稳定下来,并合并回主干。
- 每天都将主干上的变更合并到每个分支上。
- 对于每个分支,每次签入后都要运行单元和验收测试。
- 每次一个分支合并回主干时,在主干上都要运行所有的测试(包括集成测试)。
小结
“在软件开发过程中能够对所创建和依赖的资产进行有效控制”这一点对于任何项目的成功都是至关重要的。“持续集成”与“创建分支”这两者的愿望之间从根本上就有一种张力。在使用持续集成方式做软件开发时,一旦你决定创建分支,就是在一定程度上做出了妥协。到底使用哪种模式呢?你应该先识别出对团队和软件项目来说最优的流程,然后在此基础上再做出选择。一方面,从持续集成的角度来说:每次修改都应该尽早地提交到主干。主干总是处于最完整且最新的状态,因为会用它来做部署。无论使用哪种技术,或者合并工具如何强大,假如变更无法被及时提交到主干,那么时间越长,合并时的风险就越高,当最终合并时,就会越容易发生问题。另一方面,当存在某些因素(比如网络连接不稳定、构建速度较慢或方便性)时,分支可能会更高效一些。讨论了一系列为了获得更高的团队开发效率,才对持续集成进行一定程度妥协的备选方法。然而,很重要的一点是,每次创建分支,都要认识到它带来的成本。这种成本在于“增加了风险”,而唯一最小化风险的方法就是无论由于什么样的理由创建了分支,都要努力保证任何活跃分支每天(甚至更频繁地)合并回主干。不这么做的话,这个过程就不再是持续集成了。