英文原文: Configuring CruiseControl the CruiseControl way
I'm an Infrastructure Specialist at ThoughtWorks. In my role I make sure that we are building our software so it can successfully be deployed to production. In this series of blog posts I hope to pass on my top ten tips for using CruiseControl Enterprise effectively. I'm writing these with the developers or systems administrators in mind: the people who most often manage CruiseControl. However, I hope that anybody who is interested in Continuous Integration will get something from these articles.
# 3: Configuring CruiseControl the CruiseControl way : 用 CruiseControl 的方式来配置 CruiseControl.
你刚刚开始使用CruiseControl, 你用一个版本控制系统来管理你的代码, 你把CruiseControl安装在办公室里一台空闲的机器上. 一切都很不错, 你的代码改变后它能够立刻给你反馈. 然后那台空闲机器上的硬盘完蛋了, 于是你的这台构建服务器只好继续着它以前空闲时门闩的角色.
"没问题", 你想: "所有的代码改变都在版本控制系统里, 我们能够重新生成任何我们需要的构件. 事实上, 我们需要的仅仅是那个配置文件 ...". 是的, 那个配置文件. 那个硬盘上的配置文件再也不能工作了. 这篇blog将简略叙述一下如何管理你的CruiseControl的配置而不必害怕失去它. 像许多工具一样, CruiseControl将会失去作用, 如果没有配置的话.
<?xml version="1.0"?>
<cruisecontrol>
<project name="config">
<labelincrementer defaultLabel="${project.name}-1" separator="-"/>
<listeners>
<currentbuildstatuslistener file="/var/spool/cruisecontrol/logs/${project.name}/
currentbuildstatus.txt"/>
</listeners>
<bootstrappers>
<svnbootstrapperlocalWorkingCopy="/etc/cruisecontrol"/>
</bootstrappers>
<modificationsetquietperiod="30">
<svnlocalWorkingCopy="/etc/cruisecontrol"/>
</modificationset>
<schedule interval="60">
<ant antWorkingDir="/etc/cruisecontrol" antscript="/var/spool/cruisecontrol/tools/apache-ant-1.6.5
/bin/ant" uselogger="true"/>
</schedule>
<publishers>
<artifactspublisher
file="${project.name}/build.log"
dest="logs/${project.name}"/>
</publishers>
</project>
</cruisecontrol>
这将机械的更新配置, 直到世界末日. 它简单却相当有效, 现在我们不再依赖那个能够更改CruiseControl的家伙了. 突然之间他们就不需要代表团队中其他人来做些琐碎的更改了, 因为每个人都可以安全的改变配置. 如果有人确实check in了一个有问题的配置文件, 没关系, 一切都在版本控制系统中. 你可以revert这次改动, 可以找到是谁做的修改, 可以试着理解为什么他们想这么改.
package org.juliansimpson;
import java.io.File;
import net.sourceforge.cruisecontrol.CruiseControlException;
import net.sourceforge.cruisecontrol.config.XMLConfigManager;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
public class ConfigValidator extends Task {
public String configFile;
public void execute() throws BuildException {
try {
File file = new File(configFile);
new XMLConfigManager(file);
} catch (CruiseControlException e) {
throw new BuildException("Invalid CruiseControl Config");
}
}
public void setConfigFile(String config) {
configFile = config;
}
}
这个validator使用CruiseControl自己内部的一个类来校验配置. 最好是能有一个公开的接口来做这件事--可以是一个命令行选项或者一个"官方"的Ant task. 我请求过CruiseControl Enterprise Team在以后的release中考虑一下这个问题. 这种校验方式确实意味着你需要设置一下classpath, 以便让你的validator能够找到它引用的来自CruiseControl内部的类. 但是你会发现它确实能够保证目前的配置对于你正在使用的CruiseControl版本来说是有效的. 我倾向于以Ant task的方式来运行校验. 它非常简单, 并且每个人都能很容易的看到它做了什么. 下面是我把它放在一个简单的Ant脚本中:
<project name="cruisevalidator" default="publish" >
<import file="build-library.xml"/>
<target name="validated-config" depends="cruise-validator.jar">
<taskdef name="validate" classname="org.juliansimpson.ConfigValidator" classpathref="main"/>
<echo message="validating ${config}" />
<validate configFile="${config}" />
</target>
<target name="publish" depends="validated-config">
<echo level="info" message="copying CruiseControl config to server" />
<copy file="${config}" todir="${cruisecontrol.dir}" failοnerrοr="true"
description="Copy configuration to CruiseControl server" />
<echo level="info" message="forcing a reload of config on server" />
<get src="http://localhost:8000/invoke?operation=reloadConfigFile&objectname=CruiseControl+Manager%3Aid%3Dunique"
dest="${build.dir}/reload.html" />
</target>
</project>
它们合在一起像下面这样工作: CruiseControl的BootsStrapper获取最新的配置文件, 但是放在不同于CruiseControl安装目录的目录中. 你依然还不清楚它是否是一个有效的配置文件. 然后"validated-config" target会调用ConfigValidator 这个Ant task.这将调用到CruiseControl中足够的逻辑来确保配置是合法的,并且配置文件中涉及到的一些目录都存在.如果通过了这一步,那么 "publish"target就会把配置拷贝到CruiseControlserver自身的目录中覆盖原来的文件.最后还是 "publish"target会发一个简单的Http请求到JMX接口,来强制CruiseControl来重新加载一下配置.这将确保新配置会立即被 加载,这样team就会知道新配置是合法的.谢谢我的同事Tim Brown的这个非凡的主意.
我不得不承认有时我会不小心弄坏XML配置文件. 这种方式对我来说工作的尤其好, 因为我有校验的保护网. 我对我的邮件服务器和web服务器做了相似的事情, 希望很快能有机会写一下它们. 文中validator的源代码和构建脚本可以在我的网站上下载: http://www.juliansimpson.org/.
©Julian Simpson 2007. All rights reserved.
我想这个实践的核心是:
1, 将CruiseControl的配置文件check in到版本控制系统中, 以解决意外损坏的问题
2, 使用专门的"project"来自动更新配置, 以解决每次需要有人专门登录到build server上去更新的瓶颈问题.
3, 复用但不依赖于CruiseControl对配置文件的validation, 以同时获得 "阻止有问题的配置文件被应用到build server的能力" 和 "迅速获知有人check in了有问题的配置的能力"