你刚刚开始使用CruiseControl, 你用一个版本控制系统来管理你的代码, 你把CruiseControl安装在办公室里一台空闲的机器上.
一切都很不错, 你的代码改变后它能够立刻给你反馈. 然后那台空闲机器上的硬盘完蛋了, 于是你的这台构建服务器只好继续着它以前空闲时门闩的角色.
"没问题", 你想: "所有的代码改变都在版本控制系统里, 我们能够重新生成任何我们需要的构件. 事实上, 我们需要的仅仅是那个配置文件
...". 是的, 那个配置文件. 那个硬盘上的配置文件再也不能工作了. 这篇blog将简略叙述一下如何管理你的CruiseControl的配置而不必害怕失去它.
像许多工具一样, CruiseControl将会失去作用, 如果没有配置的话.
在 ThoughtWorks 之前的项目中, 我们老是需要给予某个人访问构建服务器的权限, 来修改CruiseControl的配置.
一旦项目壮大到不再是少数几个Developer, 让每个人都熟悉项目的安装配置就会变得很困难. 最终往往是某个人(有时是我,
你卑微的讲述者)变成了项目专职的CruiseControl管理员. 这种情形就为开发团队制造了一个瓶颈: 所有对CruiseControl的修改都汇集到一个人那里等待处理.
改善这种情形的第一步就是想办法让CruiseControl自己来应用配置的改变. 让我们开始吧. 除了那些来构建和测试你代码的<project>,
你还可以有一个专门的<project>来把配置改变应用到构建服务器. 我们一直这么做, 把配置文件放到正确的地方, 当它们改变的时候就使用CruiseControl的<bootstrapper> plugin来更新配置
:
<?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这次改动, 可以找到是谁做的修改, 可以试着理解为什么他们想这么改.
这前进了一大步. 但是如果你check in了一个有问题的配置, 它还是会被应用到CruiseControl. 幸运的是CruiseControl有很好的判断力不去应用有问题的配置,
但这将使你失去重要的反馈. 对于这个问题, 你需要自己写一个简单的validator, 像下面这样:
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}" failonerror="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.