I recently thought it might be a good idea to start using Travis CI to run builds of my personal repositories on a regular basis. A lot of my repositories are pet projects, but that doesn’t mean that I don’t depend on them on a daily basis.
That couldn’t be more true of my dotfiles. My
zshrc and my
vimrc get exercised tens if not hundreds of times per day. Sometimes I’ll make a change to test out something new, verify that it doesn’t blow up, commit it, and move on. That’s probably not the best way to do things, but I figure that I’ll never start using the new hotness if I don’t jump in and start using it right away. Usually this works out well and I’ve simply added a new tool to my repertoire, but it can potentially break my environment in subtle ways. Continuous integration can help with that: if I commit a breaking change, I can get an email when the “build” breaks. I’ll immediately know which commit broke something without having to resort to
git blame or something similar.
Travis CI offers a fantastic free service, but I haven’t really had a chance to use it yet.1 I figured that setting up CI for my small dotfiles repository would be a great way to learn a tool that many open source projects use today.
There was one huge hurdle: I use
zsh, and most of my dotfile setup scripts are written in
zsh, but the Travis environment only comes with the
bash shell installed.2
Some existing open source projects use Travis with
zsh, but they all use the legacy environment that still allows
sudo, not the newer container-based environment. The apt addon can help install packages in containers, but the latest version of
zsh on Ubuntu 12.04 is 4.3.17.
zsh 5 is a requirement for most modern usages, so that’s a non-starter. I thought that someone would have come across this already and solved it, and maybe they have, but I couldn’t easily find a solution.
We need to build and install
zsh, and we need to do it without
build-essential is already available on the Travis CI virtual machines, and we could use the aforementioned apt addon if it wasn’t.
After much trial and error, I finally got a Travis config that makes sure a recent version of
zsh is set up before running the build. I chose to do this in the
before_install step because that seems to be where additional dependencies should be installed, but I suppose it could be done anywhere in the build lifecycle before
script runs the actual tests.
The full Travis config follows, but the
before_install step is what really matters:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
First, we make a temporary directory to install
zsh to. Remember, no
sudo means no access to
/usr/bin/local, so we need to choose a safe location to install.
Next, we download the latest version of
zsh. If you want to use a different mirror or download an archive with a different compression, you just need to change this line to handle that and the rest should work. If you change the version, make sure to update the following line that changes directories to the archive you just decompressed.
Then we build
zsh: configure with the prefix set to the directory we created earlier, then
make it and
make install it to the prefixed directory.
cd back to the directory we were in – these build lifecycle steps are run in series so we need to hop back to the directory we were in before building
zsh – and, more importantly, we add the temporary directory to the beginning of our path so that
zsh can be found.
before_install steps could probably be extracted into a script, but I wanted to go with the simplest Travis config with the least overhead to get up and running with
zsh. Now, when the test script runs,
zsh is available and we can check our scripts for errors!
I look forward to exploring more of what is possible with Travis. On my horizon: using
vint to lint my vimrc and writing tests for the majority of my private repositories that don’t currently have any verification.
We use Jenkins at work, which is a blessing and a curse. Mostly the latter, but the sheer number of plugins available coupled with the fact that I work with some awesome people who know Jenkins better than I ever will makes it ok. ↩
Really, it comes with whatever shell is default for the operating system that Travis VMs use. Since they run Ubuntu 12.04, that means that
bashis available but
zshis not. It seems like Travis didn’t set out to explicitly support shell-based projects, but because their machines are (mostly) Linux, that comes for “free” if you know how to configure things. ↩