Package buildbot :: Package status :: Package web :: Package hooks :: Module github
[frames] | no frames]

Source Code for Module buildbot.status.web.hooks.github

  1  #!/usr/bin/env python 
  2  """ 
  3  github_buildbot.py is based on git_buildbot.py 
  4   
  5  github_buildbot.py will determine the repository information from the JSON  
  6  HTTP POST it receives from github.com and build the appropriate repository. 
  7  If your github repository is private, you must add a ssh key to the github 
  8  repository for the user who initiated the build on the buildslave. 
  9   
 10  """ 
 11   
 12  import tempfile 
 13  import logging 
 14  import re 
 15  import sys 
 16  import traceback 
 17  from twisted.web import server, resource 
 18  from twisted.internet import reactor 
 19  from twisted.spread import pb 
 20  from twisted.cred import credentials 
 21  from optparse import OptionParser 
 22  from buildbot.changes.changes import Change 
 23  import datetime 
 24  import time 
 25  from twisted.python import log 
 26  import calendar 
 27  import time 
 28  import calendar 
 29  import datetime 
 30  import re 
 31   
 32  try: 
 33      import json 
 34  except ImportError: 
 35      import simplejson as json 
 36   
 37  # python is silly about how it handles timezones 
38 -class fixedOffset(datetime.tzinfo):
39 """ 40 fixed offset timezone 41 """
42 - def __init__(self, minutes, hours, offsetSign = 1):
43 self.minutes = int(minutes) * offsetSign 44 self.hours = int(hours) * offsetSign 45 self.offset = datetime.timedelta(minutes = self.minutes, 46 hours = self.hours)
47
48 - def utcoffset(self, dt):
49 return self.offset
50
51 - def dst(self, dt):
52 return datetime.timedelta(0)
53
54 -def convertTime(myTestTimestamp):
55 #"1970-01-01T00:00:00+00:00" 56 matcher = re.compile(r'(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)([-+])(\d\d):(\d\d)') 57 result = matcher.match(myTestTimestamp) 58 (year, month, day, hour, minute, second, offsetsign, houroffset, minoffset) = \ 59 result.groups() 60 if offsetsign == '+': 61 offsetsign = 1 62 else: 63 offsetsign = -1 64 65 offsetTimezone = fixedOffset( minoffset, houroffset, offsetsign ) 66 myDatetime = datetime.datetime( int(year), 67 int(month), 68 int(day), 69 int(hour), 70 int(minute), 71 int(second), 72 0, 73 offsetTimezone) 74 return calendar.timegm( myDatetime.utctimetuple() )
75
76 -def getChanges(request, options = None):
77 """ 78 Reponds only to POST events and starts the build process 79 80 :arguments: 81 request 82 the http request object 83 """ 84 try: 85 payload = json.loads(request.args['payload'][0]) 86 user = payload['repository']['owner']['name'] 87 repo = payload['repository']['name'] 88 repo_url = payload['repository']['url'] 89 private = payload['repository']['private'] 90 changes = process_change(payload, user, repo, repo_url) 91 log.msg("Received %s changes from github" % len(changes)) 92 return changes 93 except Exception: 94 logging.error("Encountered an exception:") 95 for msg in traceback.format_exception(*sys.exc_info()): 96 logging.error(msg.strip())
97
98 -def process_change(payload, user, repo, repo_url):
99 """ 100 Consumes the JSON as a python object and actually starts the build. 101 102 :arguments: 103 payload 104 Python Object that represents the JSON sent by GitHub Service 105 Hook. 106 """ 107 changes = [] 108 newrev = payload['after'] 109 refname = payload['ref'] 110 log.msg( "in process_change" ) 111 # We only care about regular heads, i.e. branches 112 match = re.match(r"^refs\/heads\/(.+)$", refname) 113 if not match: 114 logging.info("Ignoring refname `%s': Not a branch" % refname) 115 116 branch = match.group(1) 117 if re.match(r"^0*$", newrev): 118 log.msg("Branch `%s' deleted, ignoring" % branch) 119 return [] 120 else: 121 for commit in payload['commits']: 122 files = [] 123 if 'added' in commit: 124 files.extend(commit['added']) 125 if 'modified' in commit: 126 files.extend(commit['modified']) 127 if 'removed' in commit: 128 files.extend(commit['removed']) 129 when = convertTime( commit['timestamp']) 130 change = {'revision': commit['id'], 131 'revlink': commit['url'], 132 'comments': commit['message'], 133 'branch': branch, 134 'who': commit['author']['name'] 135 + " <" + commit['author']['email'] + ">", 136 'files': files, 137 'links': [commit['url']], 138 'properties': {'repository': repo_url}, 139 } 140 141 log.msg("New revision: %s" % change['revision'][:8]) 142 for key, value in change.iteritems(): 143 logging.debug(" %s: %s" % (key, value)) 144 changeObject = Change(\ 145 who = commit['author']['name'] 146 + " <" + commit['author']['email'] + ">", 147 files = files, 148 comments = commit['message'], 149 links = [commit['url']], 150 revision = commit['id'], 151 when = when, 152 branch = branch, 153 revlink = commit['url'], 154 repository = repo_url) 155 changes.append(changeObject) 156 return changes
157