橘子红了
橘子红了很好看,CI(持续集成)红了就不是那么回事了。
一段时间,我们项目组受到了同事的激烈批评,其中的一个原因在于:CI红了,没人修复,周末红了两天。是啊,周末没人加班,绿了才是见鬼了呢。
我们并不服气,因为每次提交前我们都会在本地运行所有的测试,测试通过后我们才会提交,然而,一旦提交,CI却并不总是领情,一段时间里主要原因在于CI环境。我们在CI服务器上启动了Day CQ,每次代码提交后都会被打成Bundle,安装到Day CQ上,然后开始执行自动化测试。理论上OSGI框架应该支持无数次的热部署,可随着Bundle和代码基的扩大,情况开始变得糟糕,不知道什么时候,Day CQ就失去响应,测试自然就失败了。一段时间以来,一旦谁的提交破坏了CI,我们的CI猴就会站起来,很希曼的大吼一声:CQ挂了!然后刚才提交代码的那个倒霉蛋就屁颠屁颠去CI服务器重启Day CQ,剩下人则一起大笑,此时,提交拼的是人品。
这次也不能例外,重启DayCQ,手动告诉Cruise重新执行,于是CI就绿了。
于是,我们显得理直气壮,这不是我的错!
那么,这是谁的错呢?
在公司,不管是任何项目的开发,都会在项目开发地点的最高处架上CI环境的显示器,那里躺着Cruise那张让人欢喜让人忧的老脸。所有人都有基本的共识:一旦CI失败,必须要有人尽快修复,在修复之前,所有人都不能提交。CI是项目最重要的可视化手段之一。认知,就是测量。
回到问题上来,CI红了是问题吗?不是,这只是现象,CI所能做的只是暴露问题,事实上的问题是:由于CI的随机失败,整个团队的提交频率下降很快,经常有开发人员一天都提交不了的情况出现;由于提交频率下降,本地代码慢慢积累,开始出现在CI飘红基础上继续提交的现象,原因无外乎抱有侥幸心理:这是Day CQ的原因重启一下就好了,这样当大家忽略CI结果继续提交时,CI的根本好处就丢失了:自动阻止开发流程,迫使问题及时解决。
如何修复这个问题?实际并不复杂,我们改进了CI流程,在代码编译前增加了重启Day CQ环境的任务。一段时间后,通过持续集成状态分析工具iAnalyse(http://code.google.com/p/ianalyse/,同事胡凯作品),我们发现CI的通过率从原先的50%迅速提高到90%,排队提交的现象得到缓解,同时,我们强制了一次破坏CI而迟迟不能修复的代码的回滚。
为什么最开始没有将重启DayCQ加入到CI流程,原因是最开始的代码规模并不大,频繁的安装Bundle并没有产生破坏Day CQ的影响,而每次重启需要大概1分钟,在最初整个自动化测试只需要5分钟左右的情况下,这一时间显得过长。随着时间的推移,自动化测试增长到20分钟左右,CI通过率逐渐下降,终于使得没重启Day CQ成为瓶颈。换句话说,就是CI流程也需要不断重构。通常,当人们熟悉一件事情后,就会忘掉为什么最开始事情就是这样,他们会认为这是很正常的事情,那怕有人指出来,最初的时候人们也会想:他并不了解实际情况。于是,人们会说,是的,他说的非常对,但是,我们有我们特殊的情况。
尽管最开始被指出问题时并不舒服,但是所有问题的解决都会经过这一阶段。最根本的,是在所有项目开发团队间都存在对CI的共识,总有些原则是需要遵守的。