From 954357c49963ef51945c81c41fd4345002f9fb98 Mon Sep 17 00:00:00 2001 From: Nejc Habjan Date: Wed, 24 Feb 2021 00:18:49 +0100 Subject: [PATCH] feat(api): add MR pipeline manager in favor of pipelines() method --- docs/gl_objects/mrs.rst | 29 +++++++-- gitlab/cli.py | 3 +- gitlab/v4/objects/merge_requests.py | 21 +----- gitlab/v4/objects/pipelines.py | 41 ++++++++++++ .../objects/test_merge_request_pipelines.py | 64 +++++++++++++++++++ 5 files changed, 134 insertions(+), 24 deletions(-) create mode 100644 tests/unit/objects/test_merge_request_pipelines.py diff --git a/docs/gl_objects/mrs.rst b/docs/gl_objects/mrs.rst index be93f1240..29cbced88 100644 --- a/docs/gl_objects/mrs.rst +++ b/docs/gl_objects/mrs.rst @@ -127,10 +127,6 @@ List the changes of a MR:: changes = mr.changes() -List the pipelines for a MR:: - - pipelines = mr.pipelines() - List issues that will close on merge:: mr.closes_issues() @@ -185,3 +181,28 @@ Get user agent detail for the issue (admin only):: Attempt to rebase an MR:: mr.rebase() + +Merge Request Pipelines +======================= + +Reference +--------- + +* v4 API: + + + :class:`gitlab.v4.objects.ProjectMergeRequestPipeline` + + :class:`gitlab.v4.objects.ProjectMergeRequestPipelineManager` + + :attr:`gitlab.v4.objects.ProjectMergeRequest.pipelines` + +* GitLab API: https://docs.gitlab.com/ee/api/merge_requests.html#list-mr-pipelines + +Examples +-------- + +List pipelines for a merge request:: + + pipelines = mr.pipelines.list() + +Create a pipeline for a merge request:: + + pipeline = mr.pipelines.create() diff --git a/gitlab/cli.py b/gitlab/cli.py index a5044ffda..c053a38d5 100644 --- a/gitlab/cli.py +++ b/gitlab/cli.py @@ -53,6 +53,7 @@ def register_custom_action( cls_names: Union[str, Tuple[str, ...]], mandatory: Tuple[str, ...] = tuple(), optional: Tuple[str, ...] = tuple(), + custom_action: Optional[str] = None, ) -> Callable[[__F], __F]: def wrap(f: __F) -> __F: @functools.wraps(f) @@ -74,7 +75,7 @@ def wrapped_f(*args: Any, **kwargs: Any) -> Any: if final_name not in custom_actions: custom_actions[final_name] = {} - action = f.__name__.replace("_", "-") + action = custom_action or f.__name__.replace("_", "-") custom_actions[final_name][action] = (mandatory, optional, in_obj) return cast(__F, wrapped_f) diff --git a/gitlab/v4/objects/merge_requests.py b/gitlab/v4/objects/merge_requests.py index dd118d0db..e8c2a96c8 100644 --- a/gitlab/v4/objects/merge_requests.py +++ b/gitlab/v4/objects/merge_requests.py @@ -28,6 +28,7 @@ ProjectMergeRequestApprovalRuleManager, ) from .notes import ProjectMergeRequestNoteManager # noqa: F401 +from .pipelines import ProjectMergeRequestPipelineManager # noqa: F401 __all__ = [ "MergeRequest", @@ -145,6 +146,7 @@ class ProjectMergeRequest( ("diffs", "ProjectMergeRequestDiffManager"), ("discussions", "ProjectMergeRequestDiscussionManager"), ("notes", "ProjectMergeRequestNoteManager"), + ("pipelines", "ProjectMergeRequestPipelineManager"), ("resourcelabelevents", "ProjectMergeRequestResourceLabelEventManager"), ("resourcemilestoneevents", "ProjectMergeRequestResourceMilestoneEventManager"), ("resourcestateevents", "ProjectMergeRequestResourceStateEventManager"), @@ -240,25 +242,6 @@ def changes(self, **kwargs): path = "%s/%s/changes" % (self.manager.path, self.get_id()) return self.manager.gitlab.http_get(path, **kwargs) - @cli.register_custom_action("ProjectMergeRequest") - @exc.on_http_error(exc.GitlabListError) - def pipelines(self, **kwargs): - """List the merge request pipelines. - - Args: - **kwargs: Extra options to send to the server (e.g. sudo) - - Raises: - GitlabAuthenticationError: If authentication is not correct - GitlabListError: If the list could not be retrieved - - Returns: - RESTObjectList: List of changes - """ - - path = "%s/%s/pipelines" % (self.manager.path, self.get_id()) - return self.manager.gitlab.http_get(path, **kwargs) - @cli.register_custom_action("ProjectMergeRequest", tuple(), ("sha",)) @exc.on_http_error(exc.GitlabMRApprovalError) def approve(self, sha=None, **kwargs): diff --git a/gitlab/v4/objects/pipelines.py b/gitlab/v4/objects/pipelines.py index 79b080245..5118e7831 100644 --- a/gitlab/v4/objects/pipelines.py +++ b/gitlab/v4/objects/pipelines.py @@ -1,3 +1,5 @@ +import warnings + from gitlab import cli from gitlab import exceptions as exc from gitlab.base import RequiredOptional, RESTManager, RESTObject @@ -15,6 +17,8 @@ ) __all__ = [ + "ProjectMergeRequestPipeline", + "ProjectMergeRequestPipelineManager", "ProjectPipeline", "ProjectPipelineManager", "ProjectPipelineJob", @@ -32,6 +36,43 @@ ] +class ProjectMergeRequestPipeline(RESTObject): + pass + + +class ProjectMergeRequestPipelineManager(CreateMixin, ListMixin, RESTManager): + _path = "/projects/%(project_id)s/merge_requests/%(mr_iid)s/pipelines" + _obj_cls = ProjectMergeRequestPipeline + _from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"} + + # If the manager was called directly as a callable via + # mr.pipelines(), execute the deprecated method for now. + # TODO: in python-gitlab 3.0.0, remove this method entirely. + + @cli.register_custom_action("ProjectMergeRequest", custom_action="pipelines") + @exc.on_http_error(exc.GitlabListError) + def __call__(self, **kwargs): + """List the merge request pipelines. + + Args: + **kwargs: Extra options to send to the server (e.g. sudo) + + Raises: + GitlabAuthenticationError: If authentication is not correct + GitlabListError: If the list could not be retrieved + + Returns: + RESTObjectList: List of changes + """ + warnings.warn( + "Calling the ProjectMergeRequest.pipelines() method on " + "merge request objects directly is deprecated and will be replaced " + "by ProjectMergeRequest.pipelines.list() in python-gitlab 3.0.0.\n", + DeprecationWarning, + ) + return self.list(**kwargs) + + class ProjectPipeline(RefreshMixin, ObjectDeleteMixin, RESTObject): _managers = ( ("jobs", "ProjectPipelineJobManager"), diff --git a/tests/unit/objects/test_merge_request_pipelines.py b/tests/unit/objects/test_merge_request_pipelines.py new file mode 100644 index 000000000..c620cb027 --- /dev/null +++ b/tests/unit/objects/test_merge_request_pipelines.py @@ -0,0 +1,64 @@ +""" +GitLab API: https://docs.gitlab.com/ee/api/merge_requests.html#list-mr-pipelines +""" +import pytest +import responses + +from gitlab.v4.objects import ProjectMergeRequestPipeline + +pipeline_content = { + "id": 1, + "sha": "959e04d7c7a30600c894bd3c0cd0e1ce7f42c11d", + "ref": "master", + "status": "success", +} + + +@pytest.fixture() +def resp_list_merge_request_pipelines(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/merge_requests/1/pipelines", + json=[pipeline_content], + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture() +def resp_create_merge_request_pipeline(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.POST, + url="http://localhost/api/v4/projects/1/merge_requests/1/pipelines", + json=pipeline_content, + content_type="application/json", + status=201, + ) + yield rsps + + +def test_merge_requests_pipelines_deprecated_raises_warning( + project, resp_list_merge_request_pipelines +): + with pytest.deprecated_call(): + pipelines = project.mergerequests.get(1, lazy=True).pipelines() + + assert len(pipelines) == 1 + assert isinstance(pipelines[0], ProjectMergeRequestPipeline) + assert pipelines[0].sha == pipeline_content["sha"] + + +def test_list_merge_requests_pipelines(project, resp_list_merge_request_pipelines): + pipelines = project.mergerequests.get(1, lazy=True).pipelines.list() + assert len(pipelines) == 1 + assert isinstance(pipelines[0], ProjectMergeRequestPipeline) + assert pipelines[0].sha == pipeline_content["sha"] + + +def test_create_merge_requests_pipelines(project, resp_create_merge_request_pipeline): + pipeline = project.mergerequests.get(1, lazy=True).pipelines.create() + assert isinstance(pipeline, ProjectMergeRequestPipeline) + assert pipeline.sha == pipeline_content["sha"] pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy