Skip to content

Commit 1feabc0

Browse files
authored
Merge pull request #2084 from calve/protected-environments
feat: Add support for Protected Environments
2 parents 8342f53 + 1dc9d0f commit 1feabc0

File tree

6 files changed

+109
-3
lines changed

6 files changed

+109
-3
lines changed

docs/api-objects.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ API examples
4343
gl_objects/projects
4444
gl_objects/project_access_tokens
4545
gl_objects/protected_branches
46+
gl_objects/protected_environments
4647
gl_objects/releases
4748
gl_objects/runners
4849
gl_objects/remote_mirrors

docs/gl_objects/environments.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ Delete an environment for a project::
3939
# or
4040
environment.delete()
4141

42-
Stop an environments::
42+
Stop an environment::
4343

4444
environment.stop()
45+
46+
To manage protected environments, see :doc:`/gl_objects/protected_environments`.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
######################
2+
Protected environments
3+
######################
4+
5+
You can list and manage protected environments in a project.
6+
7+
References
8+
----------
9+
10+
* v4 API:
11+
12+
+ :class:`gitlab.v4.objects.ProjectProtectedEnvironment`
13+
+ :class:`gitlab.v4.objects.ProjectProtectedEnvironmentManager`
14+
+ :attr:`gitlab.v4.objects.Project.protected_environment`
15+
16+
* GitLab API: https://docs.gitlab.com/ee/api/protected_environments.html
17+
18+
Examples
19+
--------
20+
21+
Get the list of protected environments for a project::
22+
23+
p_environments = project.protected_environments.list()
24+
25+
Get a single protected environment::
26+
27+
p_environments = project.protected_environments.get('production')
28+
29+
Protect an existing environment::
30+
31+
p_environment = project.protected_environments.create(
32+
{
33+
'name': 'production',
34+
'deploy_access_levels': [
35+
{'access_level': 40}
36+
],
37+
}
38+
)
39+
40+
41+
Unprotect a protected environment::
42+
43+
p_environment = project.protected_environments.delete('production')
44+
# or
45+
p_environment.delete()

gitlab/v4/objects/environments.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
__all__ = [
1919
"ProjectEnvironment",
2020
"ProjectEnvironmentManager",
21+
"ProjectProtectedEnvironment",
22+
"ProjectProtectedEnvironmentManager",
2123
]
2224

2325

@@ -55,3 +57,30 @@ def get(
5557
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
5658
) -> ProjectEnvironment:
5759
return cast(ProjectEnvironment, super().get(id=id, lazy=lazy, **kwargs))
60+
61+
62+
class ProjectProtectedEnvironment(ObjectDeleteMixin, RESTObject):
63+
_id_attr = "name"
64+
_repr_attr = "name"
65+
66+
67+
class ProjectProtectedEnvironmentManager(
68+
RetrieveMixin, CreateMixin, DeleteMixin, RESTManager
69+
):
70+
_path = "/projects/{project_id}/protected_environments"
71+
_obj_cls = ProjectProtectedEnvironment
72+
_from_parent_attrs = {"project_id": "id"}
73+
_create_attrs = RequiredOptional(
74+
required=(
75+
"name",
76+
"deploy_access_levels",
77+
),
78+
optional=("required_approval_count", "approval_rules"),
79+
)
80+
81+
def get(
82+
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
83+
) -> ProjectProtectedEnvironment:
84+
return cast(
85+
ProjectProtectedEnvironment, super().get(id=id, lazy=lazy, **kwargs)
86+
)

gitlab/v4/objects/projects.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@
3131
from .deploy_keys import ProjectKeyManager # noqa: F401
3232
from .deploy_tokens import ProjectDeployTokenManager # noqa: F401
3333
from .deployments import ProjectDeploymentManager # noqa: F401
34-
from .environments import ProjectEnvironmentManager # noqa: F401
34+
from .environments import ( # noqa: F401
35+
ProjectEnvironmentManager,
36+
ProjectProtectedEnvironmentManager,
37+
)
3538
from .events import ProjectEventManager # noqa: F401
3639
from .export_import import ProjectExportManager, ProjectImportManager # noqa: F401
3740
from .files import ProjectFileManager # noqa: F401
@@ -175,6 +178,7 @@ class Project(RefreshMixin, SaveMixin, ObjectDeleteMixin, RepositoryMixin, RESTO
175178
pagesdomains: ProjectPagesDomainManager
176179
pipelines: ProjectPipelineManager
177180
pipelineschedules: ProjectPipelineScheduleManager
181+
protected_environments: ProjectProtectedEnvironmentManager
178182
protectedbranches: ProjectProtectedBranchManager
179183
protectedtags: ProjectProtectedTagManager
180184
pushrules: ProjectPushRulesManager

tests/unit/objects/test_environments.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import pytest
55
import responses
66

7-
from gitlab.v4.objects import ProjectEnvironment
7+
from gitlab.v4.objects import ProjectEnvironment, ProjectProtectedEnvironment
88

99

1010
@pytest.fixture
@@ -22,9 +22,34 @@ def resp_get_environment():
2222
yield rsps
2323

2424

25+
@pytest.fixture
26+
def resp_get_protected_environment():
27+
content = {
28+
"name": "protected_environment_name",
29+
"last_deployment": "my birthday",
30+
}
31+
32+
with responses.RequestsMock() as rsps:
33+
rsps.add(
34+
method=responses.GET,
35+
url="http://localhost/api/v4/projects/1/protected_environments/2",
36+
json=content,
37+
content_type="application/json",
38+
status=200,
39+
)
40+
yield rsps
41+
42+
2543
def test_project_environments(project, resp_get_environment):
2644
environment = project.environments.get(1)
2745
assert isinstance(environment, ProjectEnvironment)
2846
assert environment.id == 1
2947
assert environment.last_deployment == "sometime"
3048
assert environment.name == "environment_name"
49+
50+
51+
def test_project_protected_environments(project, resp_get_protected_environment):
52+
protected_environment = project.protected_environments.get(2)
53+
assert isinstance(protected_environment, ProjectProtectedEnvironment)
54+
assert protected_environment.last_deployment == "my birthday"
55+
assert protected_environment.name == "protected_environment_name"

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