你剛剛開始使用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.