Reducing Travis CI Build Times for WordPress Projects

Recently I’ve been working to reduce the Travis CI build times of not only WordPress core, but also the WordPress plugins and projects that I maintain.

I’m going to use this post to document patterns and tips that you can use to speed up your build times. Comments welcome!

Disable XDebug

Travis CI runs its builds with XDebug enabled by default. This is handy if you’re generating code coverage reports, but it really slows things down. On the WordPress core project, build times reduced by a whopping 40% when XDebug was disabled.

Add this line to your .travis.yml file and watch your build times plummet:

before_install:
  - phpenv config-rm xdebug.ini

Move Away From the WP_MULTISITE Pattern

If you test your plugin on both multisite and single-site environments, you might be using the WP_MULTISITE environment variable method in .travis.yml:

env:
  - WP_VERSION=latest WP_MULTISITE=1
  - WP_VERSION=latest WP_MULTISITE=0
script:
  - phpunit

This causes two jobs to run with each build, which isn’t optimal. Instead, switch to a test script which runs PHPUnit once with multisite enabled and once without. This halves the number of jobs, greatly reducing the overall build time.

env:
  - WP_VERSION=latest
script:
  - ./bin/test.sh

And in bin/test.sh:

# Run single-site unit tests:
export WP_MULTISITE=0
phpunit --exclude-group=ms-required

# Run Multisite unit tests:
export WP_MULTISITE=1
phpunit --exclude-group=ms-excluded

Cache All The Things

Caching on Travis CI is very effective and very well structured. You can cache Composer dependencies, for example, and they’ll be stored between builds in a persistent cache which is specific to the environment (eg. PHP version). This greatly reduces subsequent build times.

This should cover most of your needs for a WordPress project:

cache:
  apt: true
  directories:
    - node_modules
    - vendor
    - $HOME/.composer/cache

Enable Fast Finishing

If you’ve got allowed failures in your test matrix and you enable fast finishing, Travis CI will mark your build as finished as soon as one of two conditions are met: The only remaining jobs are allowed to fail, or a job has already failed.

While this doesn’t technically reduce your build times, it certainly reduces the time you need to wait for the build status to be reported. Drop this into your .travis.yml:

matrix:
  fast_finish: true

Keep Your Fixtures Under Control

Not specific to Travis CI or CI in general, but keeping your fixtures (items such as posts created with the factories) under control can greatly reduce your test times. As an example, if you have a large number of tests which require sites, posts, users, or terms to be set up, consider setting them up once in the wpSetUpBeforeClass() method and re-using them between tests. This means you only create your fixtures once per test case class, instead of once per test, which reduces the test time.

Take a look at some of the places in WordPress core where tests have been refactored to reuse fixtures between tests.

Reduce Your Environment Matrix

You might not need to test your project on every single version of PHP. My current pattern for my publicly released plugins is to test on the latest in the 5.x and 7.x branches. Currently, this means:

php:
  - 7.2
  - 5.6

If you’re testing on earlier versions of PHP 5, consider removing them if you’re sure that your project doesn’t include functionality specific to those versions.

If your project is a client project with a known environment, then you’ve no need to test on other environments at all. For example, if the live site is hosted on a server running PHP 7.0, then you only need to test 7.0 on Travis CI:

php:
  - 7.0

Automatically Cancel Waiting Builds

If you push to a repo several times in quick succession, you may start to see a backlog of Travis builds. You can now instruct Travis to automatically cancel waiting builds when new build requests flow in from GitHub. This greatly reduces backlogs of builds and allows you to see test results for your latest build sooner.

(Thanks for the reminder from Inderpreet Singh in the comments.)

Comments?

If you have any more tips to reducing test and build times, let me know in the comments!

3 thoughts on “Reducing Travis CI Build Times for WordPress Projects

  1. Not sure I’d cache vendor and node_modules. $HOME/.npm is a safer bet to avoid build issues in js land. One of the biggest speed ups I saw was caching the WP dev repo checkout too.

Leave a Reply

Your email address will not be published. Required fields are marked *