Configuring TeamCity for a PHP project

This post describes configuring TeamCity for a PHP project using composer. Setting up continuous integration of unit testing from a git repository.

Setting up PHP, composer and git

The first step to running your PHP project on TeamCity is installing PHP and the appropriate libraries. The only requirement for this is that PHP is installed somewhere that TeamCity is able to access. It does not need to be set in your path.

In addition, since PHP doesn’t need to be in your path it means that you can have multiple PHP versions installed. I will be installing PHP 5.6 and 7.1 to run continuous integration concurrently on both versions.

Once PHP has been installed you will need to install composer. Depending on your operating system you can either install a windows binary or run a composer install shell script. Full details are available on the composer Intro document.

Since I am using a git based version management system I had to install git. To do this you either need to install it via your package manager (apt-get/dnf/yum install git) or for windows you can install the binary. The git website offers multiple ways to download git one of which should work for your operating system.

Setting up a VCS Root with Git

I am going to configure TeamCity to run continuous integration on all branches in a git repository. The fetch URL of the VCS root is the URL that git will use to load the repository. This can be any method that git clone supports including https and SSH.

The default branch is the primary branch that this VCS root will be configured on. TeamCity will default to using this branch. Additional branches can be configured by using the “branch specification” field. To monitor all branches you can use a wildcard.

+:refs/heads/*

The above branch specification rule will add all branches in the git repository.

Depending on the fetch URL you may need to add authentication to the fetch method. This allows both password and private key authentication for authenticating to your repository.

Configuring Build Commands for Composer and PHPunit

For a composer based project you will need to run composer install to download all required assets. This should be the first build step. This can be added as a command line build step with the custom script value of composer install. Once this first build step has finished all required assets should be installed and your project should be prepared.

Now we can configure PHPUnit to run all the unit tests in the project.  Again we create this as a custom command line build step. Here we set the command executable to php and the parameter to point to phpunit.

Command executable: php
Command parameters: vendor\phpunit\phpunit\phpunit -c build/phpunit.xml

If you are going to run multiple PHP versions the path to your command executable could be a build variable. Using something like %phpExe% and then defining this variable for each build will let you easily configure which php version you want to build with.

Above we point to the phpunit file in the composer vendor folder and our phpunit xml file. This phpunit file defines where the tests live and how to run them. My example phpunit file includes:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         colors="true"
         convertErrorsToExceptions="false"
         convertNoticesToExceptions="false"
         convertWarningsToExceptions="false"
         bootstrap="../vendor/autoload.php"
>
    <testsuites>
        <testsuite name="main">
            <directory>../src</directory>
            <directory>../tests</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist>
            <directory>../src</directory>
            <directory>../tests</directory>
        </whitelist>
    </filter>
    <logging>
        <log type="coverage-html" target="coverage"/>
        <log type="coverage-clover" target="logs/clover.xml"/>
        <log type="coverage-crap4j" target="logs/crap4j.xml"/>
        <log type="junit" target="logs/junit.xml" logIncompleteSkipped="false"/>
    </logging>
</phpunit>

This tells PHPUnit where the source code, and test locations and also defines some additional coverage data to be logged. The composer autoloader file is specified by setting the bootstrap variable to the vendor autoload file.

Generating Artifacts

The final step once we have PHPUnit producing coverage information is to package these as build artefacts. These are taken from the working directory after running all the build steps and saved. Using my PHPUnit XML file combined with the following lines added to the Artifacts Path text box we are able to save our coverage artefacts.

build/coverage => coverage.zip
build/logs/junit.xml => junit.xml
build/logs/clover.xml => clover.xml

Here this packages the coverage folder as a coverage zip file. This was produced by PHPUnit and is a browseable set of HTML files showing test coverage. TeamCity lets you view this zip file without downloading it and means you can easily review coverage.

The other XML files allow easy importing of unit test coverage data into your IDE of choice.

Running your Tests

Now your unit tests are set up so that whenever a new commit is pushed into your repository the unit tests will run. In addition, coverage will be analysed and a HTML report is created. This is an important step in ensuring new code doesn’t regress older feature and therefore, ensuring a projects stability.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.