Add support for gitlab squash merge

Add support for allowing to squash merge request in Gitlab. It is
possible to enforce in Gitlab requiring squashing. With this change we
can use `merge-mode: squash-merge` on the project to be able to merge.
This sets parameter `squash: True` for the API request.

Change-Id: I2ce9f7f9fc570809ee0250970546e457568a45b8
This commit is contained in:
Artem Goncharov 2021-08-26 17:28:42 +02:00 committed by Artem Goncharov
parent 617d2ef1c6
commit 8b6a5ce584
4 changed files with 34 additions and 7 deletions

View File

@ -122,24 +122,24 @@ pipeline.
.. value:: merge
Uses the default git merge strategy (recursive). This maps to
the merge mode ``merge`` in Github.
the merge mode ``merge`` in Github and Gitlab.
.. value:: merge-resolve
Uses the resolve git merge strategy. This is a very
conservative merge strategy which most closely matches the
behavior of Gerrit. This maps to the merge mode ``merge`` in
Github.
Github and Gitlab.
.. value:: cherry-pick
Cherry-picks each change onto the branch rather than
performing any merges. This is not supported by Github.
performing any merges. This is not supported by Github and Gitlab.
.. value:: squash-merge
Squash merges each change onto the branch. This maps to the
merge mode ``squash`` in Github.
merge mode ``squash`` in Github and Gitlab.
.. attr:: vars
:default: None

View File

@ -0,0 +1,4 @@
---
features:
- |
Add support for squashing MR with gitlab.

View File

@ -398,9 +398,13 @@ class GitlabAPIClient():
# https://docs.gitlab.com/ee/api/merge_requests.html#accept-mr
def merge_mr(self, project_name, number,
method,
zuul_event_id=None):
path = "/projects/%s/merge_requests/%s/merge" % (
quote_plus(project_name), number)
params = {}
if method == "squash":
params['squash'] = True
resp = self.put(self.baseurl + path, zuul_event_id=zuul_event_id)
try:
self._manage_error(*resp, zuul_event_id=zuul_event_id)
@ -653,9 +657,10 @@ class GitlabConnection(ZKChangeCacheMixin, CachedBranchConnection):
# Will be done in a folloup commit
return []
def mergeMR(self, project_name, number, event=None):
def mergeMR(self, project_name, number, method='merge', event=None):
log = get_annotated_logger(self.log, event)
self.gl_client.merge_mr(project_name, number, zuul_event_id=event)
self.gl_client.merge_mr(
project_name, number, method, zuul_event_id=event)
log.info("Merged MR %s#%s", project_name, number)

View File

@ -17,6 +17,8 @@ import logging
import voluptuous as v
from zuul.reporter import BaseReporter
from zuul.model import MERGER_MERGE_RESOLVE, MERGER_MERGE, MERGER_MAP, \
MERGER_SQUASH_MERGE
from zuul.lib.logutil import get_annotated_logger
from zuul.driver.gitlab.gitlabsource import GitlabSource
from zuul.exceptions import MergeFailure
@ -28,6 +30,13 @@ class GitlabReporter(BaseReporter):
name = 'gitlab'
log = logging.getLogger("zuul.GitlabReporter")
# Merge modes supported by gitlab
merge_modes = {
MERGER_MERGE: 'merge',
MERGER_MERGE_RESOLVE: 'merge',
MERGER_SQUASH_MERGE: 'squash'
}
def __init__(self, driver, connection, pipeline, config=None):
super(GitlabReporter, self).__init__(driver, connection, config)
self._create_comment = self.config.get('comment', True)
@ -78,9 +87,18 @@ class GitlabReporter(BaseReporter):
project = item.change.project.name
mr_number = item.change.number
merge_mode = item.current_build_set.getMergeMode()
if merge_mode not in self.merge_modes:
mode = [x[0] for x in MERGER_MAP.items() if x[1] == merge_mode][0]
self.log.warning('Merge mode %s not supported by Gitlab', mode)
raise MergeFailure('Merge mode %s not supported by Gitlab' % mode)
merge_mode = self.merge_modes[merge_mode]
for i in [1, 2]:
try:
self.connection.mergeMR(project, mr_number)
self.connection.mergeMR(project, mr_number, merge_mode)
item.change.is_merged = True
return
except MergeFailure: