用持续集成技术把版本发布周期从2周压到2小时,我们踩过的所有坑
上周三凌晨两点,我在公司茶水间啃凉包子的时候,还在骂三年前拍板上持续集成的CTO。
谁懂啊。
当时团队二十多个人,每周五下午准能看到半个研发部围着测试环境的服务器日志骂街,要么是本地能跑的代码一合并就崩,要么是第三方依赖的版本号没对齐,攒了一周的功能到发布当天直接卡壳,改完bug天都亮了。
我那时候真觉得,这CTO是脑子进了水,放着好好的“周五攒包、周末加班”的传统流程不维持,非要搞什么花里胡哨的持续集成技术。
直到上个月我们把版本发布周期从2周压到2小时,我在发布群里看着大家准点下班去吃火锅的时候,才偷偷给CTO发了个道歉的表情包。
持续集成流水线代码合并冲突处理效率对比柱状图
说出来你可能不信,就这么个简单的规矩,第一个月就把我们的合并返工率从38%降到了11%。之前每周五下午的“冲突大战”直接消失,大家再也不用为了处理攒了一周的冲突熬到半夜。
持续集成流水线分阶段测试执行流程图
改完之后我们再统计,流水线结果的遵守率从之前的22%涨到了94%。说真的,之前总觉得是大家的执行力差,现在才明白,是我们一开始把规则设计得反人类——谁愿意为了一个提交等50分钟的流水线结果?
别拿教科书上的定义糊弄人,我们用持续集成解决的第一个真问题
很多人第一次接触持续集成,看到的都是教科书上干巴巴的定义:“开发者频繁将代码合并到主干,通过自动构建和自动测试验证合并的流程”。我之前背这句话的时候都快睡着了。 去年中科院软件所发的那份DevOps效能调研我翻了三遍,里面说真正把持续集成跑通的团队,代码合并的平均返工率能降62%——我之前还以为是课题组凑出来的漂亮数字,直到我们把流水线跑顺的第一周,合并冲突的处理时间从每天人均1.5小时砍到12分钟,才知道之前的日子有多离谱。 真的爽。 之前大家都是攒着三五天的代码一次性往主分支合,一合就是几十上百个文件的冲突,有人为了躲冲突甚至偷偷把主分支的保护规则关了,合完拍拍屁股就下班,留第二天的同事当接盘侠。 我就接过那种烂摊子。 那天早上我刚到工位,就看到主分支的测试环境全挂了,查了俩小时才发现是前一天晚上有人合代码的时候,把同事写的支付模块的依赖给覆盖了,他自己都不知道。 跑了持续集成之后,我们定的规矩特别简单:每个人每天至少把本地分支往主分支同步一次,流水线自动跑编译、单元测试、静态代码扫描,有问题的代码根本合不进去,谁写的问题谁第一时间收到告警,根本不用攒到周五算总账。
持续集成流水线代码合并冲突处理效率对比柱状图
说出来你可能不信,就这么个简单的规矩,第一个月就把我们的合并返工率从38%降到了11%。之前每周五下午的“冲突大战”直接消失,大家再也不用为了处理攒了一周的冲突熬到半夜。
踩了两年的坑,才摸透持续集成技术最容易被忽略的细节
别觉得搭个Jenkins、把代码拉下来跑个编译就算把持续集成跑通了。2024年ACM软件工程分会的那篇关于CI流水线有效性的研究我特意找来看了,里面有个数据看得我直冒冷汗:超过70%的团队搭的CI流水线是“摆设”。 我之前就是那70%里的。 我们最早搭的流水线有多蠢?搭完之后把所有单元测试、集成测试、甚至端到端的UI测试全堆在第一步跑,每次提交代码要等50分钟才能看到结果。后来大家学乖了,本地跑个编译就直接推,流水线爱跑啥跑啥,反正合都合了,等流水线跑完出问题,早就有人把代码部署到测试环境了。 那时候我们的流水线告警群,每天有一半的消息是“流水线失败了但我已经合完了,大家帮忙看看”,现在想起来都觉得好笑。 后来我们翻了一堆研究文档,才看到那个被无数团队验证过的结论:别让流水线的等待时间超过开发者的耐心阈值——当单次流水线执行时间超过10分钟,开发者主动等待结果的比例会掉一半,超过30分钟,大家就直接无视流水线结果了。 我们花了三周时间把流水线拆成了三层: 第一层是提交到远程分支就跑的快速校验,只跑编译和核心模块的单元测试,整个过程控制在3分钟以内,有问题立刻通知提交人,根本不等到合并; 第二层是合并到主分支之后跑的全量单元测试和静态扫描,10分钟跑完,发现问题直接回滚合并记录; 第三层是每天固定时段跑的全量集成测试和UI测试,不卡日常合并流程。
持续集成流水线分阶段测试执行流程图
改完之后我们再统计,流水线结果的遵守率从之前的22%涨到了94%。说真的,之前总觉得是大家的执行力差,现在才明白,是我们一开始把规则设计得反人类——谁愿意为了一个提交等50分钟的流水线结果?