持续集成学习总结(三)
(三)持续集成的具体实施经验举例
持续集成有很多很多的好处。可是持续集成要做好的话,本身就有很多的讲究。从持续集成工具的选择到持续集成具体实施,每一点都可能影响到你使用持续集成的效果。持续集成不是持续编译,也不是仅仅用来发发邮件的工具而已。
首先选择一个好的工具很重要,可能会觉得QuickBuild这个工具真得很不错。工具选好了,具体怎么做呢?这个没有什么标准可以遵循,每个项目都是不一样的,我谈谈我们这里的具体过程吧。
首先,我们对编码有一些规范需要遵从,所以我们制定了一系列的FindBugs和PMD的规则用于检查代码。
其次,我们使用Cobertura作为我们的代码覆盖(code coverage)工具。
再次,我们使用JUnit作为我们的unit test工具
基于上述几点,我们编写了我们的Ant脚本,这个脚本有一系列的task,基本上就是:
compile, source code analytics, unit test, generate reports, generate javadoc, package artifacts
这个,也是Java领域中经常使用的一个完整的过程。
有了这样一个脚本以后,我们开始配置我们的项目到QuickBuild中去,在QuickBuild中,我们配置一个configuration,然后设定我们的SCM repository,对应于我们的ant task,我们配置了一系列的step,用于完成整个过程。由于我们的测试需要跨平台,所以对应与同一个unit test的task,我们使用QuickBuild的分布式的step功能,使之在不同平台上可以进行测试,这一点也是使用CI Server的一个好处吧。
对应于这个configuration,我们配置了四个子configuration,分布是 Development Configuration, QA Configuration,Integration Configuration和Release Configuration。这几个configuration分别对应于我们开发过程的四个阶段,我们的每日构建都是在Development configuration上的,所以我们配置为每日一次,而对于其它三个则不做自动的构建。因为我们是通过Promote来做的。对于 Development Configuration,我们没有对SCM自动打Label,而对于其它的,我们则对每一个Build自动对SCM进行打Label。
有了这些以后,开发工作开始了,我们每天的代码在下班前都提交到subversion里去,第二天,Development Configuration就自动的编译完成了,并且发送通知给我们。我们通常会会开一个Morning Meeting,首先我们会到在QuickBuild的页面上,看到昨天有哪些个改动,测试的状况,比如说哪些测试修正了,哪些测试还没有被修正,哪些 source code没有通过代码检查。然后我们会点到具体的报告中去分析,这些报告都可以很容易的打开source code,我们可以直接在上面对各个改动做code review。通常这个工程耗时约30分钟结束。
经过这样开发之后一段时间,我们的功能很多已经就绪,就可以提交给QA作test了,由于当日的构建可能失败,或者不是我们特别想给QA的,那么我们会选择之前几日的一个好的build做 Promote,这个promote就会自动触发QA Configuration去做build,QA Configuration的build做完以后,就会发送一个邮件通知QA Lead,这封邮件里QuickBuild会把所有与上一个QA build的changes都列出来,这样他就知道我们这个版本里增加了什么功能,修正了什么bug。
再如此经过几个迭代后,我们开发组和QA组一致认为功能基本实现了,bug也不多了,于是就由QA的Lead做一个Promote,触发Integration Configuration不build一个大版本交给客户,做VOC (Voice of Customer),听却客户的意见,如果客户没有什么易见的话,那么就会在Integration Configuration上做一个Promote到Release Configuration上去。
通过这样做,我们基本上可以很容易的知道每一个版本之间有什么变化,甚至我们可以很容易的重新build出任何一个时间点上的版本。而且,我们基本上无需操心什么时候给SCM打什么样的Label,因为对于我们而言,我们需要看到的只是每一个版本的build。而如果用subversion来管理的话,也许你也可以通过命令来列出在SCM中各个版本的变化,但是如果有一天,你头昏忘记打label的话,或者打错label的话,也许要找到这个问题就不是那么容易了。又也许,你可以通过一系列的命令来完成这里提到的所有功能,但是我是懒惰的,而且很容易做错事情,所以我觉得如果机器可以完成的话,就让机器去做吧。