Skip to content

Commit e77554c

Browse files
Merge pull request #1323 from python-gitlab/feat/mr-pipeline-manager
feat(api): add merge request pipeline manager and deprecate mr.pipelines() method
2 parents 1f5b3c0 + 954357c commit e77554c

File tree

5 files changed

+134
-24
lines changed

5 files changed

+134
-24
lines changed

docs/gl_objects/mrs.rst

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,6 @@ List the changes of a MR::
127127

128128
changes = mr.changes()
129129

130-
List the pipelines for a MR::
131-
132-
pipelines = mr.pipelines()
133-
134130
List issues that will close on merge::
135131

136132
mr.closes_issues()
@@ -185,3 +181,28 @@ Get user agent detail for the issue (admin only)::
185181
Attempt to rebase an MR::
186182

187183
mr.rebase()
184+
185+
Merge Request Pipelines
186+
=======================
187+
188+
Reference
189+
---------
190+
191+
* v4 API:
192+
193+
+ :class:`gitlab.v4.objects.ProjectMergeRequestPipeline`
194+
+ :class:`gitlab.v4.objects.ProjectMergeRequestPipelineManager`
195+
+ :attr:`gitlab.v4.objects.ProjectMergeRequest.pipelines`
196+
197+
* GitLab API: https://docs.gitlab.com/ee/api/merge_requests.html#list-mr-pipelines
198+
199+
Examples
200+
--------
201+
202+
List pipelines for a merge request::
203+
204+
pipelines = mr.pipelines.list()
205+
206+
Create a pipeline for a merge request::
207+
208+
pipeline = mr.pipelines.create()

gitlab/cli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def register_custom_action(
5353
cls_names: Union[str, Tuple[str, ...]],
5454
mandatory: Tuple[str, ...] = tuple(),
5555
optional: Tuple[str, ...] = tuple(),
56+
custom_action: Optional[str] = None,
5657
) -> Callable[[__F], __F]:
5758
def wrap(f: __F) -> __F:
5859
@functools.wraps(f)
@@ -74,7 +75,7 @@ def wrapped_f(*args: Any, **kwargs: Any) -> Any:
7475
if final_name not in custom_actions:
7576
custom_actions[final_name] = {}
7677

77-
action = f.__name__.replace("_", "-")
78+
action = custom_action or f.__name__.replace("_", "-")
7879
custom_actions[final_name][action] = (mandatory, optional, in_obj)
7980

8081
return cast(__F, wrapped_f)

gitlab/v4/objects/merge_requests.py

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
ProjectMergeRequestApprovalRuleManager,
2929
)
3030
from .notes import ProjectMergeRequestNoteManager # noqa: F401
31+
from .pipelines import ProjectMergeRequestPipelineManager # noqa: F401
3132

3233
__all__ = [
3334
"MergeRequest",
@@ -145,6 +146,7 @@ class ProjectMergeRequest(
145146
("diffs", "ProjectMergeRequestDiffManager"),
146147
("discussions", "ProjectMergeRequestDiscussionManager"),
147148
("notes", "ProjectMergeRequestNoteManager"),
149+
("pipelines", "ProjectMergeRequestPipelineManager"),
148150
("resourcelabelevents", "ProjectMergeRequestResourceLabelEventManager"),
149151
("resourcemilestoneevents", "ProjectMergeRequestResourceMilestoneEventManager"),
150152
("resourcestateevents", "ProjectMergeRequestResourceStateEventManager"),
@@ -240,25 +242,6 @@ def changes(self, **kwargs):
240242
path = "%s/%s/changes" % (self.manager.path, self.get_id())
241243
return self.manager.gitlab.http_get(path, **kwargs)
242244

243-
@cli.register_custom_action("ProjectMergeRequest")
244-
@exc.on_http_error(exc.GitlabListError)
245-
def pipelines(self, **kwargs):
246-
"""List the merge request pipelines.
247-
248-
Args:
249-
**kwargs: Extra options to send to the server (e.g. sudo)
250-
251-
Raises:
252-
GitlabAuthenticationError: If authentication is not correct
253-
GitlabListError: If the list could not be retrieved
254-
255-
Returns:
256-
RESTObjectList: List of changes
257-
"""
258-
259-
path = "%s/%s/pipelines" % (self.manager.path, self.get_id())
260-
return self.manager.gitlab.http_get(path, **kwargs)
261-
262245
@cli.register_custom_action("ProjectMergeRequest", tuple(), ("sha",))
263246
@exc.on_http_error(exc.GitlabMRApprovalError)
264247
def approve(self, sha=None, **kwargs):

gitlab/v4/objects/pipelines.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import warnings
2+
13
from gitlab import cli
24
from gitlab import exceptions as exc
35
from gitlab.base import RequiredOptional, RESTManager, RESTObject
@@ -15,6 +17,8 @@
1517
)
1618

1719
__all__ = [
20+
"ProjectMergeRequestPipeline",
21+
"ProjectMergeRequestPipelineManager",
1822
"ProjectPipeline",
1923
"ProjectPipelineManager",
2024
"ProjectPipelineJob",
@@ -32,6 +36,43 @@
3236
]
3337

3438

39+
class ProjectMergeRequestPipeline(RESTObject):
40+
pass
41+
42+
43+
class ProjectMergeRequestPipelineManager(CreateMixin, ListMixin, RESTManager):
44+
_path = "/projects/%(project_id)s/merge_requests/%(mr_iid)s/pipelines"
45+
_obj_cls = ProjectMergeRequestPipeline
46+
_from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
47+
48+
# If the manager was called directly as a callable via
49+
# mr.pipelines(), execute the deprecated method for now.
50+
# TODO: in python-gitlab 3.0.0, remove this method entirely.
51+
52+
@cli.register_custom_action("ProjectMergeRequest", custom_action="pipelines")
53+
@exc.on_http_error(exc.GitlabListError)
54+
def __call__(self, **kwargs):
55+
"""List the merge request pipelines.
56+
57+
Args:
58+
**kwargs: Extra options to send to the server (e.g. sudo)
59+
60+
Raises:
61+
GitlabAuthenticationError: If authentication is not correct
62+
GitlabListError: If the list could not be retrieved
63+
64+
Returns:
65+
RESTObjectList: List of changes
66+
"""
67+
warnings.warn(
68+
"Calling the ProjectMergeRequest.pipelines() method on "
69+
"merge request objects directly is deprecated and will be replaced "
70+
"by ProjectMergeRequest.pipelines.list() in python-gitlab 3.0.0.\n",
71+
DeprecationWarning,
72+
)
73+
return self.list(**kwargs)
74+
75+
3576
class ProjectPipeline(RefreshMixin, ObjectDeleteMixin, RESTObject):
3677
_managers = (
3778
("jobs", "ProjectPipelineJobManager"),
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""
2+
GitLab API: https://docs.gitlab.com/ee/api/merge_requests.html#list-mr-pipelines
3+
"""
4+
import pytest
5+
import responses
6+
7+
from gitlab.v4.objects import ProjectMergeRequestPipeline
8+
9+
pipeline_content = {
10+
"id": 1,
11+
"sha": "959e04d7c7a30600c894bd3c0cd0e1ce7f42c11d",
12+
"ref": "master",
13+
"status": "success",
14+
}
15+
16+
17+
@pytest.fixture()
18+
def resp_list_merge_request_pipelines():
19+
with responses.RequestsMock() as rsps:
20+
rsps.add(
21+
method=responses.GET,
22+
url="http://localhost/api/v4/projects/1/merge_requests/1/pipelines",
23+
json=[pipeline_content],
24+
content_type="application/json",
25+
status=200,
26+
)
27+
yield rsps
28+
29+
30+
@pytest.fixture()
31+
def resp_create_merge_request_pipeline():
32+
with responses.RequestsMock() as rsps:
33+
rsps.add(
34+
method=responses.POST,
35+
url="http://localhost/api/v4/projects/1/merge_requests/1/pipelines",
36+
json=pipeline_content,
37+
content_type="application/json",
38+
status=201,
39+
)
40+
yield rsps
41+
42+
43+
def test_merge_requests_pipelines_deprecated_raises_warning(
44+
project, resp_list_merge_request_pipelines
45+
):
46+
with pytest.deprecated_call():
47+
pipelines = project.mergerequests.get(1, lazy=True).pipelines()
48+
49+
assert len(pipelines) == 1
50+
assert isinstance(pipelines[0], ProjectMergeRequestPipeline)
51+
assert pipelines[0].sha == pipeline_content["sha"]
52+
53+
54+
def test_list_merge_requests_pipelines(project, resp_list_merge_request_pipelines):
55+
pipelines = project.mergerequests.get(1, lazy=True).pipelines.list()
56+
assert len(pipelines) == 1
57+
assert isinstance(pipelines[0], ProjectMergeRequestPipeline)
58+
assert pipelines[0].sha == pipeline_content["sha"]
59+
60+
61+
def test_create_merge_requests_pipelines(project, resp_create_merge_request_pipeline):
62+
pipeline = project.mergerequests.get(1, lazy=True).pipelines.create()
63+
assert isinstance(pipeline, ProjectMergeRequestPipeline)
64+
assert pipeline.sha == pipeline_content["sha"]

0 commit comments

Comments
 (0)
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