Skip to content

Commit

Permalink
add ref_deleted event and support tag events
Browse files Browse the repository at this point in the history
  • Loading branch information
EmilioPeJu committed Jun 23, 2017
1 parent 063ec56 commit a0bfa2e
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 36 deletions.
112 changes: 90 additions & 22 deletions master/buildbot/test/unit/test_www_hooks_bitbucketserver.py
Expand Up @@ -542,7 +542,7 @@
"name": "1.0.0",
"target": {
"type": "commit",
"hash": "8eecf59b93ba4fd8d6bb578f6632fc3f5994d331"
"hash": "793d4754230023d85532f9a38dba3290f959beb4"
}
},
"new": null
Expand All @@ -561,14 +561,14 @@
"repository": {
"scmId": "git",
"project": {
"key": "BUIL",
"name": "buildbot"
"key": "CI",
"name": "Continuous Integration"
},
"slug": "py-repo",
"links": {
"self": [
{
"href": "http://localhost:7990/projects/BUIL/repos/py-repo/browse"
"href": "http://localhost:7990/projects/CI/repos/py-repo/browse"
}
]
},
Expand All @@ -590,7 +590,7 @@
"name": "branch_1496758965",
"target": {
"type": "commit",
"hash": "8eecf59b93ba4fd8d6bb578f6632fc3f5994d331"
"hash": "793d4754230023d85532f9a38dba3290f959beb4"
}
},
"new": null
Expand All @@ -600,6 +600,54 @@
}
"""

newTagJsonPayload = u"""
{
"actor": {
"username": "John",
"displayName": "John Smith"
},
"repository": {
"scmId": "git",
"project": {
"key": "CI",
"name": "Continuous Integration"
},
"slug": "py-repo",
"links": {
"self": [
{
"href": "http://localhost:7990/projects/CI/repos/py-repo/browse"
}
]
},
"public": false,
"ownerName": "CI",
"owner": {
"username": "CI",
"displayName": "CI"
},
"fullName": "CI/py-repo"
},
"push": {
"changes": [
{
"created": true,
"closed": false,
"old": null,
"new": {
"type": "tag",
"name": "1.0.0",
"target": {
"type": "commit",
"hash": "793d4754230023d85532f9a38dba3290f959beb4"
}
}
}
]
}
}
"""


def _prepare_request(payload, headers=None, change_dict=None):
headers = headers or {}
Expand All @@ -614,24 +662,11 @@ def _prepare_request(payload, headers=None, change_dict=None):

class TestChangeHookConfiguredWithGitChange(unittest.TestCase):

"""Unit tests for Bitbucket Server Change Hook
"""

def setUp(self):
self.change_hook = change_hook.ChangeHookResource(
dialects={'bitbucketserver': {}}, master=fakeMasterForHooks())

@defer.inlineCallbacks
def testHookWithChangeOnPushEvent(self):

request = _prepare_request(
pushJsonPayload,
headers={_HEADER_EVENT: 'repo:push'})

yield request.test_render(self.change_hook)

self.assertEqual(len(self.change_hook.master.addedChanges), 1)
change = self.change_hook.master.addedChanges[0]
def _checkPush(self, change):
self.assertEqual(
change['repository'],
'http://localhost:7990/projects/CI/repos/py-repo/')
Expand All @@ -642,11 +677,24 @@ def testHookWithChangeOnPushEvent(self):
self.assertEqual(
change['comments'], 'Bitbucket Server commit '
'793d4754230023d85532f9a38dba3290f959beb4')
self.assertEqual(change['branch'], 'refs/heads/branch_1496411680')
self.assertEqual(
change['revlink'],
'http://localhost:7990/projects/CI/repos/py-repo/commits/'
'793d4754230023d85532f9a38dba3290f959beb4')

@defer.inlineCallbacks
def testHookWithChangeOnPushEvent(self):

request = _prepare_request(
pushJsonPayload,
headers={_HEADER_EVENT: 'repo:push'})

yield request.test_render(self.change_hook)

self.assertEqual(len(self.change_hook.master.addedChanges), 1)
change = self.change_hook.master.addedChanges[0]
self._checkPush(change)
self.assertEqual(change['branch'], 'refs/heads/branch_1496411680')
self.assertEqual(change['category'], 'push')

def _checkPullRequest(self, change):
Expand Down Expand Up @@ -773,21 +821,41 @@ def testHookWithUnhandledEvent(self):
self.assertEqual(len(self.change_hook.master.addedChanges), 0)
self.assertEqual(request.written, "Unknown event: invented_event")

@defer.inlineCallbacks
def testHookWithChangeOnCreateTag(self):
request = _prepare_request(
newTagJsonPayload,
headers={_HEADER_EVENT: 'repo:push'})
yield request.test_render(self.change_hook)
self.assertEqual(len(self.change_hook.master.addedChanges), 1)
change = self.change_hook.master.addedChanges[0]
self._checkPush(change)
self.assertEqual(change['branch'], 'refs/tags/1.0.0')
self.assertEqual(change['category'], 'push')

@defer.inlineCallbacks
def testHookWithChangeOnDeleteTag(self):
request = _prepare_request(
deleteTagJsonPayload,
headers={_HEADER_EVENT: 'repo:push'})
yield request.test_render(self.change_hook)
self.assertEqual(len(self.change_hook.master.addedChanges), 0)
self.assertEqual(len(self.change_hook.master.addedChanges), 1)
change = self.change_hook.master.addedChanges[0]
self._checkPush(change)
self.assertEqual(change['branch'], 'refs/tags/1.0.0')
self.assertEqual(change['category'], 'ref-deleted')

@defer.inlineCallbacks
def testHookWithChangeOnDeleteBranch(self):
request = _prepare_request(
deleteBranchJsonPayload,
headers={_HEADER_EVENT: 'repo:push'})
yield request.test_render(self.change_hook)
self.assertEqual(len(self.change_hook.master.addedChanges), 0)
self.assertEqual(len(self.change_hook.master.addedChanges), 1)
change = self.change_hook.master.addedChanges[0]
self._checkPush(change)
self.assertEqual(change['branch'], 'refs/heads/branch_1496758965')
self.assertEqual(change['category'], 'ref-deleted')

@defer.inlineCallbacks
def testHookWithInvalidContentType(self):
Expand Down
35 changes: 22 additions & 13 deletions master/buildbot/www/hooks/bitbucketserver.py
Expand Up @@ -21,8 +21,9 @@

from twisted.python import log

GIT_BRANCH_REF = "refs/heads/{}"
GIT_MERGE_REF = "refs/pull-requests/{}/merge"
GIT_HEAD_REF = "refs/heads/{}"
GIT_TAG_REF = "refs/tags/{}"

_HEADER_EVENT = 'X-Event-Key'

Expand Down Expand Up @@ -68,22 +69,30 @@ def handle_repo_push(self, payload):
repo_url = repo_url.rstrip('browse')

for payload_change in payload['push']['changes']:
if not payload_change['new']:
# skip change if deleting a tag or a branch
continue
if payload_change['new']:
age = 'new'
category = 'push'
else: # when new is null the ref is deleted
age = 'old'
category = 'ref-deleted'

commit_hash = payload_change[age]['target']['hash']

if payload_change[age]['type'] == 'branch':
branch = GIT_BRANCH_REF.format(payload_change[age]['name'])
elif payload_change[age]['type'] == 'tag':
branch = GIT_TAG_REF.format(payload_change[age]['name'])

change = {
'revision': payload_change['new']['target']['hash'],
'revlink': '{}commits/{}'.format(
repo_url, payload_change['new']['target']['hash']),
'revision': commit_hash,
'revlink': '{}commits/{}'.format(repo_url, commit_hash),
'repository': repo_url,
'author': '{} <{}>'.format(payload['actor']['displayName'],
payload['actor']['username']),
'comments': 'Bitbucket Server commit {}'.format(
payload_change['new']['target']['hash']),
'branch': GIT_HEAD_REF.format(payload_change['new']['name']),
'comments': 'Bitbucket Server commit {}'.format(commit_hash),
'branch': branch,
'project': project,
'category': 'push'
'category': category
}

if callable(self._codebase):
Expand All @@ -110,14 +119,14 @@ def handle_pullrequest_updated(self, payload):
def handle_pullrequest_fulfilled(self, payload):
return self.handle_pullrequest(
payload,
GIT_HEAD_REF.format(
GIT_BRANCH_REF.format(
payload['pullrequest']['toRef']['branch']['name']),
"pull-fulfilled")

def handle_pullrequest_rejected(self, payload):
return self.handle_pullrequest(
payload,
GIT_HEAD_REF.format(
GIT_BRANCH_REF.format(
payload['pullrequest']['fromRef']['branch']['name']),
"pull-rejected")

Expand Down
2 changes: 1 addition & 1 deletion master/docs/manual/cfg-wwwhooks.rst
Expand Up @@ -209,7 +209,7 @@ Bitbucket Server hook
When this is setup you should add a webhook pointing to ``/change_hook/bitbucketserver`` relative to the root of the web status.

According to the type of the event, the change category is set to ``push``, ``pull-created``, ``pull-rejected``, ``pull-updated`` or ``pull-fulfilled``.
According to the type of the event, the change category is set to ``push``, ``pull-created``, ``pull-rejected``, ``pull-updated``, ``pull-fulfilled`` or ``ref-deleted``.

The Bitbucket Server hook may have the following optional parameters:

Expand Down

0 comments on commit a0bfa2e

Please sign in to comment.