Tag Archives: bash

Xcode Server Slack Integration

After spending a day last week struggling to get a working integration of Xcode Server and Slack (the popular messaging platform) I finally have arrived upon a reliable solution. What started out as a long bash script (and sed, and cut, and tr) that eventually called a Python program, is now just a Python program run by the Xcode ‘Trigger Script’ functionality. Read on for how I did it.

Working with a client on an iOS app we wanted to keep everyone aware of the project’s progress and the current state of all tests, both server and iOS. So, our team added the client as a Slack single-channel guest and got to work integrating our server-side Strider Continuous Integration server and Xcode Server.

Not knowing any better I dove into the output of the Xcode Build located in /Library/Developer/XcodeServer/IntegrationAssets and poked around. I found the file buildService.log which contained build output detailing everything I needed to know about the build, looking like this:

Which, I immediately thought, “I know, I’ll tackle it with bash and sed!”. So I got to work writing a script to parse these entries and ultimately distribute them out to our Slack channel so everyone can see progress as we go along. Here’s the bash script I wrote:

This seemed to work! But, however, proved problematic as I discovered (only after I’d written the script!) that there lies a chicken-and-egg problem with when Xcode will execute a script versus when it’s all done packaging up the buildService.log files. The pattern that Xcode follows is: run the project tests, run the post-process script, then build the buildService.log files. So, the script above was running on a previous build, not the most current one.

I poked around a bit more but ultimately couldn’t come up with a solution of how to solve this. So, I searched around on Twitter and found @mjmoriarity, a wonderfully helpful Apple engineer who pointed me towards my ultimate solution of using Xcode’s set environment variables. Using these, my script was now reduced to a handful of lines and is wonderfully reliable: