PHP Continuous Integration with Atlassian Bamboo
Continuous integration is all the rage these days; you are unit testing your code are you not? During some consulting in January with the help of Sebastian Bergmann, from thePHP.cc, we setup continuous integration utilizing Atlassian Bamboo and received training on PHPUnit.
Using Atlassian Bamboo for continuous integration will take you a bit to setup, however, I have found it to be an invaluable tool when utilizing the Atlassian stack (JIRA, Confluence, Crucible, Bamboo and Crowd).
Overview
This posting assumes the following:
- You have Atlassian Bamboo setup
- Ant is available on the system
- You already have PHPUnit setup for your project
- You have selected a coding standard
This posting will go over the following:
- Getting Started
- PHP Depend
- PHP Code Browser
- PHP Code Sniffer
- PHP Copy/Paste Detector
- PHP Mess Detector
- PHPUnit
Getting Started
Welcome to the voyage of continuous integration with Bamboo, now that you are ready, lets get started.
Installing the PHP Tools
We will assume using the PEAR installer for installing all of the tools.
PHP Depend
pear channel-discover pear.pdepend.org
pear install pdepend/PHP_Depend-beta
PHP Code Browser
pear channel-discover pear.phpunit.de
pear install phpunit/PHP_CodeBrowser-alpha
PHP Code Sniffer
pear install PHP_CodeSniffer
PHP Copy/Paste Detector
pear install phpunit/phpcpd
PHP Mess Detector
pear channel-discover pear.phpmd.org
pear install --alldeps phpmd/PHP_PMD-beta
PHPUnit
pear install phpunit/PHPUnit
Build Setup in Bamboo
The Plugins
There are a few plugins that we will utilize to capture build metrics. You will want to install these to follow along:
Plan Details
Assuming that you are new to Bamboo and have not created a build as of yet, you will need to login to Bamboo and then click on “Create Plan” in the navigation. Here you will find a few options, most of these are self explanatory. Just remember that you can have several different builds so you may want to specify if it is a trunk build or a specific component build. Once you are completed, click on next.
Source Repository
Put in the details to your source code repository. If the source code repository is not available, there is likely a plug-in for it available. Download it, restart bamboo, and continue to this step. We do not force a clean build every time, this is due to some additional configuration that we have set for an environment in a configuration file and to reduce the amount of time to do a build. Lastly, we do polling to detect if we need to do a build. This helps us because we do not want a 5 minute build during every change but rather within 10 minutes of any change. This helps reduce building too frequently or causing a potential for a race condition (assuming there was a bug in Bamboo). Go to the next step…
Builder
Let’s use ant for the build process. Do not worry about this for now, we will get more into the ant build script later on. State the build file as “build.xml” which will live in the main root of the source code (you could place this elsewhere but for simplicity sakes lets put it here and assume you’re not storing the htdocs at the root – please tell me you’re not). Under target place “clean build” since we will do some manual cleanup of existing build information.
Under the following questions you will want to fill out information:
- Where should Bamboo look for the test result files?
- Check: “The build will produce test results.”
- Specify custom results directories: “**/build/logs/phpunit.xml”
- Where should Bamboo look for the PMD code analysis output?
- Check: “PMD output will be produced”
- PMD XML Directory: “**/build/logs/pmd*.xml”
- Would you like to view Clover Code Coverage for this plan?
- Check: “Use Clover to collect Code Coverage for this build.”
- Integration Options: Select “Clover is already integrated into this build…”
- Clover XML Location: “**/build/logs/clover.xml”
- Where should Bamboo look for the CheckStyle style analysis output?
- Check: “CheckStyle output will be produced”
- CheckStyle Output Directory: “**/build/logs/checkstyle.xml”
- We left the rest of the options blank as we have a few areas to catch up on – don’t we all?
Now go on, the hard work is just about done for setting up the build…
Requirements
In this screen you should see that the JDK is available and Ant is available. Go on…
Artifacts
We are producing several artifacts that we produce during every build, you may want to as well, therefore, lets get them all setup. Don’t worry about what all of these are at the moment, you will have a better idea later.
| Label | Source Directory | Copy Pattern |
|---|---|---|
| Dependency Report | build/dependencies | **/*.* |
| CheckStyle | build/logs | **/checkstyle.xml |
| Code Coverage Report | build/coverage | **/*.* |
| PHP CPD | build/logs | **/pmd-cpd.xml |
| CPD Report | build/cpd | **/*.* |
| PHPUnit | build/logs | **/phpunit.xml |
| Clover | build/logs | **/clover.xml |
| JDepend | build/logs | **/jdepend.xml |
| Code Browser | build/codebrowser | **/*.* |
Notifications
Determine the types of notifications that you are looking for, I simply have myself notified on every build and a different level to ensure that the notification goes out to anyone that has been attributed to a failed build. This is solely up to you and you can change it all later if you would like to.
Post Actions
We currently are not utilizing these, but I am sure that someone will find some more use for them, I am thinking of things like deploying to our testing environment, however, that’s more than a leap away at this point.
Permissions
Setup the permissions that you would like to have on the build plan, this is really up to you.
Finish up and save your build plan. Now you will have a failing build as we need to get it up and running.
Setting up Ant
Since we specified the Ant builder, we need to setup our build.xml file in the directory root of the source control that we are utilizing. In here, we want to run our tasks in parallel to expedite our processing and then run our unit testing. The following is our build.xml file, without a few excludes and such:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | <project name="My Project Name" default="build"> <target name="clean"> <delete dir="${basedir}/build" /> </target> <target name="prepare"> <mkdir dir="${basedir}/build/logs" /> <mkdir dir="${basedir}/build/codebrowser" /> <mkdir dir="${basedir}/build/coverage" /> <mkdir dir="${basedir}/build/cpd" /> <mkdir dir="${basedir}/build/dependencies" /> </target> <target name="phpcs"> <exec dir="${basedir}" executable="phpcs" failonerror="false" output="/dev/null"> <arg line="--extensions=php --ignore=build/*,tests/* --standard=Zend --tab-width=4 --report=checkstyle --report-file=${basedir}/build/logs/checkstyle.xml ." /> </exec> </target> <target name="phpmd"> <exec dir="${basedir}" executable="phpmd" failonerror="false"> <arg line=". xml codesize --reportfile ${basedir}/build/logs/pmd.xml" /> </exec> </target> <target name="phpcpd"> <exec dir="${basedir}" executable="phpcpd" failonerror="false"> <arg line="--log-pmd=${basedir}/build/logs/pmd-cpd.xml --exclude=build --exclude=tests ." /> </exec> <exec dir="${basedir}/build/logs" executable="xsltproc" failonerror="false" output="${basedir}/build/cpd/index.html"> <arg line="/path/to/cpd.xsl ${basedir}/build/logs/pmd-cpd.xml" /> </exec> </target> <target name="pdepend"> <exec dir="${basedir}" executable="pdepend" failonerror="false"> <arg line="--jdepend-xml=${basedir}/build/logs/jdepend.xml --jdepend-chart=${basedir}/build/dependencies/jdepend.svg --overview-pyramid=${basedir}/build/dependencies/pyramid.svg --optimization=best --exclude=build,tests ." /> </exec> <exec dir="${basedir}/build/dependencies" executable="cp" failonerror="false"> <arg line="${basedir}/path/to/dependencies.html index.html" /> </exec> </target> <target name="phpcb"> <exec dir="${basedir}" executable="phpcb" failonerror="false"> <arg line="--log ${basedir}/build/logs --source ${basedir} --output ${basedir}/build/codebrowser" /> </exec> </target> <target name="phpunit"> <exec dir="${basedir}/tests" executable="phpunit" failonerror="true"> <arg line="--log-junit ${basedir}/build/logs/phpunit.xml --coverage-clover ${basedir}/build/logs/clover.xml --coverage-html ${basedir}/build/coverage" /> </exec> </target> <target name="parallel"> <parallel> <antcall target="phpcs" /> <antcall target="phpmd" /> <antcall target="phpcpd" /> <antcall target="pdepend" /> </parallel> </target> <target name="build" depends="clean,prepare,parallel,phpunit,phpcb" /> </project> |
Additional Files Referenced
I referenced a few files above that you will not have, mainly these files help to display some of the components that we have pushed out into our Artifacts. I’ve linked one file and given what is in another for reference.
- cpd.xsl
- dependencies.html – a simple file that embeds the svg images.
exit(0);
This should help you get up and running with Atlassian Bamboo for PHP. We’ve been using this for the last 3+ months and it has been extremely valuable. If you have any feedback or anything to add let me know through the comments.
Cloud Computing
Hi,
Trying to follow your guide to evaluate Bamboo I discovered that the plugins you provide are not compatible with the lates 2.5 release of Bamboo. You actually need to go back and reinstall Bamboo version 2.2 or preferably 2.1 if you require ceckstyle and mess detection. Unfortunatelly there are no alternatives for the latest Bamboo release. I think it’s worth mentioning in you walkthrough.
Good luck and thanks for the overview.
Dmitry.
@Dmitry,
Actually, I have been using both of those in the current version of Bamboo. They do actually work. The compatible versions are not always entirely correct on the plugin wiki.
Hi, Mike.
So you’re lucky to work with the current version. Probably it’s me doing something wrong, but i never got the plugins appear in Administration or BuildPlan creation. It took me a wile to figure out the version incompatibility so after i rolled back to 2.2 everything whent fine. I’ll try to investigate the reason and maybe reinstall.
Anyways thanks to your article Bamboo was the easiest CI server to set up for bulding PHP projects from my experience. And by the way (just curious) – what was the reason you picked Ant as your builder? Have you considered Phing?
Dmitry.
Hi,
Very usefull.
Can you share your dependencies.htm?
Thanks a lot,
Sérgio
@Dmitry
One of the reasons I didn’t use Phing was due to wanting to run most of the build in parallel. Also, I enjoy that Ant has so many tasks and is quite mature. Further, it is integrated with the Linux package management and I just feel that it works how I expect it to.
From what I hear of Phing, it is not great but not a bad choice either. I took a look at it previously and ended up using an ant based build process anyhow.
Great post and very informative too…..!
You have covered the main points very brilliantly here in the post. This is very beneficial for me and for all starters as well.
Looking to have such good information from your side in future too.
Good luck and have a nice time!
if you’re using git you need this plugin http://github.com/krosenvold/bgit
version 1.2 of this plugin requires git 1.6.1, you’ll have to compile a new version if you’re using the latest version.
Also you need apache ant 1.8.1, my system was running 1.7 for some reason.
In your build.xml file, where you state:
–log-pmd=${basedir}/build/logs/pmd-cpd.xml
I had to change this to:
–log-pmd ${basedir}/build/logs/pmd-cpd.xml
With a space instead of =, otherwise I would get errors from phpcpd.
Ivo – this likely changed in a version after the one that I was utilizing initially. Most of the items when we added these things in were still in alpha / beta so I wouldn’t be surprised if this happens more in the future. Thanks!