This post is brought to you by ServerCentral Turing Group in Chicago, a Platinum level sponsor of the meta::hack conference in 2018. For the past 3 years we’ve had the privilege of having meta::hack at the ServerCentral office space in Chicago.
ServerCentral Turing Group (SCTG) is a trusted provider of AWS consulting, managed clouds, cloud-native software development, and global data center services for startups, enterprises, and Fortune 500 companies.
Managing Your Travis CI Config Files with App::CISetup
If you write software, you (hopefully) write tests. If you write tests, it’s easy to forget to run them. Using Continuous Integration (CI) for your software is one way around this. Many of us use Travis CI for CI. In this post we’ll go over ways to make your Travis CI faster and hopefully better.
Setting Up a New Travis CI Config
Travis builds rely on a
.travis.yml file which lives in the top level of your repository. There are several ways to set up a new config.
- You can do it by hand
- You can have Dist::Zilla create the file for you when you create a new distribution
- You can use App::CISetup
I’m going to cover the last option here, since it’s so easy and possibly the least known of the options mentioned above.
First, install the module:
Then create a new config file:
setup-travis-yml.pl --create --dir .
This will create a file which looks something like this:
addons: apt: packages: - aspell - aspell-en language: perl perl: - blead - dev - 5.28 - 5.26 - 5.24 - 5.22 - 5.20 - 5.18 - 5.16 - 5.14 cache: directories: - $HOME/perl5 matrix: allow_failures: - perl: blead fast_finish: 1 include: - env: COVERAGE=1 perl: 5.28 env: global: - AUTHOR_TESTING=1 - RELEASE_TESTING=1 before_install: - eval $(curl https://travis-perl.github.io/init) --auto --always-upgrade-modules ### __app_cisetup__ # --- # force_threaded_perls: 0 # perl_caching: 1 ### __app_cisetup__
Let’s break down some parts of this file to see what we can learn.
--- addons: apt: packages: - aspell - aspell-en
What’s going on here? The issue is that some Pod spelling tests will skip running tests if they don’t find the proper dictionary files. If your tests are not running in verbose mode, you may not even know that tests are being skipped. So, this part of the setup ensures that there is an English dictionary available for spell checking. Obviously you can add other languages if your Pod needs this.
cache: directories: - $HOME/perl5
In many test builds, installing your CPAN dependencies can add a lot of extra time to the total build time. This tells Travis to cache your module installs. Note that each Perl version which you test as a part of your Travis build does its own module install. So, if you’re running 6 different jobs as part of a Travis build, you’ll actually have 6 different caches. You don’t have to worry about a cache from Perl 5.26 contaminating a cache for Perl 5.24.
Now we’re at the build matrix:
matrix: allow_failures: - perl: blead fast_finish: 1 include: - env: COVERAGE=1 perl: '5.28'
We are going to allow some failures:
allow_failures: - perl: blead
In the case of
blead Perl we do care if something breaks, but we probably don’t want to prevent any code from being merged because of a test failure from
If you’re wondering what
blead is, it’s explained at dev.perl.org/perl5/source.html
The master branch, where the development takes places, is named blead
fast_finish allows us to fail faster. The Travis blog explains it nicely:
With fast finishing enabled, 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. In these cases, the status of the build can already be determined, so there’s no need to wait around until the other jobs finish.
fast_finish allows us to get faster notifications from Travis, if we have builds in the
This brings us to the build matrix includes:
include: - env: COVERAGE=1 perl: '5.28'
In this case we’re saying that we want to run an additional build. We want to run an extra Perl 5.28 build that uses Devel::Cover.
If we are going to run a coverage build, we’ll likely also want to use coveralls.io to track changes to our coverage. Setting up Coveralls is outside the scope of this post, but if you haven’t started using it yet, I highly recommend taking a few minutes to get set up with this service.
Moving along, we can see that some global environment variables are being set.
env: global: - AUTHOR_TESTING=1 - RELEASE_TESTING=1
The above configuration ensures that author and release tests are run on all jobs in your build unless you override or unset these variables. Personally, I prefer to run release tests on just one job per build, but that’s just me. I may eventually change my mind about that.
The last configuration looks simple, but it does a lot:
before_install: - eval $(curl https://travis-perl.github.io/init) --auto --always-upgrade-modules
The above ensures that your build uses the Travis Perl Helpers, which does so much handy stuff I’ll leave exploration of that as an exercise for the reader. I should note, however, that
--always-upgrade-modules is enabled here, so even though we are caching our CPAN modules, Travis will automatically refresh our Perl module cache if it has gotten stale.
After that APP::CISetup tracks some of our choices as comments, so that Travis does not know or care about them:
### __app_cisetup__ # --- # force_threaded_perls: 0 # perl_caching: 1 ### __app_cisetup__
Now, what’s missing from our Travis config?
Updating a .travis.yml file
In future you can run
setup-travis-yml.pl --dir . as many times as you’d like. (Note that this is not exactly the same command that we used earlier, since we have dropped the
--create.) This will increment your Perl versions as new versions become available. This will also remove
sudo: false from any config files which currently contain this option. Try running this on your existing
.travis.yml files to see what happens.
Doing it Manually
All of the above can also be achieved by making these configurations by hand. Using
App::CISetup is not for everyone. You may, for example, not want your YAML to be rewritten by a script which is outside of your direct control. Maybe you want things ordered in a certain way. Maybe you don’t want to test on the latest version(s) of Perl. However you decide to manage your config files, I hope you’ve found some useful information here.
At some point after I began writing this post and before I finished Travis CI was acquired. I won’t get into the specifics as I’m not close to the situation but as with any change of ownership, but it’s something to be aware of.