Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR Builder GitLab Integration #6066

Merged
merged 10 commits into from Aug 19, 2019
@@ -42,6 +42,12 @@
GITHUB_PULL_REQUEST_SYNC = 'synchronize'
GITHUB_CREATE = 'create'
GITHUB_DELETE = 'delete'
GITLAB_MERGE_REQUEST = 'merge_request'
GITLAB_MERGE_REQUEST_CLOSE = 'close'
GITLAB_MERGE_REQUEST_MERGE = 'merge'
GITLAB_MERGE_REQUEST_OPEN = 'open'
GITLAB_MERGE_REQUEST_REOPEN = 'reopen'
GITLAB_MERGE_REQUEST_UPDATE = 'update'
GITLAB_TOKEN_HEADER = 'HTTP_X_GITLAB_TOKEN'
GITLAB_PUSH = 'push'
GITLAB_NULL_HASH = '0' * 40
@@ -401,7 +407,7 @@ class GitLabWebhookView(WebhookMixin, APIView):
"""
Webhook consumer for GitLab.
Accepts webhook events from GitLab, 'push' events trigger builds.
Accepts webhook events from GitLab, 'push' and 'merge_request' events trigger builds.
Expects the following JSON::
@@ -413,10 +419,26 @@ class GitLabWebhookView(WebhookMixin, APIView):
...
}
For merge_request events:
{
"object_kind": "merge_request",
"object_attributes": {
"iid": 2,
"last_commit": {
"id": "717abb9a6a0f3111dbd601ef6f58c70bdd165aef",
},
"action": "open"
...
},
...
}
See full payload here:
- https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#push-events
- https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#tag-events
- https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#merge-request-events
"""

integration_type = Integration.GITLAB_WEBHOOK
@@ -441,6 +463,17 @@ def is_payload_valid(self):
return False
return token == secret

def get_external_version_data(self):
"""Get commit SHA and merge request number from payload."""
try:
identifier = self.data['object_attributes']['last_commit']['id']
verbose_name = str(self.data['object_attributes']['iid'])

return identifier, verbose_name

except KeyError:
raise ParseError('Parameters "id" and "iid" are required')

This comment has been minimized.

Copy link
@ericholscher

ericholscher Aug 12, 2019

Member

Where is this ParseError handled?

This comment has been minimized.

Copy link
@saadmk11

saadmk11 Aug 13, 2019

Author Member

When there is a ParseError we return 400 to the API. We do the same thing for the push events.

try:
branches = [self._normalize_ref(data['ref'])]
return self.get_response_push(self.project, branches)
except KeyError:
raise ParseError('Parameter "ref" is required')


def handle_webhook(self):
"""
Handle GitLab events for push and tag_push.
@@ -450,6 +483,7 @@ def handle_webhook(self):
0000000000000000000000000000000000000000 ('0' * 40)
"""
event = self.request.data.get('object_kind', GITLAB_PUSH)
action = self.data.get('object_attributes', {}).get('action', None)
webhook_gitlab.send(
Project,
project=self.project,
@@ -470,6 +504,25 @@ def handle_webhook(self):
return self.get_response_push(self.project, branches)
except KeyError:
raise ParseError('Parameter "ref" is required')

if (
self.project.has_feature(Feature.EXTERNAL_VERSION_BUILD) and
event == GITLAB_MERGE_REQUEST and action
):
if (
action in
[
GITLAB_MERGE_REQUEST_OPEN,
GITLAB_MERGE_REQUEST_REOPEN,
GITLAB_MERGE_REQUEST_UPDATE
]
):
# Handle open, update, reopen merge_request event.
return self.get_external_version_response(self.project)

if action in [GITLAB_MERGE_REQUEST_CLOSE, GITLAB_MERGE_REQUEST_MERGE]:
# Handle merge and close merge_request event.
return self.get_delete_external_version_response(self.project)
return None

def _normalize_ref(self, ref):
@@ -91,4 +91,5 @@
RTD_BUILD_STATUS_API_NAME = 'continuous-documentation/read-the-docs'

GITHUB_EXTERNAL_VERSION_NAME = 'Pull Request'
GITLAB_EXTERNAL_VERSION_NAME = 'Merge Request'
GENERIC_EXTERNAL_VERSION_NAME = 'External Version'
@@ -27,7 +27,10 @@
GITHUB_URL,
GITHUB_PULL_REQUEST_URL,
GITHUB_PULL_REQUEST_COMMIT_URL,
GITLAB_BRAND,
GITLAB_COMMIT_URL,
GITLAB_MERGE_REQUEST_URL,
GITLAB_MERGE_REQUEST_COMMIT_URL,
GITLAB_URL,
PRIVACY_CHOICES,
PRIVATE,
@@ -44,6 +47,7 @@
BUILD_TYPES,
GENERIC_EXTERNAL_VERSION_NAME,
GITHUB_EXTERNAL_VERSION_NAME,
GITLAB_EXTERNAL_VERSION_NAME,
INTERNAL,
LATEST,
NON_REPOSITORY_VERSIONS,
@@ -178,7 +182,14 @@ def vcs_url(self):
repo=repo,
number=self.verbose_name,
)
# TODO: Add VCS URL for other Git Providers
if 'gitlab' in self.project.repo:
user, repo = get_gitlab_username_repo(self.project.repo)
return GITLAB_MERGE_REQUEST_URL.format(
user=user,
repo=repo,
number=self.verbose_name,
)
# TODO: Add VCS URL for BitBucket.
return ''

url = ''
@@ -787,7 +798,19 @@ def get_commit_url(self):
number=self.version.verbose_name,
commit=self.commit
)
# TODO: Add External Version Commit URL for other Git Providers
if 'gitlab' in repo_url:
user, repo = get_gitlab_username_repo(repo_url)
if not user and not repo:
return ''

repo = repo.rstrip('/')
return GITLAB_MERGE_REQUEST_COMMIT_URL.format(
user=user,
repo=repo,
number=self.version.verbose_name,
commit=self.commit
)
# TODO: Add External Version Commit URL for BitBucket.
else:
if 'github' in repo_url:
user, repo = get_github_username_repo(repo_url)
@@ -845,8 +868,11 @@ def external_version_name(self):
if self.is_external:
if self.project.git_provider_name == GITHUB_BRAND:
return GITHUB_EXTERNAL_VERSION_NAME
# TODO: Add External Version Name for other Git Providers

if self.project.git_provider_name == GITLAB_BRAND:
return GITLAB_EXTERNAL_VERSION_NAME

# TODO: Add External Version Name for BitBucket.
return GENERIC_EXTERNAL_VERSION_NAME
return None

@@ -353,8 +353,19 @@
'https://gitlab.com/{user}/{repo}/'
'commit/{commit}'
)
GITLAB_MERGE_REQUEST_COMMIT_URL = (
'https://gitlab.com/{user}/{repo}/'
'commit/{commit}?merge_request_iid={number}'
)
GITLAB_MERGE_REQUEST_URL = (
'https://gitlab.com/{user}/{repo}/'
'merge_requests/{number}'
)

# Patterns to pull merge/pull request from providers
GITHUB_PR_PULL_PATTERN = 'pull/{id}/head:external-{id}'
GITLAB_MR_PULL_PATTERN = 'merge-requests/{id}/head:external-{id}'

# Git provider names
GITHUB_BRAND = 'GitHub'
GITLAB_BRAND = 'GitLab'
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.