Skip to content

Commit bd82d74

Browse files
fix: use POST method and return dict in cancel_merge_when_pipeline_succeeds() (#2350)
* Call was incorrectly using a `PUT` method when should have used a `POST` method. * Changed return type to a `dict` as GitLab only returns {'status': 'success'} on success. Since the function didn't work previously, this should not impact anyone. * Updated the test fixture `merge_request` to add ability to create a pipeline. * Added functional test for `mr.cancel_merge_when_pipeline_succeeds()` Fixes: #2349
1 parent 2974966 commit bd82d74

File tree

4 files changed

+47
-9
lines changed

4 files changed

+47
-9
lines changed

docs/gl_objects/merge_requests.rst

+7-1
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,14 @@ Accept a MR::
122122

123123
mr.merge()
124124

125-
Cancel a MR when the build succeeds::
125+
Schedule a MR to merge after the pipeline(s) succeed::
126126

127+
mr.merge(merge_when_pipeline_succeeds=True)
128+
129+
Cancel a MR from merging when the pipeline succeeds::
130+
131+
# Cancel a MR from being merged that had been previously set to
132+
# 'merge_when_pipeline_succeeds=True'
127133
mr.cancel_merge_when_pipeline_succeeds()
128134

129135
List commits of a MR::

gitlab/v4/objects/merge_requests.py

+8-7
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,7 @@ class ProjectMergeRequest(
165165

166166
@cli.register_custom_action("ProjectMergeRequest")
167167
@exc.on_http_error(exc.GitlabMROnBuildSuccessError)
168-
def cancel_merge_when_pipeline_succeeds(
169-
self, **kwargs: Any
170-
) -> "ProjectMergeRequest":
168+
def cancel_merge_when_pipeline_succeeds(self, **kwargs: Any) -> Dict[str, str]:
171169
"""Cancel merge when the pipeline succeeds.
172170
173171
Args:
@@ -179,17 +177,20 @@ def cancel_merge_when_pipeline_succeeds(
179177
request
180178
181179
Returns:
182-
ProjectMergeRequest
180+
dict of the parsed json returned by the server
183181
"""
184182

185183
path = (
186184
f"{self.manager.path}/{self.encoded_id}/cancel_merge_when_pipeline_succeeds"
187185
)
188-
server_data = self.manager.gitlab.http_put(path, **kwargs)
186+
server_data = self.manager.gitlab.http_post(path, **kwargs)
187+
# 2022-10-30: The docs at
188+
# https://docs.gitlab.com/ee/api/merge_requests.html#cancel-merge-when-pipeline-succeeds
189+
# are incorrect in that the return value is actually just:
190+
# {'status': 'success'} for a successful cancel.
189191
if TYPE_CHECKING:
190192
assert isinstance(server_data, dict)
191-
self._update_attrs(server_data)
192-
return ProjectMergeRequest(self.manager, server_data)
193+
return server_data
193194

194195
@cli.register_custom_action("ProjectMergeRequest")
195196
@exc.on_http_error(exc.GitlabListError)

tests/functional/api/test_merge_requests.py

+16
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,27 @@ def test_merge_request_reset_approvals(gitlab_url, project, wait_for_sidekiq):
181181
assert mr.reset_approvals()
182182

183183

184+
def test_cancel_merge_when_pipeline_succeeds(project, merge_request, wait_for_sidekiq):
185+
mr = merge_request(source_branch="test_merge_request_merge", create_pipeline=True)
186+
# Set to merge when the pipeline succeeds, which should never happen
187+
mr.merge(merge_when_pipeline_succeeds=True)
188+
wait_for_sidekiq(timeout=60)
189+
190+
mr = project.mergerequests.get(mr.iid)
191+
assert mr.merged_at is None
192+
assert mr.merge_when_pipeline_succeeds is True
193+
cancel = mr.cancel_merge_when_pipeline_succeeds()
194+
assert cancel == {"status": "success"}
195+
196+
184197
def test_merge_request_merge(project, merge_request, wait_for_sidekiq):
185198
mr = merge_request(source_branch="test_merge_request_merge")
186199
mr.merge()
187200
wait_for_sidekiq(timeout=60)
188201

202+
mr = project.mergerequests.get(mr.iid)
203+
assert mr.merged_at is not None
204+
assert mr.merge_when_pipeline_succeeds is False
189205
with pytest.raises(gitlab.GitlabMRClosedError):
190206
# Two merge attempts should raise GitlabMRClosedError
191207
mr.merge()

tests/functional/conftest.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ def merge_request(project, wait_for_sidekiq):
379379

380380
to_delete = []
381381

382-
def _merge_request(*, source_branch: str):
382+
def _merge_request(*, source_branch: str, create_pipeline: bool = False):
383383
# Wait for processes to be done before we start...
384384
# NOTE(jlvillal): Sometimes the CI would give a "500 Internal Server
385385
# Error". Hoping that waiting until all other processes are done will
@@ -401,6 +401,21 @@ def _merge_request(*, source_branch: str):
401401
"commit_message": "New commit in new branch",
402402
}
403403
)
404+
if create_pipeline:
405+
project.files.create(
406+
{
407+
"file_path": ".gitlab-ci.yml",
408+
"branch": source_branch,
409+
"content": """
410+
test:
411+
rules:
412+
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
413+
script:
414+
- sleep 24h # We don't expect this to finish
415+
""",
416+
"commit_message": "Add a simple pipeline",
417+
}
418+
)
404419
mr = project.mergerequests.create(
405420
{
406421
"source_branch": source_branch,

0 commit comments

Comments
 (0)