1   
  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   
 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   
 50   
 52          return datetime.timedelta(0) 
   53       
 55       
 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   
 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   
 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           
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