Merge pull request #2359 from coreos-inc/fix-gitlab-tag
Fix handling of gitlab web hooks when tagging
This commit is contained in:
commit
c8e5eb5ad1
4 changed files with 154 additions and 13 deletions
|
@ -82,7 +82,8 @@ def _catch_timeouts(func):
|
|||
return wrapper
|
||||
|
||||
|
||||
def get_transformed_webhook_payload(gl_payload, default_branch=None, lookup_user=None):
|
||||
def get_transformed_webhook_payload(gl_payload, default_branch=None, lookup_user=None,
|
||||
lookup_commit=None):
|
||||
""" Returns the Gitlab webhook JSON payload transformed into our own payload
|
||||
format. If the gl_payload is not valid, returns None.
|
||||
"""
|
||||
|
@ -93,9 +94,13 @@ def get_transformed_webhook_payload(gl_payload, default_branch=None, lookup_user
|
|||
|
||||
payload = JSONPathDict(gl_payload)
|
||||
|
||||
if payload['object_kind'] != 'push' and payload['object_kind'] != 'tag_push':
|
||||
# Unknown kind of webhook.
|
||||
raise SkipRequestException
|
||||
|
||||
# Check for empty commits. The commits list will be empty if the branch is deleted.
|
||||
commits = payload['commits']
|
||||
if not commits:
|
||||
if payload['object_kind'] == 'push' and not commits:
|
||||
raise SkipRequestException
|
||||
|
||||
config = SafeDictSetter()
|
||||
|
@ -104,16 +109,25 @@ def get_transformed_webhook_payload(gl_payload, default_branch=None, lookup_user
|
|||
config['default_branch'] = default_branch
|
||||
config['git_url'] = payload['repository.git_ssh_url']
|
||||
|
||||
# Find the commit associated with the checkout_sha. Gitlab doesn't (necessary) send this in
|
||||
# any order, so we cannot simply index into the commits list.
|
||||
found_commit = None
|
||||
for commit in commits:
|
||||
if commit['id'] == payload['checkout_sha']:
|
||||
found_commit = JSONPathDict(commit)
|
||||
break
|
||||
found_commit = JSONPathDict({})
|
||||
if payload['object_kind'] == 'push':
|
||||
# Find the commit associated with the checkout_sha. Gitlab doesn't (necessary) send this in
|
||||
# any order, so we cannot simply index into the commits list.
|
||||
found_commit = None
|
||||
for commit in commits:
|
||||
if commit['id'] == payload['checkout_sha']:
|
||||
found_commit = JSONPathDict(commit)
|
||||
break
|
||||
|
||||
if found_commit is None:
|
||||
raise SkipRequestException
|
||||
if found_commit is None:
|
||||
raise SkipRequestException
|
||||
|
||||
elif payload['object_kind'] == 'tag_push':
|
||||
# Gitlab doesn't send commit information for tag pushes (WHY?!), so we need to lookup the
|
||||
# commit SHA directly.
|
||||
if lookup_commit:
|
||||
found_commit_info = lookup_commit(payload['project_id'], payload['checkout_sha'])
|
||||
found_commit = JSONPathDict(found_commit_info or {})
|
||||
|
||||
config['commit_info.url'] = found_commit['url']
|
||||
config['commit_info.message'] = found_commit['message']
|
||||
|
@ -121,7 +135,7 @@ def get_transformed_webhook_payload(gl_payload, default_branch=None, lookup_user
|
|||
|
||||
# Note: Gitlab does not send full user information with the payload, so we have to
|
||||
# (optionally) look it up.
|
||||
author_email = found_commit['author.email']
|
||||
author_email = found_commit['author.email'] or found_commit['author_email']
|
||||
if lookup_user and author_email:
|
||||
author_info = lookup_user(author_email)
|
||||
if author_info:
|
||||
|
@ -333,6 +347,18 @@ class GitLabBuildTrigger(BuildTriggerHandler):
|
|||
def get_repository_url(self):
|
||||
return gitlab_trigger.get_public_url(self.config['build_source'])
|
||||
|
||||
@_catch_timeouts
|
||||
def lookup_commit(self, repo_id, commit_sha):
|
||||
if repo_id is None:
|
||||
return None
|
||||
|
||||
gl_client = self._get_authorized_client()
|
||||
commit = gl_client.getrepositorycommit(repo_id, commit_sha)
|
||||
if commit is False:
|
||||
return None
|
||||
|
||||
return commit
|
||||
|
||||
@_catch_timeouts
|
||||
def lookup_user(self, email):
|
||||
gl_client = self._get_authorized_client()
|
||||
|
@ -441,7 +467,8 @@ class GitLabBuildTrigger(BuildTriggerHandler):
|
|||
|
||||
default_branch = repo['default_branch']
|
||||
metadata = get_transformed_webhook_payload(payload, default_branch=default_branch,
|
||||
lookup_user=self.lookup_user)
|
||||
lookup_user=self.lookup_user,
|
||||
lookup_commit=self.lookup_commit)
|
||||
prepared = self.prepare_build(metadata)
|
||||
|
||||
# Check if we should skip this build.
|
||||
|
|
|
@ -392,6 +392,68 @@ class TestPrepareTrigger(unittest.TestCase):
|
|||
self.assertSchema('gitlab_webhook_multicommit', expected, gl_webhook, lookup_user=lookup_user)
|
||||
|
||||
|
||||
def test_gitlab_webhook_for_tag(self):
|
||||
expected = {
|
||||
'commit': u'82b3d5ae55f7080f1e6022629cdb57bfae7cccc7',
|
||||
'commit_info': {
|
||||
'author': {
|
||||
'avatar_url': 'http://some/avatar/url',
|
||||
'url': 'http://gitlab.com/jzelinskie',
|
||||
'username': 'jzelinskie'
|
||||
},
|
||||
'date': '2015-08-13T19:33:18+00:00',
|
||||
'message': 'Fix link\n',
|
||||
'url': 'https://some/url',
|
||||
},
|
||||
'git_url': u'git@example.com:jsmith/example.git',
|
||||
'ref': u'refs/tags/v1.0.0',
|
||||
}
|
||||
|
||||
def lookup_user(_):
|
||||
return {
|
||||
'username': 'jzelinskie',
|
||||
'html_url': 'http://gitlab.com/jzelinskie',
|
||||
'avatar_url': 'http://some/avatar/url',
|
||||
}
|
||||
|
||||
def lookup_commit(repo_id, commit_sha):
|
||||
if commit_sha == '82b3d5ae55f7080f1e6022629cdb57bfae7cccc7':
|
||||
return {
|
||||
"id": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7",
|
||||
"message": "Fix link\n",
|
||||
"timestamp": "2015-08-13T19:33:18+00:00",
|
||||
"url": "https://some/url",
|
||||
"author_name": "Foo Guy",
|
||||
"author_email": "foo@bar.com",
|
||||
}
|
||||
|
||||
return None
|
||||
|
||||
self.assertSchema('gitlab_webhook_tag', expected, gl_webhook, lookup_user=lookup_user,
|
||||
lookup_commit=lookup_commit)
|
||||
|
||||
|
||||
def test_gitlab_webhook_for_tag_nocommit(self):
|
||||
expected = {
|
||||
'commit': u'82b3d5ae55f7080f1e6022629cdb57bfae7cccc7',
|
||||
'git_url': u'git@example.com:jsmith/example.git',
|
||||
'ref': u'refs/tags/v1.0.0',
|
||||
}
|
||||
|
||||
def lookup_user(_):
|
||||
return {
|
||||
'username': 'jzelinskie',
|
||||
'html_url': 'http://gitlab.com/jzelinskie',
|
||||
'avatar_url': 'http://some/avatar/url',
|
||||
}
|
||||
|
||||
self.assertSchema('gitlab_webhook_tag', expected, gl_webhook, lookup_user=lookup_user)
|
||||
|
||||
|
||||
def test_gitlab_webhook_for_other(self):
|
||||
self.assertSkipped('gitlab_webhook_other', gl_webhook)
|
||||
|
||||
|
||||
def test_gitlab_webhook_payload_with_lookup(self):
|
||||
expected = {
|
||||
'commit': u'fb88379ee45de28a0a4590fddcbd8eff8b36026e',
|
||||
|
|
14
test/triggerjson/gitlab_webhook_other.json
Normal file
14
test/triggerjson/gitlab_webhook_other.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"object_kind": "someother",
|
||||
"ref": "refs/tags/v1.0.0",
|
||||
"checkout_sha": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7",
|
||||
"repository":{
|
||||
"name": "Example",
|
||||
"url": "ssh://git@example.com/jsmith/example.git",
|
||||
"description": "",
|
||||
"homepage": "http://example.com/jsmith/example",
|
||||
"git_http_url":"http://example.com/jsmith/example.git",
|
||||
"git_ssh_url":"git@example.com:jsmith/example.git",
|
||||
"visibility_level":0
|
||||
}
|
||||
}
|
38
test/triggerjson/gitlab_webhook_tag.json
Normal file
38
test/triggerjson/gitlab_webhook_tag.json
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"object_kind": "tag_push",
|
||||
"before": "0000000000000000000000000000000000000000",
|
||||
"after": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7",
|
||||
"ref": "refs/tags/v1.0.0",
|
||||
"checkout_sha": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7",
|
||||
"user_id": 1,
|
||||
"user_name": "John Smith",
|
||||
"user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",
|
||||
"project_id": 1,
|
||||
"project":{
|
||||
"name":"Example",
|
||||
"description":"",
|
||||
"web_url":"http://example.com/jsmith/example",
|
||||
"avatar_url":null,
|
||||
"git_ssh_url":"git@example.com:jsmith/example.git",
|
||||
"git_http_url":"http://example.com/jsmith/example.git",
|
||||
"namespace":"Jsmith",
|
||||
"visibility_level":0,
|
||||
"path_with_namespace":"jsmith/example",
|
||||
"default_branch":"master",
|
||||
"homepage":"http://example.com/jsmith/example",
|
||||
"url":"git@example.com:jsmith/example.git",
|
||||
"ssh_url":"git@example.com:jsmith/example.git",
|
||||
"http_url":"http://example.com/jsmith/example.git"
|
||||
},
|
||||
"repository":{
|
||||
"name": "Example",
|
||||
"url": "ssh://git@example.com/jsmith/example.git",
|
||||
"description": "",
|
||||
"homepage": "http://example.com/jsmith/example",
|
||||
"git_http_url":"http://example.com/jsmith/example.git",
|
||||
"git_ssh_url":"git@example.com:jsmith/example.git",
|
||||
"visibility_level":0
|
||||
},
|
||||
"commits": [],
|
||||
"total_commits_count": 0
|
||||
}
|
Reference in a new issue