A laptop with visible code on a desk next to some books
Development Integrating with Travis CI (5 mins read)

By Christopher Crawford, Published on Nov 14, 2020

As I was in the process of creating this blogging platform, I was looking for a CI setup that was fairly easy to get up and running as well as something that would easily give me a nice look at my coverage outside of the IDE.

What I came up with was Travis CI & Code Cov after looking for a while. There are of course other options that you can choose from.

Travis CI Setup

So the first stage of this is to get Travis up and running. Travis CI only provides free builds if your repository is an open-source project, so keep that in mind as we go on.

First things first, lets get a configuration file setup. In the root of your Laravel project, you'll need a file called .travis.yml This is where we will set up all of our steps. Below I have provided an example of what this config file could look like.

Lets break this down.

dist: bionic

language: php

php:
  - 7.3

services:
  - mysql

cache:
  directories:
    - node_modules
    - vendor

before_script:
  - cp .env.travis .env
  - sudo mysql -e 'CREATE DATABASE testing;'
  - composer self-update
  - composer install --prefer-source --no-interaction --dev
  - php artisan key:generate
  - php artisan migrate --no-interaction -vvv
script:
  - vendor/bin/phpunit --coverage-clover clover.xml

after_script:
  - bash <(curl -s https://codecov.io/bash)


dist: bionic - Travis needs to know which environment you want to use. Ideally I would recommend using the latest which at the time of writing is bionic, this is using Ubuntu 18.04 LTS. This is particularly important in terms of a Laravel application as its using MySQL 5.7.x, previous versions such as precise & trusty are using older versions of MySQL which will throw the max key length is 767 bytes on specific table fields such as email when it comes to testing. You can find the full list of different versions on Travis CI's docs.

language: php - This is fairly self explanitory, we let Travis know that this build should include the PHP language, after all this is a Laravel application and PHP is a base requirement.

services - By default Travis will not start any extra services in order to preserve resources, so anything that your application needs to run and complete tests successfully should be defined here. There are plenty of different drivers i.e MongoDb, MySQL, PostgreSQL etc.. So depending on what your driver is, you will need to start the correct one. In this case we're sticking with the default MySQL.

cache - You can define folders that are not likely to change all that often to give a performance boost and speed up the build process, here I have defined the node_modules & vendor folders as they are not changing much in this application. There are certain things you should not cache such as Docker images as Travis will spin up a new VM for every build.

before_script - This is where you will want to list and define all the steps that need to occur before your tests are run, this can range from setting up a database, copying files across and bring in dependencies. For databases you will need a file from which travis can copy across the details as I have done in the first command in the block. Any example of this file is below, although you can add or modify this file to fit your needs.

.env.travis

APP_NAME=TravisTest
APP_ENV=testing
APP_KEY=base64:Dhtsut2yoe1Oc7Glfl3zPrGLQEKECbi3NoRNQh2N4/c=
APP_DEBUG=true
APP_URL=http://localhost/

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=testing
DB_USERNAME=travis
DB_PASSWORD=

BCRYPT_ROUNDS=4
CACHE_DRIVER=array
MAIL_DRIVER=array
QUEUE_CONNECTION=sync
SESSION_DRIVER=array


script - In our case, this is where we will execute the phpunit command to run our tests and generate a coverage file. This will of course be run after the before_script steps.

after_script- Once the main script has finished running, you can define steps that should take place after the script has finished. Its important to note that this is not what should happen after a particular outcome, i.e success or failure. If you want to control something in these situations you can define the after_success and after_failure blocks. Travis has some good explanations in their docs.

We are using the after_script to get in contact with codecov.io to produce a code coverage report.


Codecov Setup

As we are firing a request to codecov upon completion of our build, we have to do some setup for this.

  • Install Codecov in repository
  • Create a yaml config file(optional)

So first of all, install Codecov into your GitHub account, you can either search the GitHub marketplace. Click install and you will be asked if you want to provide access to all repositories or only selected, this is entirely up to you, personally I cherry pick which repositories to use it on.

Once this is done, in theory you should be able to let Travis contact Codecov when your build has completed and it will generate a report for you. However in this case, I have found that sometimes the coverage numbers can be a little off due to it looking over Laravel's default classes such as the LoginController.php and others like this, if that doesnt bother you too much then you're all set from here and can stop reading!

If you wish to configure it slightly to skip these directories / files then you can create a codecov.yml file in the root of your Laravel application. Inside there you can define an ignore block and list specific files or directories to exclude.

ignore:
 - "app/Http/Controllers/Auth"
 - "app/Http/Middleware/"

You could also provide it with a wildcard such as 

 - "prefix_*.php" // Wildcards like this will skip all php files with a prefix

You're pretty much setup and good to go from here, happy testing ?