基于 CruiseControl 和 Rational 统一变更管理实现的软件开发中的自动化持续构建

转自:http://www.ibm.com/developerworks/cn/rational/r-cn-cruisecontrolucm/
本文介绍了持续构建工具 CruiseControl 和 IBM Rational 统一变更管理集成的解决方案。通过本文中的解决方案,可以尽早的发现和规避代码中存在的风险,遵守统一的流程及时获取可发布的软件,确保敏捷开发的速度和质量。

统一变更管理系统中持续集成的必要性

使用 IBM Rational ClearCase 和 IBM Rational ClearQuest 实现的统一变更管理软件将配置管理和变更管理紧密结合起来,尤其针对大中型项目,实现软件开发生命周期的流程控制和管理。在这个过程中,面向变更所做的代 码在开发流上被不断的检入和交付到集成流。可能在交付前,开发人员已经在个人开发流上对代码进行过编译和单元测试。然而由于在交付过程中可能发生的代码冲 突和归并,或者由于构建环境改变,导致集成流上的构建和测试失败。为了尽早发现和规避交付后产生的风险,加快构建和发布的速度,代码需要不断被集成,所以 持续集成构建工具是必不可少的。同时为了减少在构建过程中人工干预所带来的错误,对所有发布遵守统一的构建流程,我们希望进程构建工具尽可能做到自动化。

CruiseControl 正是这样一个提供了自动化的可持续集成和构建流程管理的工具。CruiseControl 是基于 Ant 技术实现的,它实现的 plug-ins 提供了对不同的源代码管理工具和构建工具的集成,并且实现了构建结果 email 通知和构建 artifacts 统一 web 界面管理。此外,CruiseControl 是 Java 语言实现的开放源码,所以用户可以通过修改代码或者安插脚本实现构建过程个性化。

本文主要介绍了 CruiseControl 和基于 IBM Rational ClearCase 和 ClearQuest 实现的统一变更管理的集成方案,通过个性化的脚本将 CruiseControl 融入软件生命周期管理,实现整个开发流程的自动化。

两种构建模式 -- 单元构建和每日构建

基于 IBM Rational ClearCase 和 ClearQuest 实现的统一变更管理主要应用于大中型团队项目。为了尽早发现交付中代码归并产生的问题,频繁的交付和集成是关键。对于大中型项目,如果每人每天都进行一次 交付,为了尽可能快速发现问题并且缩小问题范围,集成构建工具需要尽快对每次交付进行集成构建。然而,一般的项目可能需要几个小时完成构建。为了缩短构建 时间同时尽可能发现问题,这里引入了单元构建和每日构建的概念。

单元构建

为了达到尽早发现问题的目的,我们设计了单元构建。单元构建是基于前一次成功构建,仅对修改的源代码进行编译和单元测试的构建过程。 CruiseControl 提供的与 ClearCase 集成的功能可以监控 UCM 项目的集成流,当基于变更请求的代码被交付到集成流,新的元素版本在流上被创建,CruiseControl 这时启动单元构建程序。这个构建可以采用增量编译,目的在于迅速发现被交付的代码与集成流上的代码归并后是否存在错误。当然有些问题只有在完全编译中才能 被发现,但是考虑到这种问题如果不是经常发生,而且为了达到短时间完成单元构建,然后可以对其他被交付的代码进行检查的目的,我们可以将完全构建发生的问 题留到每日构建中解决。此外,为了尽早发现集成的代码中存在的问题,也可以在构建脚本中加入基本的自动测试脚本。脚本中的任何测试用例的执行失败都会直接 导致单元构建失败。


图 1. 持续集成中单元构建的典型流程
持续集成中单元构建的典型流程

每日构建

不管是使用敏捷开发还是瀑布开发模式的项目,最好每天至少完成一次完全构建。和单元构建相比,每天进行的完全构建产生可以用来测试和发布的 artifacts,并且在统一变更管理系统中创建和维护基线,记录当前构建是否成功。通过基线,开发人员可以回溯项目的历史版本重新建构历史发布,也可 以重构失败构建的代码环境来分析和解决问题。和单元构建一样,在构建 artifacts 产生后,也可以在构建脚本中加入基本的自动测试。如果自动测试中的任何测试用例执行失败,那么每日构建也标记为失败。由于每日构建是完全构建,并且调用的 测试用例可能也比单元构建多,所以需要较长时间完成。为了不占用白天的服务器资源,我们可以设定在晚上的某一时间启动每日构建。


图 2. 每日持续集成构建的典型流程
每日持续集成构建的典型流程

在 CruiseControl 中实现与 UCM 集成的持续集成构建

通过配置 CruiseControl 安装目录下的文件 config.xml,可以实现项目的持续集成构建。上一章节介绍了单元构建和集成构建的典型构建流程,在这一章节我们详细介绍如果在 CruiseControl 中通过配置 XML 元素和属性实现这两种流程。

在 CruiseContrl 与 UCM 集成环境实现单元构建

首先设置监控任务,透过事先创建的集成视图监控集成流上是否有新的交付版本,决定是否启动单元构建。在下面的示例代码中 schedule 任务每 120 秒检查一次,查找集成流上是否有新的版本,然后运行单元构建脚本 cc-build-unit.xml。在所有新的版本创建后等待 300 秒启动单元构建,这样做的目的是防止单元构建在交付的途中(部分代码被检入的时候)就被启动。


清单 1. 配置监控任务
<!-- Defines where cruise looks for changes, to decide whether to run the build --&gt

viewPath="C:/TestProject_int_view/Test.CompVOB"
contributors="true"/>


<!-- Configures the actual build loop, how often and which build file/target --&gt

buildfile="cc-build-unit.xml"
target="build">





接下来的任务是在文件 cc-build-unit.xml 中配置的。首先更新构建用的集成视图,装入集成流上最新的代码版本。


清单 2. 更新构建区域源代码
 








代码更新后启动项目的构建脚本,对刚才交付的代码进行增量编译和测试


清单 3. 启动构建脚本


编译和测试结束后,脚本 cc-build-unit.xml 的任务也都完成。单元构建通过 config.xml 中的 任务将编译和测试产生的日志文件合并到 CruiseControl 为本次构建产生的日志文件,通过 web 控制台发布。


清单 4. 合并单元构建脚本的日志文件和 CruiseControl 的日志文件





此外,为了将构建结果及时通知给交付代码的开发人员以及其他项目相关人员,可以通过 email 的方式,将构建结果和日志内嵌到 email 中通知项目组成员。这里 子元素定制在构建失败后,除了进行代码交付的可发人员,其他人是否收到 email 通知。


清单 5. 通过 email 通知构建结果
<!-- Publishers are run *after* a build completes --&gt

buildresultsurl="http://build-server:8080/cruisecontrol/buildresults/${project.name}"
mailhost="mail-server"
returnaddress="CruiseControl@build-server "
returnname="CruiseControl"
subjectprefix="[CruiseControl]"
xsldir="webapps/cruisecontrol/xsl"
css="webapps/cruisecontrol/css/cruisecontrol.css"
skipusers="false">





在 CruiseContrl 与 UCM 集成环境实现每日构建

与上一章节介绍的单元构建不同,每日构建是每天定时启动的。如果在规定的启动时间之前集成流上有代码交付,CruiseControl 启动构建。下面的设置在晚上 9 点启动任务,如果有新的版本在集成流 TestProject_Integration 上创建,CruiseControl 执行每日构建脚本 cc-build-nightly.xml。


清单 6. 配置定时启动任务
 <!-- Defines where cruise looks for changes, to decide whether to run the build --&gt

viewPath="C:/TestProject_int_view/Test.CompVOB"
contributors="true"/>


<!-- Configures the actual build loop, how often and which build file/target --&gt

buildfile="cc-build-nightly.xml"
target="build"
time="2100">






接下来的构建任务是在 cc-build-nightly.xml 中完成的。每日构建中产生的 artifacts 可以用来发布给测试团队和客户,所以在执行构建的时候需要更严格。为了确保构建区域代码的稳定和干净,我们需要在脚本中给集成流加锁,清空构建区域的所有 文件,重新装载集成流上的最新代码到构建区域。


清单 7. 清空和装载构建区域源代码





















这之后和单元构建一样,执行清单 3 中的构建脚本进行完全编译和自动测试。结束后返回到 config.xml,和清单 4 一样,将编译和测试产生的日志文件合并到 CruiseControl 日志文件,通过 web 控制台发布。

不管 cc-build-nightly.xml 执行的编译和测试是否成功,都需要在集成流上创建基线。通过基线可以重建构建的代码环境,便于以后对成功的构建进行重构,或者对失败的构建进行调试。这个任务在 config.xml 的 任务中完成。


清单 8. 创建构建成功后的基线


buildfile="cc-build-nightly.xml"
target="make-success-baseline">






在 cc-build-nightly.xml 中加入 make-success-baseline 任务:


清单 9. 加入 make-success-baseline 任务










这里我们假设 ClearCase 项目使用的 projectname_basename_date 格式的基线模板,所以上面的创建基线操作只需要输入 basename 部分就够了。

对于构建成功后创建的基线,我们用 ${label} 作为基线的 basename。这个变量是 CruiseControl 提供的对成功构建的标识,默认的第一次成功构建的标识是 build.1,项目每次构建成功后”.”后面的数字依次加 1。也可以通过 修改构建标识的格式。在这里生成的基线名称是 TestProject_build.1_20090724。

如果构建失败,我们可以使用不同的 basename 创建失败的基线。


清单 10. 创建构建失败后的基线


buildfile="cc-build-nightly.xml"
target="make-failed-baseline">






在 cc-build-nightly.xml 中加入 make-failed-baseline 目标:


清单 11. 加入 make-failed-baseline 目标









CruiseControl 为每个产品的每个构建创建单独的目录,用于发布构建产生的 aritfacts。测试人员通过 web 控制台可以下载 build artifacts 用于测试,发布经理可以将这些 artifacts 打包给客户。在构建成功后,使用 将构建产生的 aritifacts 拷贝到 CruiseControl 提供的发布目录。


清单 12. 发布构建产生的 artifacts


dir="C:/TestProject_int_view/artifacts"
dest="artifacts/${project.name}" />



此外,在构建开始集成流被加锁,现在构建结束,我们还要对集成流解锁。这个工作也在 config.xml 的 部分中完成。


清单 13. 对集成流解锁

buildfile="cc-build-nightly.xml"
target="unlock-stream">




在 cc-build-nightly.xml 中加入 unlock-stream 目标:


清单 14. 加入 unlock-stream 目标
 





通过 CruiseControl 和 UCM 集成的功能进行进一步优化

ClearCase 和 ClearQuest 本身都提供对 Perl 脚本语言的支持,CruiseControl 是基于 Ant 实现的,通过 Ant 也很容易可以执行构建服务器上和随 ClearCase 安装的 ccperl 编译器,通过调用 Perl 脚本,可以在 CruiseControl 中完成任何对 UCM 系统的操作。下面举两个具体的例子。

在单元构建产生构建目标加速构建

前面的章节提到在单元构建中采用了增量编译和自动测试。为近一步缩短时间加速构建完成,我们可以根据构建中修改的代码所属的模块进行部分模块编译,然后选择相关测试用例进行测试。

为达到这一目的,首先构建脚本和自动测试脚本需要支持模块化编译和测试,这里我们对脚本编写不作具体的讨论。我们需要解决的是如何在 CruiseControl 中得到本次构建中哪些代码被修改,从而产生构建目标。

首先在 cc-build-unit.xml 更新构建区域源代码(清单 2)后,启动构建之前,插入下面的代码调用 Perl 脚本生成构建目标。


清单 15. 生成构建目标
 



这里 ucmlastbuild 变量是 CruiseControl 提供的,代表前一次成功构建的发生时间,格式是 dd-MMMM-yyyy.HH:mm:ss。根据这个时间,我们可以在脚本 getBuildTargetFromCC.pl 中利用 ClearCase lshistory 命令得到本次构建中哪些文件被修改,产生构建目标。


清单 16. 产生本次构建所有修改文件列表
 my $full_list = `cleartool lshist -branch $cc.stream -r -nco -fmt 
"%o~#~%n\\n" -since $ucmlastbuild $cc.viewroot/test.CompVOB`;

my @lines = split(/\n/, $full_list);
foreach my $line (@lines)
{
my ($type, $version) = split(/~#~/, $line);

// Not consider operation like mkbranch, rmbranch or rmver
if ($type ne "mkbranch" && $type ne "rmbranch" && $type ne "rmver")
{
push @change_list, $version;
}
}
...

构建成功后在 ClearQuest 数据库中记录构建信息

统一变更管理系统中,ClearQuest 数据库中维护变更请求的详细信息。通过 CruiseControl 对 Perl 脚本的调用,可以自动更新某一变更请求是在哪个构建中修复的。

假设在 ClearQuest schema 中为变更请求加入 FixedInBuild 属性。我们可以通过 ClearQuest 提供的 Perl API 将 CruiseControl 产生的构建标识加入到被交付的变更请求的 FixedInBuild 属性。

首先在 cc-build-nightly.xml 的目标 make-success-baseline 创建基线(清单 8)成功后加入下面的代码 :


清单 17. 在 ClearQuest 数据库中记录构建信息




在 add_build_to_cq.pl 中通过 ClearCase diffbl 命令比较本次构建和前一次构建创建的基线的区别,得到本次构建包含的被交付变更请求,然后将构建标识 ${label} 更新到变更请求的 FixedInBuild 属性。


清单 18. 更新变更请求的 FixedInBuild 属性
// Get the baseline created by CruiseControl, which is the latest baseline 
// on integration stream
my $baseline = `cleartool desc -fmt "%[latest_bls]p" stream:$cc.stream`;

// Get activities contained in the baseline, the list is same as the ChangeRequests
// delivered in the build
my $activities = `cleartool diffbl -activities -predecessor $baseline;
@activities = split(/\n/,$activities);

// Add build label (build.1) to CR’s FixedInBuild field
my $session = CQSession::Build();
foreach my $CR (@activityset)
{
my $CR_entity = $session->GetEntityById("ChangeRequest", $CR);
$session->EditEntity($CR_entity, "Modify");
$CR_entity->SetFieldValue("FixedInBuild", $label);
$CR_entity ->Validate();
$CR_entity ->Commit();

总结

本文介绍了通过对脚本的开发,将持续集成工具 CruiseControl 和统一变更管理系统 ClearCase/ClearQuest 相结合,创建一个有效的持续集成环境的全过程。通过在软件开发生命周期管理中加入自动构建和发布以及信息反馈,为实现敏捷开发提供基础,确保敏捷开发的速 度和质量。在现实环境中,读者可以结合自己的配置管理系统和项目需要,对配置文件和脚本进行定制,实现满足项目需求的持续集成系统。

}

上面只是介绍了两个典型应用,通过 CruiseControl 对脚本的调用,可以将构建的很多相关信息加入到 UCM 系统,通过对变更请求生命周期的管理实现开发流程的自动,避免人工干预带来的错误。同时对基于同一代码库的不同项目提供统一的构建流程管理,加速发布速 度。

 

最后,和单元构建一样,在 config.xml 通过 email 的形式可以快速通知相关开发人员构建结果。这个部分通过在 中直接调用清单 5 种定义的 实现。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14780914/viewspace-623551/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/14780914/viewspace-623551/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值