A build matrix in Travis is made up by several multiple jobs that run in parallel. This can be useful in many cases, but the two primary reasons we see people use matricies is for reducing the overall build execution time and running tests against different versions of runtimes or dependencies to get the best version of the build. Let's learn about Build Matricies in Travis CI.
Build Matrix and setting up the .travis.yml
As you know by now, you need to tell Travis which language environment to select for your project. You can do so using the language
key option, in this Cookbook we'll be using PHP. You can specify which PHP versions will the tests be executed. Not introducing patch versions tells Travis to use the latest available, which is sometimes referred to edge
, or if it's the stable version, you guessed it, it's called stable
. So let's start building out our .travis.yml
:
language: php
php:
- 5.3.3
- 5.4
- 5.5
- 5.6
- hhvm
Env Vars
Let's tell Travis to do multiple runs/builds with different sets of env var
values. To do so, add an env key
. Each segment is understood as a different environment and tests are run separately as such. We are going to use PHP_SEGMENT_TEST
later in the file to run tester with the argument of -p
and hhvm
option in HHVM environment, so in your .travis.yml
file, add the env
segment:
env:
- PHP_SEGMENT_TESTRUN="php-cgi"
- PHP_SEGMENT_TEST="hhvm"
Now simple math would have it, the combination of five PHP versions and the two env vars
generates a total of 10 runs.
Dependency installation using Composer
You'll obviously have an install segment in your .travis.yml
. Each sub-segment means one single command. Composer installs your dev dependencies by default. You should use --no-interaction so Composer doesn't ask questions Travis can't answer, and can continue the build.
You'll want the latest build, so in you .travis.yml
make sure you run the update
flag at before_install
, so it would look like:
before_install:
- composer self-update
install:
- composer install --no-interaction
The Build Matrix
Depending on the configuration above (different segments and sub segments), a build matrix wil be generated. The matrix contains all combinations the environment settings. A single combination is called a job and is run separately. You can modify the matrix in matrix section.
If you want to exclude a job, use the exclude
key. In our case, we don't want to use -p hhvm parameter for standard PHP versions and -p php-cgi for HHVM:
matrix:
exclude:
- php: 5.3.3
env: PHP_SEGMENT_TEST="hhvm"
- php: 5.4
env: TPHP_SEGMENT_TEST="hhvm"
- php: 5.5
env: PHP_SEGMENT_TEST="hhvm"
- php: 5.6
env: PHP_SEGMENT_TEST="hhvm"
- php: hhvm
env: PHP_SEGMENT_TESTRUN="php-cgi"
To your pleasure, you can define jobs that are allowed to fail without causing the whole build to shown as failed. To do so, declare allow_failures. For our sake, we allow HHVM to fail, lets do this via:
matrix:
allow_failures:
- php: hhvm
I only specified the PHP version, not the environment variables. This means all jobs with HHVM version will be allowed to fail/retry (if that is an option you have in your .travis.yml
. Anyway, nevermind the environment variables values. It works with exclude
also.
Running the scripts/tests
Tests are run in script segment of the .travis.yml
. Let's assume your tests are in scripts/
folder in your file tree and you provide your own php.ini
in the same folder. Additionally, we can tell TESTER
to display information about skipped tests with the -s
flag and to use value of earlier declared TESTER_SEGMENT_TEST
as PHP binary with the -p flag:
script:
- ./vendor/bin/tester -p $TESTER_SEGMENT_TEST -s -c ./tests/php.ini ./tests
If the build fails
we want to use after_failure
to get the exact values via:
after_failure:
# Prints *.actual files contents (if not revert)
- for i in $(find ./tests -name \*.actual); do echo "--- $i"; cat $i; echo; echo; done
Other services
Travis comes with multiple popular services and has no shortages of them, (e.g. MySQL, Redis, Docker) pre-installed. However, if you need to use for example Redis storage, you can tell Travis in services section via:
services:
- redis-server
DB Init
Depending on what database you chose to use, it can vary -- in this example we are using MySQL
. MySQL runs on 127.0.0.1 and you can log in using travis or root as username. Say you have a DB setup script, and it's in tests/montana/testbase.sql.
, here's a sample segment:
before_script:
- mysql -u root -e 'CREATE DATABASE testbase;'
- mysql -u root testbase < tests/montana/testbase.sql
.travis.yml in it's final form
After a lot of this segment config, this is what you're left with:
language: php
php:
- 5.3.3
- 5.4
- 5.5
- 5.6
- hhvm
env:
- TESTER_SEGMENT_TEST="php-cgi"
- TESTER_SEGMENT_TESTRUN="hhvm"
matrix:
allow_failures:
- php: hhvm
exclude:
- php: 5.3.3
env: TESTER_SEGMENT_TEST="hhvm"
- php: 5.4
env: TESTER_SEGMENT_TEST="hhvm"
- php: 5.5
env: TESTER_SEGMENT_TEST="hhvm"
- php: 5.6
env: TESTER_SEGMENT_TEST="hhvm"
- php: hhvm
env: TESTER_SEGMENT_TESTRUN="php-cgi"
services:
- redis-server
before_install:
- composer self-update
install:
- composer install --no-interaction --prefer-source
before_script:
- mysql -u root -e 'CREATE DATABASE testbase;'
- mysql -u root testbase < tests/montana/testbase.sql
script:
- ./vendor/bin/tester -p $TESTER_SEGMENT_TEST -c ./tests/php.ini -s ./tests/
after_failure: # to find actual variables if needed, a verbose esque way of doing things
# Prints *.actual files content
- for i in $(find ./tests -name \*.actual); do echo "--- $i"; cat $i; echo; echo; done
Activate webhook
Go to www.travis-ci.com, and flip switch to ON
for all repositories you'd like to enable. Travis will now add your repository to queue after every pushed commit or created pull-request. After a short while, your repository will be tested. Now if you'd like the opposite, there's a bash script I've created, which I will attach right below this - as some people find this more efficient:
#!/usr/bin/env sh
echo "Hello from Montana at Travis"
echo $TRAVIS_PULL_REQUEST
if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
surge --project ./dist --domain auto-deploy-test.surge.sh
else
echo "This is a PR, not deploying"
fi
To know if your build is successful either check the GitHub status, or generate a status image.
Congratulations
This is Travis's Build Matrix in a nutshell, it can seem a bit confusing but after going over it a few times, it will start to make sense.
Top comments (0)