Llogiq on stuff

Shave Some Time From Your Travis Builds

A lot of projects in the Rustoshpere use travis for their continuous integration (CI) builds. The idea behind this is that you let them build on every PR and thus can see if something fails before merging, theoretically allowing you to keep a working master at all times (I say theoretically, because even that may fail in the face of changing dependencies, but they’re rare for normal projects unlike unstable compiler plugins like clippy).

Travis is a Berlin/Germany-based company that thrives by selling their CI build superpowers to companies and giving open source projects free access to their build platforms. Having used their services for most of my projects, I can attest to their general awesomeness. The way you setup their build is to register with their service and add a travis.yml file into your project containing the setup. For Rust projects, the minimum file will be:

language: Rust

That is enough to get you a plain build+test cycle. Travis can also be configured to upload docs (see Huon Wilson’s travis-cargo), or do whatever you would do in a shell. Good stuff.

However, all that awesome power for free can make one forget that they have to burn cycles to build our stuff, and also the less time it takes to build the faster we can merge new features into our projects. So there’s some motivation to make the builds perform as fast as possible. Here are three general hints to make the builds fast:

1. Use container-based builds if possible

Unless you need to be root (and if you do, you may want to stop and think if you can change your build to remove that requirement) you can add sudo: false to your .travis.yml. This will speed up your build considerably (although I don’t have numbers, I remember noticing the speedup when making the switch for optional).

2. Cache cargo dependencies

With the line cache: cargo in your .travis.yml, travis will remember the contents of $HOME/.cargo and $TRAVIS_BUILD_DIR/target, so that you only need to recompile dependencies if they or the compiler were upgraded. For some dependency-heavy projects, this can make quite the difference.

3. Only build what you need

If you just want to test, you don’t need a release build (unless your tests are so massive that running them from a debug build is slower than building a release build + running them there). If you want to benchmark, you don’t need a debug build (you can cargo test --release to stop building two separate builds). Know what compiler/cargo flags change build behavior. For example, -C debug-assertions=on enables debug assertions (including integer overflow checking) even on release builds. To reliably do this with cargo, you can call cargo * --verbose (where * is any of the other commands, usually build, test or doc) and copy the respective rustc commands into your build. You can then use cargo rustc -- .. to add the same flags to your build when using cargo.