1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
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 dateutil.parser import parse as dateparse
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':
changes = self._process_note_addition_to_merge_request(
|