Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9f9e25b

Browse files
feat: add support for deployment approval endpoint
Add support for the deployment approval endpoint[1][1]https://docs.gitlab.com/ee/api/deployments.html#approve-or-reject-a-blocked-deploymentCloses:#2253
1 parentf67514e commit9f9e25b

File tree

4 files changed

+199
-3
lines changed

4 files changed

+199
-3
lines changed

‎docs/gl_objects/deployments.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ Update a deployment::
4040
deployment.status = "failed"
4141
deployment.save()
4242

43+
Approve a deployment::
44+
45+
deployment = project.deployments.get(42)
46+
# `status` must be either "approved" or "rejected".
47+
deployment.approval(status="approved")
48+
49+
Reject a deployment::
50+
51+
deployment = project.deployments.get(42)
52+
# Using the optional `comment` and `represented_as` arguments
53+
deployment.approval(status="rejected", comment="Fails CI", represented_as="security")
54+
4355
Merge requests associated with a deployment
4456
===========================================
4557

‎gitlab/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,10 @@ class GitlabUserRejectError(GitlabOperationError):
301301
pass
302302

303303

304+
classGitlabDeploymentApprovalError(GitlabOperationError):
305+
pass
306+
307+
304308
# For an explanation of how these type-hints work see:
305309
# https://mypy.readthedocs.io/en/stable/generics.html#declaring-decorators
306310
#

‎gitlab/v4/objects/deployments.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1-
fromtypingimportAny,cast,Union
1+
"""
2+
GitLab API:
3+
https://docs.gitlab.com/ee/api/deployments.html
4+
"""
5+
fromtypingimportAny,cast,Dict,Optional,TYPE_CHECKING,Union
26

7+
fromgitlabimportcli
8+
fromgitlabimportexceptionsasexc
39
fromgitlab.baseimportRESTManager,RESTObject
410
fromgitlab.mixinsimportCreateMixin,RetrieveMixin,SaveMixin,UpdateMixin
511
fromgitlab.typesimportRequiredOptional
@@ -15,6 +21,50 @@
1521
classProjectDeployment(SaveMixin,RESTObject):
1622
mergerequests:ProjectDeploymentMergeRequestManager
1723

24+
@cli.register_custom_action(
25+
"ProjectDeployment",
26+
mandatory=("status",),
27+
optional=("comment","represented_as"),
28+
)
29+
@exc.on_http_error(exc.GitlabDeploymentApprovalError)
30+
defapproval(
31+
self,
32+
status:str,
33+
comment:Optional[str]=None,
34+
represented_as:Optional[str]=None,
35+
**kwargs:Any,
36+
)->Dict[str,Any]:
37+
"""Approve or reject a blocked deployment.
38+
39+
Args:
40+
status: Either "approved" or "rejected"
41+
comment: A comment to go with the approval
42+
represented_as: The name of the User/Group/Role to use for the
43+
approval, when the user belongs to multiple
44+
approval rules.
45+
**kwargs: Extra options to send to the server (e.g. sudo)
46+
47+
Raises:
48+
GitlabAuthenticationError: If authentication is not correct
49+
GitlabMRApprovalError: If the approval failed
50+
51+
Returns:
52+
A dict containing the result.
53+
54+
https://docs.gitlab.com/ee/api/deployments.html#approve-or-reject-a-blocked-deployment
55+
"""
56+
path=f"{self.manager.path}/{self.encoded_id}/approval"
57+
data= {"status":status}
58+
ifcommentisnotNone:
59+
data["comment"]=comment
60+
ifrepresented_asisnotNone:
61+
data["represented_as"]=represented_as
62+
63+
server_data=self.manager.gitlab.http_post(path,post_data=data,**kwargs)
64+
ifTYPE_CHECKING:
65+
assertisinstance(server_data,dict)
66+
returnserver_data
67+
1868

1969
classProjectDeploymentManager(RetrieveMixin,CreateMixin,UpdateMixin,RESTManager):
2070
_path="/projects/{project_id}/deployments"

‎tests/unit/objects/test_deployments.py

Lines changed: 132 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,25 @@
66

77

88
@pytest.fixture
9-
defresp_deployment():
9+
defresp_deployment_get():
10+
withresponses.RequestsMock()asrsps:
11+
rsps.add(
12+
method=responses.GET,
13+
url="http://localhost/api/v4/projects/1/deployments/42",
14+
json=response_get_content,
15+
content_type="application/json",
16+
status=200,
17+
)
18+
yieldrsps
19+
20+
21+
@pytest.fixture
22+
defdeployment(project):
23+
returnproject.deployments.get(42,lazy=True)
24+
25+
26+
@pytest.fixture
27+
defresp_deployment_create():
1028
content= {"id":42,"status":"success","ref":"main"}
1129

1230
withresponses.RequestsMock()asrsps:
@@ -31,7 +49,42 @@ def resp_deployment():
3149
yieldrsps
3250

3351

34-
deftest_deployment(project,resp_deployment):
52+
@pytest.fixture
53+
defresp_deployment_approval():
54+
content= {
55+
"user": {
56+
"id":100,
57+
"username":"security-user-1",
58+
"name":"security user-1",
59+
"state":"active",
60+
"avatar_url":"https://www.gravatar.com/avatar/e130fcd3a1681f41a3de69d10841afa9?s=80&d=identicon",
61+
"web_url":"http://localhost:3000/security-user-1",
62+
},
63+
"status":"approved",
64+
"created_at":"2022-02-24T20:22:30.097Z",
65+
"comment":"Looks good to me",
66+
}
67+
68+
withresponses.RequestsMock()asrsps:
69+
rsps.add(
70+
method=responses.POST,
71+
url="http://localhost/api/v4/projects/1/deployments/42/approval",
72+
json=content,
73+
content_type="application/json",
74+
status=200,
75+
)
76+
yieldrsps
77+
78+
79+
deftest_deployment_get(project,resp_deployment_get):
80+
deployment=project.deployments.get(42)
81+
assertdeployment.id==42
82+
assertdeployment.iid==2
83+
assertdeployment.status=="success"
84+
assertdeployment.ref=="main"
85+
86+
87+
deftest_deployment_create(project,resp_deployment_create):
3588
deployment=project.deployments.create(
3689
{
3790
"environment":"Test",
@@ -48,3 +101,80 @@ def test_deployment(project, resp_deployment):
48101
deployment.status="failed"
49102
deployment.save()
50103
assertdeployment.status=="failed"
104+
105+
106+
deftest_deployment_approval(deployment,resp_deployment_approval)->None:
107+
result=deployment.approval(status="approved")
108+
assertresult["status"]=="approved"
109+
assertresult["comment"]=="Looks good to me"
110+
111+
112+
response_get_content= {
113+
"id":42,
114+
"iid":2,
115+
"ref":"main",
116+
"sha":"a91957a858320c0e17f3a0eca7cfacbff50ea29a",
117+
"created_at":"2016-08-11T11:32:35.444Z",
118+
"updated_at":"2016-08-11T11:34:01.123Z",
119+
"status":"success",
120+
"user": {
121+
"name":"Administrator",
122+
"username":"root",
123+
"id":1,
124+
"state":"active",
125+
"avatar_url":"http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
126+
"web_url":"http://localhost:3000/root",
127+
},
128+
"environment": {
129+
"id":9,
130+
"name":"production",
131+
"external_url":"https://about.gitlab.com",
132+
},
133+
"deployable": {
134+
"id":664,
135+
"status":"success",
136+
"stage":"deploy",
137+
"name":"deploy",
138+
"ref":"main",
139+
"tag":False,
140+
"coverage":None,
141+
"created_at":"2016-08-11T11:32:24.456Z",
142+
"started_at":None,
143+
"finished_at":"2016-08-11T11:32:35.145Z",
144+
"user": {
145+
"id":1,
146+
"name":"Administrator",
147+
"username":"root",
148+
"state":"active",
149+
"avatar_url":"http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
150+
"web_url":"http://gitlab.dev/root",
151+
"created_at":"2015-12-21T13:14:24.077Z",
152+
"bio":None,
153+
"location":None,
154+
"skype":"",
155+
"linkedin":"",
156+
"twitter":"",
157+
"website_url":"",
158+
"organization":"",
159+
},
160+
"commit": {
161+
"id":"a91957a858320c0e17f3a0eca7cfacbff50ea29a",
162+
"short_id":"a91957a8",
163+
"title":"Merge branch 'rename-readme' into 'main'\r",
164+
"author_name":"Administrator",
165+
"author_email":"admin@example.com",
166+
"created_at":"2016-08-11T13:28:26.000+02:00",
167+
"message":"Merge branch 'rename-readme' into 'main'\r\n\r\nRename README\r\n\r\n\r\n\r\nSee merge request !2",
168+
},
169+
"pipeline": {
170+
"created_at":"2016-08-11T07:43:52.143Z",
171+
"id":42,
172+
"ref":"main",
173+
"sha":"a91957a858320c0e17f3a0eca7cfacbff50ea29a",
174+
"status":"success",
175+
"updated_at":"2016-08-11T07:43:52.143Z",
176+
"web_url":"http://gitlab.dev/root/project/pipelines/5",
177+
},
178+
"runner":None,
179+
},
180+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp