Thursday, February 18

Installing PHPunderControl in ubuntu

First of all we need to install the applications and extensions we need
$ sudo apt-get install gitosis php5-dev
$ sudo pear channel-discover pear.phpunit.de
$ sudo pear channel-discover pear.symfony-project.com
$ sudo pear install --alldeps phpunit/PHPUnit

Now we have to download CruiseControl, pick any method you want, here a wget example
$ wget http://downloads.sourceforge.net/project/cruisecontrol/CruiseControl/2.8.3/cruisecontrol-bin-2.8.3.zip?use_mirror=ufpr

We must unzip the downloaded file, I'm decompressing it directly where it will reside
$ sudo unzip cruisecontrol.zip /opt

Now we must create a group and user for the system
$ sudo groupadd cimasters
$ sudo useradd -G cimasters cimaster

Change the owner of CruiseControl files
$ sudo chown cimaster:cimasters /opt/cruisecontrol* -R

Create a script to launch it directly as a service
$ sudo kate /etc/init.d/cruisecontrol

with the contents
#!/bin/sh
CC_USER=cimaster
CC_INSTALL_DIR=/opt/cruisecontrol
CC_WORK_DIR=$CC_INSTALL_DIR
CC_LOGFILE_DIR=$CC_INSTALL_DIR
export JAVA_HOME=/opt/jdk1.5.0_11
PATH_ADDITIONS=
CC_WEBPORT=8484
CC_JMXPORT=8888
CC_RMIPORT=8585
NAME=cruisecontrol
DESC="CruiseControl - continuous integration build loop"
PATH=/usr/lib/jdk/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/bin:/bin
if [ -n "$PATH_ADDITIONS" ]; then
PATH=$PATH_ADDITIONS:$PATH
fi
export PATH
CC_DAEMON=$CC_INSTALL_DIR/cruisecontrol.sh
CC_CONFIG_FILE=$CC_INSTALL_DIR/config.xml
CC_LOG_FILE=$CC_LOGFILE_DIR/cruisecontrol.log
CC_COMMAND="cd $CC_WORK_DIR; $CC_DAEMON -configfile $CC_CONFIG_FILE -webport $CC_WEBPORT -jmxport $CC_JMXPORT"
if [ -f /etc/default/cruisecontrol ]; then
. /etc/default/cruisecontrol
fi
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
PARPID=`ps -ea -o "pid ppid args" | grep -v grep | grep "${CC_DAEMON}" | sed -e 's/^ *//' -e 's/ .*//'`
if [ "${PARPID}" != "" ]
then
PID=`ps -ea -o "pid ppid args" | grep -v grep | grep java | grep "${PARPID}" | \
sed -e 's/^ *//' -e 's/ .*//'`
fi
case "$1" in
'start')
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}, web on ${CC_WEBPORT}, rmi on ${CC_RMIPORT}"
;;
'stop')
if [ "${PID}" != "" ]; then
kill -9 ${PID} ${PARPID}
$0 status
RETVAL=$?
else
echo "$NAME is not running"
RETVAL=1
fi
;;
'status')
# echo PARPIDs $PARPID
# echo PIDs $PID
kill -0 $PID >/dev/null 2>&1
if [ "$?" = "0" ]; then
echo $NAME \(pids $PARPID $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

Give it permissions to run
$ sudo chmod +x /etc/init.d/cruisecontrol

For some reason, there are some hardcoded scripts and some failures in setting the java_home, so to take a sortcut, we'll just create symlinks to the correct places
$ sudo ln -s /usr/lib/jdk/ /opt/jdk1.5.0_11
$ sudo ln -s /usr/lib/jdk/bin/java /bin/java

With this CruiseControl should be ready to run
$ sudo service cruisecontrol start

The message tells us which ports are being used, to change them modify the script in /etc/init.d/

Now PHPunderControl
We create a temp directory
$ cd ~ && mkdir phpundercontrol && cd phpundercontrol

We'll download from the git repository
$ git clone git://github.com/manuelpichler/phpUnderControl.git

Now we only need to install it
$ cd phpUnderControl/bin && sudo php phpuc.php install /opt/cruisecontrol/

With this PHPunderControl should be ready, we only need to restart CruiseControl
$ sudo service cruisecontrol restart

Now we need a project, we have to go to the cruise control directory to create the directories
$ cd /opt/cruisecontrol/projects && sudo mkdir project && cd project

The folder will need sublic acces so CruiseControl can execute and write
$ sudo chmod -rv 777 ./

One we have the project directory we must create some directories for the builds and source code
$ mkdir source && mkdir build && mkdir build/api && mkdir build/coverage && mkdir build/logs

Now inside source directory, we'll download our code from our subversion server
$ cd source && svn co http://localhost/svn/trunk/

Now we have to create the build configurations for the project
$ cd .. && kate build.xml

And put the following code, the idea is that build will require all the other actions
1. update the code from svn
2. generate documentation
3. sniff the code looking for errors
4. apply phpunit test cases, the phpunit will look for a class phpucAllTests inside source/tests/AllTests.php

<?xml version="1.0" encoding="UTF-8"?>
<project name="project" basedir=".">
  <target name="checkout">
    <exec executable="svn" dir="${basedir}/source">
      <arg line="up" />
    </exec>
  </target>

  <target name="php-documentor">
    <exec executable="phpdoc" dir="${basedir}/source">
      <arg line="-ct type -ue on -t ${basedir}/build/api
           -tb /usr/share/php/phpUnderControl/Data/phpdoc
           -d ./"/>
    </exec>
  </target>

  <target name="php-codesniffer">
    <exec executable="phpcs"
          dir="${basedir}/source"
          output="${basedir}/build/logs/checkstyle.xml">
      <arg line="--report=checkstyle
           --standard=PEAR
           --ignore=src/autoload src/"/>
    </exec>
  </target>

  <target name="phpunit">
    <exec executable="phpunit" dir="${basedir}/source" failonerror="off">
      <arg line="--log-xml ${basedir}/build/logs/phpunit.xml
           --log-pmd ${basedir}/build/logs/phpunit.pmd.xml
           --log-metrics ${basedir}/build/logs/phpunit.metrics.xml
           --coverage-xml  ${basedir}/build/logs/phpunit.coverage.xml
           --coverage-html ${basedir}/build/coverage
           phpucAllTests tests/AllTests.php" />
    </exec>
  </target>

  <target name="build"
          depends="checkout,php-documentor,php-codesniffer,phpunit" />
</project>


We can test our build typing
$ ../../apache-ant-1.7.0/bin/ant build

Now we just need to add the project to the cruise control configuration file
$ cd ../.. && kate config.xml

add the following code inside tags, the name of the project should be the same as the name of the directory containing the build and source directories

<cruisecontrol>
<project name="project" buildafterfailed="true">
  <plugin name="svn" classname="net.sourceforge.cruisecontrol.sourcecontrols.SVN" />
  <modificationset quietperiod="60">
    <svn localWorkingCopy="projects/${project.name}/source/"/>
  </modificationset>
  <bootstrappers>
    <svnbootstrapper localWorkingCopy="projects/${project.name}/" file="build.xml"/>
  </bootstrappers>
  <schedule interval="300">
    <ant anthome="apache-ant-1.7.0" buildfile="projects/${project.name}/build.xml"/>
  </schedule>
  <listeners>
    <currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
  </listeners>
  <log dir="logs/${project.name}">
    <merge dir="projects/${project.name}/build/logs/"/>
  </log>
  <publishers>
    <artifactspublisher dir="projects/${project.name}/build/api" dest="artifacts/${project.name}" subdirectory="api"/>
    <artifactspublisher dir="projects/${project.name}/build/coverage" dest="artifacts/${project.name}" subdirectory="coverage"/>
    <execute command="phpuc graph logs/${project.name} artifacts/${project.name}"/>
  </publishers>
</project>
</cruisecontrol>

And that's it ... more simple than it looks ...