免费注册!6月19-20日,「亚马逊云科技中国峰会」重磅来袭! 了解详情
写点什么

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

  • 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:248808
用户头像

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

关注

评论

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

【iOS逆向】某车之家sign签名分析

小陈

iOS逆向

开发一套高容错分布式系统

JAVA活菩萨

Java 程序员 后端 java程序员 java编程

2022版史上最全Java八股文,没有任何异议

Java工程师

Java 面试 八股文

博云入选Gartner中国云原生领域代表性厂商

BoCloud博云

云计算 容器 云原生 Gartner

安装失败怎么办

和牛

测试

阿里大牛最新分享springboot实战派文档,开发之路必不可少

Java工程师

Java spring springboot

华为应用市场“图章链接”功能上线 让APP分发突破机型壁垒

极客天地

iOS逆向之某茅台App抓包

小陈

iOS逆向 i茅台

学python,怎么能不学习scrapy呢!

华为云开发者联盟

Python 爬虫 开发 代码

阿里出品Spring Security王者晋级笔记,并附上源码解析

冉然学Java

编程 spring security java; Spring Boot CLI 源码、

精品!阿里P7爆款《K8s+Jenkins》技术笔记,高质量干货必收藏!

冉然学Java

jenkins java; 技术笔记 编程‘’ #k8s

小程序+自定义插件的混合模式

Geek_99967b

小程序

从云计算到函数计算

阿里巴巴云原生

阿里云 Serverless 云原生 函数计算

Python 教程之输入输出(4)—— 用于竞争性编程的 Python 输入法

海拥(haiyong.site)

Python 8月月更

6000字深度总结!极狐GitLab 首次揭秘内部 DevOps 最佳实践

极狐GitLab

git DevOps gitlab 安全 CI/CD

RabbitMQ(五)死信队列

JAVA活菩萨

Java 程序员 后端 java程序员 java编程

基础到高级涵盖11个技术,Alibaba最新出品711页Java面试神册真香

JAVA活菩萨

Java 程序员面试 大厂技能 秋招 大厂面经

iOS逆向之某多多App抓包

小陈

拼多多 iOS逆向

重新审视分布式系统:永远不会有完美的一致性方案……

JAVA活菩萨

Java 程序员 java程序员 java 编程

容器化 | 在 NFS 备份恢复 RadonDB MySQL 集群数据

RadonDB

MySQL 数据库 容器化 Kubernetes 集群 备份 & 恢复

全新出品!Github总榜排行第七的SpringCloud生态全栈笔记我粉了

JAVA活菩萨

Java 程序员面试 大厂技能 秋招 大厂面经

移动平台助力推进智慧型科研院所信息化建设

BeeWorks

《机器学习的随机矩阵方法》

计算机与AI

Python 机器学习 数学

NFT盲盒挖矿系统dapp开发NFT链游搭建

薇電13242772558

dapp NFT

不需要服务器,教你仅用30行代码搞定实时健康码识别

华为云开发者联盟

云计算 疫情 文字识别 健康码

开源一夏 | 文件和目录操作|多进程和多线程【python进阶篇】

恒山其若陋兮

开源 8月月更

【Android逆向】rpc调用某安App的X-App-Token签名函数

小陈

逆向技术

力拓信创生态,博睿数据多款产品获得东方通与达梦数据库产品兼容互认证明

博睿数据

可观测性 智能运维 博睿数据 东方通 达梦数据

浅谈运用低代码技术如何实现物流企业的降本增效

王平

如何模拟后台API调用场景,很细!

Liam

前后端分离 开发 Postman API 前后端协作

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