8000 feat(api): add support for external status check · python-gitlab/python-gitlab@175b355 · GitHub
[go: up one dir, main page]

Skip to content
< 8000 header class="HeaderMktg header-logged-out js-details-container js-header Details f4 py-3" role="banner" data-is-top="true" data-color-mode=light data-light-theme=light data-dark-theme=dark>

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

< 8000 /qbsearch-input>
Appearance settings

Commit 175b355

Browse files
SachinKSingh28nejch
authored andcommitted
feat(api): add support for external status check
1 parent de29503 commit 175b355

File tree

8 files changed

+258
-0
lines changed

8 files changed

+258
-0
lines changed

docs/api-objects.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ API examples
6363
gl_objects/settings
6464
gl_objects/snippets
6565
gl_objects/statistics
66+
gl_objects/status_checks
6667
gl_objects/system_hooks
6768
gl_objects/templates
6869
gl_objects/todos

docs/gl_objects/status_checks.rst

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#######################
2+
External Status Checks
3+
#######################
4+
5+
Manage external status checks for projects and merge requests.
6+
7+
8+
Project external status checks
9+
===============================
10+
11+
Reference
12+
---------
13+
14+
* v4 API:
15+
16+
+ :class:`gitlab.v4.objects.ProjectExternalStatusCheck`
17+
+ :class:`gitlab.v4.objects.ProjectExternalStatusCheckManager`
18+
+ :attr:`gitlab.v4.objects.Project.external_status_checks`
19+
20+
* GitLab API: https://docs.gitlab.com/ee/api/status_checks.html
21+
22+
Examples
23+
---------
24+
25+
List external status checks for a project::
26+
27+
status_checks = project.external_status_checks.list()
28+
29+
Create an external status check with shared secret::
30+
31+
status_checks = project.external_status_checks.create({
32+
"name": "mr_blocker",
33+
"external_url": "https://example.com/mr-status-check",
34+
"shared_secret": "secret-string"
35+
})
36+
37+
Create an external status check with shared secret for protected branches::
38+
39+
protected_branch = project.protectedbranches.get('main')
40+
41+
status_check = project.external_status_checks.create({
42+
"name": "mr_blocker",
43+
"external_url": "https://example.com/mr-status-check",
44+
"shared_secret": "secret-string",
45+
"protected_branch_ids": [protected_branch.id]
46+
})
47+
48+
49+
Update an external status check::
50+
51+
status_check.external_url = "https://example.com/mr-blocker"
52+
status_check.save()
53+
54+
Delete an external status check::
55+
56+
status_check.delete(status_check_id)
57+

gitlab/v4/objects/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
from .sidekiq import *
6969
from .snippets import *
7070
from .statistics import *
71+
from .status_checks import *
7172
from .tags import *
7273
from .templates import *
7374
from .todos import *

gitlab/v4/objects/merge_requests.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
from .notes import ProjectMergeRequestNoteManager # noqa: F401
4545
from .pipelines import ProjectMergeRequestPipelineManager # noqa: F401
4646
from .reviewers import ProjectMergeRequestReviewerDetailManager
47+
from .status_checks import ProjectMergeRequestStatusCheckManager
4748

4849
__all__ = [
4950
"MergeRequest",
@@ -167,6 +168,7 @@ class ProjectMergeRequest(
167168
resourcemilestoneevents: ProjectMergeRequestResourceMilestoneEventManager
168169
resourcestateevents: ProjectMergeRequestResourceStateEventManager
169170
reviewer_details: ProjectMergeRequestReviewerDetailManager
171+
status_checks: ProjectMergeRequestStatusCheckManager
170172

171173
@cli.register_custom_action(cls_names="ProjectMergeRequest")
172174
@exc.on_http_error(exc.GitlabMROnBuildSuccessError)

gitlab/v4/objects/projects.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
ProjectAdditionalStatisticsManager,
105105
ProjectIssuesStatisticsManager,
106106
)
107+
from .status_checks import ProjectExternalStatusCheckManager # noqa: F401
107108
from .tags import ProjectProtectedTagManager, ProjectTagManager # noqa: F401
108109
from .templates import ( # noqa: F401
109110
ProjectDockerfileTemplateManager,
@@ -253,6 +254,7 @@ class Project(
253254
secure_files: ProjectSecureFileManager
254255
services: ProjectServiceManager
255256
snippets: ProjectSnippetManager
257+
external_status_checks: ProjectExternalStatusCheckManager
256258
storage: "ProjectStorageManager"
257259
tags: ProjectTagManager
258260
triggers: ProjectTriggerManager

gitlab/v4/objects/status_checks.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from gitlab.base import RESTManager, RESTObject
2+
from gitlab.mixins import (
3+
CreateMixin,
4+
DeleteMixin,
5+
ListMixin,
6+
ObjectDeleteMixin,
7+
SaveMixin,
8+
UpdateMethod,
9+
UpdateMixin,
10+
)
11+
from gitlab.types import ArrayAttribute, RequiredOptional
12+
13+
__all__ = [
14+
"ProjectExternalStatusCheck",
15+
"ProjectExternalStatusCheckManager",
16+
"ProjectMergeRequestStatusCheck",
17+
"ProjectMergeRequestStatusCheckManager",
18+
]
19+
20+
21+
class ProjectExternalStatusCheck(SaveMixin, ObjectDeleteMixin, RESTObject):
22+
pass
23+
24+
25+
class ProjectExternalStatusCheckManager(
26+
ListMixin, CreateMixin, UpdateMixin, DeleteMixin, RESTManager
27+
):
28+
_path = "/projects/{project_id}/external_status_checks"
29+
_obj_cls = ProjectExternalStatusCheck
30+
_from_parent_attrs = {"project_id": "id"}
31+
_create_attrs = RequiredOptional(
32+
required=("name", "external_url"),
33+
optional=("shared_secret", "protected_branch_ids"),
34+
)
35+
_update_attrs = RequiredOptional(
36+
optional=("name", "external_url", "shared_secret", "protected_branch_ids")
37+
)
38+
_types = {"protected_branch_ids": ArrayAttribute}
39+
40+
41+
class ProjectMergeRequestStatusCheck(SaveMixin, RESTObject):
42+
pass
43+
44+
45+
class ProjectMergeRequestStatusCheckManager(ListMixin, RESTManager):
46+
_path = "/projects/{project_id}/merge_requests/{merge_request_iid}/status_checks"
47+
_obj_cls = ProjectMergeRequestStatusCheck
48+
_from_parent_attrs = {"project_id": "project_id", "merge_request_iid": "iid"}
49+
_update_attrs = RequiredOptional(
50+
required=("sha", "external_status_check_id", "status")
51+
)
52+
_update_method = UpdateMethod.POST

tests/functional/api/test_projects.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,3 +399,19 @@ def test_project_transfer(gl, project, group):
399399

400400
project = gl.projects.get(project.id)
401401
assert project.namespace["path"] == gl.user.username
402+
403+
404+
@pytest.mark.gitlab_premium
405+
def test_project_external_status_check_create(gl, project):
406+
status_check = project.external_status_checks.create(
407+
{"name": "MR blocker", "external_url": "https://example.com/mr-blocker"}
408+
)
409+
assert status_check.name == "MR blocker"
410+
assert status_check.external_url == "https://example.com/mr-blocker"
411+
412+
413+
@pytest.mark.gitlab_premium
414+
def test_project_external_status_check_list(gl, project):
415+
status_checks = project.external_status_checks.list()
416+
417+
assert len(status_checks) == 1
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
"""
2+
GitLab API: https://docs.gitlab.com/ee/api/status_checks.html
3+
"""
4+
5+
import pytest
6+
import responses
7+
8+
9+
@pytest.fixture
10+
def external_status_check():
11+
return {
12+
"id": 1,
13+
"name": "MR blocker",
14+
"project_id": 1,
15+
"external_url": "https://example.com/mr-blocker",
16+
"hmac": True,
17+
"protected_branches": [
18+
{
19+
"id": 1,
20+
"project_id": 1,
21+
"name": "main",
22+
"created_at": "2020-10-12T14:04:50.787Z",
23+
"updated_at": "2020-10-12T14:04:50.787Z",
24+
"code_owner_approval_required": False,
25+
}
26+
],
27+
}
28+
29+
30+
@pytest.fixture
31+
def updated_external_status_check():
32+
return {
33+
"id": 1,
34+
"name": "Updated MR blocker",
35+
"project_id": 1,
36+
"external_url": "https://example.com/mr-blocker",
37+
"hmac": True,
38+
"protected_branches": [
39+
{
40+
"id": 1,
41+
"project_id": 1,
42+
"name": "main",
43+
"created_at": "2020-10-12T14:04:50.787Z",
44+
"updated_at": "2020-10-12T14:04:50.787Z",
45+
"code_owner_approval_required": False,
46+
}
47+
],
48+
}
49+
50+
51+
@pytest.fixture
52+
def resp_list_external_status_checks(external_status_check):
53+
with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
54+
rsps.add(
55+
method=responses.GET,
56+
url="http://localhost/api/v4/projects/1/external_status_checks",
57+
json=[external_status_check],
58+
content_type="application/json",
59+
status=200,
60+
)
61+
yield rsps
62+
63+
64+
@pytest.fixture
65+
def resp_create_external_status_checks(external_status_check):
66+
with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
67+
rsps.add(
68+
method=responses.POST,
69+
url="http://localhost/api/v4/projects/1/external_status_checks",
70+
json=external_status_check,
71+
content_type="application/json",
72+
status=200,
73+
)
74+
yield rsps
75+
76+
77+
@pytest.fixture
78+
def resp_update_external_status_checks(updated_external_status_check):
79+
with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
80+
rsps.add(
81+
method=responses.PUT,
82+
url="http://localhost/api/v4/groups/1/external_status_checks",
83+
json=updated_external_status_check,
84+
content_type="application/json",
85+
status=200,
86+
)
87+
yield rsps
88+
89+
90+
@pytest.fixture
91+
def resp_delete_external_status_checks():
92+
content = []
93+
94+
with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
95+
rsps.add(
96+
method=responses.DELETE,
97+
url="http://localhost/api/v4/projects/1/external_status_checks/1",
98+
status=204,
99+
)
100+
rsps.add(
101+
method=responses.GET,
102+
url="http://localhost/api/v4/projects/1/external_status_checks",
103+
json=content,
104+
content_type="application/json",
105+
status=200,
106+
)
107+
yield rsps
108+
109+
110+
def test_list_external_status_checks(gl, resp_list_external_status_checks):
111+
status_checks = gl.projects.get(1, lazy=True).external_status_checks.list()
112+
assert len(status_checks) == 1
113+
assert status_checks[0].name == "MR blocker"
114+
115+
116+
def test_create_external_status_checks(gl, resp_create_external_status_checks):
117+
access_token = gl.projects.get(1, lazy=True).external_status_checks.create(
118+
{"name": "MR blocker", "external_url": "https://example.com/mr-blocker"}
119+
)
120+
assert access_token.name == "MR blocker"
121+
assert access_token.external_url == "https://example.com/mr-blocker"
122+
123+
124+
def test_delete_external_status_checks(gl, resp_delete_external_status_checks):
125+
gl.projects.get(1, lazy=True).external_status_checks.delete(1)
126+
status_checks = gl.projects.get(1, lazy=True).external_status_checks.list()
127+
assert len(status_checks) == 0

0 commit comments

Comments
 (0)
0