Skip to content

Instantly share code, notes, and snippets.

@kfr2
Last active March 14, 2016 13:27
Show Gist options
  • Save kfr2/75c29b975aa6b5e0a493 to your computer and use it in GitHub Desktop.
Save kfr2/75c29b975aa6b5e0a493 to your computer and use it in GitHub Desktop.
send Codeship build notifications to OSX User Notifications
"""
Codeship build notifications via OSX User Notifications.
Requirements:
* python-requests
* terminal-notifier
Environment settings:
* CODESHIP_API_KEY -- get it from https://codeship.com/user/edit
* CODESHIP_REPO_NAME -- the full name of the repository to watch
ex: myorganization/repository-name
* CODESHIP_POLLING_INTERVAL -- how often to poll for updates. defaults to 60 seconds
"""
import os
import signal
import subprocess
import sys
from time import sleep
import requests
API_KEY = os.environ.get('CODESHIP_API_KEY')
REPOSITORY_NAME = os.environ.get('CODESHIP_REPO_NAME')
POLLING_INTERVAL = os.environ.get('CODESHIP_POLLING_INTERVAL', 60) # in seconds
CODESHIP_PROJECTS_URL = 'https://codeship.com/api/v1/projects.json?api_key={}'.format(API_KEY)
def signal_handler(*args):
print 'Goodbye!'
sys.exit(0)
def send_notification(title, message, url):
subprocess.call(['terminal-notifier', '-title', title, '-message', message, '-open', url])
class BuildCache(object):
def __init__(self, project_id, project_name, *args, **kwargs):
self.project_id = project_id
self.project_name = project_name
self._cache = {}
def process_update(self, build_data):
"""
Process the build_data from the Codeship project endpoint to
determine which actions need to occur.
"""
for build in build_data:
build_id = build['id']
build_url = 'https://codeship.com/projects/{}/builds/{}'.format(
self.project_id, build_id)
if build_id not in self._cache and build['status'] == 'testing':
send_notification(self.project_name, 'A build was started for {} ({})'.format(
build['branch'], build['message'][:100]), build_url)
self._cache[build_id] = build
if build['id'] in self._cache:
if build['status'] == 'success':
send_notification(self.project_name, 'A build for {} succeeded!'.format(
build['branch']), build_url)
del self._cache[build_id]
elif build['status'] == 'error':
send_notification(self.project_name, 'A build for {} *failed*.'.format(
build['branch']), build_url)
del self._cache[build_id]
r = requests.get(CODESHIP_PROJECTS_URL)
if r.status_code != 200:
sys.exit('Ensure you have provided a valid Codeship API key.')
project = None
repo_info = r.json()
for p in repo_info['projects']:
if p['repository_name'] == REPOSITORY_NAME:
project = p
break
if project is None:
sys.exit('Ensure you have provided a valid repository name.')
project_id = project['id']
project_url = 'https://codeship.com/api/v1/projects/{}.json?api_key={}'.format(
project['id'], API_KEY)
cache = BuildCache(project_id, REPOSITORY_NAME)
print 'Watching for notifications for {}. Press ctrl+c to exit...'.format(REPOSITORY_NAME)
signal.signal(signal.SIGINT, signal_handler)
while True:
r = requests.get(project_url)
if r.status_code != 200:
sys.exit('Received a non-200 status code from project URL: {} - {}'.format(r.status_code, r.text))
data = r.json()
cache.process_update(data['builds'])
sleep(POLLING_INTERVAL)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment