summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Villalovos <john@sodarock.com>2022-10-31 03:24:27 -0700
committerGitHub <noreply@github.com>2022-10-31 10:24:27 +0000
commitbd82d745c8ea9ff6ff078a4c961a2d6e64a2f63c (patch)
tree823e263cad7af8dea77309e8ef69a3c23589e9d9
parent29749660b9ca97dda1e7ad104d79266d5ed24d7b (diff)
downloadgitlab-bd82d745c8ea9ff6ff078a4c961a2d6e64a2f63c.tar.gz
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
-rw-r--r--docs/gl_objects/merge_requests.rst8
-rw-r--r--gitlab/v4/objects/merge_requests.py15
-rw-r--r--tests/functional/api/test_merge_requests.py16
-rw-r--r--tests/functional/conftest.py17
4 files changed, 47 insertions, 9 deletions
diff --git a/docs/gl_objects/merge_requests.rst b/docs/gl_objects/merge_requests.rst
index 02121dc..fd57e60 100644
--- a/docs/gl_objects/merge_requests.rst
+++ b/docs/gl_objects/merge_requests.rst
@@ -122,8 +122,14 @@ Accept a MR::
mr.merge()
-Cancel a MR when the build succeeds::
+Schedule a MR to merge after the pipeline(s) succeed::
+ mr.merge(merge_when_pipeline_succeeds=True)
+
+Cancel a MR from merging when the pipeline succeeds::
+
+ # Cancel a MR from being merged that had been previously set to
+ # 'merge_when_pipeline_succeeds=True'
mr.cancel_merge_when_pipeline_succeeds()
List commits of a MR::
diff --git a/gitlab/v4/objects/merge_requests.py b/gitlab/v4/objects/merge_requests.py
index 2e1ab09..d4c3933 100644
--- a/gitlab/v4/objects/merge_requests.py
+++ b/gitlab/v4/objects/merge_requests.py
@@ -165,9 +165,7 @@ class ProjectMergeRequest(
@cli.register_custom_action("ProjectMergeRequest")
@exc.on_http_error(exc.GitlabMROnBuildSuccessError)
- def cancel_merge_when_pipeline_succeeds(
- self, **kwargs: Any
- ) -> "ProjectMergeRequest":
+ def cancel_merge_when_pipeline_succeeds(self, **kwargs: Any) -> Dict[str, str]:
"""Cancel merge when the pipeline succeeds.
Args:
@@ -179,17 +177,20 @@ class ProjectMergeRequest(
request
Returns:
- ProjectMergeRequest
+ dict of the parsed json returned by the server
"""
path = (
f"{self.manager.path}/{self.encoded_id}/cancel_merge_when_pipeline_succeeds"
)
- server_data = self.manager.gitlab.http_put(path, **kwargs)
+ server_data = self.manager.gitlab.http_post(path, **kwargs)
+ # 2022-10-30: The docs at
+ # https://docs.gitlab.com/ee/api/merge_requests.html#cancel-merge-when-pipeline-succeeds
+ # are incorrect in that the return value is actually just:
+ # {'status': 'success'} for a successful cancel.
if TYPE_CHECKING:
assert isinstance(server_data, dict)
- self._update_attrs(server_data)
- return ProjectMergeRequest(self.manager, server_data)
+ return server_data
@cli.register_custom_action("ProjectMergeRequest")
@exc.on_http_error(exc.GitlabListError)
diff --git a/tests/functional/api/test_merge_requests.py b/tests/functional/api/test_merge_requests.py
index 75afb08..56ee7bc 100644
--- a/tests/functional/api/test_merge_requests.py
+++ b/tests/functional/api/test_merge_requests.py
@@ -181,11 +181,27 @@ def test_merge_request_reset_approvals(gitlab_url, project, wait_for_sidekiq):
assert mr.reset_approvals()
+def test_cancel_merge_when_pipeline_succeeds(project, merge_request, wait_for_sidekiq):
+ mr = merge_request(source_branch="test_merge_request_merge", create_pipeline=True)
+ # Set to merge when the pipeline succeeds, which should never happen
+ mr.merge(merge_when_pipeline_succeeds=True)
+ wait_for_sidekiq(timeout=60)
+
+ mr = project.mergerequests.get(mr.iid)
+ assert mr.merged_at is None
+ assert mr.merge_when_pipeline_succeeds is True
+ cancel = mr.cancel_merge_when_pipeline_succeeds()
+ assert cancel == {"status": "success"}
+
+
def test_merge_request_merge(project, merge_request, wait_for_sidekiq):
mr = merge_request(source_branch="test_merge_request_merge")
mr.merge()
wait_for_sidekiq(timeout=60)
+ mr = project.mergerequests.get(mr.iid)
+ assert mr.merged_at is not None
+ assert mr.merge_when_pipeline_succeeds is False
with pytest.raises(gitlab.GitlabMRClosedError):
# Two merge attempts should raise GitlabMRClosedError
mr.merge()
diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py
index 3700ae6..b75a1e1 100644
--- a/tests/functional/conftest.py
+++ b/tests/functional/conftest.py
@@ -379,7 +379,7 @@ def merge_request(project, wait_for_sidekiq):
to_delete = []
- def _merge_request(*, source_branch: str):
+ def _merge_request(*, source_branch: str, create_pipeline: bool = False):
# Wait for processes to be done before we start...
# NOTE(jlvillal): Sometimes the CI would give a "500 Internal Server
# Error". Hoping that waiting until all other processes are done will
@@ -401,6 +401,21 @@ def merge_request(project, wait_for_sidekiq):
"commit_message": "New commit in new branch",
}
)
+ if create_pipeline:
+ project.files.create(
+ {
+ "file_path": ".gitlab-ci.yml",
+ "branch": source_branch,
+ "content": """
+test:
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
+ script:
+ - sleep 24h # We don't expect this to finish
+""",
+ "commit_message": "Add a simple pipeline",
+ }
+ )
mr = project.mergerequests.create(
{
"source_branch": source_branch,