Zum Inhalt springen

Continuous Integration – Teil 3 (Hudson CI)

Im dritten Teil der CI-Serie geht es um den Hudson-CI. Es handelt sich dabei ebenfalls um einen Java CI Server. Dieser ist aufgrund seiner einfach Konfiguration über sein Webinterface und die große Auswahl an Pugins sowohl bei Entwicklern als auch bei Administratoren sehr beliebt. In diesem Beitrag gehe ich auf die Installation und Konfiguration und natürlich auf die Integration von PHP ein.

Installation:
Als Basis System wird wieder Debian Squeeze genutzt. Als Vorarbeit benötigt man Java. Hudson bietet auf seine Homepage Pakete für die verschiedenen Distributionen an. Somit wird die Installation relativ einfach. Man fügt zuerst den GPG Key des Repositorys zum apt hinzu.

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

Dann passt man in /etc/apt/sources.list die angefragten Repositories an, indem man folgende Zeile hinzufügt.

deb http://hudson-ci.org/debian binary/

Anschließend führt man ein Update von apt durch und installiert den Hudson.

Jetzt hat man den Hudson bereits installiert und am Laufen. Die Konfiguration wird über das Webinterface durchgeführt, welches man über http://<ip>:8080 erreicht. Nun muss man 2 Dinge durchführen. Einerseits die notwendigen Plugins installieren und anschließend ein Projekt (oder genauer einen Job) anlegen.

Plugins installieren
Notwendige Plugins:

  • Checkstyle – für dir Codesniffer Visualisierung
  • DRY – für den Copy & Paste Detector
  • HTML Publisher – für den CodeBrowser
  • xUnit – für die PHPUnit Auswertung
  • Clover – für die Auswertung der PHPUnit Testabdeckung
  • JDepend – für die PHPDepend Auswertung

Optionale Plugins:

  • Chuck Norris – weil es Spaß macht
  • CI Game – Entwicklerrangliste, für bestimmte Aktionen gibt es Punkte
  • GreenBalls – erfolgreiche Builds sind Grün statt Blau
  • Jabber – Benachrichtigungen per Jabber
  • PMD – für PHPMD

Die Builds arbeiten in dieser Beschreibung mit ant. Wenn ant nicht bereits installiert ist auf dem System, kann man die entsprechende Ant Version ganz einfach im Menüpunkt „konfigurieren“ in den Hudson integrieren.

Projekt anlegen:
Über den Punkt „Jobs anlegen“ kann man nun einen neuen Job anlegen. Im Screenshot sieht man das Projekt mit dem Namen „Example“, dieses wird als Freestyle Projekt angelegt.

In der Projektkonfiguration muss man zuerst das SVN-Repository mit dem Hudson verknüpfen. Als lokales Modulverzeichnis muss man „svn“ angeben, wenn man das hier bereitgestellte build-Skript nutzen möchte. Ansonsten werden die Dateien vom SVN direkt im Workspace abgelegt. Wenn man etwas Überblick über die einzelnen xml-Dateien, die gleich vorgestellt werden, haben möchte ist es unbedingt notwendig ein Unterverzeichnis anzugeben.

Falls man für den CI-Server einen speziellen SVN-Benutzer nutzt oder allgemein eine Authentifizierung erforderlich ist, so bekommt man nach Angabe des SVN-Pfades die Möglichkeit die „Credentials“ anzugeben. Natürlich hat man hier die Wahl wie man sich authentifizieren möchte.

Nun könnte man schon mit einem Klick ein Checkout veranlassen. Dies wäre dann der Build #1. Jedoch wollen wir die Konfiguration noch etwas vervollständigen. Im CI – Teil 1 werden die verschiedenen Trigger beschrieben. Diese richten wir jetzt ein, damit man nicht immer manuell den Buildprozess anstoßen muss. Auf dem Screenshot-Ausschnitt sieht man einen SVN-getriggerten Build. Nach Auswahl des entsprechenden „Auslösers“ muss man noch einen Zeitplan angeben. Unix-Benutzer fühlen sich hier gleich heimisch, da die Konfiguration ähnlich der Cron-Konfiguration durchgeführt wird. Man gibt nun an, wann der SVN-Server angefragt werden soll. In dem Beispiel sieht man die Konfiguration für „alle 5 Minuten“ nachfragen. Genauer wird hier immer zu jeder Minute nachgefragt, ob eine Änderung existiert, wenn die Minutenanzahl durch 5 teilbar ist.

Gibt es keine Änderung wird der Build nicht ausgelöst. Wurden in dem 5 Minuten Intervall mehrere Commits durchgeführt, so werden die Änderungen gesammelt geladen und der Build gestartet. Benötigt man zu jedem Commit einen Build, so muss man sich um einen post-commit Hook im svn kümmern. Das ist aber ein anderes interessantes Thema.

Nun gibt man das Buildverfahren an. Bei dem beschriebenen Beispiel wählt man „ant aufrufen“ aus und gibt die folgenden Targets an. Diese befinden sich in der build.xml (Download-Link am Ende des Beitrags).

  • clean
  • prepare
  • phpcpd
  • pdepend
  • phpcs
  • phpcb
  • phpunit
  • release_single

Nun werden bei einem Build auch gleich alle xml-Dateien erzeugt, die die folgenden Plugins nutzen. Die Plugins erzeugen daraus schöne Grafiken und erleichtern das Entwicklerleben.

PHP_Codesniffer:

Anfangen wollen wir mit phpcs. Der CodeSniffer erzeugt zu Checkstyle kompatible xml-Dateien und daher muss nur der Punkt Checkstyle aktiviert und der Pfad zur xml-Datei angepasst werden.

PHPCPD:

Der nächste Punkt ist phpcpd. Die Copy and Paste Detection zeigt duplizierten Quelltext an. phpcpd ist zu pmd-cpd komaptibel, bzw die Ausgabeformate sind gleich, somit muss auch hier nur der entsprechende Menüpunkt aktiviert und der Pfad zur xml-Datei angegeben werden.

Artefakt:

Die nächste Option tanzt etwas aus der Reihe. Im Build-Skript gibt es ein Target, dass den Source aus svn nimmt und in eine zip-Datei packt, wobei die .svn Verzeichnisse verworfen werden. Idee ist hier ein Artefakt zu erzeugen, dass man so mehr oder weniger direkt deployen kann. Ein Entwickler hat die Möglichkeit den gepackten Source eines bestimmten Builds direkt vom CI-Server zu beziehen. Es ist geplant in einer zukünftigen Version ein automatisiertes Deployment einzubinden (Stichwort: Continuous Deployment). Der Punkt Artefakt archivieren muss aktiviert werden und die zip-Datei bekannt gegeben werden. Der Name hängt vom angegebenen Projekt in der Ant-Datei ab. Im Beispiel heißt das Projekt bspw. Clortho.

PHP_CodeBrowser:

Der nächste Publisher ist richtig hübsch. Der hübsche CodeBrowser von phpUnderControl ist auch beim Hudson zu finden. Hierzu wird der Einfachheit halber der HTML Publisher genutzt. Dieser wird genutzt um html-Dateien bereitzustellen. Das CodeBrowser Tool macht nichts anderes. Aus bestimmten Informationen und dem Quelltext werden HTML-Dateien und Javascript erzeugt. Alle diese Dateien liegen im codebrowser Verzeichnis. Als Eingangspunkt wird die index.html genutzt und man findet den CodeBrowser später unter dem Punkt CodeBrowser im Projekt. Hört sich eigentlich einfach an und ist es auch.

PHPUnit:

Nun kommen wir zu dem Punkt, den die meisten Entwickler bei einem CI-Server sehen. Den Unittests. PHPUnit ist hier das Tool der Wahl und dieses erzeugt eine Unittest-xml. Wir nutzen das xUnit Plugin, da die erzeugte Datei nicht so ganz kompatibel zu jUnit ist. xUnit kennt aber explizit phpUnit und so gibt es keine Probleme.

PDepend:

Bevor wir zum letzten Punkt kommen, benutzen wir noch das jDepend Plugin. Dieses bereitet die Informationen von PHPDepend (oder pDepend) auf. Auch hier arbeiten wir nach dem bekannten Prinzip. jDepend Plugin aktivieren und Pfad angeben.

PHPUnit – zum Zweiten:

Jetzt kommt der letzte Punkt in der Liste an die Reihe. Das Clover Plugin. PHPUnit erzeugt neben den Unittests auch eine Testabdeckungsdatei, falls xdebug installiert ist. Diese kann das Clover Plugin verstehen und gibt einen netten Bericht zur Testabdeckung aus. Insbesondere fließt die Information in das Wettersymbol des Projekts ein. Das Clover Plugin ist etwas anders in der Konfiguration, aber auch kein Hexenwerk. Man gibt hier den Pfad und die xml-Datei getrennt an. Dann kann man noch angeben, welche Bestandteile zu welchem Prozentsatz wie eingestuft werden. Ich habe die Standard-Werte beibehalten. Wird das System genutzt kann man sich hier in Feintuning üben, wenn man möchte.

PHPDocumentor:

Als optionaler Punkt kann man nun noch phpdoc nutzen. Hierbei muss das Buildtarget „phpdoc“ im Menüpunkt Buildverfahren hinzugefügt werden. Und aktiviert den Menüpunkt Javadoc publizieren. Dort gibt man nur den Pfad zum javadoc an, das durch das Ant-Target erzeugt wird. Man muss hier aufpassen, dass dieses Target sehr lange in der Ausführung braucht. Bei einem privaten Projekt bin ich mit ca 10 Minuten dabei. Die restlichen Targets benötigen zum Vergleich ca 40 Sekunden.

Ant-Build Skript:

Das Build-Skript, dass im Laufe dieses Artikels ein paar mal genannt wurde kann man hier herunterladen.

PHP-Tools:

Das Buildskript macht nichts magisches. Es nutzt ein paar PHP-Tools um die xml-Datein zu erzeugen. Hier sind diese nun aufgelistet mit den entsprechenden Links und Installationsbeschreibungen. Hierbei kann man einen kleinen Trick nutzen, um sich Schreibarbeit zu sparen. Man installiert phpundercontrol und installiert somit alle Abhängigkeiten mit. Dann hat man schon fast alles was man benötigt.

pear channel-discover components.ez.no
pear channel-discover pear.phpundercontrol.org
pear install --alldeps phpuc/phpUnderControl-beta

Nun installiert man noch den CodeBrowser. Der Codebrowser ist im phpunit Pear-Repository zu finden. Dieses ist durch phpuc aber schon vorhanden.

pear install phpunit/PHP_CodeBrowser-alpha

Copy&Paste Teile im Code findet man mit phpcpd, dies installiert man so:

pear install phpunit/phpcpd

Eine statistische Auswertung der Klassenstruktur ist auch immer sinnvoll, also installiert man noch pdepend:

pear channel-discover pear.pdepend.org
pear install pdepend/PHP_Depend-beta

Optional:
Phpmd erzeugt eine Analyse des Code unter dem Gesichtspunkt verschiedener Metriken. Es nutzt dazu pdepend.

pear channel-discover pear.phpmd.org 
pear install --alldeps phpmd/PHP_PMD-alpha

Nun kann man einen Build durchführen. Schlägt dieser fehl, kann man auf dem Hudson in der entsprechenden Buildversion die Konsolenausgabe einsehen. Häufige Fehler sind falsche Zugriffsrechte und nicht vorhandene Komponenten. Ein Unittest ohne Tests macht bspw keinen Sinn.

Tipp für Fortgeschrittene:
Man benötigt normalerweise nicht alle Builds. So kann man die Option aktivieren, dass nur eine bestimmte Anzahl an Builds vorgehalten werden soll. Ich nutze hier bspw 10. Ansonsten sollte man die Festplatte des Rechners im Auge behalten.

Published inAllgemeinDevTools

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close