diff --git a/buildbot/reporters/gitlab.py b/buildbot/reporters/gitlab.py index 5a403d5d0..a6fc698e2 100644 --- a/buildbot/reporters/gitlab.py +++ b/buildbot/reporters/gitlab.py @@ -169,8 +169,8 @@ class GitLabStatusPush(ReporterBase): # FIXME: probably only want to report status for the last commit in the changeset for sourcestamp in sourcestamps: sha = sourcestamp['revision'] - if 'source_project_id' in props: - proj_id = props['source_project_id'] + if 'target_project_id' in props: + proj_id = props['target_project_id'] else: proj_id = yield self.getProjectId(sourcestamp) if proj_id is None: @@ -191,8 +191,11 @@ class GitLabStatusPush(ReporterBase): description=description ) if res.code not in (200, 201, 204): - message = yield res.json() - message = message.get('message', 'unspecified error') + if res.code.startswith("{"): + message = yield res.json() + message = message.get('message', 'unspecified error') + else: + message = res.code log.msg( f'Could not send status "{state}" for ' f'{sourcestamp["repository"]} at {sha}: {message}') diff --git a/buildbot/www/hooks/gitlab.py b/buildbot/www/hooks/gitlab.py index 8f2f80a83..40de0273e 100644 --- a/buildbot/www/hooks/gitlab.py +++ b/buildbot/www/hooks/gitlab.py @@ -19,6 +19,8 @@ import re from dateutil.parser import parse as dateparse +import gitlab as python_gitlab + from twisted.internet.defer import inlineCallbacks from twisted.python import log @@ -28,6 +30,7 @@ from buildbot.www.hooks.base import BaseHookHandler _HEADER_EVENT = b'X-Gitlab-Event' _HEADER_GITLAB_TOKEN = b'X-Gitlab-Token' +_HOSTED_BASE_URL = 'https://gitlab.com' class GitLabHandler(BaseHookHandler): @@ -94,6 +97,34 @@ class GitLabHandler(BaseHookHandler): return changes + def _configGitlabRest(self, token, baseURL=None): + if baseURL is None: + baseURL = _HOSTED_BASE_URL + if baseURL.endswith('/'): + baseURL = baseURL[:-1] + return python_gitlab.Gitlab(url=baseURL, private_token=token) + + #@inlineCallbacks + def _getFiles(self, attrs): + """ + get the files changes + """ + files = [] + project = self.gl.projects.get(attrs['target']['id']) + mr = project.mergerequests.get(attrs['iid']) + changes = mr.changes() + if isinstance(changes['changes'], list): + for change in changes['changes']: + print(change['old_path']) + print(change['new_path']) + print(change['new_file']) + print(change['renamed_file']) + print(change['deleted_file']) + if change['old_path'] == change['new_path']: + files.append(change['old_path']) + print(f"Files: {files}") + return files + def _process_merge_request_change(self, payload, event, codebase=None): """ Consumes the merge_request JSON as a python object and turn it into a buildbot change. @@ -126,7 +157,7 @@ class GitLabHandler(BaseHookHandler): changes = [{ 'author': f"{commit['author']['name']} <{commit['author']['email']}>", - 'files': [], # @todo use rest API + 'files': self._getFiles(attrs), 'comments': f"MR#{attrs['iid']}: {attrs['title']}\n\n{attrs['description']}", 'revision': commit['id'], 'when_timestamp': when_timestamp, @@ -220,17 +251,21 @@ class GitLabHandler(BaseHookHandler): request the http request object """ + p = Properties() + p.master = self.master expected_secret = isinstance(self.options, dict) and self.options.get('secret') if expected_secret: received_secret = request.getHeader(_HEADER_GITLAB_TOKEN) received_secret = bytes2unicode(received_secret) - - p = Properties() - p.master = self.master expected_secret_value = yield p.render(expected_secret) if received_secret != expected_secret_value: raise ValueError("Invalid secret") + + baseUrl_value = isinstance(self.options, dict) and self.options.get('baseUrl') + expected_token = isinstance(self.options, dict) and self.options.get('token') + expected_token_value = yield p.render(expected_token) + try: content = request.content.read() payload = json.loads(bytes2unicode(content)) @@ -250,6 +285,7 @@ class GitLabHandler(BaseHookHandler): changes = self._process_change( payload, user, repo, repo_url, event_type, codebase=codebase) elif event_type == 'merge_request': + self.gl = self._configGitlabRest(expected_token_value, baseURL=baseUrl_value) changes = self._process_merge_request_change( payload, event_type, codebase=codebase) elif event_type == 'note':