python-gitlab 4.5.0__py3-none-any.whl → 4.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gitlab/_version.py +1 -1
- gitlab/cli.py +20 -4
- gitlab/client.py +2 -2
- gitlab/mixins.py +22 -14
- gitlab/v4/cli.py +23 -11
- gitlab/v4/objects/__init__.py +1 -0
- gitlab/v4/objects/artifacts.py +5 -2
- gitlab/v4/objects/ci_lint.py +4 -4
- gitlab/v4/objects/commits.py +6 -6
- gitlab/v4/objects/container_registry.py +2 -2
- gitlab/v4/objects/deploy_keys.py +3 -1
- gitlab/v4/objects/deployments.py +2 -2
- gitlab/v4/objects/environments.py +1 -1
- gitlab/v4/objects/files.py +15 -7
- gitlab/v4/objects/geo_nodes.py +4 -4
- gitlab/v4/objects/groups.py +13 -7
- gitlab/v4/objects/integrations.py +3 -1
- gitlab/v4/objects/issues.py +6 -4
- gitlab/v4/objects/iterations.py +29 -2
- gitlab/v4/objects/jobs.py +11 -14
- gitlab/v4/objects/merge_request_approvals.py +8 -3
- gitlab/v4/objects/merge_requests.py +13 -12
- gitlab/v4/objects/milestones.py +4 -4
- gitlab/v4/objects/namespaces.py +3 -1
- gitlab/v4/objects/packages.py +4 -4
- gitlab/v4/objects/pipelines.py +4 -4
- gitlab/v4/objects/projects.py +21 -18
- gitlab/v4/objects/repositories.py +13 -9
- gitlab/v4/objects/runners.py +2 -2
- gitlab/v4/objects/secure_files.py +1 -1
- gitlab/v4/objects/service_accounts.py +18 -0
- gitlab/v4/objects/sidekiq.py +4 -4
- gitlab/v4/objects/snippets.py +3 -3
- gitlab/v4/objects/todos.py +2 -2
- gitlab/v4/objects/topics.py +2 -2
- gitlab/v4/objects/users.py +10 -10
- {python_gitlab-4.5.0.dist-info → python_gitlab-4.6.0.dist-info}/METADATA +3 -3
- {python_gitlab-4.5.0.dist-info → python_gitlab-4.6.0.dist-info}/RECORD +43 -42
- {python_gitlab-4.5.0.dist-info → python_gitlab-4.6.0.dist-info}/AUTHORS +0 -0
- {python_gitlab-4.5.0.dist-info → python_gitlab-4.6.0.dist-info}/COPYING +0 -0
- {python_gitlab-4.5.0.dist-info → python_gitlab-4.6.0.dist-info}/WHEEL +0 -0
- {python_gitlab-4.5.0.dist-info → python_gitlab-4.6.0.dist-info}/entry_points.txt +0 -0
- {python_gitlab-4.5.0.dist-info → python_gitlab-4.6.0.dist-info}/top_level.txt +0 -0
gitlab/v4/objects/issues.py
CHANGED
@@ -126,7 +126,7 @@ class ProjectIssue(
|
|
126
126
|
resource_iteration_events: ProjectIssueResourceIterationEventManager
|
127
127
|
resource_weight_events: ProjectIssueResourceWeightEventManager
|
128
128
|
|
129
|
-
@cli.register_custom_action("ProjectIssue", ("to_project_id",))
|
129
|
+
@cli.register_custom_action(cls_names="ProjectIssue", required=("to_project_id",))
|
130
130
|
@exc.on_http_error(exc.GitlabUpdateError)
|
131
131
|
def move(self, to_project_id: int, **kwargs: Any) -> None:
|
132
132
|
"""Move the issue to another project.
|
@@ -146,7 +146,9 @@ class ProjectIssue(
|
|
146
146
|
assert isinstance(server_data, dict)
|
147
147
|
self._update_attrs(server_data)
|
148
148
|
|
149
|
-
@cli.register_custom_action(
|
149
|
+
@cli.register_custom_action(
|
150
|
+
cls_names="ProjectIssue", required=("move_after_id", "move_before_id")
|
151
|
+
)
|
150
152
|
@exc.on_http_error(exc.GitlabUpdateError)
|
151
153
|
def reorder(
|
152
154
|
self,
|
@@ -178,7 +180,7 @@ class ProjectIssue(
|
|
178
180
|
assert isinstance(server_data, dict)
|
179
181
|
self._update_attrs(server_data)
|
180
182
|
|
181
|
-
@cli.register_custom_action("ProjectIssue")
|
183
|
+
@cli.register_custom_action(cls_names="ProjectIssue")
|
182
184
|
@exc.on_http_error(exc.GitlabGetError)
|
183
185
|
def related_merge_requests(self, **kwargs: Any) -> Dict[str, Any]:
|
184
186
|
"""List merge requests related to the issue.
|
@@ -199,7 +201,7 @@ class ProjectIssue(
|
|
199
201
|
assert isinstance(result, dict)
|
200
202
|
return result
|
201
203
|
|
202
|
-
@cli.register_custom_action("ProjectIssue")
|
204
|
+
@cli.register_custom_action(cls_names="ProjectIssue")
|
203
205
|
@exc.on_http_error(exc.GitlabGetError)
|
204
206
|
def closed_by(self, **kwargs: Any) -> Dict[str, Any]:
|
205
207
|
"""List merge requests that will close the issue when merged.
|
gitlab/v4/objects/iterations.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
from gitlab import types
|
1
2
|
from gitlab.base import RESTManager, RESTObject
|
2
3
|
from gitlab.mixins import ListMixin
|
3
4
|
|
@@ -16,11 +17,37 @@ class GroupIterationManager(ListMixin, RESTManager):
|
|
16
17
|
_path = "/groups/{group_id}/iterations"
|
17
18
|
_obj_cls = GroupIteration
|
18
19
|
_from_parent_attrs = {"group_id": "id"}
|
19
|
-
|
20
|
+
# When using the API, the "in" keyword collides with python's "in" keyword
|
21
|
+
# raising a SyntaxError.
|
22
|
+
# For this reason, we have to use the query_parameters argument:
|
23
|
+
# group.iterations.list(query_parameters={"in": "title"})
|
24
|
+
_list_filters = (
|
25
|
+
"include_ancestors",
|
26
|
+
"include_descendants",
|
27
|
+
"in",
|
28
|
+
"search",
|
29
|
+
"state",
|
30
|
+
"updated_after",
|
31
|
+
"updated_before",
|
32
|
+
)
|
33
|
+
_types = {"in": types.ArrayAttribute}
|
20
34
|
|
21
35
|
|
22
36
|
class ProjectIterationManager(ListMixin, RESTManager):
|
23
37
|
_path = "/projects/{project_id}/iterations"
|
24
38
|
_obj_cls = GroupIteration
|
25
39
|
_from_parent_attrs = {"project_id": "id"}
|
26
|
-
|
40
|
+
# When using the API, the "in" keyword collides with python's "in" keyword
|
41
|
+
# raising a SyntaxError.
|
42
|
+
# For this reason, we have to use the query_parameters argument:
|
43
|
+
# project.iterations.list(query_parameters={"in": "title"})
|
44
|
+
_list_filters = (
|
45
|
+
"include_ancestors",
|
46
|
+
"include_descendants",
|
47
|
+
"in",
|
48
|
+
"search",
|
49
|
+
"state",
|
50
|
+
"updated_after",
|
51
|
+
"updated_before",
|
52
|
+
)
|
53
|
+
_types = {"in": types.ArrayAttribute}
|
gitlab/v4/objects/jobs.py
CHANGED
@@ -16,7 +16,7 @@ __all__ = [
|
|
16
16
|
|
17
17
|
|
18
18
|
class ProjectJob(RefreshMixin, RESTObject):
|
19
|
-
@cli.register_custom_action("ProjectJob")
|
19
|
+
@cli.register_custom_action(cls_names="ProjectJob")
|
20
20
|
@exc.on_http_error(exc.GitlabJobCancelError)
|
21
21
|
def cancel(self, **kwargs: Any) -> Dict[str, Any]:
|
22
22
|
"""Cancel the job.
|
@@ -34,7 +34,7 @@ class ProjectJob(RefreshMixin, RESTObject):
|
|
34
34
|
assert isinstance(result, dict)
|
35
35
|
return result
|
36
36
|
|
37
|
-
@cli.register_custom_action("ProjectJob")
|
37
|
+
@cli.register_custom_action(cls_names="ProjectJob")
|
38
38
|
@exc.on_http_error(exc.GitlabJobRetryError)
|
39
39
|
def retry(self, **kwargs: Any) -> Dict[str, Any]:
|
40
40
|
"""Retry the job.
|
@@ -52,7 +52,7 @@ class ProjectJob(RefreshMixin, RESTObject):
|
|
52
52
|
assert isinstance(result, dict)
|
53
53
|
return result
|
54
54
|
|
55
|
-
@cli.register_custom_action("ProjectJob")
|
55
|
+
@cli.register_custom_action(cls_names="ProjectJob")
|
56
56
|
@exc.on_http_error(exc.GitlabJobPlayError)
|
57
57
|
def play(self, **kwargs: Any) -> None:
|
58
58
|
"""Trigger a job explicitly.
|
@@ -70,7 +70,7 @@ class ProjectJob(RefreshMixin, RESTObject):
|
|
70
70
|
assert isinstance(result, dict)
|
71
71
|
self._update_attrs(result)
|
72
72
|
|
73
|
-
@cli.register_custom_action("ProjectJob")
|
73
|
+
@cli.register_custom_action(cls_names="ProjectJob")
|
74
74
|
@exc.on_http_error(exc.GitlabJobEraseError)
|
75
75
|
def erase(self, **kwargs: Any) -> None:
|
76
76
|
"""Erase the job (remove job artifacts and trace).
|
@@ -85,7 +85,7 @@ class ProjectJob(RefreshMixin, RESTObject):
|
|
85
85
|
path = f"{self.manager.path}/{self.encoded_id}/erase"
|
86
86
|
self.manager.gitlab.http_post(path, **kwargs)
|
87
87
|
|
88
|
-
@cli.register_custom_action("ProjectJob")
|
88
|
+
@cli.register_custom_action(cls_names="ProjectJob")
|
89
89
|
@exc.on_http_error(exc.GitlabCreateError)
|
90
90
|
def keep_artifacts(self, **kwargs: Any) -> None:
|
91
91
|
"""Prevent artifacts from being deleted when expiration is set.
|
@@ -100,7 +100,7 @@ class ProjectJob(RefreshMixin, RESTObject):
|
|
100
100
|
path = f"{self.manager.path}/{self.encoded_id}/artifacts/keep"
|
101
101
|
self.manager.gitlab.http_post(path, **kwargs)
|
102
102
|
|
103
|
-
@cli.register_custom_action("ProjectJob")
|
103
|
+
@cli.register_custom_action(cls_names="ProjectJob")
|
104
104
|
@exc.on_http_error(exc.GitlabCreateError)
|
105
105
|
def delete_artifacts(self, **kwargs: Any) -> None:
|
106
106
|
"""Delete artifacts of a job.
|
@@ -115,7 +115,7 @@ class ProjectJob(RefreshMixin, RESTObject):
|
|
115
115
|
path = f"{self.manager.path}/{self.encoded_id}/artifacts"
|
116
116
|
self.manager.gitlab.http_delete(path, **kwargs)
|
117
117
|
|
118
|
-
@cli.register_custom_action("ProjectJob")
|
118
|
+
@cli.register_custom_action(cls_names="ProjectJob")
|
119
119
|
@exc.on_http_error(exc.GitlabGetError)
|
120
120
|
def artifacts(
|
121
121
|
self,
|
@@ -156,7 +156,7 @@ class ProjectJob(RefreshMixin, RESTObject):
|
|
156
156
|
result, streamed, action, chunk_size, iterator=iterator
|
157
157
|
)
|
158
158
|
|
159
|
-
@cli.register_custom_action("ProjectJob")
|
159
|
+
@cli.register_custom_action(cls_names="ProjectJob")
|
160
160
|
@exc.on_http_error(exc.GitlabGetError)
|
161
161
|
def artifact(
|
162
162
|
self,
|
@@ -199,7 +199,7 @@ class ProjectJob(RefreshMixin, RESTObject):
|
|
199
199
|
result, streamed, action, chunk_size, iterator=iterator
|
200
200
|
)
|
201
201
|
|
202
|
-
@cli.register_custom_action("ProjectJob")
|
202
|
+
@cli.register_custom_action(cls_names="ProjectJob")
|
203
203
|
@exc.on_http_error(exc.GitlabGetError)
|
204
204
|
def trace(
|
205
205
|
self,
|
@@ -209,7 +209,7 @@ class ProjectJob(RefreshMixin, RESTObject):
|
|
209
209
|
*,
|
210
210
|
iterator: bool = False,
|
211
211
|
**kwargs: Any,
|
212
|
-
) ->
|
212
|
+
) -> Optional[Union[bytes, Iterator[Any]]]:
|
213
213
|
"""Get the job trace.
|
214
214
|
|
215
215
|
Args:
|
@@ -236,12 +236,9 @@ class ProjectJob(RefreshMixin, RESTObject):
|
|
236
236
|
)
|
237
237
|
if TYPE_CHECKING:
|
238
238
|
assert isinstance(result, requests.Response)
|
239
|
-
|
239
|
+
return utils.response_content(
|
240
240
|
result, streamed, action, chunk_size, iterator=iterator
|
241
241
|
)
|
242
|
-
if TYPE_CHECKING:
|
243
|
-
assert isinstance(return_value, dict)
|
244
|
-
return return_value
|
245
242
|
|
246
243
|
|
247
244
|
class ProjectJobManager(RetrieveMixin, RESTManager):
|
@@ -89,6 +89,8 @@ class ProjectMergeRequestApprovalManager(GetWithoutIdMixin, UpdateMixin, RESTMan
|
|
89
89
|
approver_ids: Optional[List[int]] = None,
|
90
90
|
approver_group_ids: Optional[List[int]] = None,
|
91
91
|
approval_rule_name: str = "name",
|
92
|
+
*,
|
93
|
+
approver_usernames: Optional[List[str]] = None,
|
92
94
|
**kwargs: Any,
|
93
95
|
) -> RESTObject:
|
94
96
|
"""Change MR-level allowed approvers and approver groups.
|
@@ -104,6 +106,7 @@ class ProjectMergeRequestApprovalManager(GetWithoutIdMixin, UpdateMixin, RESTMan
|
|
104
106
|
"""
|
105
107
|
approver_ids = approver_ids or []
|
106
108
|
approver_group_ids = approver_group_ids or []
|
109
|
+
approver_usernames = approver_usernames or []
|
107
110
|
|
108
111
|
data = {
|
109
112
|
"name": approval_rule_name,
|
@@ -111,6 +114,7 @@ class ProjectMergeRequestApprovalManager(GetWithoutIdMixin, UpdateMixin, RESTMan
|
|
111
114
|
"rule_type": "regular",
|
112
115
|
"user_ids": approver_ids,
|
113
116
|
"group_ids": approver_group_ids,
|
117
|
+
"usernames": approver_usernames,
|
114
118
|
}
|
115
119
|
if TYPE_CHECKING:
|
116
120
|
assert self._parent is not None
|
@@ -118,12 +122,13 @@ class ProjectMergeRequestApprovalManager(GetWithoutIdMixin, UpdateMixin, RESTMan
|
|
118
122
|
self._parent.approval_rules
|
119
123
|
)
|
120
124
|
# update any existing approval rule matching the name
|
121
|
-
existing_approval_rules = approval_rules.list()
|
125
|
+
existing_approval_rules = approval_rules.list(iterator=True)
|
122
126
|
for ar in existing_approval_rules:
|
123
127
|
if ar.name == approval_rule_name:
|
124
128
|
ar.user_ids = data["user_ids"]
|
125
129
|
ar.approvals_required = data["approvals_required"]
|
126
130
|
ar.group_ids = data["group_ids"]
|
131
|
+
ar.usernames = data["usernames"]
|
127
132
|
ar.save()
|
128
133
|
return ar
|
129
134
|
# if there was no rule matching the rule name, create a new one
|
@@ -145,14 +150,14 @@ class ProjectMergeRequestApprovalRuleManager(CRUDMixin, RESTManager):
|
|
145
150
|
"name",
|
146
151
|
"approvals_required",
|
147
152
|
),
|
148
|
-
optional=("user_ids", "group_ids"),
|
153
|
+
optional=("user_ids", "group_ids", "usernames"),
|
149
154
|
)
|
150
155
|
# Important: When approval_project_rule_id is set, the name, users and
|
151
156
|
# groups of project-level rule will be copied. The approvals_required
|
152
157
|
# specified will be used.
|
153
158
|
_create_attrs = RequiredOptional(
|
154
159
|
required=("name", "approvals_required"),
|
155
|
-
optional=("approval_project_rule_id", "user_ids", "group_ids"),
|
160
|
+
optional=("approval_project_rule_id", "user_ids", "group_ids", "usernames"),
|
156
161
|
)
|
157
162
|
|
158
163
|
def get(
|
@@ -168,7 +168,7 @@ class ProjectMergeRequest(
|
|
168
168
|
resourcestateevents: ProjectMergeRequestResourceStateEventManager
|
169
169
|
reviewer_details: ProjectMergeRequestReviewerDetailManager
|
170
170
|
|
171
|
-
@cli.register_custom_action("ProjectMergeRequest")
|
171
|
+
@cli.register_custom_action(cls_names="ProjectMergeRequest")
|
172
172
|
@exc.on_http_error(exc.GitlabMROnBuildSuccessError)
|
173
173
|
def cancel_merge_when_pipeline_succeeds(self, **kwargs: Any) -> Dict[str, str]:
|
174
174
|
"""Cancel merge when the pipeline succeeds.
|
@@ -197,7 +197,7 @@ class ProjectMergeRequest(
|
|
197
197
|
assert isinstance(server_data, dict)
|
198
198
|
return server_data
|
199
199
|
|
200
|
-
@cli.register_custom_action("ProjectMergeRequest")
|
200
|
+
@cli.register_custom_action(cls_names="ProjectMergeRequest")
|
201
201
|
@exc.on_http_error(exc.GitlabListError)
|
202
202
|
def closes_issues(self, **kwargs: Any) -> RESTObjectList:
|
203
203
|
"""List issues that will close on merge."
|
@@ -222,7 +222,7 @@ class ProjectMergeRequest(
|
|
222
222
|
manager = ProjectIssueManager(self.manager.gitlab, parent=self.manager._parent)
|
223
223
|
return RESTObjectList(manager, ProjectIssue, data_list)
|
224
224
|
|
225
|
-
@cli.register_custom_action("ProjectMergeRequest")
|
225
|
+
@cli.register_custom_action(cls_names="ProjectMergeRequest")
|
226
226
|
@exc.on_http_error(exc.GitlabListError)
|
227
227
|
def commits(self, **kwargs: Any) -> RESTObjectList:
|
228
228
|
"""List the merge request commits.
|
@@ -248,7 +248,9 @@ class ProjectMergeRequest(
|
|
248
248
|
manager = ProjectCommitManager(self.manager.gitlab, parent=self.manager._parent)
|
249
249
|
return RESTObjectList(manager, ProjectCommit, data_list)
|
250
250
|
|
251
|
-
@cli.register_custom_action(
|
251
|
+
@cli.register_custom_action(
|
252
|
+
cls_names="ProjectMergeRequest", optional=("access_raw_diffs",)
|
253
|
+
)
|
252
254
|
@exc.on_http_error(exc.GitlabListError)
|
253
255
|
def changes(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]:
|
254
256
|
"""List the merge request changes.
|
@@ -266,7 +268,7 @@ class ProjectMergeRequest(
|
|
266
268
|
path = f"{self.manager.path}/{self.encoded_id}/changes"
|
267
269
|
return self.manager.gitlab.http_get(path, **kwargs)
|
268
270
|
|
269
|
-
@cli.register_custom_action("ProjectMergeRequest", (
|
271
|
+
@cli.register_custom_action(cls_names="ProjectMergeRequest", optional=("sha",))
|
270
272
|
@exc.on_http_error(exc.GitlabMRApprovalError)
|
271
273
|
def approve(self, sha: Optional[str] = None, **kwargs: Any) -> Dict[str, Any]:
|
272
274
|
"""Approve the merge request.
|
@@ -295,7 +297,7 @@ class ProjectMergeRequest(
|
|
295
297
|
self._update_attrs(server_data)
|
296
298
|
return server_data
|
297
299
|
|
298
|
-
@cli.register_custom_action("ProjectMergeRequest")
|
300
|
+
@cli.register_custom_action(cls_names="ProjectMergeRequest")
|
299
301
|
@exc.on_http_error(exc.GitlabMRApprovalError)
|
300
302
|
def unapprove(self, **kwargs: Any) -> None:
|
301
303
|
"""Unapprove the merge request.
|
@@ -317,7 +319,7 @@ class ProjectMergeRequest(
|
|
317
319
|
assert isinstance(server_data, dict)
|
318
320
|
self._update_attrs(server_data)
|
319
321
|
|
320
|
-
@cli.register_custom_action("ProjectMergeRequest")
|
322
|
+
@cli.register_custom_action(cls_names="ProjectMergeRequest")
|
321
323
|
@exc.on_http_error(exc.GitlabMRRebaseError)
|
322
324
|
def rebase(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]:
|
323
325
|
"""Attempt to rebase the source branch onto the target branch
|
@@ -333,7 +335,7 @@ class ProjectMergeRequest(
|
|
333
335
|
data: Dict[str, Any] = {}
|
334
336
|
return self.manager.gitlab.http_put(path, post_data=data, **kwargs)
|
335
337
|
|
336
|
-
@cli.register_custom_action("ProjectMergeRequest")
|
338
|
+
@cli.register_custom_action(cls_names="ProjectMergeRequest")
|
337
339
|
@exc.on_http_error(exc.GitlabMRResetApprovalError)
|
338
340
|
def reset_approvals(
|
339
341
|
self, **kwargs: Any
|
@@ -351,7 +353,7 @@ class ProjectMergeRequest(
|
|
351
353
|
data: Dict[str, Any] = {}
|
352
354
|
return self.manager.gitlab.http_put(path, post_data=data, **kwargs)
|
353
355
|
|
354
|
-
@cli.register_custom_action("ProjectMergeRequest")
|
356
|
+
@cli.register_custom_action(cls_names="ProjectMergeRequest")
|
355
357
|
@exc.on_http_error(exc.GitlabGetError)
|
356
358
|
def merge_ref(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]:
|
357
359
|
"""Attempt to merge changes between source and target branches into
|
@@ -367,9 +369,8 @@ class ProjectMergeRequest(
|
|
367
369
|
return self.manager.gitlab.http_get(path, **kwargs)
|
368
370
|
|
369
371
|
@cli.register_custom_action(
|
370
|
-
"ProjectMergeRequest",
|
371
|
-
(
|
372
|
-
(
|
372
|
+
cls_names="ProjectMergeRequest",
|
373
|
+
optional=(
|
373
374
|
"merge_commit_message",
|
374
375
|
"should_remove_source_branch",
|
375
376
|
"merge_when_pipeline_succeeds",
|
gitlab/v4/objects/milestones.py
CHANGED
@@ -31,7 +31,7 @@ __all__ = [
|
|
31
31
|
class GroupMilestone(SaveMixin, ObjectDeleteMixin, RESTObject):
|
32
32
|
_repr_attr = "title"
|
33
33
|
|
34
|
-
@cli.register_custom_action("GroupMilestone")
|
34
|
+
@cli.register_custom_action(cls_names="GroupMilestone")
|
35
35
|
@exc.on_http_error(exc.GitlabListError)
|
36
36
|
def issues(self, **kwargs: Any) -> RESTObjectList:
|
37
37
|
"""List issues related to this milestone.
|
@@ -58,7 +58,7 @@ class GroupMilestone(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
58
58
|
# FIXME(gpocentek): the computed manager path is not correct
|
59
59
|
return RESTObjectList(manager, GroupIssue, data_list)
|
60
60
|
|
61
|
-
@cli.register_custom_action("GroupMilestone")
|
61
|
+
@cli.register_custom_action(cls_names="GroupMilestone")
|
62
62
|
@exc.on_http_error(exc.GitlabListError)
|
63
63
|
def merge_requests(self, **kwargs: Any) -> RESTObjectList:
|
64
64
|
"""List the merge requests related to this milestone.
|
@@ -108,7 +108,7 @@ class ProjectMilestone(PromoteMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
108
108
|
_repr_attr = "title"
|
109
109
|
_update_method = UpdateMethod.POST
|
110
110
|
|
111
|
-
@cli.register_custom_action("ProjectMilestone")
|
111
|
+
@cli.register_custom_action(cls_names="ProjectMilestone")
|
112
112
|
@exc.on_http_error(exc.GitlabListError)
|
113
113
|
def issues(self, **kwargs: Any) -> RESTObjectList:
|
114
114
|
"""List issues related to this milestone.
|
@@ -135,7 +135,7 @@ class ProjectMilestone(PromoteMixin, SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
135
135
|
# FIXME(gpocentek): the computed manager path is not correct
|
136
136
|
return RESTObjectList(manager, ProjectIssue, data_list)
|
137
137
|
|
138
|
-
@cli.register_custom_action("ProjectMilestone")
|
138
|
+
@cli.register_custom_action(cls_names="ProjectMilestone")
|
139
139
|
@exc.on_http_error(exc.GitlabListError)
|
140
140
|
def merge_requests(self, **kwargs: Any) -> RESTObjectList:
|
141
141
|
"""List the merge requests related to this milestone.
|
gitlab/v4/objects/namespaces.py
CHANGED
@@ -24,7 +24,9 @@ class NamespaceManager(RetrieveMixin, RESTManager):
|
|
24
24
|
def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Namespace:
|
25
25
|
return cast(Namespace, super().get(id=id, lazy=lazy, **kwargs))
|
26
26
|
|
27
|
-
@cli.register_custom_action(
|
27
|
+
@cli.register_custom_action(
|
28
|
+
cls_names="NamespaceManager", required=("namespace", "parent_id")
|
29
|
+
)
|
28
30
|
@exc.on_http_error(exc.GitlabGetError)
|
29
31
|
def exists(self, namespace: str, **kwargs: Any) -> Namespace:
|
30
32
|
"""Get existence of a namespace by path.
|
gitlab/v4/objects/packages.py
CHANGED
@@ -48,8 +48,8 @@ class GenericPackageManager(RESTManager):
|
|
48
48
|
_from_parent_attrs = {"project_id": "id"}
|
49
49
|
|
50
50
|
@cli.register_custom_action(
|
51
|
-
"GenericPackageManager",
|
52
|
-
("package_name", "package_version", "file_name", "path"),
|
51
|
+
cls_names="GenericPackageManager",
|
52
|
+
required=("package_name", "package_version", "file_name", "path"),
|
53
53
|
)
|
54
54
|
@exc.on_http_error(exc.GitlabUploadError)
|
55
55
|
def upload(
|
@@ -123,8 +123,8 @@ class GenericPackageManager(RESTManager):
|
|
123
123
|
return self._obj_cls(self, attrs=attrs)
|
124
124
|
|
125
125
|
@cli.register_custom_action(
|
126
|
-
"GenericPackageManager",
|
127
|
-
("package_name", "package_version", "file_name"),
|
126
|
+
cls_names="GenericPackageManager",
|
127
|
+
required=("package_name", "package_version", "file_name"),
|
128
128
|
)
|
129
129
|
@exc.on_http_error(exc.GitlabGetError)
|
130
130
|
def download(
|
gitlab/v4/objects/pipelines.py
CHANGED
@@ -60,7 +60,7 @@ class ProjectPipeline(RefreshMixin, ObjectDeleteMixin, RESTObject):
|
|
60
60
|
test_report_summary: "ProjectPipelineTestReportSummaryManager"
|
61
61
|
variables: "ProjectPipelineVariableManager"
|
62
62
|
|
63
|
-
@cli.register_custom_action("ProjectPipeline")
|
63
|
+
@cli.register_custom_action(cls_names="ProjectPipeline")
|
64
64
|
@exc.on_http_error(exc.GitlabPipelineCancelError)
|
65
65
|
def cancel(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]:
|
66
66
|
"""Cancel the job.
|
@@ -75,7 +75,7 @@ class ProjectPipeline(RefreshMixin, ObjectDeleteMixin, RESTObject):
|
|
75
75
|
path = f"{self.manager.path}/{self.encoded_id}/cancel"
|
76
76
|
return self.manager.gitlab.http_post(path, **kwargs)
|
77
77
|
|
78
|
-
@cli.register_custom_action("ProjectPipeline")
|
78
|
+
@cli.register_custom_action(cls_names="ProjectPipeline")
|
79
79
|
@exc.on_http_error(exc.GitlabPipelineRetryError)
|
80
80
|
def retry(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]:
|
81
81
|
"""Retry the job.
|
@@ -201,7 +201,7 @@ class ProjectPipelineSchedule(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
201
201
|
variables: ProjectPipelineScheduleVariableManager
|
202
202
|
pipelines: ProjectPipelineSchedulePipelineManager
|
203
203
|
|
204
|
-
@cli.register_custom_action("ProjectPipelineSchedule")
|
204
|
+
@cli.register_custom_action(cls_names="ProjectPipelineSchedule")
|
205
205
|
@exc.on_http_error(exc.GitlabOwnershipError)
|
206
206
|
def take_ownership(self, **kwargs: Any) -> None:
|
207
207
|
"""Update the owner of a pipeline schedule.
|
@@ -219,7 +219,7 @@ class ProjectPipelineSchedule(SaveMixin, ObjectDeleteMixin, RESTObject):
|
|
219
219
|
assert isinstance(server_data, dict)
|
220
220
|
self._update_attrs(server_data)
|
221
221
|
|
222
|
-
@cli.register_custom_action("ProjectPipelineSchedule")
|
222
|
+
@cli.register_custom_action(cls_names="ProjectPipelineSchedule")
|
223
223
|
@exc.on_http_error(exc.GitlabPipelinePlayError)
|
224
224
|
def play(self, **kwargs: Any) -> Dict[str, Any]:
|
225
225
|
"""Trigger a new scheduled pipeline, which runs immediately.
|
gitlab/v4/objects/projects.py
CHANGED
@@ -3,6 +3,7 @@ GitLab API:
|
|
3
3
|
https://docs.gitlab.com/ee/api/projects.html
|
4
4
|
"""
|
5
5
|
|
6
|
+
import io
|
6
7
|
from typing import (
|
7
8
|
Any,
|
8
9
|
Callable,
|
@@ -230,7 +231,7 @@ class Project(
|
|
230
231
|
variables: ProjectVariableManager
|
231
232
|
wikis: ProjectWikiManager
|
232
233
|
|
233
|
-
@cli.register_custom_action("Project", ("forked_from_id",))
|
234
|
+
@cli.register_custom_action(cls_names="Project", required=("forked_from_id",))
|
234
235
|
@exc.on_http_error(exc.GitlabCreateError)
|
235
236
|
def create_fork_relation(self, forked_from_id: int, **kwargs: Any) -> None:
|
236
237
|
"""Create a forked from/to relation between existing projects.
|
@@ -246,7 +247,7 @@ class Project(
|
|
246
247
|
path = f"/projects/{self.encoded_id}/fork/{forked_from_id}"
|
247
248
|
self.manager.gitlab.http_post(path, **kwargs)
|
248
249
|
|
249
|
-
@cli.register_custom_action("Project")
|
250
|
+
@cli.register_custom_action(cls_names="Project")
|
250
251
|
@exc.on_http_error(exc.GitlabDeleteError)
|
251
252
|
def delete_fork_relation(self, **kwargs: Any) -> None:
|
252
253
|
"""Delete a forked relation between existing projects.
|
@@ -261,7 +262,7 @@ class Project(
|
|
261
262
|
path = f"/projects/{self.encoded_id}/fork"
|
262
263
|
self.manager.gitlab.http_delete(path, **kwargs)
|
263
264
|
|
264
|
-
@cli.register_custom_action("Project")
|
265
|
+
@cli.register_custom_action(cls_names="Project")
|
265
266
|
@exc.on_http_error(exc.GitlabGetError)
|
266
267
|
def languages(self, **kwargs: Any) -> Union[Dict[str, Any], requests.Response]:
|
267
268
|
"""Get languages used in the project with percentage value.
|
@@ -276,7 +277,7 @@ class Project(
|
|
276
277
|
path = f"/projects/{self.encoded_id}/languages"
|
277
278
|
return self.manager.gitlab.http_get(path, **kwargs)
|
278
279
|
|
279
|
-
@cli.register_custom_action("Project")
|
280
|
+
@cli.register_custom_action(cls_names="Project")
|
280
281
|
@exc.on_http_error(exc.GitlabCreateError)
|
281
282
|
def star(self, **kwargs: Any) -> None:
|
282
283
|
"""Star a project.
|
@@ -294,7 +295,7 @@ class Project(
|
|
294
295
|
assert isinstance(server_data, dict)
|
295
296
|
self._update_attrs(server_data)
|
296
297
|
|
297
|
-
@cli.register_custom_action("Project")
|
298
|
+
@cli.register_custom_action(cls_names="Project")
|
298
299
|
@exc.on_http_error(exc.GitlabDeleteError)
|
299
300
|
def unstar(self, **kwargs: Any) -> None:
|
300
301
|
"""Unstar a project.
|
@@ -312,7 +313,7 @@ class Project(
|
|
312
313
|
assert isinstance(server_data, dict)
|
313
314
|
self._update_attrs(server_data)
|
314
315
|
|
315
|
-
@cli.register_custom_action("Project")
|
316
|
+
@cli.register_custom_action(cls_names="Project")
|
316
317
|
@exc.on_http_error(exc.GitlabCreateError)
|
317
318
|
def archive(self, **kwargs: Any) -> None:
|
318
319
|
"""Archive a project.
|
@@ -330,7 +331,7 @@ class Project(
|
|
330
331
|
assert isinstance(server_data, dict)
|
331
332
|
self._update_attrs(server_data)
|
332
333
|
|
333
|
-
@cli.register_custom_action("Project")
|
334
|
+
@cli.register_custom_action(cls_names="Project")
|
334
335
|
@exc.on_http_error(exc.GitlabDeleteError)
|
335
336
|
def unarchive(self, **kwargs: Any) -> None:
|
336
337
|
"""Unarchive a project.
|
@@ -349,7 +350,9 @@ class Project(
|
|
349
350
|
self._update_attrs(server_data)
|
350
351
|
|
351
352
|
@cli.register_custom_action(
|
352
|
-
"Project",
|
353
|
+
cls_names="Project",
|
354
|
+
required=("group_id", "group_access"),
|
355
|
+
optional=("expires_at",),
|
353
356
|
)
|
354
357
|
@exc.on_http_error(exc.GitlabCreateError)
|
355
358
|
def share(
|
@@ -378,7 +381,7 @@ class Project(
|
|
378
381
|
}
|
379
382
|
self.manager.gitlab.http_post(path, post_data=data, **kwargs)
|
380
383
|
|
381
|
-
@cli.register_custom_action("Project", ("group_id",))
|
384
|
+
@cli.register_custom_action(cls_names="Project", required=("group_id",))
|
382
385
|
@exc.on_http_error(exc.GitlabDeleteError)
|
383
386
|
def unshare(self, group_id: int, **kwargs: Any) -> None:
|
384
387
|
"""Delete a shared project link within a group.
|
@@ -395,7 +398,7 @@ class Project(
|
|
395
398
|
self.manager.gitlab.http_delete(path, **kwargs)
|
396
399
|
|
397
400
|
# variables not supported in CLI
|
398
|
-
@cli.register_custom_action("Project", ("ref", "token"))
|
401
|
+
@cli.register_custom_action(cls_names="Project", required=("ref", "token"))
|
399
402
|
@exc.on_http_error(exc.GitlabCreateError)
|
400
403
|
def trigger_pipeline(
|
401
404
|
self,
|
@@ -426,7 +429,7 @@ class Project(
|
|
426
429
|
assert isinstance(attrs, dict)
|
427
430
|
return ProjectPipeline(self.pipelines, attrs)
|
428
431
|
|
429
|
-
@cli.register_custom_action("Project")
|
432
|
+
@cli.register_custom_action(cls_names="Project")
|
430
433
|
@exc.on_http_error(exc.GitlabHousekeepingError)
|
431
434
|
def housekeeping(self, **kwargs: Any) -> None:
|
432
435
|
"""Start the housekeeping task.
|
@@ -442,7 +445,7 @@ class Project(
|
|
442
445
|
path = f"/projects/{self.encoded_id}/housekeeping"
|
443
446
|
self.manager.gitlab.http_post(path, **kwargs)
|
444
447
|
|
445
|
-
@cli.register_custom_action("Project")
|
448
|
+
@cli.register_custom_action(cls_names="Project")
|
446
449
|
@exc.on_http_error(exc.GitlabRestoreError)
|
447
450
|
def restore(self, **kwargs: Any) -> None:
|
448
451
|
"""Restore a project marked for deletion.
|
@@ -457,7 +460,7 @@ class Project(
|
|
457
460
|
path = f"/projects/{self.encoded_id}/restore"
|
458
461
|
self.manager.gitlab.http_post(path, **kwargs)
|
459
462
|
|
460
|
-
@cli.register_custom_action("Project", optional=("wiki",))
|
463
|
+
@cli.register_custom_action(cls_names="Project", optional=("wiki",))
|
461
464
|
@exc.on_http_error(exc.GitlabGetError)
|
462
465
|
def snapshot(
|
463
466
|
self,
|
@@ -500,7 +503,7 @@ class Project(
|
|
500
503
|
result, streamed, action, chunk_size, iterator=iterator
|
501
504
|
)
|
502
505
|
|
503
|
-
@cli.register_custom_action("Project", ("scope", "search"))
|
506
|
+
@cli.register_custom_action(cls_names="Project", required=("scope", "search"))
|
504
507
|
@exc.on_http_error(exc.GitlabSearchError)
|
505
508
|
def search(
|
506
509
|
self, scope: str, search: str, **kwargs: Any
|
@@ -523,7 +526,7 @@ class Project(
|
|
523
526
|
path = f"/projects/{self.encoded_id}/search"
|
524
527
|
return self.manager.gitlab.http_list(path, query_data=data, **kwargs)
|
525
528
|
|
526
|
-
@cli.register_custom_action("Project")
|
529
|
+
@cli.register_custom_action(cls_names="Project")
|
527
530
|
@exc.on_http_error(exc.GitlabCreateError)
|
528
531
|
def mirror_pull(self, **kwargs: Any) -> None:
|
529
532
|
"""Start the pull mirroring process for the project.
|
@@ -538,7 +541,7 @@ class Project(
|
|
538
541
|
path = f"/projects/{self.encoded_id}/mirror/pull"
|
539
542
|
self.manager.gitlab.http_post(path, **kwargs)
|
540
543
|
|
541
|
-
@cli.register_custom_action("Project")
|
544
|
+
@cli.register_custom_action(cls_names="Project")
|
542
545
|
@exc.on_http_error(exc.GitlabGetError)
|
543
546
|
def mirror_pull_details(self, **kwargs: Any) -> Dict[str, Any]:
|
544
547
|
"""Get a project's pull mirror details.
|
@@ -561,7 +564,7 @@ class Project(
|
|
561
564
|
assert isinstance(result, dict)
|
562
565
|
return result
|
563
566
|
|
564
|
-
@cli.register_custom_action("Project", ("to_namespace",))
|
567
|
+
@cli.register_custom_action(cls_names="Project", required=("to_namespace",))
|
565
568
|
@exc.on_http_error(exc.GitlabTransferProjectError)
|
566
569
|
def transfer(self, to_namespace: Union[int, str], **kwargs: Any) -> None:
|
567
570
|
"""Transfer a project to the given namespace ID
|
@@ -786,7 +789,7 @@ class ProjectManager(CRUDMixin, RESTManager):
|
|
786
789
|
@exc.on_http_error(exc.GitlabImportError)
|
787
790
|
def import_project(
|
788
791
|
self,
|
789
|
-
file:
|
792
|
+
file: io.BufferedReader,
|
790
793
|
path: str,
|
791
794
|
name: Optional[str] = None,
|
792
795
|
namespace: Optional[str] = None,
|