Skip to content

Commit

Permalink
Merge pull request #6066 from saadmk11/gitlab-integration
Browse files Browse the repository at this point in the history
PR Builder GitLab Integration
  • Loading branch information
ericholscher authored Aug 19, 2019
2 parents 4d8828e + 4c89847 commit 3ccf7c3
Show file tree
Hide file tree
Showing 9 changed files with 481 additions and 14 deletions.
55 changes: 54 additions & 1 deletion readthedocs/api/v2/views/integrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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::
Expand All @@ -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
Expand All @@ -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')

def handle_webhook(self):
"""
Handle GitLab events for push and tag_push.
Expand All @@ -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,
Expand All @@ -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):
Expand Down
1 change: 1 addition & 0 deletions readthedocs/builds/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
32 changes: 29 additions & 3 deletions readthedocs/builds/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -44,6 +47,7 @@
BUILD_TYPES,
GENERIC_EXTERNAL_VERSION_NAME,
GITHUB_EXTERNAL_VERSION_NAME,
GITLAB_EXTERNAL_VERSION_NAME,
INTERNAL,
LATEST,
NON_REPOSITORY_VERSIONS,
Expand Down Expand Up @@ -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 = ''
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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

Expand Down
11 changes: 11 additions & 0 deletions readthedocs/projects/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Loading

0 comments on commit 3ccf7c3

Please sign in to comment.