Building on Travis CI with Nightly Mono Builds

When first getting started with Mr. Gibbs it was just a simple spike to see if I could use bluetooth to connect to the pebble. I never even created a test project until very recently, certainly never set up CI. I know better, had this been a "work" project I would have insisted upon tests and setup some DevOps right away. But it's a hobby project, and I didn't.

Of course I regret it now. There's a couple dozen assemblies that need tests, and I've had a painful hit-or-miss build process for it that involved either a patched mono build or a bleeding edge mono build and dependency issues that I never quite nailed down. Thankfully after a few people contacted me attempting to replicate some of my work I've decided it's time to clean up my mess and start treating it like a real project if I want the project to have any longevity, and especially if I would like some pull requests from other contributors.

The dependency issue for the most recent version (based on blueZ 5) stems from the fork of dbus-sharp that I did which requires socket control messages to send/receive file descriptors, the relevant Mono code has not made it into a release yet. Additionally, I needed to change the framework target to 4.6.1 (from Mono/4.5) for it to locate the correct Mono.Posix assembly in the Gac. (You can tell when it isn't using the right assembly because the compiler will bark about missing Mono.Unix.Native.Cmsghdr

What I've been doing on my development machine is using Mono nightly snapshots and their handy mono-snapshot tool to run Mr. Gibbs. On the Pi Zero it's a another story, it has to be built from source. (The ArmHF builds from mono work fine on the Pi 2, but not the zero).

I decided that going through the exercise of setting up CI would help me nail down my dependency and build issues, and indeed it did. My first instinct for CI is to use jenkins, but after examining the options it looked like TravisCI (which I hadn't used before) might be even easier since it runs on debian and has mono support built in. Setting up Travis is a simple matter of adding it via github services, and then defining a .travis.yml file.

![Adding travis](/content/images/2016/04/add-travis.png)

The tricky part is that by default, if you simply tell travis to compile with mono it's going to use the latest stable mono release, which of course is going to fail. My first few attempts to use the mono nightly snapshots to install mono failed miserably because of apt throwing an error. There is a whitelist of both apt sources and packages maintained by Travis, and mono-snapshot-latest and mono-snapshot-common are not on it.

My next move was to simply pull the mono source and build it.

![cloning and building mono manually](/content/images/2016/04/pull.png)
This works, but seems rather wasteful of bandwidth, cpu, and time. My build times were a little ridiculous considering the size of the projects.
![15 minute build times](/content/images/2016/04/build.jpg)

Finally I discovered that while mono-snapshots were not whitelisted, the mono-nightly apt repo was, and the standard mono-devel package was on the whitelist. With this in mind I could simply use the apt addon in travis to install my mono build.

![apt addon](/content/images/2016/04/apt-addon-1.png)

The last small hitch was that Mr. Gibbs makes pretty extensive use of git submodules to bring all the libs togethor, and by default Travis was not pulling recursive, easy enough to fix with a before-build step to init the submodules.

![init submodules](/content/images/2016/04/submodule.png)

With this in place, my build times are far more reasonable since it's not building mono too.

![final build times (~1 min)](/content/images/2016/04/final.png)

At the end of the day it was quite a productive exercise. I learned to use Travis, I sorted out my dependency issues, and I found a reliable method to build Mr. Gibbs. Now to do something about the missing tests...