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