Getting started with PHP
Introduction
TeamCity supports your Continuous Integration (CI) process in many technologies. In this tutorial, we'll configure a Continuous Integration (CI) process for a PHP project. We will be using the open-source PHP project PHPExcel as a sample project we want to provide CI for. This project features a large amount of code, PHPUnit tests and uses Phing to create build artifacts. Using TeamCity, we will automate the build process and make it ready for immediate feedback once the source code on GitHub changes.
This tutorial assumes you already have a PHP environment with PEAR, PHPUnit and Phing installed. If not, now is the time. You can find more info on configuring your PHP environment through this blog post.
Setting up the project
We'll start by creating a new project and build configuration in TeamCity. The build number for this new build configuration will be 1.7.6.{0}
since PHPExcel is currently in the 1.7.6.x
version range.
PHPExcel comes with a build script that creates build artifacts under the build/release/*
directory, which means we can already add that path as the artifact path TeamCity monitors.
The PHPExcel project has a GitHub repository, a URL which we can configure in the Version Control System (VCS) settings.
Adding build steps
A build configuration consists of several build steps which perform the actions we desire during build.
Unit tests
Since PHP is an interpreted language, we don't need a compilation step and can immediately start with unit tests: we want to make sure all tests are green every time source code is changed. Whenever there is a failing unit test, we want to fail the entire build and not provide any build artifacts. TeamCity comes with a number of predefined build steps for Java and .NET, but since we're on PHP we'll have to select the Command Line build runner.
We want to run the PHPUnit configuration that's provided with PHPExcel source code. Invoking this can be done using the following command line script:
By default, TeamCity will import the test results provided by PHPUnit. However we can also report real-time test results to TeamCity, so that we can already see results during a build run before it's even finished. Using a wrapper around PHPUnit which uses service messages to report build results. Locate the wrapper somewhere on the build agent or have the build agent download it from the above GitHub repository directly using a second VCS root.
We can already invoke our build configuration and should be getting unit test results displayed. But we're not finished yet, we want to add some more build steps.
Running Phing
Our next build step will be invoking Phing, a PHP project build system or build tool based on Apache Ant. PHPExcel comes with a Phing build script which we'll invoke after all unit tests have passed. Let's add a new Command Line build step which uses Phing's command-line tool and pass some parameters to it:
PHPExcel has four build targets defined (release-standard, release-documentation, release-pear and release-phar), all providing different build artifacts. The release-standard target which we've now specified at the command line is the default build for PHPExcel which generates a ZIP file containing all source code and phpDocumentor output.
We are also passing Phing the current build number from TeamCity using Phing's -D
command line switches. The build script can use these to create the correct file names.
If you haven't configured the artifact paths while creating our build project, it's best to do so now (see Setting up the project). We want to make sure that the ZIP file generated in this build script is available from TeamCity's web interface.
When we run another build, we'll now see that unit tests are being run and afterwards the Phing build script is being run. Once the entire build is completed, we can find the ZIP file generated by the Phing build script as a downloadable build artifact.
Code coverage
The first build step we created was running unit tests using PHPUnit. The nice thing about PHPUnit is that it can provide code coverage information as well, nicely formatted as an HTML report. TeamCity can display HTML reports on a custom tab in the build results.
Let's first make sure code coverage is enabled. Edit the first build step (running PHPUnit) and make sure it uses PHPExcel's phpunit-cc.xml
configuration file for configuring PHPUnit. This configuration file which is specific to PHPExcel outputs its code coverage report in the unitTests/codeCoverage folder. While it is possible to add all generated files to TeamCity as a build artifact, it's cleaner to ZIP that entire folder and make it available as one single file. We can have TeamCity create this ZIP file for us by using a special artifact path pattern! Edit the build artifacts again and make sure the following two artifact paths are specified:
We can let TeamCity create a ZIP archive from the unitTests/codeCoverage path by simply using => and specifying a target artifact name.
Run the build again. Once it completes, the Artifacts tab should contain the coverage.zip file we've just created. Next to that, there should now be an additional tab Code Coverage available which displays code coverage results. Since we're using a TeamCity convention for reporting code coverage, namely creating a coverage.zip build artifact, TeamCity will automatically display the coverage results in a new report tab.
It's possible to add additional build reporting and display results from PHP mess detector, PHPLint or even have a tab available which displays phpDocumentor contents by creating custom report tabs based on information from build artifacts.
Exploring build results
Using TeamCity, we can view build history, VCS history, commits and so on. We have general build statistics such as success rate, build duration and test count in a graphical format.
When working with an environment based on the IntelliJ Platform, like PhpStorm or WebStorm, it's easy to link TeamCity with the IDE. After installing the TeamCity plugin into your IDE you'll notice that there are some useful little things like opening a unit test in the IDE from within TeamCity:
As we've seen in this tutorial, it's very straightforward to run builds for PHP and provide Continuous Integration for your PHP projects!
Happy building!