Implementating Continous Integration

In my last post, "Branching Your Code," I touched on the fact that I've been working on updating OCLC’s code libraries for authentication in PHP and Ruby. As part of this process, I've been adding continuous integration (CI) testing to the libraries where it wasn't present. For those of you who aren't familiar with the concept of CI, it is a development practice through which code is checked into a repository and verified by an automated build and test process. Performing CI allows problems in the code base to be identified early. It also helps identify dependencies issues that might arise from building in different environments. There are several different tools that can be used for CI, including Jenkins, Hudson, and Travis-CI.  

For Developer Network code libraries and projects, we use Travis-CI because it is hosted, supports many different languages and easily integrates with GitHub. The basic setup for Travis-CI requires a .travis.yml file for configuration. Within this file, you specify several things, including

  • what versions of the language to build and test the code against and
  • where and when to send build notifications.

Depending on the language your code library or application uses, your Travis CI configuration file will have specific bits of information. Let's take a look at the configuration file for the OCLC PHP Authentication library.

language: php
# list any PHP version you want to test against
php:
# using major version aliases
# aliased to a recent 5.6.x version
- 5.6
#alias to a recent 7.0.x version
- 7.0
install:
    - composer install
# omitting "script:" will default to phpunit
script: vendor/bin/phpunit --configuration phpunit.xml --coverage-text
# configure notifications (email, IRC, campfire etc)
notifications:
    email:
        recipients:
        - coombsk@oclc.org
        on_success: always
        on_failure: always

In this file, you can see  

  • builds for two different versions of PHP are being performed,
  • composer is installed and used to install dependencies, and
  • tests run using PHPUnit.

When a new change is committed to the repository, the builds and tests are run. Here is what the results look like for a build of the PHP Authentication library.

file

Related CI Tools

Travis-CI offers integration with other cloud-based tools for testing, measuring code coverage and managing releases, packages and deployment.  

In the case of OCLC's code libraries, we've just started using Codecov (https://codecov.io/) to keep track of code coverage. For those who might be unfamiliar with the concept of code coverage, code coverage reports are designed to describe the degree to which a particular set of code is tested via a particular test suite. Most code coverage reports identify which pieces of code are tested and which are not. This allows developer to constantly improve tests to ensure the code is bug free.

For our PHP libraries, we're using the xdebug (https://xdebug.org/) extension for PHP in concert with phpunit to create our code coverage reports. To make this work, you need to make sure that the xdebug extension for PHP is installed. Once that is done, you can add the following to your phpunit configuration file:

  <logging>
    <log type="coverage-clover" target="clover.xml"/>
  </logging>
  <filter>
    <whitelist>
        <directory suffix=".php">src/</directory>
    </whitelist>


And then, in the command line, you can run phpunit with the option

vendor/bin/phpunit --coverage-clover=coverage.xml

This creates reports in an XML format. These reports are then uploaded to codecov.io, where they can be viewed. Making this all happen via the Travis-CI builds process requires a slight change to the .travis.yml file.

script: 
    - vendor/bin/phpunit --coverage-clover=coverage.xml 
 
after_success:
    - bash <(curl -s https://codecov.io/bash)

This configuration creates a code coverage report, which it then uploads to codecov.io, where you can view it.

file

In addition to code coverage, it is also possible to create API documentation in HTML format and deploy it to GitHub Pages. Before the documentation can be deployed, it has to be created. I recommend using phpDocumentor (https://www.phpdoc.org) for this. To utilize this tool, you'll need to make sure you include it in your composer file as a development dependency.

    "require-dev" : {
        "phpunit/phpunit" : "^5",
        "php-vcr/php-vcr" : "1.3.1",
        "php-vcr/phpunit-testlistener-vcr" : "*",
        "zendframework/zend-log" : "2.*",
        "phpdocumentor/phpdocumentor" : "2.*"
    }

Now that you have the dependency installed, phpdoc can be run from the command line to create documentation.

vendor/bin/phpdoc -d src  -t api_docs --template="clean"

Now that you've ensured that the documentation is being created the way you want, you can setup Travis-CI to create the documentation on each successful deploy.

after_success:
    - vendor/bin/phpdoc -d src  -t api_docs --template="clean"

Lastly, you'll need to configure Travis-CI to upload the documentation to your GitHub pages. This can be done a couple ways, such as

  1. using a personal access token for GitHub and a set of command line git operations, or
  2. using .travis.yml configuration options (https://docs.travis-ci.com/user/deployment/pages/).

I'm using the latter method because it is incredibly simple and easy to configure. You have to specify the local directory to synch. You also have to get a personal access token from GitHub and store this in the Travis environment variables for the project. The result is a config file that looks like this:

deploy: 
  provider: pages 
  skip_cleanup: true 
  github_token: $GITHUB_TOKEN # Set in travis-ci.org dashboard 
  local_dir: api_docs 
  on: 
    branch: master

Once the documentation is created, it lives on the appropriate GitHub pages. In the case of the oclc-auth-php library, the API documentation is at http://oclc-developer-network.github.io/oclc-auth-php.

Ideally, I'd like to store a "dashboard" of more build details within the GitHub pages: the HTML version of the code coverage, the API documentation and some other HTML reports on the quality of the code. However, setting this up is going to require some additional planning and work. For now, though, all of our code libraries have basic continuous integration testing in place, which ensures greater reliability and quality in the code libraries.

  • Karen Coombs

    Karen Coombs

    Senior Product Analyst