Introduction to Travis.CI Part 2

introduction to travis.ci part 2

As we started discussing in my last article Introduction to Travis.CI, modern application development is a pretty demanding task. Whether that’s because of the complexity of modern applications, or the sheer number of moving parts which have to be managed, there’s no denying that it’s a lot of work.

But gladly, thanks to a range of modern tools such as continuous integration servers, the amount of work involved can be significantly reduced – if done properly. Travis CI, as we had a good introduction to in last week’s post, is one of those tools. And what’s more, depending on your needs – it’s free.

In case you missed the previous instalment, we started by looking at what Travis is, and how it’s configured. We then stepped through a series of builds, viewing the information provided, and how they work, and finished up configuring simple email notifications.

Now that’s great, but it only just scratches the surface of what’s possible. In this instalment, I’m going to take you further, showing you a richer range of functionality. We’re going to look at integrating notifications with third party applications and services, including IRC, HipChat, and CodeClimate.

Notifications

OK, let’s get started adding further notification options. We’ll start with IRC.

 IRC

If you’re not familiar with it, IRC is a simple, text-based, chat system, created in 1988 by Jarkko Oikarinen. It was one of the earlier chat systems, preceding most everything we know today; whether that’s ICQ, Facebook Messenger, Slack, HipChat, and so on.

Whilst it’s not nearly as popular as it once was, it’s still a very well used medium, with some reports saying it has a user base of around half a million active users, at any one time.

Like most software and protocols this old, there are a range of clients from it, both in the console and for the GUI. Some of the more popular GUI clients are mIRC, for Windows, Colloquy for MAC OSX, and XChat for Linux.

Now let’s get the IRC notification setup. For the purposes of this article, I’ve setup a new IRC channel on freenode called #conetix-blog. To configure it to use it, in your .travis.yml, add the following configuration.

irc:
    channels:
      - "irc.freenode.net#conetix-blog"
    use_notice: true
    on_success: always
    on_failure: always
    skip_join: true

Stepping through the options, the channel is set under channels, on_success and on_failure ensure that no matter the status of a build, a notification will be sent.

I’ve then set use_notice so that a notice style message is sent, instead of a normal message. This makes it simpler to distinguish between normal conversation and notification messages.

Finally, I’ve set skip_join to true, so that the bot doesn’t have to join before it can send a message. You may or may not like taking this approach. As always, commit and push the changes to .travis.yml to the repository. When the next build is done, in your IRC channel, you should see a message appear.

 HipChat

HipChat is one of the newer, cooler online chat services available today. Acquired by Atlassian in 2012, HipChat is a service providing both private and group chat, and instant messaging.

Available for Mac, Linux, and Windows, as well as Android and iOS, it’s one of the biggest services around, handling 60 messages per/second and containing over half a terabyte of searchable data.

If you’re team’s not already using it, and are looking for a chat solution, I’ve used it and thoroughly enjoy and recommend it. So that’s why we’re going to integrate with it today. To do so, add the following configuration to your .travis.yml configuration file.

hipchat:
    rooms:
      - <API_Token>@<Room_Name>
    format: html
    on_success: always
    on_failure: always

Stepping through the configuration, the rooms option requires an API token and the room name which the message will be sent to. To get the API token, you first need to login to your HipChat account, on the web, then under Rooms click the room name.

In the navigation on the left-hand side, click Tokens, where you’ll need to generate a new token, specifying the token’s scope. I’ve chosen “Send Notification” only. After that, you’ll see the token available in the Token list, as below. For the Room Name, you’ll find that at the top of the same page.

hip chat admin overview

Finally, I’ve used format: html, which sets the format of the sent message to be HTML. Please be aware that it disables some features, such as @mentions. As with IRC, I’ve stipulated on_success and on_failure to be set to always so that notifications are always sent to the chat room.

Integrating with CodeClimate

Now that we’ve setup more powerful notifications, let’s look at adding code quality analysis. There are a range of tools available to do this, some open-source, some closed. But one I want to look at today is a 3rd party service called CodeClimate.

What is CodeClimate

In essence, in the words of the CodeClimate team, the service:

Consolidates the results from a suite of static analysis tools into a single, real-time report, giving your team the information it needs to identify hotspots, evaluate new approaches, and improve code quality.

CodeClimate is a great service which helps developers improve the quality of their code by analysing a range of key metrics. These include:

  • Duplicated Code
  • Excess Public Methods
  • High Total Complexity
  • Complex Methods
  • Debug functions are present
  • Short Variable Names
  • Use of the system command

It integrates with a number of existing tools, such as PHPUnit for PHP, where it takes account of those tools in the overall calculation of the code’s GPA. We’ll see a bit of that soon when I add some code coverage to the project.

Logging In With GitHub

Before we can get everything setup, you’ll need to ensure you have an account. Gladly, you don’t need to register. All you need to do is click “Log in with GitHub” at the bottom of the login page. If this is your first time logging in with GitHub, you’ll be redirected to GitHub, where you’ll be asked to authorise Codeclimate for access to your GitHub credentials. Click OK and you’ll be redirected back to Codeclimate and logged in.

Adding Your Project

After that, you’ll see any projects you may already have listed, none if this is your first time. Otherwise you’ll see one, as I have in the screenshot below.

To add a new one, click “Add Open Source Repo” on the right hand side, where you can specify the account and repository name, under “GitHub repo name”, and click “Import Repo from GitHub” to start the import process.

Whilst that’s happening, you’ll see a page, similar to the one below. This page doesn’t refresh automatically. So to check the status, which shouldn’t take too long, reload the page after about 30 seconds – 1 minute. When everything is finished importing, you’ll see an initial page as below.

I think it’s pretty thoughtful how the ranking system is similar to a school report, where you get a GPA ranking for your code – so you know in a moment how it’s faired. A GPA of 4.0’s pretty good, don’t you think?

Updating Travis’ Configuration

Now that was the easy part. Next comes the fun. For this, you need to make a number of changes. Specifically, we’re going to need to:

  1. Add a new Composer package
  2. Update the PHPUnit configuration
  3. Add a CodeClimate Configuration in .travis.yml

Let’s start at the top. Firstly, run composer require codeclimate/php-test-reporter –dev in the root of the project directory, which will add the CodeClimate test reporter for PHP package to the dev requirements section, and update the vendor directory.

Next, you need to update phpunit.xml.dist, to enable logging, specifically using the Clover format. To do that, add the following line to the file.

<logging>
      <log type="coverage-clover" target="./build/logs/clover.xml"/>
    </logging>

To ensure that the ./build/logs/ directory is always present, run the following command. This will ensure that it’s present and under Git control:

bash mkdir -p ./build/logs && touch ./build/logs/.gitkeep

Now we’re down to the last step, configuring Travis to work with CodeClimate. To do that, in .travis.yml, add the following further configuration options:

after_script:
  - vendor/bin/test-reporter
addons:
  code_climate:
    repo_token: <YOUR_TOKEN>

To get the token, to replace <YOUR_TOKEN> with, when viewing your project in CodeClimate, click Settings -> Test Coverage, and down under “PHP Instructions”, under Step 4, copy the token which it has listed there. This token is specific to this repo on Code Climate.

Note: This should be enough to get it working for you. However, if you see the lineUnexpected response: -60 server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none, in the job output, then, you need to add the configuration below, as this is a known issue.

Alternate Configuration

after_script:
  - CODECLIMATE_REPO_TOKEN="<YOUR_TOKEN>" vendor/bin/test-reporter --stdout > codeclimate.json
  - "curl -X POST -d @codeclimate.json -H 'Content-Type: application/json' -H 'User-Agent: Code Climate (PHP Test Reporter v0.1.1)' https://codeclimate.com/test_reports"

Adding Code Coverage

Now if we don’t change anything, the CodeClimate project Timeline’s not going to change, as we’ve not met the criteria for it to do so.

Gladly, they’re quite straight-forward, one of them being an increase in code coverage. So to do that, I’ve added a simplistic constructor to the entity, and a test class for the SalesData entity, which you can see below.

// new SalesData entity constructor
    public function __construct($data = array())
    {
        if (!empty($data)) {
            foreach(get_class_vars(__CLASS__) as $property => $value) {
                if (isset($data[$property])) {
                    $this->{$property} = $data[$property];
                }
            }
        }
    }
<?php
// SalesData entity test
namespace AuraFramework_Project;

use DatabaseObjectsEntitySalesData;

/**
 * @coversDefaultClass DatabaseObjectsEntitySalesData
 */
class EntityTest extends PHPUnit_Framework_TestCase
{
    /**
     * @covers ::__construct
     */
    public function testObjectIsInitiallyEmpty()
    {
        $salesData = new SalesData(array());
        foreach(get_object_vars($salesData) as $property) {
            $this->assertTrue(is_null($property), "Property {$property} should be null.");
        }
    }

    /**
     * @covers ::__construct
     */
    public function testObjectCanBeInitialised()
    {
        $data = [
            'TrackId' => 1, 'TotalSales' => 100, 'TrackName' => 'Hey Baby!',
            'Genre' => 'Bubblegum Pop', 'AlbumTitle' => 'Tragic Love Songs',
            'ArtistName' => 'Unknown'
        ];

        $salesData = new SalesData($data);

        foreach(get_object_vars($salesData) as $property => $value) {
            $this->assertEquals(
                $data[$property],
                $salesData->{$property},
                sprintf("Property %s should be set to %s", $property, $data[$property])
            );
        }
    }
}

When that’s done, commit all the changes and push them to the repository. When the next build’s done, you should see the timeline for your project in CodeClimate change to look something like the following.

travis.ci codeclimate timeline

Note: If you're keen to learn more about CodeClimate, either get started with them by adding an open source project of your own, or stay tuned for an upcoming article on them.

 Wrapping Up

And that’s how to use some of the more advanced configuration options and features of Travis CI, including notifications to HipChat and IRC, and integrating it with CodeClimate to help reduce the stress and overhead of managing your software projects.

Are you already using Travis? Share your thoughts in the comments. If this is your first time seeing Travis, are you keen to add it to your workflow?

Back to the Blog

avatar of matthew setter

Matthew Setter

  • Conetix
  • Conetix

Let's Get Started

  • This field is for validation purposes and should be left unchanged.