Chris Hannah
My little piece of the internet

Currently Listening

Having Some Fun With Continuous Integration

I had an interesting day at work today, as I was configuring a new project work with our CI server, and have things like Unit/UI Tests in a readable format, and also convert the code coverage into something that could be stored along with the build artefacts.

Just for some background, we use Bamboo as a server, and I’m pretty limited with what I can actually configure myself, without getting someone with higher privileges. So I try to work within my limitations, and see what I can come up with.

I use Fastlane as the main solution to manage the whole process. And that means I can use the scan and slather commands to do the heavy lifting for the testing/code coverage. The way I had to integrate it in our CI server was reasonably simple. The test results were handled by setting the output type to junit, and then adding a simple JUnit Parser task on Bamboo. The code coverage was slightly more complex, as it needed me to run a python package that converts it into a “Clover” format that Bamboo could understand.

What was more tricky, was getting this data nicely formatted when it was sent to our Slack room. The previous build plans all had notifications handled form Bamboo, and it just gave a short message with the number of tests that passed/failed. I wanted more insight this time though, as I knew the test data was available, and also that I had code coverage being generated. I decided that the simplest (maybe it wasn’t in the end) solution was to just find a way to read the information from the .xml files, and send a custom message to Slack as part of the Fastlane process.

What I ended up with is a kind of monstrous-masterpiece. In Fastlane I had the Slack command being called with some basic information about the build, such as the branch, project name, and whether it passed/failed. But to get the results of the Unit/UI tests, I thought I’d use grep to find the line in the junit file that had text like “tests=100 failures=0”, I then used sed to clean up the surrounding text, and had the final output as “Passed: 100, Failed: 0”. The code coverage was slightly harder. I used grep and sed again in the same way to find the total code coverage, but it was formatted like “1.00000000”, and I wanted a percentage. So I piped that through bc with a small calculation, and they’re not formatted as a percentage with two decimal spaces.

Then with some magic of environment variables, I added two build-specific URLs to the message payload. One for the build details, and the other which linked directly to the code coverage report.

What I ended up with was something like this:

  • iOS App
  • Tests Passed: 100, Failed: 0
  • Code Coverage 100.00%
  • Coverage URL https://build.com/coverage/IOS_BUILD_99
  • Build URL https://build.com/IOS_BUILD_99/something
  • Result Success
  • Git Branch master

I’m not sure if all of that is relevant for each build, or if I’ll have to include some other things I’ve forgotten about. But what I can say, is that it was really fun to come with all of these little scripts that come together with something so simple at the end. And it’s quite likely that no-one else seeing the messages will have any idea the lengths I went to to make everything appear so simple.