Travis status in my menu bar

I run tests on Travis a lot, so would like some notification of when they have finished running. However, I am allergic to things such as email and Slack notifications; plus I don’t want something pinging in my face, I’d like something I can glance at, like a clock.

BitBar is a little app that lets you put anything you like in your Mac OS X menu bar, by converting the output of any script into an icon and menu choices. It has a Travis plugin that looked pretty neat – something in my menu bar I can glance at. Here is the plugin’s example screenshot:

BitBar Travis plugin example screenshot

However, it wasn’t quite right. You could give it a list of repositories and branches (defaulting to the main branch (master) only), and it would find the latest Travis build for each branch and show its output in a list. I wanted it to cover any and all branches; show me previous runs too (some can take a while even if I’ve already kicked off a new one); and lastly, I work in a team, so don’t care if my colleagues’ builds are failing, only my own.

Showing all branches

Thankfully, it being script based, and in Python, meant it was eminently hackable. Firstly, I tweaked it so that if I supplied True rather than a list of branches, it would fetch the latest 50 Travis builds (per repository) instead:

if 'branches' in repo and isinstance(repo['branches'], bool) and repo['branches']:
    url = 'repo/' + urllib2.quote(repo['name'], safe='') + '/builds?limit=50'

Showing older builds for the same branches

I then altered the display loop, so that it stored all the builds for the same branch (or pull request) together, with non-newest builds as submenu entries off the newest one for that branch/PR (BitBar has a straightforward textual output for having submenus/colours/etc). I also tweaked the display to e.g. include the pull request number on PR entries:

color = 'color={}'.format(COLORS[build['state']]) if COLORS.get(build['state']) else ''
symbol = SYMBOLS[build['state']] or NO_SYMBOL
href = 'href=https://travis-ci' + TRAVIS_TLD + '{}/builds/{}'.format(repo['name'], build['id'])

created_by = build['created_by']['login']
if build['event_type'] == 'pull_request':
    message = '#%s' % build['pull_request_number']
    message = build['branch']['name']

output_msg = u'{symbol} {repo_name} {message}@{sha}, {by}'.format(
    sha=build['commit']['sha'][:8], by=created_by,
    symbol=symbol, repo_name=repo['name'] if len(repos)>1 else '', message=message)

if message in output_key_to_output:
    submenu = '-- '
   submenu = ''
    output_key_to_output[message] = []

output_key_to_output[message].append(u'{}{} | {} {}'.format(submenu, output_msg, href, color))

Only summing up my own failures

Lastly, the main menu bar icon was a green tick if all was okay, an orange number and symbol of in progress builds if there are any, or a red number and cross if there are any failed builds. I altered the counter code so that it only included failed builds if they were by me:

elif build['state'] == "failed" and build['event_type'] == 'push' and created_by == USER and message not in seen:
    fail_count += 1


With these changes (and one more, changing yellow to orange as I found yellow unreadable), I find this an invaluable tool to save me either looking at a web page every few minutes (or more likely, forgetting about it entirely). It’s much nicer than having push notifications.

Example of the BitBar Travis plugin in use on my menu
bar, showing some in progress and some successful builds.

I’ve put the source code here in case it’s helpful to anyone.