写点什么

持续集成之“分支策略”​

  • 2011-03-09
  • 本文字数:2811 字

    阅读完需:约 9 分钟

现代版本控制系统(SCM)的作用已不仅仅是保存历史版本,它还是各软件开发组织利用其分支功能实现多人并行开发,提高生产效率的一种工具。对于稍有历史的软件产品来说,一般都会有代码分支的出现,也常常见到一些历史悠久的产品其错综复杂的分支版本树甚至将产品交付团队拖入“无尽维护”的泥潭。分支的目的是希望“分而治之”,而持续集成的目的是“频繁集成”,这二者之间又有哪些联系呢?

在《测试三角形与分段构建策略原则》一文中,咱们说到:由于自动化测试时间较长,Joe 的团队实施了分阶段的持续集成。虽然这么做引入了一些风险(比如因提交阶段构建中的测试覆盖面小而不能尽早发现代码中问题),但提高了整个团队的开发效率。而且,Joe 会根据实际运行情况,在提交构建和次级构建之间不断调整自动化测试用例集来缓解分阶段构建带来的风险。

现在,这个软件游戏平台的第一个版本已经接近完成,马上就要进行内测了。团队面临的问题是:“如何做分支管理?持续集成该怎么做?”

一、短周期发布分支策略

今天是星期五。下班后,Joe 和Alice 等主要开发人员并没有马上回家,而是在一个小酒吧里聊天呢。

Alice 说道:“现在我们一直使用主干开发方式,团队所有人都工作在 Trunk 上,与之对应的只有一个持续集成环境。下星期就要做内测了,我们是不是应该拉一个测试分支,用于修复测试中发现的缺陷,在主干继续开发新功能呢?一旦修复完内测缺陷的话,我们就可以在这个分支上进行发布,再把这个测试分支的代码变更合并回主干。就像这样。”她拿了一张纸画了出来(如图 1 所示)。

“好啊,好啊。我们分成两个团队,一个在测试分支上工作,修复内测过程中发现的缺陷;另一个在主干上工作,开发新的功能。”Bob 回应道。

“对于拉分支做测试这件事,我没有疑问。但是,我不同意最后再把代码合并到主干上。”Joe 说道。“我们一直在使用持续集成实践,目的就是尽早集成。为什么要等到发布以后再将测试分支的代码合并回主干,而不是每次修复一个缺陷就合并回来呢?每次缺陷修复的代码变更不会太多,所以合并起来很容易。等到最后再合并,首先是容易漏掉一些代码,其次是一次合并代码太多,容易出错。所以,我建议下星期拉分支时,为测试分支也建立一个持续集成环境。每次发现缺陷时,都为它写一个测试,加到测试套件中。修复代码提交后,就会触发测试分支对应的持续集成构建。一旦构建成功,就将其合并回主干。”说完之后,他在 Alice 画的那张图上修改了一下(如图 2 所示)。

  1. 拉分支之后,开发团队可以继续开发新的功能。而测试团队可以单独对分支进行测试、部署,不受开发团队的影响。
  2. 一旦测试中发现问题,载发人员要在该分支上修复。
  3. 在分支发布之后,一旦发现了严重问题,仅在该发布分支上修复后即可发布补丁版本。
  4. 在分支上做修改后,就要根据实际情况进行分析,是否要合并回主干。如果需要合并,应该立即进行。

“那由谁来负责把发布分支中的 Bugfix 合并回主干呢?”

“当然是由 Bugfix 的人来负责了,他是确保合并正确性的关键。如果 Trunk 上的代码已被修改,无法合并,Bug 负责人就要与主干开发人员交流,这个 Bug 在主干的有效性,然后再决定是否修改,在哪里修改的问题。”

“我们要对发布分支上的 Bug 定义修复标准,尽量在 Trunk 上修复 Bug,除非这个 Bug 严重影响发布质量。这样可以避免无休止地在发布分支上做代码修改。这样,Bug 数才会收敛,发布分支的活跃期才会缩短。”

“嗯,相对于我们一直使用的主干开发方式来说,这种短发布分支策略的成本是:

  1. 需要多套独立的持续集成环境。即每个分支在处于活跃期时,要有与之对应的一套持续集成环境,以便不受影响。
  2. 每次发布分支上修复缺陷后,只要分支对应的持续集成构建成功,就要将其合并回主干。
  3. 由于主干开发的代码可能因架构改进使原有缺陷不复存在,所以每次合并时都需要人为判断一下合并的必要性。”

二、长周期发布分支策略?

“哦,我之前工作的一家公司,就是用这种分支策略。”Bob 说道,“但情况变得非常复杂。版本满天飞,想做合并都不容易。”

Joe 说道:“我想,可能是因为他们的客户不想升级版本,所以必须在已发布的版本上再发小版本吧?”

“的确是这样的。”Bob 回答道,“他们的发布周期大约是半年。由于已发布的版本质量不佳,所以总是有紧急修复的版本上线。另外,客户比较担心新版本的稳定性,所以只要满足自己的当前需求,就会一直使用旧版本。有些大客户还会要求公司开发针对其自身的特别需求,并快速上线,结果可想而知。”

Alice 说道:“其实,这已经是短周期发布分支的变形,即有多个活跃分支的长周期发布分支策略(如图 3 所示)。这种分支策略是应该尽量避免的,它的复杂性和维护成本都很高,因为:

  1. 每次都要把缺陷修复代码合并到后续的多个发布? 分支上,尤其是当该缺陷发生在较老的版本,而当前已有多个活跃版本需要维护时。
  2. 随着时间的推移,每个分支上的自动化测试用例增多,更多的分支会对持续集成环境中的测试机数量的需求快速增加。
  3. 发布周期长诱使团队在已有的发布分支上再做子分支 (如图 3 中的 R1.1),这会让集成和验证工作变得更加复杂(如图 3 中从 R1.1 到 R2.0 的 Cherry Picking 操作表明:需要向多个分支上合并部分代码)。
  4. 由于每个活跃分支都要对应一个持续集成环境,因此,分支越多,对持续集成环境的维护成本也就越高。

Bob 问道:“有什么办法避免这种糟糕的多活跃分支开发策略吗?”

“办法当然有,但不能解决所有问题。”Joe 回答道,“比方说,首先,要确保每个版本的开发质量,让客户放心升级。其次,软件产品要支持自动升级。在通常情况下,只要满足需求,用户就不会轻易升级软件。所以,要让软件具有自动发现新版本并在后台自动升级的能力。当然,在升级后要通知用户。这样,只要将新版本发布到互联网上的某个服务器上就行了。最后,也是最重要的一点,新版本发布周期要短一些,不断快速地推出新特性,这样就可以让用户对产品及研发团队有信心,让客户感觉他们的需求很快就会被满足。”

“对于那些企业用户来说,这种方法可能不管用。因为,企业内网很少可以连通外网。”Alice 说道。

“如果是这种情况的话,除了软件本身质量好且能自动无缝升级以外,在销售时可以与客户签订协议,告知所售软件版本的生命周期(比如 18 个月)以及升级条款,促使企业升级该软件,比如免费的大版本升级,或者因缺陷原因可免费升级等等。”Joe 回答道。

“嗯,我们开发的是游戏软件平台,部署在互联网上,所以不会遇到这个问题。”Alice 说道。

Joe 微笑着说道:“我们将会面临另外一种问题,即多个小团队开发不同的游戏组件问题。”

“哦,对了!现在我们的游戏平台中虽然仅有几个游戏,目前还一起在主干上开发。但在下一版本中,我们会增加大量的游戏组件,那应该如何应对?我们的持续集成环境应该是什么样的呢?”Alice 大声地问道。

“嗯,是个好问题!”Joe 回答道。“我已经有了一些想法。我们内测结束后,再详细讨论吧!时间也不早啦,大家回去休息吧,周末愉快!”

2011-03-09 23:248953
用户头像

发布了 100 篇内容, 共 24.8 次阅读, 收获喜欢 5 次。

关注

评论

发布
暂无评论
发现更多内容

当前中小企业网络营销缺少的三个方面

源字节1号

前端开发 后端开发 小程序开发 网站开发

浅谈SAP顾问未来十年在中国的发展前景

SAP虾客

SAP顾问 技术专家 行业专家

刷新三项世界纪录!浪潮云ICP ARM架构获SPEC Cloud测试全球第一名

云计算

一款免费的排队叫号工具,居然有这么多功能,赶紧收藏起来!

天天预约

小程序 SaaS 工具分享 排队

确保 Kubernetes 安全合规的 6 个最佳实践

Rancher

Kubernetes k8s rancher

做SAP freelancer 的几个注意事项

SAP虾客

SAP freelancer 黑名单 业界名声

Kubernetes Gateway API - 服务网络的演进

Flomesh

Kubernetes Gateway ingress

云原生数据库的下一次变革发生在哪里?

亚马逊云科技 (Amazon Web Services)

数据库 云原生

全栈、云原生的数据分析时代已来,我们如何抓住机会?

亚马逊云科技 (Amazon Web Services)

数据分析 云原生 全栈

得物技术Filament Creator材质编辑工具的实现

得物技术

模型 3D模型 3D 渲染 引擎

50万条数据 深挖四川数字经济“发展密码”:四川数字经济发展分析

易观分析

数字经济

建站建设必备的资料是什么?

源字节1号

软件开发

web前端培训 | 代码如何配置规范并格式化

@零度

前端开发

Yii2文件/图片上传实例

Owen Zhang

php

5G 时代,我们需要更便捷的RTC技术服务

曲多多(嗨翻屋)版权音乐

RTC 音乐

JavaScript this全解析

源字节1号

软件开发 前端开发 后端开发 小程序开发

开源生态|打造活力开源社区,共建开源新生态!

Orillusion

开源 WebGL 元宇宙 Metaverse webgpu

IM即时通讯为企业业务移动化带来了怎样的便利?

BeeWorks

面试突击51:为什么单例一定要加 volatile?

王磊

Java 面试

【高并发】优化加锁方式时竟然死锁了!!

冰河

并发编程 多线程 高并发 协程 异步编程

大咖说|Kubernetes自动伸缩实现方式深度讲解

云智慧AIOps社区

云计算 微服务 云原生 #Kubernetes#

什么是知识管理?知识管理的方法?

小炮

数据指标体系如何搭建才最有效,从0到1带你快速入门丨02期直播回顾

袋鼠云数栈

云端的 ABAP Restful 服务开发以及通过 abapGit 传输到其他系统的详细步骤

汪子熙

git SAP abap 5月月更 abapgit

打码打码Python爬虫,某省建筑市场请求地址参数分析,手慢无爬虫

梦想橡皮擦

5月月更

【直播回顾】Hello HarmonyOS进阶课程第四课——ArkUI动画开发

HarmonyOS开发者

HarmonyOS

原生即时通讯APP四合一成品聊天软件源码搭建个性化需求定制开发

BeeWorks

企业上云,安全合规如何进阶 ——一文拆解亚马逊云科技云安全理念与实践

亚马逊云科技 (Amazon Web Services)

云安全 亚马逊云

【LeetCode】房屋偷盗Java题解

Albert

LeetCode 5月月更

JVM进阶(十九)——Class文件常量池

No Silver Bullet

JVM class 5月月更

案例成果展 | 灵雀云助力中国人民银行清算总中心构建裸金属容器平台

York

灵雀云 容器 微服务 云原生

持续集成之“分支策略”​_Java_乔梁_InfoQ精选文章