Skip to content

Commit

Permalink
Merge pull request #1632 from esben/github-pr
Browse files Browse the repository at this point in the history
Add pull_request support for github change hook handler
  • Loading branch information
Mikhail Sobolev committed Apr 15, 2015
2 parents 1571f39 + f9b7dd6 commit f9cddec
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 1 deletion.
37 changes: 37 additions & 0 deletions master/buildbot/status/web/hooks/github.py
Expand Up @@ -111,6 +111,43 @@ def handle_push(self, payload):

return changes, 'git'

def handle_pull_request(self, payload):
changes = []
number = payload['number']
refname = 'refs/pull/%d/head' % (number,)
commits = payload['pull_request']['commits']

log.msg('Processing GitHub PR #%d' % number, logLevel=logging.DEBUG)

action = payload.get('action')
if action not in ('opened', 'reopened', 'synchronize'):
log.msg("GitHub PR #%d %s, ignoring" % (number, action))
return changes, 'git'

change = {
'revision': payload['pull_request']['head']['sha'],
'when_timestamp': dateparse(payload['pull_request']['created_at']),
'branch': refname,
'revlink': payload['pull_request']['_links']['html']['href'],
'repository': payload['repository']['clone_url'],
'category': 'pull',
# TODO: Get author name based on login id using txgithub module
'author': payload['sender']['login'],
'comments': 'GitHub Pull Request #%d (%d commit%s)' % (
number, commits, 's' if commits != 1 else ''),
}

if callable(self._codebase):
change['codebase'] = self._codebase(payload)
elif self._codebase is not None:
change['codebase'] = self._codebase

changes.append(change)

log.msg("Received %d changes from GitHub PR #%d" % (
len(changes), number))
return changes, 'git'

def _process_change(self, payload, user, repo, repo_url, project):
"""
Consumes the JSON as a python object and actually starts the build.
Expand Down
151 changes: 151 additions & 0 deletions master/buildbot/test/unit/test_status_web_hooks_github.py
Expand Up @@ -115,6 +115,131 @@
}
"""

gitJsonPayloadPullRequest = """
{
"action": "opened",
"number": 50,
"pull_request": {
"url": "https://api.github.com/repos/defunkt/github/pulls/50",
"html_url": "https://github.com/defunkt/github/pull/50",
"number": 50,
"state": "open",
"title": "Update the README with new information",
"user": {
"login": "defunkt",
"id": 42,
"type": "User"
},
"body": "This is a pretty simple change that we need to pull into master.",
"created_at": "2014-10-10T00:09:50Z",
"updated_at": "2014-10-10T00:09:50Z",
"closed_at": null,
"merged_at": null,
"merge_commit_sha": "cd3ff078a350901f91f4c4036be74f91d0b0d5d6",
"head": {
"label": "defunkt:changes",
"ref": "changes",
"sha": "05c588ba8cd510ecbe112d020f215facb17817a7",
"user": {
"login": "defunkt",
"id": 42,
"type": "User"
},
"repo": {
"id": 43,
"name": "github",
"full_name": "defunkt/github",
"owner": {
"login": "defunkt",
"id": 42,
"type": "User"
},
"html_url": "https://github.com/defunkt/github",
"description": "",
"url": "https://api.github.com/repos/defunkt/github",
"created_at": "2014-05-20T22:39:43Z",
"updated_at": "2014-07-25T16:37:51Z",
"pushed_at": "2014-10-10T00:09:49Z",
"git_url": "git://github.com/defunkt/github.git",
"ssh_url": "git@github.com:defunkt/github.git",
"clone_url": "https://github.com/defunkt/github.git",
"default_branch": "master"
}
},
"base": {
"label": "defunkt:master",
"ref": "master",
"sha": "69a8b72e2d3d955075d47f03d902929dcaf74034",
"user": {
"login": "defunkt",
"id": 42,
"type": "User"
},
"repo": {
"id": 43,
"name": "github",
"full_name": "defunkt/github",
"owner": {
"login": "defunkt",
"id": 42,
"type": "User"
},
"html_url": "https://github.com/defunkt/github",
"description": "",
"url": "https://api.github.com/repos/defunkt/github",
"created_at": "2014-05-20T22:39:43Z",
"updated_at": "2014-07-25T16:37:51Z",
"pushed_at": "2014-10-10T00:09:49Z",
"git_url": "git://github.com/defunkt/github.git",
"ssh_url": "git@github.com:defunkt/github.git",
"clone_url": "https://github.com/defunkt/github.git",
"default_branch": "master"
}
},
"_links": {
"self": {
"href": "https://api.github.com/repos/defunkt/github/pulls/50"
},
"html": {
"href": "https://github.com/defunkt/github/pull/50"
},
"commits": {
"href": "https://api.github.com/repos/defunkt/github/pulls/50/commits"
}
},
"commits": 1,
"additions": 2,
"deletions": 0,
"changed_files": 1
},
"repository": {
"id": 43,
"name": "github",
"full_name": "defunkt/github",
"owner": {
"login": "defunkt",
"id": 42,
"type": "User"
},
"html_url": "https://github.com/defunkt/github",
"description": "",
"url": "https://api.github.com/repos/defunkt/github",
"created_at": "2014-05-20T22:39:43Z",
"updated_at": "2014-07-25T16:37:51Z",
"pushed_at": "2014-10-10T00:09:49Z",
"git_url": "git://github.com/defunkt/github.git",
"ssh_url": "git@github.com:defunkt/github.git",
"clone_url": "https://github.com/defunkt/github.git",
"default_branch": "master"
},
"sender": {
"login": "defunkt",
"id": 42,
"type": "User"
}
}
"""

gitJsonPayloadEmpty = """
{
"before": "5aef35982fb2d34e9d9d4502f6ede1072793222d",
Expand Down Expand Up @@ -382,6 +507,32 @@ def test_git_with_non_branch_changes_encoded(self):
def test_git_with_non_branch_changes_json(self):
self._check_git_with_non_branch_changes(gitJsonPayloadNonBranch)

@defer.inlineCallbacks
def _check_git_with_pull(self, payload):
self.request = _prepare_request('pull_request', payload)
yield self.request.test_render(self.changeHook)
self.assertEquals(len(self.request.addedChanges), 1)
change = self.request.addedChanges[0]
self.assertEquals(change["repository"],
"https://github.com/defunkt/github.git")
self.assertEquals(timegm(change["when_timestamp"].utctimetuple()),
1412899790)
self.assertEquals(change["author"],
"defunkt")
self.assertEquals(change["revision"],
'05c588ba8cd510ecbe112d020f215facb17817a7')
self.assertEquals(change["comments"],
"GitHub Pull Request #50 (1 commit)")
self.assertEquals(change["branch"], "refs/pull/50/head")
self.assertEquals(change["revlink"],
"https://github.com/defunkt/github/pull/50")

def test_git_with_pull_encoded(self):
self._check_git_with_pull([gitJsonPayloadPullRequest])

def test_git_with_pull_json(self):
self._check_git_with_pull(gitJsonPayloadPullRequest)


class TestChangeHookConfiguredWithStrict(unittest.TestCase):

Expand Down
2 changes: 1 addition & 1 deletion master/docs/manual/cfg-statustargets.rst
Expand Up @@ -607,7 +607,7 @@ The GitHub hook has the following parameters:
``class`` (default `None`)
A class to be used for processing incoming payloads.
If the value is `None` (default), the default class -- :py:class:`buildbot.status.web.hooks.github.GitHubEventHandler` -- will be used.
The default class handles `ping` and `push` events only.
The default class handles `ping`, `push` and `pull_request` events only.
If you'd like to handle other events (see `Event Types & Payloads <https://developer.github.com/v3/activity/events/types/>`_ for more information), you'd need to subclass `GitHubEventHandler` and add handler methods for the corresponding events.
For example, if you'd like to handle `blah` events, your code should look something like this::

Expand Down
2 changes: 2 additions & 0 deletions master/docs/relnotes/index.rst
Expand Up @@ -89,6 +89,8 @@ Features

* GitHub change hook now supports function as codebase argument.

* GitHub change hook now supports pull_request events.

Fixes
~~~~~

Expand Down

0 comments on commit f9cddec

Please sign in to comment.