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