Continuous Integration mit Hudson und PHP

Diese Installationsanleitung für Hudson bezieht sich auf einen Debian „Lenny“ Server.

Inhalt:

  1. Vorwort
  2. Hudson vs. phpUnderControl
  3. Installation Hudson auf Debian
  4. Hudson Plugins für PHP
  5. Hudson konfigurieren
  6. Benötigte PHP Tools installieren
  7. Projekt einrichten
  8. Hudson Ant File für das Projekt
  9. Weiterführende Links

Vorwort

Für die nächste Version von BIGACE arbeite ich momentan an einem Server, der einen noch offeneren Entwicklungsweg ermöglicht.

Ein Continuous Integration Server muss also her und mit von der Partie sollen alle bekannten (QM) Tools aus der PHP Welt sein:

Bezugnehmend auf den Artikel von JepaMedia beschreibe hier die Installation von Hudson unter Debian und der Einrichtung aller benötigten Komponenten für ein neues PHP Projekt.

Hudson vs. phpUnderControl vs. Arbit

Bevor ich damit anfange, schweife ich aber noch kurz ab und erläutere wieso ich Hudson vorziehe und nicht phpUnderControl oder Arbit.

Ich habe bereits intern vor einigen Monaten angefangen Bigace mit einem Continuos Intergration Server zu bauen und habe damals nach geeigneten Kandidaten gesucht. Zur Auswahl standennach kurzer Evaluation folgende 3 Kandidaten:

  • Arbit war nicht produktiv nutzbar (und scheint es mir auch heute nicht so richtig zu sein, wer anderes weiß lässt es mich bitte wissen!).
  • Hudson war mir zu Java-lastig und ich wollte ein PHP näheres Tool einsetzen.
  • Womit phpUnderControl die logische Konsequenz war und sich bis auf einige kleinere Mängel bisher gut bewährt hat.

Nachdem ich nun einige Monate mit phpUnderControl gearbeitet habe, wollte ich nicht nur endlich mal wieder ein neues Tool kennenlernen (Softwarentwickler sind furchtbare neugierige Spielnaturen), ich wollte auch die Dinge, die mich bisher im Build Prozess störten, versuchen mit dem Ansatz von Hudson auszumerzen.

Weitere Gründe sind u.a. die weite Verbreitung und damit der de-facto Standard von Hudson, die vielen guten Plugins, die saubere Unterstützung von PHP Projekten, Staged-builds, eine gut strukturierte Oberfläche und deutlich mehr Möglichkeiten von Hause aus Statistiken zu erzeugen und einzubinden.

Da ich Bigace bereits seit den ersten Tagen mit Ant baue, nahm ich an, das der Wechsel des CI-Systems also auch keinen großen Aufwand darstellen sollte.

An der Stelle sei man vorgewarnt, das es nicht klug ist, im gleichen Schritt die Testinfrastruktur und den gesamten Build Prozess umzubauen 😉

Kommen wir aber nun endlich zum eigentlichen Teil des Beitrags: der Installation von Hudson und dem schrittweisen Einrichten der Plugins und des späteren Projekts…

Installation Hudson auf Debian

Die Installation von Hudson (aktuell in Version 1.367) findet auf einem Debian (Version „Lenny“) basierten Virtual-Server statt.

Sollten Sie nicht Debian verwenden, schau Sie am besten in den Hudson Installationsanleitungen nach Ihrem OS! Dieser Artikel bezieht sich auf Linux bzw. Debian und ist in großen Teilen Betriebssystemabhängig.

Zuerst fügen wir neue Quellen hinzu…

wget -O /tmp/key http://hudson-ci.org/debian/hudson-ci.org.key
sudo apt-key add /tmp/key

… und installieren dann Hudson.

wget -O /tmp/hudson.deb http://hudson-ci.org/latest/debian/hudson.deb
sudo dpkg --install /tmp/hudson.deb

Bei mir traten unter einem frischen Debian Lenny jetzt Abhängigkeitsprobleme auf, die sich aber leicht lösen ließen mit:

sudo apt-get -f install

Überprüfen kann man jetzt nochmal mit:

sudo apt-get update
sudo apt-get install hudson

Wobei dann sowas rauskommen sollte:

Paketlisten werden gelesen... Fertig
Abhängigkeitsbaum wird aufgebaut       
Lese Status-Informationen ein... Fertig
hudson ist schon die neueste Version.
0 aktualisiert, 0 neu installiert, 0 zu entfernen und 0 nicht aktualisiert.

Was noch interessant sein könnte:

  • Startskript liegt unter /etc/init.d/hudson
  • Logfile ist unter /var/log/hudson/hudson.log erreichbar
  • Es gibt jetzt einen hudson User
  • Hudson selbst liegt unter /var/lib/hudson/

Wir starten Hudson mal eben testweise mit:

sudo /etc/init.d/hudson start

Und schauen uns die Ausgabe im Browser an unter http://ihreIP:8080/

Hudson Plugins für PHP

Nachdem Hudson nun initial installiert wurde, installieren wir im nächsten Schritt die notwendigen Plugins für den Build eines PHP Projektes.

Netterweise sind bereits Plugins für CVS und SVN vorinstalliert. Sollten Sie auf eine andere Versionsverwaltung (wie z.B. GIT) setzen, installieren Sie entsprechende Plugins im nächsten Schritt gleich noch mit!

Tipp: Sollten Sie noch keine Versionsverwaltung verwenden oder auf Subversion umsteigen wollen, können Sie hier nachlesen wie man Subversion einrichtet.

Zunächst wechseln wir auf der Hudson Seite nach „Hudson verwalten“ und wählen dort „Plugins verwalten“. Auf dem Reiter „Verfügbar“ tauchen nach einiger Wartezeit (Liste wird per Javascript nachgeladen) alle Plugins auf die wir benötigen und die nur noch mit einem Häkchen versehen müssen.

Ich nutze hier nun folgende Plugins, welche uns nachher helfen den Output der verschiedenen PHP-Tools zu interpretieren bzw. anzuzeigen:

  • Clover – zur Verarbeitung von PHPUnit Logdateien im Clover Format
  • Checkstyle – zur Verarbeitung von PHP_CodeSniffer Logdateien im Checkstyle Format
  • JDepend – zur Verarbeitung von PHP_Depend Logdateien im JDepend Format
  • PMD – zur Verarbeitung von phpmd Logdateien im PMD Format
  • Violations – zur Verarbeitung von verschiedenen Logdateien wie CodeSniffer, PMD und CPD
  • HTML Publisher Plugin – zum Veröffentlichen von HTML Reports wie der PHPDoc API und der PHPUnit Code Coverage
  • xUnit Plugin – zur Verarbeitung von PHPUnit Logdateien im JUnit Format
  • DRY – zur Bearbeitung von phpcpd Logdateien im PMD-CPD Format
  • Green Balls – bringt ein wenig phpUnderControl Feeling in die GUI und außerdem sind wir auf Grün als positive Signalfarbe stärker konditioniert 😉

Ein Klick auf Installieren und ein wenig Wartezeit später sehen wir die fertig installierten Plugins und können Hudson per Knopfdruck neu starten.

Es sind übrogens nicht alle genannten Hudson Plugins für den ersten Start notwendig, aber das findet man mit der Zeit schon raus … und ein wenig persönliche Note macht ja auch Spaß.

Hudson konfigurieren

Benutzer- und Rechteverwaltung

Sollten Sie Hudson auf einem öffentlichen Webserver verwenden, empfiehlt es sich spätestens jetzt einen Benutzer anzulegen und die Rechteverwaltung ein wenig anzupassen. Dazu geht man unter Hudson verwalten auf System konfigurieren und aktiviert Hudson absichern.

  • Benutzerverzeichnis: Hudsons eingebautes Benutzerverzeichnis
  • Rechtevergabe: Matrix-basierte Sicherheit

Weitere Sicherheitstipps entnehmen Sie bitte der offiziellen Doku unter: Standard Security Setup.

Hudson und Apache

Normalerweise haben wir ja nicht nur den Build Server, sondern Dokumentation u.v.m. was wir dem Benutzer zur Verfügung stellen wollen. Daher bietet es sich an eine eigene Entwicklungs-Subdomain anzulegen und Hudson dort als Verzeichnis einzubinden.

Wie man Hudson hinter dem Apache „versteckt“, steht unter http://wiki.hudson-ci.org/display/HUDSON/Running+Hudson+behind+Apache anschaulich beschrieben.

Benötigte PHP Tools installieren

Um den Build überhaupt ausführen zu können, müssen wir natürlich noch die benötigten Softwarekomponenten installieren:

sudo apt-get install php5-xdebug
sudo apt-get install sun-java6-jdk
sudo apt-get install php5-dev
sudo apt-get install php-pear

Und dann die ganzen PHP Tools hinterher:

pecl install XDebug 
pear channel-discover pear.pdepend.org
pear channel-discover pear.phpunit.de
pear channel-discover components.ez.no
pear channel-discover pear.symfony-project.com
pear channel-discover pear.phpmd.org

Bei den folgenden Paketen bitte manuell testen, ob bereits neuere Versionen vorliegen, das ändert sich oft ziemlich schnell! Und falls sich ein Paket nicht installieren lässt, einfach mal die Reihenfolge vertauschen – ich habe diese Liste erst nachträglich erstellt.

pear upgrade-all
pear update-channels

pear install PHPDocumentor
pear install pdepend/PHP_Depend-beta
pear install PHPUnit-1.3.2
pear install --alldeps ezc/eZComponents
pear install --alldeps phpunit/PHPUnit
pear install phpunit/File_Iterator
pear install phpunit/phpcpd
pear install PHP_CodeSniffer
pear install --alldeps phpmd/PHP_PMD-alpha

Damit wäre die Vorbereitung endlich abgeschlossen und wir können mit dem Anlegen des ersten Projektes beginnen!

Projekt/Job einrichten

Für das Beispiel nutze ich hier Bigace als Grundlage, grundsätzlich ist dies aber bei den meisten PHP Projekten ähnlich, auch wenn sich die einzelnen Build Schritte inhaltlich leicht unterscheiden mögen.

Wenn Sie bis hierher vorgedrungen sind, ist die Anpassung nachher sicher auch kein Problem mehr, Sie können aber auch gerne Fragen in den Kommentaren stellen!

Wechseln wir also zurück auf die Hudson Startseite und wählen „Neuen Job“ anlegen aus. In der folgenden Maske geben Sie einen Namen ein und wählen dann das „Free Style Softwareprojekt“ aus.

In der folgenden Konfigurationsmaske sind einige Punkte auszufüllen. Da Bilder in manchen Fällen aber tatsächlich mehr sagen als tausend Worte, habe ich hier einen Screenshot der notwendigen Einstellungen hinterlegt. Bitte stellen Sie Ihr Projekt genauso ein, damit im nächsten Schritt die Pfade der Build Dateien übereinsteimmen und keine Fehler verursachen!

Hudson Ant File für das Projekt

So, die Tools sind vorbereitet und der Job ist angelegt, jetzt fehlt nur noch das Ant-Build Skript, welches wie folgt angelegt wird:

sudo vim /var/lib/hudson/jobs/Bigace/workspace/build.xml

Hinweis: Mein originales Skript wäre aufgrund weitere Abhängigkeiten und Includes bei Ihnen nciht lauffähig, daher habe ich es „sinnvoll“ gekürzt. Sollten Fehler auftreten, hndelt es sich eventuell um Copy&Paste Fehler auf meiner Seite. Ich würde mich dbzgl. über Hinweise freuen!

Jetzt aber das build.xml:

<project name="Bigace" default="build">

    <description>
        Hudson CI - build file for BIGACE Web CMS 3.

        This file must be copied to:
        $HUDSON_HOME/jobs/Bigace/workspace/build.xml

        See http://dev.bigace.org/ for further informations.

        BIGACE - a PHP based Web CMS.
        Copyright (C) 2009-2010 Keleo (www.keleo.de).
        Distributed under the terms of the GNU General Public License.

        $Id: build.xml 796 2010-05-27 10:11:40Z bigace $
    </description>

    <target name="clean">
        <delete dir="${basedir}/build"/>
    </target>

    <target name="prepare">
        <mkdir dir="${basedir}/build/api"/>
        <mkdir dir="${basedir}/build/code-browser"/>
        <mkdir dir="${basedir}/build/coverage"/>
        <mkdir dir="${basedir}/build/logs"/>
        <mkdir dir="${basedir}/build/artifacts"/>
    </target>

    <target name="phpdoc">
        <exec dir="${basedir}" executable="phpdoc">
            <arg line="-c ${basedir}/svn/core/build/phpdoc.ini"/>
        </exec>
    </target>

    <!-- phpcpd: Copy and Paste Detection -->
    <target name="phpcpd">
        <exec dir="${basedir}" executable="phpcpd">
            <arg line="--exclude svn/core/library/ --log-pmd build/logs/pmd-cpd.xml svn/core"/>
        </exec>
    </target>

    <!-- pDepend: Static Code Analysis -->
    <target name="pdepend">
        <exec dir="${basedir}" executable="pdepend">
            <arg line="--jdepend-xml=build/logs/jdepend.xml svn/core"/>
        </exec>
    </target>

    <target name="phpmd">
        <exec executable="phpmd">
            <arg line="svn/core xml codesize,unusedcode --reportfile ${basedir}/build/logs/pmd.xml" />
        </exec>
    </target>

    <!-- phpcs: Code Sniffer -->
    <target name="phpcs">
        <exec dir="${basedir}" executable="phpcs" 
            output="${basedir}/build/logs/checkstyle.xml">
                <arg line=" --standard=ZEND --ignore=svn/core/public/* --report=checkstyle svn/core"/>
        </exec>
    </target>

    <!-- phpUnit: Unit Test Framework for PHP -->
    <target name="phpunit">
        <exec dir="${basedir}" executable="phpunit" failonerror="true">
            <arg line="--configuration svn/core/build/hudson-phpunit.xml" />
        </exec>
    </target>

    <!-- All Tasks in their correct order -->
    <target name="build" depends="clean,prepare,phpcs,phpdoc,pdepend,phpcpd,phpmd,phpunit" />

</project>

Sicher ist Ihnen aufgefallen, das ich hier auf eine weitere PHPUnit XML Datei verweise. Diese sieht wie folgt aus:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./svn/core/tests/bootstrap.php"
    convertErrorsToExceptions="true"
    convertNoticesToExceptions="true"
    convertWarningsToExceptions="true"
    stopOnFailure="false"
    backupGlobals="false"
    syntaxCheck="true"> 

    <testsuite name="Bigace">
        <directory suffix="Test.php">./svn/core/tests/application/</directory>
        <directory suffix="Test.php">./svn/core/tests/library/</directory>
    </testsuite>

    <logging>
        <log type="coverage-html" target="build/coverage/" title="Bigace CMS"
            charset="UTF-8" yui="true" highlight="true"
            lowUpperBound="35" highLowerBound="70"/>
        <log type="coverage-clover" target="build/logs/clover.xml"/>
        <log type="junit" target="build/logs/junit.xml" logIncompleteSkipped="false"/>
    </logging>

</phpunit>

Nachdem Sie nun alles eingerichtet haben, können Sie den „Jetzt bauen“ Link ausprobieren und sich Schritt für Schritt durch die einzelnen Fehler vorarbeiten 😉

Weiterführende Links

Und wer jetzt immer noch nicht genug von Hudson und PHP hat, dem seinen ein paar zufällig ausgewählte Links gegönnt. Aber Achtung: der Informationsinhalt könnte sich überschneiden!