I was watching a DjangoCon keynote by Cal Henderson from Flickr and he mention that they used Hudson for Continuous Integration (CI).
I know that there is phpUnderControl, but with Flickr endorsing Hudson that was enough for me to give Hudson a try over phpUnderControl. I will not be covering the installation of Hudson in this post. I would like to focus more on the integration of the PHP tools with Hudson.
I will be showing how to integrate the following tools:
Hudson Plugins
Once you have Hudson installed you will want the following plugins installed to get the PHP tools running on your code base:
Installing the Plugins
To install plugins you will want to click on Manage Hudson:

Then click on Manage Plugins:

Then go to the avaliable plugins tab and install the plugins that are described above.
Now that you have the plugins installed and you have restarted Hudson. Let's get started on creating and configuring the job.
Start a New Hudson Job
From the main Hudson page you will want to click on New Job. Give the job a name and select Build a free-style software project. Then click OK

Configure the Hudson Job
Okay, now that we have the job started let's go ahead and configure the job. After creating the job it should take you to the configure screen. Here I will go through each of the configuration options for each of the tools.
Subversion
Subversion should be pretty straight forward, choose the Subversion option. I ssh into my subversion repo so there are a few more steps to take.
Click on the question mark on the right side of the Repository URL. Click on the ****this link**** link that you see in the paragraph below see:
Specify the subversion repository URL to check out, such as "http://svn.apache.org/repos/asf/ant/". You can also add "@NNN" at the end of the URL to check out a specific revision number, if that's desirable.
When you enter URL, Hudson automatically checks if Hudson can connect to it. If access requires authentication, it will ask you the necessary credential. If you already have a working credential but would like to change it for other reasons, click ****this link**** and specify different credential.
During the build, revision number of the module that was checked out is available through the environment variable SVN_REVISION, provided that you are only checking out one module. If you have multiple modules checked out, use the svnversion command.
You should get the following screen:

Type in your Repository URL and your authentication information. Then click OK.
When you return to the main configuration page you will need to fill out one more section.
Local module directory (optional): svn

If you don't do this your repository check out will be in your main build folder (workspace directory). We do not want this so we put it into a svn folder.
Ant Build Targets

Go ahead and type in what I have as targets. We will build the Ant file later and all of this will make sense.
If you have problems with the build completing at the end of this tutorial, I would recommend doing each of the build targets one by one until one completes. Then add another one and so on until all of them complete.
Post-build Actions
The following actions process the php tools that we will be using.
Javadoc (Works with PHP Doc)
Check the Publish Javadoc and type in the Javadoc directory: build/docs/

Clover Coverage Report
Check the Publish Clover Coverage Report.
Clover report directory: build/logs
Clover report file name: clover.xml

Report JDepend (Works with PDepend)
Check the Report JDepend option and type in Pre-generated JDepend File: build/logs/jdepend.xml

Checkstyle
Check the Publish Checkstyle analysis results and fill in the Checkstyle results: build/logs/checkstyle.xml

DRY results
Check the Publish duplicate code analysis results option and fill in the Duplicate code results: build/logs/pmd.xml

Testing Tools (PHPUnit with junit.xml)
Check the Publish testing tools result report option and fill in the PHPUnit section: _build/logs/junit.xml
This is a little strange because you have to put it in _build. It is because this plugin can only put files in your repository check out folder, I chose to put it in _build because most likely you do not have a folder in your respository with that name. If you do you will also have to change the ant file to represent the new folder name.
Future versions will be based off of the workspace directory and you will be able to put it with the rest of your log files. For now this is how we have to do it.

Configuration Complete
Now we are done with the configuration so click the Save button.
Setup the Hudson Ant File for the Job
Open up a terminal and log into your server.
Okay now off to the Ant file. I am going to paste my Ant file for you to copy and paste. If you have done a normal Hudson installation you should be able to change directory to:
CODE:
-
cd /srv/hudson/jobs/Test\ Job/workspace
Test\ Job can be replaced with whatever you called your job.
Create the build.xml file and paste in the Ant file:
The Ant File
CODE:
-
<project name="Test Job" default="build">
-
<target name="clean">
-
<delete dir="${basedir}/svn/_build"/>
-
<delete dir="${basedir}/build"/>
-
</target>
-
-
<target name="prepare">
-
<mkdir dir="${basedir}/svn/_build/logs"/>
-
<mkdir dir="${basedir}/build/logs"/>
-
<mkdir dir="${basedir}/build/docs"/>
-
</target>
-
-
-
<target name="phpdoc">
-
<exec dir="${basedir}"
-
executable="phpdoc"
-
failonerror="true">
-
<arg line="-t build/docs/
-
--directory svn
-
-ti 'Test Job Docs'
-
--parseprivate on
-
--undocumentedelements on
-
--output HTML:Smarty:PHP"/>
-
</exec>
-
</target>
-
-
<target name="phpcpd">
-
<exec dir="${basedir}"
-
executable="phpcpd"
-
failonerror="true">
-
<arg line="--log-pmd=build/logs/pmd.xml svn"/>
-
</exec>
-
</target>
-
-
<target name="pdepend">
-
<exec dir="${basedir}"
-
executable="pdepend"
-
failonerror="true">
-
<arg line="--jdepend-xml=build/logs/jdepend.xml svn"/>
-
</exec>
-
</target>
-
-
<target name="phpcs">
-
<exec dir="${basedir}"
-
executable="phpcs"
-
output="${basedir}/build/logs/checkstyle.xml"
-
failonerror="false">
-
<arg line="--report=checkstyle svn"/>
-
</exec>
-
</target>
-
-
<target name="phpunit">
-
<exec dir="${basedir}"
-
executable="phpunit"
-
failonerror="true">
-
<arg line="--log-junit svn/_build/logs/junit.xml
-
--coverage-clover build/logs/clover.xml
-
svn/tests"/>
-
</exec>
-
</target>
-
-
<target name="code-coverage">
-
<exec dir="${basedir}"
-
executable="phpunit"
-
failonerror="true">
-
<arg line="--coverage-html /path/to/webserver/that/can/serve/the/coverage/pages"/>
-
</exec>
-
</target>
-
-
-
<target name="build"
-
depends="clean,prepare, phpcpd, pdepend, phpunit, code-coverage"/>
-
</project>
Please pay attention to this section:
CODE:
-
<target name="code-coverage">
-
<exec dir="${basedir}"
-
executable="phpunit"
-
failonerror="true">
-
<arg line="--coverage-html /path/to/webserver/that/can/serve/the/coverage/pages"/>
-
</exec>
-
</target>
You will have to replace /path/to/webserver/that/can/serve/the/coverage/pages with a path that can serve the web pages from your server. Also, this path has to have tomcat6 in the group permissions so that PHPUnit can write to it.
To find out more about what Ant can do go and read!
Build the Hudson Job
Now click the Build Now link and let it work it's magic.

Once set up I think that Hudson and PHP make a great team. Is this a better set up then phpUnderControl and PHP? Let me know your experiences.
ant clover code coverage continuous integration Development hudson Linux pdepend php php tools phpcpd phpcs phpdoc phpdocumentor phpunit