使用SVN+CruiseControl+ANT实现持续集成之一

📅 2026/7/5 13:38:41
使用SVN+CruiseControl+ANT实现持续集成之一
在前面的文章中介绍自己当时所在团队的处境(使用.NET开发)一个不到十个人的研发团队在保证正常开发进度同时需要并发支持四、五十个项目问题处理经常为了程序版本冲突、日常测试版本、发布版本提供等重复枯燥无味的手工劳动导致团队成员身心俱疲。经历这样痛苦的一段时间终于忍受不了通过命令行实现了包括获取、编译、发布过程的集成大大减轻版本编译的时间此时还能见到团队成员一边编译程序一边聊天轻松的笑脸这就坚定了自己持续集成的做法不过可笑是当时自己对持续集成没有任何的概念只是当时的状况逼自己走了集成之路。这个工具在经历半年使用进行了一次升级提供了更多的选项功能参见升级版本介绍。另外随着公司业务的发展2009年自己负责推出一个基于JAVA的产品平台这个平台中包括了七八个子系统。一个困难就出现在我们面前为了保持以前每周一次发版每次编译发布都需要两三个小时为了摆脱这种困局找了很多资料学习了很多新的思想对比了很多工具最终使用了基于CruiseControl(以下简称CC)实现持续集成。1. 持续集成概念对于持续集成Continuous Integration这个术语源自 XP极限编程的一个最佳实践随着XP近几年的推广持续集成被大家认可并实践但持续集成并非 XP 的专利持续集成完全可以应用在采取非XP 方法的项目里面。持续集成也不是一个新的概念在这个术语出现之前日创建daily build提供同样的含义这个典型的代表就是微软他们每天的工作都开始于每日零点的版本构建。持续集成和日创建主要区别就在于实施的频率上随着 XP 社区的大师级人物 Martin Fowler等人所著《Continuous Integration》为其正名持续集成这个术语就越来越多地出现在原来日创建出现的位置。2. 持续集成优点在传统开发模式中项目按照模块进行划分等开发完成后再集成到一起进行测试这种开发方法在小规模程序开发过程中并没有太大的不足。但随着软件技术的发展软件规模也在扩大软件需求越来越复杂软件已经不能简单地通过划分模块方式来开发因为很多Bug在项目早期就存在了如果在最后集成的时候才发现问题开发者需要在集成阶段花费大量的时间来寻找Bug由于软件的复杂性需要花费大量的时间进行定位甚至有些需要调整底层架构。在这个阶段的除虫会议bug meetings特别多会议的内容基本上都是讨论 bug 是怎么产生的最后往往发展成为不同模块的负责人互相推诿责任。持续集成最大的优点是可以避免这种传统模式在集成阶段的除虫会议。持续集成主张项目的开发人员频繁的将他们对源码的修改提交(check in)到一个单一的源码库并 验证这些改变是否对项目带来了破坏持续集成包括以下几大要点访问单一源码库将所有的源代码保存在单一的地点源码控制系统 让所有人都能从这里获取最新的源代码提倡开发人员频繁提交修改过的代码。支持自动化创建脚本使创建过程完全自动化让任何人都可以只输入一条命令或者几次点击就完成系统的创建。测试完全自动化要求开发人员提供自测试的代码让任何人都可以只输入一条命令或者几次点击就运行一套完整的系统测试。支持自动化部署能够按照不同的要求发布到测试、发布服务器提供测试环境和发布程序包自动提供集成信息按照不同情况提供通过邮件、报告等方式提供每次集成结果并且提供发布平台大家能轻易看到集成的进度和结果持续集成的关键是完全的自动化自动读取源代码、编译、测试、部署、信息发布。对于每次成功的创建要求在这个自动化过程中的每一步都不能出错而最重要的一步是测试只有最后通过测试的创建才是成功的创建。在持续集成里面创建不再只是传统的编译那么简单创建还应该包括自测试自测试的代码是开发人员提交源码的时候同时提交的是针对源码的单元测试将所有的这些自测试代码整合到一起形成测试集在所有的最新的源码通过编译之后还必须通过测试集的测试才算是成功的创建。这种测试的主要目的是为了验证创建的正确性McConnell 称之为“冒烟测试”在持续集成里面这叫做集成验收测试Build Verify Test简称 BVT。BVT 测试是质量的基础QA 小组不会感受到 BVT 的存在他们只针对成功的创建进行测试如功能测试。持续集成有一个与直觉相悖的基本要点那就是“ 经常性的集成比偶尔集成要好”。Martin Fowler 认为对于持续集成来说集成越频繁效果越好 如果你的集成不是经常进行的少于每天一次那么集成就是一件痛苦的事情如果集成偶尔才进行一次一周甚至一个月 等到集成阶段发现bug然后找原因解决bug会耗费你大量的时间与精力而且这种方式有点像传统的集成模式这违背了持续集成的初衷。根据 Martin Fowler 的观点项目 bug 的增加和时间并不是线性增长的关系而是和时间的平方成正比两次集成间隔的时间越长bug 增加的数量越是超过你的预期解决 bug 付出的工作量也越大而你越觉得付出的工作量越大你就越想推迟到以后去集成企图到最后一次性解决问题结果 bug 产生的就更多导致下一次集成的工作量更大你越感觉到集成的痛苦就越将集成的时间推后最后形成恶性循环。需要注意的是从项目的一开始就引入持续集成可以尽早的发现 bug但是并不代表持续集成可以帮你抓到所有的 bug。持续集成的排错能力取决于测试技术众所周知无法证明已经经过测试的代码就已经找到了所有的错误。前面列举了持续集成这么多优点但是创建一个持续集成的环境技术上是比较复杂的也需要一定的时间关键是在于持续集成可以“及时”抓到足够多的 bug从根本上消除传统模式的弊端这就已经值回它的开销了。ThoughtWorks 公司开放了其持续集成的工具CC的源代码持续集成对于大部分开发人员来说就不再只是停留在口头上的漂亮的术语任何人在掌握了持续集成的基础理论后都可以使用CC来体会持续集成在项目开发中的巨大威力。3. 集成框架下个图描述持续集成的硬件环境图中包括了一台独立的源码库服务器以及开发人员的终端同时也是源码库服务器的客户端出自对性能的考虑建议CC 在一台独立的服务器上运行。当然你可以将 CC 放在发布服务器上甚至某个开发人员的终端上。4. CC内部工作架构下图是CC系统内部工作架构图CC主要依赖Build Loop循环构建实现通过读取Config.xml配置文件信息在每次轮询中完成源代码的检测、编译然后把编译的版本发布Web容器中以此同时把日志信息、发布结果通过RSS、邮件、网站等形式发布给干系人。4.1. Build Loop前面在讨论持续集成的时候讲到其最重要的特征之一是自动化而 CC 的 Build Loop 就是为支持自动化而设计的Build Loop 也是 CC 的核心。Build Loop 从字面上理解就是循环创建的意思CC 提供了一个守护进程( daemon)该进程自动根据配置的时间间隔也可以指定某个具体时间读取 CC 配置文件并进行循环创建build cycle每次 CC 都会重新加载配置文件修改了配置文件不用重新启动 CC。Build Loop 过程中所做的工作如下访问源码控制系统查看是否有代码被修改如果有获取源码的新版本并根据配置对源码进行一次 Build创建一个日志文件最后向开发人员通知 build 的结果活动图如下因为 Build Loop 是根据配置文件的内容来进行的根据上面 BuildLoop 所做的工作我们可以猜出配置信息主要应该包括定时创建的时间和源码库的访问信息检查源码变化情况创建任务信息如指定 Ant 文件 记录日志创建结果通知通知的内容可以定制。4.2. CC 插件PluginCC 设计思想是one-size-fits-all也 就是CC 是由一个很精小 但是很强大的核心 Build Loop以及一些外部插件组成这给使用者提供了很大的扩展空间使用者可以根据需要扩展 CC的功能提供新的插件而且 CC 是开源项目你还可以查看源码并修改CC提供的插件。CC提供了六种不同类型的插件Listener、Bootstrappe、Modificationset、Schedule、Log以及PublisherCC 的配置是围绕这些插件展开的下面对这些插件进行一个简单的介绍Listener用于处理一些项目有关的事件Bootstrapper在 CC 进行创建之前运行是创建前的准备工作