1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
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
55
57 return datetime.timedelta(0)
58
60
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
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
95
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
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
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