Travis : Parallel jobs and override vm in matrix

26 Nov 2016

Recently in an effort to separate the frontend test and backend test on travis, we came to know about the travis feature called matrix, Which helps us to define parallel jobs in the build.

Our initial idea was to define separate ENV varaibles using matrix and conditionally run the scripts. Our .travis.yml file looked like below one.

---
sudo: required
dist: trusty

language: ruby

rvm:
  - 2.1.2

before_install:
  - sudo apt-get update -qq
  - sudo apt-get install -qq  mysql-server mysql-client unzip
  - nvm install v5.5

before_script:
  - mysql -u root -e 'create database app_test;'
  - cp config/database.travis.yml config/database.yml
  - bundle exec rake db:test:load app:generate_secret_token
  - npm install

branches:
  only:
    - master

cache:
  bundler: true

env:
  global:
    - RAILS_ENV=test
  matrix:
    - TEST_CATEGORY=frontend
    - TEST_CATEGORY=backend

matrix:
  fast_finish: true

script:
  - if [ $TEST_CATEGORY == 'frontend' ]; then npm test; fi
  - if [ $TEST_CATEGORY == 'backend' ]; then bundle exec parallel_rspec -n 2 spec; fi

We were able to run jobs in parallel, but still they boot up same vm and configure everything in both VM.

Travis Matrix Version 1

Since for our frontend spec doesn’t need any ruby related stuff we started looking for more ways to override the vm’s used for the jobs. And suddenly this comment caught our eye.

As per the comment there are ways to override vm in matrix but seems like they experimental since there is no documentation was found on it. Also travis lint will throw linting error. But anyway thought of give a try and updated my travis config to the below one.

---
sudo: required
dist: trusty

branches:
  only:
    - master

matrix:
  fast_finish: true
  include:
    - node_js: 5.5
      language: node_js
      env: NODE_ENV=test
      cache:
        directories:
          - "$HOME/.nvm"
          - "$HOME/.npm"
      before_install:
        - nvm install v5.5
      install:
        - npm install
      script:
        - npm test
    - rvm: 2.1.2
      language: ruby
      env: RAILS_ENV=test
      cache:
        bundler: true
      before_install:
        - sudo apt-get update -qq
        - sudo apt-get install -qq  mysql-server mysql-client unzip
      before_script:
        - mysql -u root -e 'create database app_test;'
        - cp config/database.travis.yml config/database.yml
        - bundle exec rake db:test:load app:generate_secret_token
      script:
        - bundle exec parallel_rspec spec

Now for frontend spec we dont need to setup anything related to ruby.

Travis Version 2

Now the frontend job uses node_js vm where as backend job uses ruby vm. Also our frontend job finished with in 3 minutes which is 5 minutes gain from previous version since we removed all the ruby and rails setup for this job.

Even though now we have multiple jobs, github integration will show only build status not per job status.

Disclaimer : The above feature is undocumented by travis and may change in future.

If you find my work helpful, You can buy me a coffee.