Travis CI ♥ Perl
Travis CI is a hosted continuous integration service for the open source community.
Essentially you set up a git post-commit hook that causes your tests to get run on every commit, against a number of different Perl versions, with databases and other services available if needed. And it's all free!
If you visit https://travis-ci.org/ you can get a feel for the interface and the tests that are being run. For a particular commit you get a build, for example WebService::Nestoria::Search build 1, which has a sub-build per Perl version, for example WebService::Nestoria::Search build 1.1 (perl 5.16). As you can see you get the full output from the Ubuntu VM that's running your tests, so if anything does go wrong it's pretty simple to debug.
For the rest of this post I'm going to describe the integration process, in particular hitting on how to make it work with Dist::Zilla-based projects.
Travis CI Basics
If you're using Github this couldn't be easier. Log into Travis CI with your Github account, go to your Travis CI profile, and flip your projects from Off to On. That causes a Github-side post-commit hook to be set up so that every time you 'git push' up to Github a Travis build will run.
Then you need to set up your .travis.yml file and commit it to your repository. Here's an example from a "normal" (non-Dist::Zilla) distribution:
language: perl perl: - "5.16" - "5.14" - "5.12" - "5.10"
That's it, that's the whole file! Travis knows from 'language: perl' that it should look for a Makefile.PL or Build.PL, install the dependencies, and then run the tests.
Once you commit that you should be able to head back to Travis CI and see the "My Repositories" tab and see that your tests are either running or have run.
Travis CI + Dist::Zilla
At the time of writing Travis CI does not support Perl distributions that don't have either a Makefile.PL or a Build.PL file. However there are a few different options for how to support a project that only has a dist.ini file...
Add this functionality to Travis CI
Travis is open source, you can see (and fork) it here: https://github.com/travis-ci
I tried adding Dist::Zilla support and failed, mostly due to my lack of Ruby :-) I suspect if somebody headed on IRC and talked to rjbs and miyagawa a solution could be found, since they both got involved on Github when I made my attempt and were very helpful in pointing out my errors and showing me towards the ways below.
Tell Travis CI to do the "right" thing for your project only
The .travis.yml file is incredibly flexible, up to and including allowing you to run arbitrary commands before and instead of the test process. That means if you make your .travis.yml file look like this...
language: perl perl: - "5.16" - "5.14" - "5.12" - "5.10" before_install: # Prevent "Please tell me who you are" errors for certain DZIL configs - git config --global user.name "TravisCI" install: # Deal with all of the DZIL dependancies, quickly and quietly - cpanm --quiet --notest --skip-satisfied Dist::Zilla - dzil authordeps | grep -vP '[^\w:]' | xargs -n 5 -P 10 cpanm --quiet --notest --skip-satisfied - export RELEASE_TESTING=1 AUTOMATED_TESTING=1 AUTHOR_TESTING=1 HARNESS_OPTIONS=j10:c HARNESS_TIMER=1 - dzil listdeps | grep -vP '[^\w:]' | cpanm --verbose script: - dzil smoke --release --author
... then your dist.ini-based module will be tested correctly, by causing it to run the appropriate cpanm and dzil commands to both install dependencies and run the tests themselves.
The Dist::Zilla plugin TravisYML (Dist::Zilla::TravisCI) will generate the file above automatically as part of your 'dzil build' if you want to do it that way.
The downside is that installing Dist::Zilla every time is very slow so your tests will take a long time. Luckily there's another way...
3. Use Git::CommitBuild and Travis CI branch whitelisting
The Dist::Zilla plugin Git::CommitBuild (Dist::Zilla::Plugin::Git::CommitBuild causes your build to be committed on a separate branch each time you run 'dzil build', or a command which implies 'build' such as 'dzil test' or 'dzil release'.
Add the plugin to your dist.ini like so:
[Git::CommitBuild] release_branch = build/%b release_message = Release build of v%v (on %b)
With that you get this:
alex@yuzu:~/Documents/Git/App-highlight$ git branch build/master * master alex@yuzu:~/Documents/Git/App-highlight$ ls bin Changes dist.ini lib README.pod t alex@yuzu:~/Documents/Git/App-highlight$ git checkout build/master Switched to branch 'build/master' alex@yuzu:~/Documents/Git/App-highlight$ ls bin Changes dist.ini lib LICENSE Makefile.PL MANIFEST META.json META.yml README README.pod t
As you can see the 'build/master' branch does have a Makefile.PL file, so Travis CI will be able to run its normal Perl testing against it. All that's left is to update your .travis.yml to tell Travis to run the tests on that branch only, like so:
language: perl perl: - "5.16" - "5.14" - "5.12" - "5.10" branches: only: - /^build/
You also need your .travis.yml file to exist on the build/master branch. To do that you need to update your dist.ini's GatherFiles and PruneCruft plugin options like so:
[GatherDir] include_dotfiles = 1 [PruneCruft] except = \.travis.yml
And with your next commit (and push to github if that's where your Travis CI hook is set up) a Travis build should be kicked off!