When we run our build suites on Travis Pro the bundling step takes the most time by a wide margin (aside from the test script itself).

Inspired by this Coderwall protip by Michał Czyż, I set about attempting to cache our completed gem bundle on S3.

Update: Checkout the bundle_cache gem for an improved version of this technique


How it works

  1. The tarballed bundle and a SHA-2 sum of the Gemfile.lock are downloaded from S3 (if they exist)
  2. Travis runs bundle install as normal (except that the bundle is installed to ~/.bundle). This shouldn’t take more than a few seconds if the bundle hasn’t changed.
  3. Travis executes all the normal build steps, as usual
  4. The bundle is tarballed and uploaded to S3 (us-east is the closest region to the new Travis workers), but only if the SHA-2 hash for the Gemfile.lock has changed

The bundle is uploaded with public-read permissions for easier downloading. This should not be a problem for most people and could be mitigated by using a really obscure filename, like a UUID.

Step by step instruction

  1. Set up a bucket on S3 in the US Standard region (us-east-1) (and possibly a new user via IAM)
  2. Install the travis gem with gem install travis
  3. Log into Travis with travis login --auto (from inside your project respository directory)
  4. Encrypt your S3 credentials with: travis encrypt AWS_S3_KEY="" AWS_S3_SECRET="" --add (be sure to add your actual credentials inside the double quotes)
  5. Add the bundle_cache.rb and bundle_install.sh files from below to the script/travis folder
  6. Modify your .travis.yml file to match the .travis.yml below
  • The BUNDLE_ARCHIVE variable will be used as the base for the uploaded bundle’s name
  • Setting AWS_S3_REGION is optional and defaults to us-east-1
  • Pay special attention to these keys:
    • bundler_args
    • env.global
    • before_install
    • after_script

If you have any questions or comments, you can comment on my gist, or tweet at me on Twitter.