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

Commit56fbe02

Browse files
authored
Merge pull request#2254 from python-gitlab/jlvillal/deploy_approve
feat: add support for deployment approval endpoint
2 parentsa35fad1 +9c9eeb9 commit56fbe02

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