CruiseControl is a great tool to automate builds; I use SVN and Maven2, so these are the steps I took to get it working. Anywhere you see HOSTNAME, replace it with the hostname of the machine on which CruiseControl is running; anywhere you see PROJECT1, replace it with the name of a Maven2 project.
- Download the binary distribution from the CruiseControl download page.
- Extract it to
/opt
. This creates the install directory, /opt/cruisecontrol-VERSION
, which I'll call INSTALL
.
- Add a new user under which CruiseControl will be run; pick whatever username you want, and keep it in mind.
sudo adduser ccmaster
- Create the working directory structure. The base directory
/var/lib/cruisecontrol
I'll call WORK
.
mkdir -p /var/lib/cruisecontrol/artifacts
mkdir /var/lib/cruisecontrol/logs
mkdir /var/lib/cruisecontrol/projects
- Move config files to the working dir.
mv INSTALL/config.xml INSTALL/dashboard-config.xml WORK
- The embedded Jetty server (for the dashboard, reporting) runs on port 8080, but I already have Tomcat on 8080, so I'm running it on port 8081. In order to do so, a few changes are needed. In
INSTALL/cruisecontrol.sh
, replace
EXEC="$JAVA_HOME/bin/java $CC_OPTS -Djavax.management.builder.initial=mx4j.server.MX4JMBeanServerBuilder -Dcc.library.dir=$LIBDIR -Djetty.logs=$JETTY_LOGS -jar $LAUNCHER $@ -jmxport 8000 -webport 8080 -rmiport 1099"
echo $EXEC
$JAVA_HOME/bin/java $CC_OPTS -Djavax.management.builder.initial=mx4j.server.MX4JMBeanServerBuilder "-Dcc.library.dir=$LIBDIR" "-Djetty.logs=$JETTY_LOGS" -jar "$LAUNCHER" $@ -jmxport 8000 -webport 8080 -rmiport 1099 &
with
EXEC="$JAVA_HOME/bin/java $CC_OPTS -Djavax.management.builder.initial=mx4j.server.MX4JMBeanServerBuilder -Dcc.library.dir=$LIBDIR -Djetty.logs=$JETTY_LOGS -jar $LAUNCHER $@ -jmxport 8000 -webport 8081 -rmiport 1099"
echo $EXEC
$JAVA_HOME/bin/java $CC_OPTS -Djavax.management.builder.initial=mx4j.server.MX4JMBeanServerBuilder "-Dcc.library.dir=$LIBDIR" "-Djetty.logs=$JETTY_LOGS" -jar "$LAUNCHER" $@ -jmxport 8000 -webport 8081 -rmiport 1099 &
For extra credit, make the webport a variable at the top of the script for easy modification.
Next make the port change in INSTALL/etc/jetty.xml
; replace
<Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
with
<Set name="port"><SystemProperty name="jetty.port" default="8081"/></Set>
Finally we need to set the dashboard URL, so add the following line to WORK/config.xml
, just inside the cruisecontrol
element:
<dashboard url="http://HOSTNAME:8081/dashboard" />
- Checkout your project(s) to the CruiseControl projects dir we created earlier. Modify the SVN URL for your project as necessary.
cd WORK/projects
svn co http://HOSTNAME/svn/PROJECT1
- Add project configuration to
WORK/config.xml
This is a single project, but you can have any number of project
s within the cruisecontrol
element.
<project name="PROJECT1" buildafterfailed="true">
<listeners>
<currentbuildstatuslistener
file="logs/PROJECT1/status.txt" />
</listeners>
<!-- Bootstrappers are run every time the build runs,
*before* the modification checks -->
<bootstrappers>
</bootstrappers>
<!-- Defines where CruiseControl looks for changes, to decide
whether to run the build -->
<modificationset quietperiod="300">
<svn localWorkingCopy="projects/PROJECT1" />
</modificationset>
<!-- Configures the actual build loop, how often and which
build file/target -->
<schedule interval="60">
<maven2
mvnhome="/usr/share/maven2/"
pomfile="projects/PROJECT1/pom.xml"
goal="clean | scm:update | package" />
</schedule>
<!-- directory to write build logs to
default: logs/[projectname] -->
<log>
<merge
dir="projects/PROJECT1"
pattern="TEST-*.xml" />
</log>
<!-- Publishers are run *after* a build completes -->
<publishers>
<artifactspublisher
file="projects/PROJECT1/target/PROJECT1.war"
dest="artifacts/PROJECT1" />
</publishers>
</project>
Using the Maven2 goal scm:update
requires that SCM info be included in your pom.xml
file; something like the following within the project
element should work, but again, modify the SVN URL as necessary:
<scm>
<connection>scm:svn:http://HOSTNAME/svn/PROJECT1/</connection>
<developerConnection>scm:svn:http://HOSTNAME/svn/PROJECT1/</developerConnection>
</scm>
- Make sure the
INSTALL
and WORK
dirs are owned by your CruiseControl user:
sudo chown -R ccmaster:ccmaster INSTALL WORK
- Setup the init script for startup and shutdown. The following was taken from the CruiseControl wiki and modified for my directory structure, CruiseControl user, Jetty port, and
JAVA_HOME
, and should be placed in /etc/init.d/cruisecontrol
.
#!/bin/sh
#content of /opt/cruisecontrol/init script
# chkconfig: 345 99 05
# description: CruiseControl build loop (see /home/tools)
# CruiseControl Unix Startup Script Version 2.1
#
# based on http://confluence.public.thoughtworks.org/display/CC/UnixStartupScriptVersion1.x
# adapted for multiple projects
# also based on the file attached to the above page created by Jerome Lacoste
#
# CruiseControl startup: Startup and kill script for Cruise Control
#
###################################################################################################
# USER CONFIGURATION
#
# Fill in these values for your Cruise Control setup
# What user will Cruise Control run as? The user will need permission to write and modify files
# in the next entries.
CC_USER=ccmaster
# Where is the CC startup script located?
CC_INSTALL_DIR=/opt/cruisecontrol-bin-2.8.3
# In what directory is the config.xml file located for CC?
# default: CC_WORK_DIR=$CC_INSTALL_DIR
CC_WORK_DIR=/var/lib/cruisecontrol
# Where will the cruisecontrol.log file be located?
# default: CC_LOGFILE_DIR=$CC_INSTALL_DIR
CC_LOGFILE_DIR=$CC_WORK_DIR
#######################
# ENVIRONMENT ADDITIONS
# Add environement variables here that are needed by your build.
# example:
# export JAVA_HOME=/usr/local/java
#
# or like this for local variables ONLY used in this file:
# JAVA_HOME=/usr/local/java
export JAVA_HOME=/usr/lib/jvm/java-6-sun/
# Add path to additional executables needed for project build. See PATH entry below for base config.
# No additional action taken when blank.
PATH_ADDITIONS=
##############################
# CRUISE CONTROL PORT SETTINGS
# Port for Jetty reporting application. You can access it by going to http://localhost:8080
# default CC_WEBPORT=8080
CC_WEBPORT=8081
# JMX port for webapp and Java Management eXtensions (JMX). You can access it by going to http://localhost:8080
# Change only if this port is in use as the webapp will also need modification.
# default CC_JMXPORT=8082
CC_JMXPORT=8082
# RMI port for control via Java's Remote Management Interface (RMI)
# Leave blank to disable.
CC_RMIPORT=
###################################################################################################
# DO NOT MODIFY ENTRIES BELOW THIS LINE
NAME=cruisecontrol
DESC="CruiseControl - continuous integration build loop"
PATH=/sbin:/usr/sbin:/usr/bin:/bin
# add additions if variable has text defined
if [ -n "$PATH_ADDITIONS" ]; then
PATH=$PATH_ADDITIONS:$PATH
fi
export PATH
CC_DAEMON=$CC_INSTALL_DIR/cruisecontrol.sh
CC_CONFIG_FILE=$CC_WORK_DIR/config.xml
CC_LOG_FILE=$CC_LOGFILE_DIR/cruisecontrol.log
CC_COMMAND="$CC_DAEMON -configfile $CC_CONFIG_FILE -webport $CC_WEBPORT -jmxport $CC_JMXPORT -rmiport $CC_RMIPORT"
# overwrite settings from default file
if [ -f /etc/default/cruisecontrol ]; then
. /etc/default/cruisecontrol
fi
# does the executable exist?
test -f $CC_DAEMON || (echo "The executable $CC_DAEMON does not exist!" && exit 0)
if [ `id -u` -ne 0 ]; then
echo "Not starting/stopping $DESC, you are not root."
exit 4
fi
# Get the PID output from the startup script
if [ -f $CC_WORK_DIR/cc.pid ]; then
CC_PID=`cat $CC_WORK_DIR/cc.pid`
else
echo "No cc.pid file found. CC process may not be controllable from this script!"
fi
case "$1" in
'start')
cd $CC_WORK_DIR
#echo "CC environtment at startup" > cc.startup.env
#env >> cc.startup.env
su $CC_USER -c "/bin/sh -c \"$CC_COMMAND >> $CC_LOG_FILE 2>&1\"" & RETVAL=$?
echo "$NAME started with jmx on port ${CC_JMXPORT}"
;;
'stop')
if [ -n "$CC_PID" ] && ps -p ${CC_PID} > /dev/null ; then
kill -9 ${CC_PID}
sleep 5
$0 status
RETVAL=$?
else
echo "$NAME is not running"
RETVAL=1
fi
;;
'status')
if [ -n "$CC_PID" ] && ps -p ${CC_PID} > /dev/null ; then
echo $NAME \(pids $CC_PID\) is running
RETVAL=0
else
echo "$NAME is stopped"
RETVAL=1
fi
;;
'restart')
$0 stop && $0 start
RETVAL=$?
;;
*)
echo "Usage: $0 { start | stop | status | restart }"
exit 1
;;
esac
#echo ending $0 $$....
exit 0;
- Make the init script executable:
sudo chmod 755 /etc/init.d/cruisecontrol
- Add CruiseControl to the default runlevel so that it starts on boot.
sudo update-rc.d cruisecontrol defaults
- Start it up!
/etc/init.d/cruisecontrol start
Check
/var/lib/cruisecontrol.log
for exceptions.
No comments:
Post a Comment