phpUnderControl ist ein AddOn für CruiseControl um seine PHP-Projekte mit Continuous Integration auszustatten.
Am Ende soll ein phpUC Prozess laufen welcher ein git-Repository (Möglich ist hier aber fast jede Versionskontrolle, u.a. auch SVN) nach Änderungen prüft, und bei Änderungen die Fassung pullt und den Buildprozess anstößt.
Installation
Java installieren
Da CruiseControl auf Java aufbaut, wird die java-jre benötigt. Damit alles richtig läuft, sollte hier die Sun-, bzw. jetzt Oracle-Java Version verwendet werden.
User anlegen und CruiseControl installieren
Als erstes legen wir einen eigenen User für CruiseControl an. Under Ubuntu sollte hier adduser verwendet werden, für den Rest gibt es useradd.
skaverat@ratbox:~$ sudo adduser cruisecontrol Adding user `cruisecontrol' ... Adding new group `cruisecontrol' (1007) ... Adding new user `cruisecontrol' (1007) with group `cruisecontrol' ... Creating home directory `/home/cruisecontrol' ... Copying files from `/etc/skel' ... Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully Changing the user information for cruisecontrol Enter the new value, or press ENTER for the default Full Name []: Room Number []: Work Phone []: Home Phone []: Other []: Is the information correct? [Y/n] y
Jetzt über su cruisecontrol zum neu erstellen User wechseln
su cruisecontrol cd ~
CruiseControl runterladen und entpacken (Versionsnummer mit der gerade aktuellen Version ersetzen):
wget -O cruisecontrol-bin-2.8.4.zip http://sourceforge.net/projects/cruisecontrol/files/CruiseControl/2.8.4/cruisecontrol-bin-2.8.4.zip/download unzip cruisecontrol-bin-2.8.4.zip mv cruisecontrol-bin-2.8.4 cruisecontrol
Damit ist CC einsatzfertig “installiert” – Fehlt noch phpUC
phpUnderControl installieren
Der bevorzugte weg ist laut phpUC über den PEAR-Channel
Falls PEAR noch nicht installiert ist:
sudo aptitude install php-pear sudo pear update-channels sudo pear upgrade-all
Nun phpUC installieren:
sudo pear channel-discover components.ez.no sudo pear channel-discover pear.phpundercontrol.org sudo pear install --alldeps phpuc/phpUnderControl-beta
Jetzt kann CC durch phpUC gepatched werden:
cruisecontrol@ratbox:~$ phpuc install ~/cruisecontrol/
dies installiert einige zusätzliche Ressourcen und tauscht Templates der originalen Metrics aus.
phpUnderControl ist damit fertig installiert.
CruiseControl konfigurieren
Die config.xml
Hier werden generelle- und projektspezifische Einstellungen vorgenommen:
<cruisecontrol>
<!-- hier den projektnamen/order (siehe nächster Abschnitt) angeben -->
<project name="phpuctestproject" buildafterfailed="false">
<!-- git plugin laden -->
<plugin name="git" classname="net.sourceforge.cruisecontrol.sourcecontrols.Git"></plugin>
<!-- wenn eine Modifikation gefunden wurde noch 60sek warten um alle Änderungen mitzubekommen -->
<modificationset quietperiod="60">
<git localworkingcopy="projects/${project.name}/source/"></git>
</modificationset>
<!-- Git Bootstrapping auf den source-ordner -->
<bootstrappers>
<gitbootstrapper localWorkingCopy="projects/${project.name}/source" />
</bootstrappers>
<schedule interval="60">
<ant anthome="apache-ant-1.7.0" buildfile="projects/${project.name}/build.xml"></ant>
</schedule>
<listeners>
<currentbuildstatuslistener file="logs/${project.name}/status.txt"></currentbuildstatuslistener>
</listeners>
<!-- php-Unit ergebnisse werden rüberkopiert -->
<log dir="logs/${project.name}">
<merge dir="projects/${project.name}/build/logs/"></merge>
<merge dir="projects/${project.name}/source/test/log/"></merge>
</log>
<!-- hier werden coveragereports und die PHP-Doc in den entsprechenden CC-logordner kopiert -->
<publishers>
<artifactspublisher dir="projects/${project.name}/build/api" dest="artifacts/${project.name}" subdirectory="api"></artifactspublisher>
<artifactspublisher dir="projects/${project.name}/source/test/log/report" dest="artifacts/${project.name}" subdirectory="coverage"></artifactspublisher>
<execute command="phpuc graph logs/${project.name} artifacts/${project.name}"></execute>
</publishers>
</project>
</cruisecontrol>
Projekt erstellen
Um ein Projekt anzulegen muss lediglich ein Ordner in “projects/” angelegt werden. Zusätzlich brauchen wir noch eine Ordnerstruktur die der obigen Konfiguration entspricht:
cd ~/cruisecontrol/projects/
mkdir -p phpuctestproject/{source,build}
mkdir phpuctestproject/build/{api,logs}
Die build.xml
Die build.xml befindet sich im Projektverzeichnis. Hier also projects/phpuctestproject/build.xml
Hier wird festgelegt welche Programme ausgeführt werden und in welcher Reihenfolge dies geschehen soll. So kann auch festgelegt werden, dass der Buildprozess gar nicht erst weitergeführt werden soll, sobald z.B. PHPUnit fehlschlägt.
<?xml version="1.0" encoding="UTF-8"?>
<project name="phpuctestproject" default="build" basedir=".">
<!-- PHPUnit soll im source/test ordner laufen. Hier liegen alle Unittests -->
<target name="phpunit">
<exec executable="phpunit" dir="${basedir}/source/test" failonerror="on">
</exec>
</target>
<target name="php-documentor">
<exec executable="phpdoc" dir="${basedir}/source">
<!-- mit -d werden die Ordner ausgewählt welche dokumentiert werden sollen, -f schließt einzelne Dateien mit ein -->
<arg line="-ct type -ue on -t ${basedir}/build/api
-tb /usr/share/php/data/phpUnderControl/data/phpdoc
-o HTML:Phpuc:phpuc
-f foo/Bar.php
-d Ordner1,MyLibs">
</arg>
</exec>
</target>
<target name="php-codesniffer">
<exec executable="phpcs" dir="${basedir}/source" output="${basedir}/build/logs/checkstyle.xml">
<!-- auch hier: die gewählten order und Dateien werden beim CodeSniffer mit eingeschlossen -->
<arg line="--report=checkstyle
--standard=ZEND
Order1/ MyLibs foo/bar.php">
</arg>
</exec>
</target>
<!-- Die Reihenfolge in "depends" bestimmt die Reihenfolge des Buildvorgangs -->
<target name="build" depends="phpunit,php-documentor,php-codesniffer"></target>
</project>
< /pre>
Git Repository initialisieren
Damit das Git-Plugin auch weiß von wo es pullen soll, muss der source-Ordner einmal mit git initialisiert werden:
cd source/ git clone example.com/projectrepository.git .
CruiseControl starten
Bevor CC gestartet werden kann, sollten noch einige Anpassungen am Startscript vorgenommen werden.
So finde ich es z.B. eher unpraktisch, dass die CC-Instanz direkt in den Hintergrund geschickt wird. Um dies zu ändern öffnen wir die cruisecontrol.sh im CC-Ordner und löschen das & am Ende von Zeile 109.
Dadurch bleibt der Prozess im Vordergrund und wir können genau sehen was gerade geschieht. Im Produktion sollte das & wieder hinzugefügt werden, oder der Server in einem screen laufen.
Weiterer Vorteil: Ctrl+C kill den Server direkt gracefully.
Ausserdem habe ich auf Port 8080, der Port auf dem CruiseControl starten will, schon einen Dienst laufen. Die webport-Nummer auf den Zeilen 107 und 109 kann daher auf einen freien Port gelegt werden, falls benötigt.
Zum Schluss: Mir wird beim Start der Fehler
./cruisecontrol.sh: line 109: /bin/java: No such file or directory
entgegengeworfen.
Laut whereis liegt mein Java unter /usr/bin/java, daher habe ich dann schnell einen Link darauf angelegt:
cd /bin sudo ln -s /usr/bin/java java
Ein ./cruisecontrol.sh startet den CC-Server, und kann wie oben erwähnt mit Ctrl-C wieder gekillt werden.
Nach einigen Sekunden kann dann unter localhost:8080/cruisecontrol/ (bzw der oben eingestellte Port) phpUnderControl aufgerufen werden.
Daemonize CruiseControl
Wer die CC-Installation lieber aus dem home-Verzeichnis verbannen, und den Prozess direkt über ein richtiges init.d-Script starten möchte, kann folgendes Startscript verwenden, welches ich bei felixdv gefunden habe.
Dazu muss der CC-Ordner erstmal nach /opt verschoben werden
sudo mv /home/cruisecontrol/cruisecontrol /opt/
Und dann foldendes Startscript als /etc/init.d/cruisecontrol angelegt werden:
#!/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:
. /lib/lsb/init-functions
JAVA_HOME=/usr
NAME=cruisecontrol
DAEMON=/opt/cruisecontrol/cruisecontrol.sh
PIDFILE=/opt/cruisecontrol/cc.pid
test -x $DAEMON || exit 5
RUNASUSER=cruisecontrol
UGID=$(getent passwd $RUNASUSER | cut -f 3,4 -d:) || true
case $1 in
start)
log_daemon_msg "Starting Cruisecontrol server" "cc"
if [ -z "$UGID" ]; then
log_failure_msg "user "$RUNASUSER" does not exist"
exit 1
fi
cd /opt/cruisecontrol/
./cruisecontrol.sh > /dev/null 2>&1
log_end_msg $?
;;
stop)
log_daemon_msg "Stopping Cruisecontrol server" "cc"
start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE
log_end_msg $?
rm -f $PIDFILE
;;
restart|force-reload)
$0 stop && sleep 2 && $0 start
;;
status)
pidofproc -p $PIDFILE $DAEMON >/dev/null
status=$?
if [ $status -eq 0 ]; then
log_success_msg "Cruisecontrol server is running."
else
log_failure_msg "Cruisecontrol server is not running."
fi
exit $status
;;
*)
echo "Usage: $0 {start|stop|restart|force-reload|status}"
exit 2
;;
esac
Das ganze muss noch über sudo chmod +x /etc/init.d/cruisecontrol ausführbar gemacht werden, und schon kann man mit dem cruisecontrol-user das Script verwenden:
cruisecontrol@ratbox:~$ /etc/init.d/cruisecontrol
Usage: /etc/init.d/cruisecontrol {start|stop|restart|force-reload|status}

I quite like looking through an article that can make men and women think.
Also, thank you for permitting me to comment!