-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add generic hooks interface for HTTP change notifications
Includes a github implementation, with room to add others * 'master' of git://github.com/PerilousApricot/buildbot: (69 commits) removing enable_change_hook making some changes from djmitche removing dummy folder removing .project removing debug prints more typos fix more timestamp munging force UTC unbomb github change hook. looks like the timestamp conversion is correct more debugging match parens get types right on times getting some better when info times are integers debug more logging strip out correct time raise after we run the fun part incresing verbosity ...
- Loading branch information
Showing
8 changed files
with
405 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# code inspired/copied from contrib/github_buildbot | ||
# and inspired from code from the Chromium project | ||
# otherwise, Andrew Melo <andrew.melo@gmail.com> wrote the rest | ||
|
||
# but "the rest" is pretty minimal | ||
from twisted.web import resource | ||
from buildbot.status.builder import FAILURE | ||
import re | ||
from buildbot import util, interfaces | ||
import traceback | ||
import sys | ||
from buildbot.process.properties import Properties | ||
from buildbot.changes.changes import Change | ||
from twisted.python.reflect import namedModule | ||
from twisted.python.log import msg,err | ||
|
||
class ChangeHookResource(resource.Resource): | ||
# this is a cheap sort of template thingy | ||
contentType = "text/html; charset=utf-8" | ||
children = {} | ||
def __init__(self, dialects={}): | ||
self.dialects = dialects | ||
|
||
def getChild(self, name, request): | ||
return self | ||
|
||
def render_GET(self, request): | ||
""" | ||
Reponds to events and starts the build process | ||
different implementations can decide on what methods they will accept | ||
""" | ||
self.render_POST(request) | ||
|
||
def render_POST(self, request): | ||
""" | ||
Reponds to events and starts the build process | ||
different implementations can decide on what methods they will accept | ||
:arguments: | ||
request | ||
the http request object | ||
""" | ||
|
||
changes = self.getChanges( request ) | ||
msg("Payload: " + str(request.args)) | ||
|
||
if not changes: | ||
msg("No changes found") | ||
return | ||
self.submitChanges( changes, request ) | ||
return "changes %s" % changes | ||
|
||
|
||
def getChanges(self, request): | ||
""" | ||
Take the logic from the change hook, and then delegate it | ||
to the proper handler | ||
http://localhost/change_hook/DIALECT will load up | ||
buildmaster/status/web/hooks/DIALECT.py | ||
and call getChanges() | ||
the return value is a list of changes | ||
if DIALECT is unspecified, a sample implementation is provided | ||
""" | ||
uriRE = re.search(r'^/change_hook/?([a-zA-Z0-9_]*)', request.uri) | ||
|
||
if not uriRE: | ||
msg("URI doesn't match change_hook regex: %s" % request.uri) | ||
return | ||
|
||
changes = [] | ||
|
||
# Was there a dialect provided? | ||
if uriRE.group(1): | ||
dialect = uriRE.group(1) | ||
else: | ||
dialect = 'base' | ||
|
||
if dialect in self.dialects.keys(): | ||
# try: | ||
# note, this should be safe, only alphanumerics and _ are | ||
# allowed in the dialect name | ||
msg("Attempting to load module buildbot.status.web.hooks" + dialect) | ||
tempModule = namedModule('buildbot.status.web.hooks.' + dialect) | ||
changes = tempModule.getChanges(request,self.dialects[dialect]) | ||
msg("Got the following changes %s" % changes) | ||
# except: | ||
# err("Encountered an exception in change_hook:") | ||
else: | ||
msg("The dialect specified %s wasn't whitelisted in change_hook" % dialect) | ||
msg("Note: if dialect is 'base' then it's possible your URL is malformed and we didn't regex it properly") | ||
|
||
return changes | ||
|
||
def submitChanges(self, changes, request): | ||
# get a control object | ||
changeMaster = request.site.buildbot_service.master.change_svc | ||
for onechange in changes: | ||
msg("injecting change %s" % onechange) | ||
changeMaster.addChange( onechange ) | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# code inspired/copied from contrib/github_buildbot | ||
# and inspired from code from the Chromium project | ||
# otherwise, Andrew Melo <andrew.melo@gmail.com> wrote the rest | ||
|
||
# but "the rest" is pretty minimal | ||
from twisted.web import resource | ||
from buildbot.status.builder import FAILURE | ||
import re | ||
from buildbot import util, interfaces | ||
import logging | ||
import traceback | ||
import sys | ||
from buildbot.process.properties import Properties | ||
from buildbot.changes.changes import Change | ||
from twisted.python.reflect import namedModule | ||
from buildbot.util import json | ||
|
||
def getChanges(self, request): | ||
""" | ||
Consumes a naive build notification (the default for now) | ||
basically, set POST variables to match commit object parameters: | ||
revision, revlink, comments, branch, who, files, links | ||
files and links will be de-json'd, the rest are interpreted as strings | ||
""" | ||
|
||
def firstOrNothing( value ): | ||
""" | ||
Small helper function to return the first value (if value is a list) | ||
or return the whole thing otherwise | ||
""" | ||
if ( type(value) == type([])): | ||
return value[0] | ||
else: | ||
return value | ||
|
||
args = request.args | ||
|
||
# first, convert files and links | ||
files = None | ||
if args.get('files'): | ||
files = json.loads( args.get('files')[0] ) | ||
else: | ||
files = [] | ||
|
||
links = None | ||
if args.get('links'): | ||
links = json.loads( args.get('links')[0] ) | ||
else: | ||
links = [] | ||
|
||
revision = firstOrNothing(args.get('revision')) | ||
when = firstOrNothing(args.get('when')) | ||
who = firstOrNothing(args.get('who')) | ||
comments = firstOrNothing(args.get('comments')) | ||
isdir = firstOrNothing(args.get('isdir',0)) | ||
branch = firstOrNothing(args.get('branch')) | ||
category = firstOrNothing(args.get('category')) | ||
revlink = firstOrNothing(args.get('revlink')) | ||
properties = Properties() | ||
# properties.update(properties, "Change") | ||
repository = firstOrNothing(args.get('repository')) | ||
project = firstOrNothing(args.get('project')) | ||
|
||
ourchange = Change(who = who, files = files, comments = comments, isdir = isdir, links = links, | ||
revision=revision, when = when, branch = branch, category = category, | ||
revlink = revlink, repository = repository, project = project) | ||
return [ourchange] | ||
|
||
|
||
|
Oops, something went wrong.