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

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

  1  # This file is part of Buildbot.  Buildbot is free software: you can 
  2  # redistribute it and/or modify it under the terms of the GNU General Public 
  3  # License as published by the Free Software Foundation, version 2. 
  4  # 
  5  # This program is distributed in the hope that it will be useful, but WITHOUT 
  6  # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  8  # details. 
  9  # 
 10  # You should have received a copy of the GNU General Public License along with 
 11  # this program; if not, write to the Free Software Foundation, Inc., 51 
 12  # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 13  # 
 14  # Copyright Buildbot Team Members 
 15   
 16  #!/usr/bin/env python 
 17  """ 
 18  github_buildbot.py is based on git_buildbot.py 
 19   
 20  github_buildbot.py will determine the repository information from the JSON  
 21  HTTP POST it receives from github.com and build the appropriate repository. 
 22  If your github repository is private, you must add a ssh key to the github 
 23  repository for the user who initiated the build on the buildslave. 
 24   
 25  """ 
 26   
 27  import logging 
 28  import re 
 29  import sys 
 30  import traceback 
 31  import datetime 
 32  from twisted.python import log 
 33  import calendar 
 34   
 35  try: 
 36      import json 
 37      assert json 
 38  except ImportError: 
 39      import simplejson as json 
 40   
 41  # python is silly about how it handles timezones 
42 -class fixedOffset(datetime.tzinfo):
43 """ 44 fixed offset timezone 45 """
46 - def __init__(self, minutes, hours, offsetSign = 1):
47 self.minutes = int(minutes) * offsetSign 48 self.hours = int(hours) * offsetSign 49 self.offset = datetime.timedelta(minutes = self.minutes, 50 hours = self.hours)
51
52 - def utcoffset(self, dt):
53 return self.offset
54
55 - def dst(self, dt):
56 return datetime.timedelta(0)
57
58 -def convertTime(myTestTimestamp):
59 #"1970-01-01T00:00:00+00:00" 60 matcher = re.compile(r'(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)([-+])(\d\d):(\d\d)') 61 result = matcher.match(myTestTimestamp) 62 (year, month, day, hour, minute, second, offsetsign, houroffset, minoffset) = \ 63 result.groups() 64 if offsetsign == '+': 65 offsetsign = 1 66 else: 67 offsetsign = -1 68 69 offsetTimezone = fixedOffset( minoffset, houroffset, offsetsign ) 70 myDatetime = datetime.datetime( int(year), 71 int(month), 72 int(day), 73 int(hour), 74 int(minute), 75 int(second), 76 0, 77 offsetTimezone) 78 return calendar.timegm( myDatetime.utctimetuple() )
79
80 -def getChanges(request, options = None):
81 """ 82 Reponds only to POST events and starts the build process 83 84 :arguments: 85 request 86 the http request object 87 """ 88 try: 89 payload = json.loads(request.args['payload'][0]) 90 user = payload['repository']['owner']['name'] 91 repo = payload['repository']['name'] 92 repo_url = payload['repository']['url'] 93 project = request.args.get('project', None) 94 if project: 95 project = project[0] 96 elif project is None: 97 project = '' 98 # This field is unused: 99 #private = payload['repository']['private'] 100 changes = process_change(payload, user, repo, repo_url, project) 101 log.msg("Received %s changes from github" % len(changes)) 102 return changes 103 except Exception: 104 logging.error("Encountered an exception:") 105 for msg in traceback.format_exception(*sys.exc_info()): 106 logging.error(msg.strip())
107
108 -def process_change(payload, user, repo, repo_url, project):
109 """ 110 Consumes the JSON as a python object and actually starts the build. 111 112 :arguments: 113 payload 114 Python Object that represents the JSON sent by GitHub Service 115 Hook. 116 """ 117 changes = [] 118 newrev = payload['after'] 119 refname = payload['ref'] 120 log.msg( "in process_change" ) 121 # We only care about regular heads, i.e. branches 122 match = re.match(r"^refs\/heads\/(.+)$", refname) 123 if not match: 124 logging.info("Ignoring refname `%s': Not a branch" % refname) 125 126 branch = match.group(1) 127 if re.match(r"^0*$", newrev): 128 log.msg("Branch `%s' deleted, ignoring" % branch) 129 return [] 130 else: 131 for commit in payload['commits']: 132 files = [] 133 if 'added' in commit: 134 files.extend(commit['added']) 135 if 'modified' in commit: 136 files.extend(commit['modified']) 137 if 'removed' in commit: 138 files.extend(commit['removed']) 139 when = convertTime( commit['timestamp']) 140 log.msg("New revision: %s" % commit['id'][:8]) 141 chdict = dict( 142 who = commit['author']['name'] 143 + " <" + commit['author']['email'] + ">", 144 files = files, 145 comments = commit['message'], 146 links = [commit['url']], 147 revision = commit['id'], 148 when = when, 149 branch = branch, 150 revlink = commit['url'], 151 repository = repo_url, 152 project = project) 153 changes.append(chdict) 154 return changes
155