gitlabform 4.0.2__tar.gz → 4.0.4__tar.gz
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.
- {gitlabform-4.0.2 → gitlabform-4.0.4}/PKG-INFO +3 -3
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/multiple_entities_processor.py +0 -16
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/branches_processor.py +24 -35
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/files_processor.py +4 -5
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform.egg-info/PKG-INFO +3 -3
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform.egg-info/requires.txt +2 -2
- {gitlabform-4.0.2 → gitlabform-4.0.4}/setup.py +2 -2
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_branches.py +35 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_files.py +36 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/LICENSE +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/README.md +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/configuration/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/configuration/common.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/configuration/core.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/configuration/groups.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/configuration/projects.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/configuration/transform.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/constants.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/commits.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/core.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/group_badges.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/group_ldap_links.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/group_variables.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/groups.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/merge_requests.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/pipelines.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/project_badges.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/project_deploy_keys.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/project_merge_requests_approvals.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/project_protected_environments.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/projects.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/python_gitlab.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/users.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/gitlab/variables.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/lists/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/lists/filter.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/lists/groups.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/lists/projects.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/output.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/abstract_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/application/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/application/application_settings_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/defining_keys.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/group/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/group/group_badges_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/group/group_labels_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/group/group_ldap_links_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/group/group_members_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/group/group_saml_links_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/group/group_settings_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/group/group_variables_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/badges_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/deploy_keys_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/hooks_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/integrations_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/job_token_scope_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/members_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/merge_requests_approval_rules.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/merge_requests_approvals.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/project_labels_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/project_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/project_push_rules_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/project_settings_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/resource_groups_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/schedules_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/tags_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/variables_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/shared/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/shared/protected_environments_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/single_entity_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/util/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/util/decorators.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/util/difference_logger.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/util/labels_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/run.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/util.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform.egg-info/SOURCES.txt +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform.egg-info/dependency_links.txt +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform.egg-info/entry_points.txt +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform.egg-info/top_level.txt +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/setup.cfg +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/conftest.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_application_settings.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_archive_project.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_badges.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_deploy_keys.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_deploy_keys_all_projects.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_files_templates.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_group_badges.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_group_labels.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_group_members_case_insensitive.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_group_members_groups.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_group_members_users.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_group_settings.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_group_variables.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_hooks.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_integrations.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_job_token_scope.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_members.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_members_add_group.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_members_enforce.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_project_group_members_case_insensitive.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_project_labels.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_project_members_case_insensitve.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_project_settings.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_resource_groups.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_running.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_schedules.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_tags.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_token_from_config.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_transfer_project.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_variables.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/configuration/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/configuration/test_case_sensitivity.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/configuration/test_inheritance_break_projects_and_groups.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/configuration/test_inheritance_break_subgroups.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/configuration/test_inheritance_break_validation.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/configuration/test_projects_and_groups.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/configuration/test_skip_groups_skip_projects.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/configuration/test_subgroups.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/configuration/test_yaml_version.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/processors/__init__.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/processors/test_abstract_processor.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/processors/test_difference_logger.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/processors/test_schedules_processor_extended_cron_pattern.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/test_access_levels.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/test_non_empty_configs_provider.py +0 -0
- {gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: gitlabform
|
|
3
|
-
Version: 4.0.
|
|
3
|
+
Version: 4.0.4
|
|
4
4
|
Summary: 🏗 Specialized configuration as a code tool for GitLab projects, groups and more using hierarchical configuration written in YAML
|
|
5
5
|
Home-page: https://gitlabform.github.io/gitlabform
|
|
6
6
|
Author: Greg Dubicki and Contributors
|
|
@@ -31,7 +31,7 @@ Requires-Dist: ruamel.yaml==0.17.21
|
|
|
31
31
|
Requires-Dist: types-requests==2.32.0.20241016
|
|
32
32
|
Requires-Dist: yamlpath==3.8.2
|
|
33
33
|
Provides-Extra: test
|
|
34
|
-
Requires-Dist: coverage==7.6.
|
|
34
|
+
Requires-Dist: coverage==7.6.8; extra == "test"
|
|
35
35
|
Requires-Dist: cryptography==43.0.3; extra == "test"
|
|
36
36
|
Requires-Dist: deepdiff==8.0.1; extra == "test"
|
|
37
37
|
Requires-Dist: mypy==1.13.0; extra == "test"
|
|
@@ -39,7 +39,7 @@ Requires-Dist: mypy-extensions==1.0.0; extra == "test"
|
|
|
39
39
|
Requires-Dist: pre-commit==2.21.0; extra == "test"
|
|
40
40
|
Requires-Dist: pytest==8.3.3; extra == "test"
|
|
41
41
|
Requires-Dist: pytest-cov==6.0.0; extra == "test"
|
|
42
|
-
Requires-Dist: pytest-rerunfailures==
|
|
42
|
+
Requires-Dist: pytest-rerunfailures==15.0; extra == "test"
|
|
43
43
|
Requires-Dist: xkcdpass==1.19.9; extra == "test"
|
|
44
44
|
Provides-Extra: docs
|
|
45
45
|
Requires-Dist: mkdocs; extra == "docs"
|
|
@@ -4,7 +4,6 @@ from cli_ui import fatal
|
|
|
4
4
|
|
|
5
5
|
import abc
|
|
6
6
|
from typing import Callable, Union, Any
|
|
7
|
-
import time
|
|
8
7
|
from gitlabform.constants import EXIT_INVALID_INPUT
|
|
9
8
|
from gitlabform.gitlab import GitLab
|
|
10
9
|
from gitlabform.processors.abstract_processor import AbstractProcessor
|
|
@@ -70,21 +69,6 @@ class MultipleEntitiesProcessor(AbstractProcessor, metaclass=abc.ABCMeta):
|
|
|
70
69
|
else:
|
|
71
70
|
enforce = False
|
|
72
71
|
|
|
73
|
-
if (
|
|
74
|
-
"members" in configuration
|
|
75
|
-
and ("protected_environments" or "merge_requests_approval_rules")
|
|
76
|
-
in configuration
|
|
77
|
-
):
|
|
78
|
-
# When gitlabform needs to update project membership and also configure
|
|
79
|
-
# settings that are dependent on the members (i.e. environment protection
|
|
80
|
-
# or MR approval rule), there seems to be an issue in GitLab. Automated
|
|
81
|
-
# acceptance tests in gitlabform creates new user and adds to the project
|
|
82
|
-
# followed by configuring other setting. In that scenario need to wait a little
|
|
83
|
-
# before calling GitLab's REST API for processing other settings. Otherwise
|
|
84
|
-
# the users are not available to be configured in other settings and it
|
|
85
|
-
# does not return any error either"
|
|
86
|
-
time.sleep(2)
|
|
87
|
-
|
|
88
72
|
# TODO: move/convert this to a configuration validation phase
|
|
89
73
|
self._find_duplicates(project_or_group, entities_in_configuration)
|
|
90
74
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
from logging import debug, info
|
|
3
3
|
from cli_ui import warning, fatal
|
|
4
|
-
from gitlab.v4.objects import Project,
|
|
4
|
+
from gitlab.v4.objects import Project, ProjectProtectedBranch
|
|
5
5
|
from gitlab import (
|
|
6
6
|
GitlabGetError,
|
|
7
7
|
GitlabDeleteError,
|
|
@@ -10,7 +10,6 @@ from gitlab import (
|
|
|
10
10
|
from gitlabform.constants import EXIT_INVALID_INPUT, EXIT_PROCESSING_ERROR
|
|
11
11
|
from gitlabform.gitlab import GitLab
|
|
12
12
|
from gitlabform.processors.abstract_processor import AbstractProcessor
|
|
13
|
-
import time
|
|
14
13
|
|
|
15
14
|
|
|
16
15
|
class BranchesProcessor(AbstractProcessor):
|
|
@@ -19,18 +18,6 @@ class BranchesProcessor(AbstractProcessor):
|
|
|
19
18
|
self.strict = strict
|
|
20
19
|
|
|
21
20
|
def _process_configuration(self, project_and_group: str, configuration: dict):
|
|
22
|
-
if "members" in configuration:
|
|
23
|
-
# When gitlabform needs to update project membership and also
|
|
24
|
-
# configure branch protection, there seems to be a race condition
|
|
25
|
-
# or delay in GitLab. Automated acceptance tests in gitlabform
|
|
26
|
-
# creates new user and adds to the project followed by configuring
|
|
27
|
-
# branch protection setting. In that scenario need to wait a little
|
|
28
|
-
# before calling GitLab's REST API for branch protection. Otherwise
|
|
29
|
-
# the API returns error code 422 with an message like "Push access
|
|
30
|
-
# levels user is not a member of the project"
|
|
31
|
-
|
|
32
|
-
time.sleep(2)
|
|
33
|
-
|
|
34
21
|
project: Project = self.gl.get_project_by_path_cached(project_and_group)
|
|
35
22
|
|
|
36
23
|
for branch in sorted(configuration["branches"]):
|
|
@@ -46,20 +33,20 @@ class BranchesProcessor(AbstractProcessor):
|
|
|
46
33
|
"""
|
|
47
34
|
Process branch protection according to gitlabform config.
|
|
48
35
|
"""
|
|
49
|
-
branch: Optional[ProjectBranch] = None
|
|
50
36
|
protected_branch: Optional[ProjectProtectedBranch] = None
|
|
51
37
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
38
|
+
if not self.is_branch_name_wildcard(branch_name):
|
|
39
|
+
try:
|
|
40
|
+
branch = project.branches.get(branch_name)
|
|
41
|
+
except GitlabGetError:
|
|
42
|
+
message = f"Branch '{branch_name}' not found when processing it to be protected/unprotected!"
|
|
43
|
+
if self.strict:
|
|
44
|
+
fatal(
|
|
45
|
+
message,
|
|
46
|
+
exit_code=EXIT_INVALID_INPUT,
|
|
47
|
+
)
|
|
48
|
+
else:
|
|
49
|
+
warning(message)
|
|
63
50
|
|
|
64
51
|
try:
|
|
65
52
|
protected_branch = project.protectedbranches.get(branch_name)
|
|
@@ -67,7 +54,7 @@ class BranchesProcessor(AbstractProcessor):
|
|
|
67
54
|
message = f"The branch '{branch_name}' is not protected!"
|
|
68
55
|
debug(message)
|
|
69
56
|
|
|
70
|
-
if
|
|
57
|
+
if branch_config.get("protected"):
|
|
71
58
|
if protected_branch and self._needs_update(
|
|
72
59
|
protected_branch.attributes, branch_config
|
|
73
60
|
):
|
|
@@ -79,27 +66,25 @@ class BranchesProcessor(AbstractProcessor):
|
|
|
79
66
|
# protected branch is not the same. So, removing existing branch protection and
|
|
80
67
|
# reconfiguring branch protection seems simpler.
|
|
81
68
|
self.unprotect_branch(protected_branch)
|
|
82
|
-
self.protect_branch(project,
|
|
69
|
+
self.protect_branch(project, branch_name, branch_config)
|
|
83
70
|
elif not protected_branch:
|
|
84
|
-
self.protect_branch(project,
|
|
71
|
+
self.protect_branch(project, branch_name, branch_config)
|
|
85
72
|
elif protected_branch and not branch_config.get("protected"):
|
|
86
73
|
self.unprotect_branch(protected_branch)
|
|
87
74
|
|
|
88
|
-
def protect_branch(
|
|
89
|
-
self, project: Project, branch: ProjectBranch, branch_config: dict
|
|
90
|
-
):
|
|
75
|
+
def protect_branch(self, project: Project, branch_name: str, branch_config: dict):
|
|
91
76
|
"""
|
|
92
77
|
Protect a branch using given config.
|
|
93
78
|
Raise exception if running in strict mode.
|
|
94
79
|
"""
|
|
95
80
|
|
|
96
|
-
debug("Setting branch '%s' as protected",
|
|
81
|
+
debug("Setting branch '%s' as protected", branch_name)
|
|
97
82
|
|
|
98
83
|
try:
|
|
99
|
-
project.protectedbranches.create({"name":
|
|
84
|
+
project.protectedbranches.create({"name": branch_name, **branch_config})
|
|
100
85
|
except GitlabCreateError as e:
|
|
101
86
|
message = (
|
|
102
|
-
f"Protecting branch '{
|
|
87
|
+
f"Protecting branch '{branch_name}' failed! Error '{e.error_message}"
|
|
103
88
|
)
|
|
104
89
|
|
|
105
90
|
if self.strict:
|
|
@@ -149,3 +134,7 @@ class BranchesProcessor(AbstractProcessor):
|
|
|
149
134
|
item["group_id"] = self.gl.get_group_id(item.pop("group"))
|
|
150
135
|
|
|
151
136
|
return branch_config
|
|
137
|
+
|
|
138
|
+
@staticmethod
|
|
139
|
+
def is_branch_name_wildcard(branch):
|
|
140
|
+
return "*" in branch or "?" in branch
|
|
@@ -135,10 +135,12 @@ class FilesProcessor(AbstractProcessor):
|
|
|
135
135
|
)
|
|
136
136
|
|
|
137
137
|
try:
|
|
138
|
+
# Returns base64 encoded content: https://python-gitlab.readthedocs.io/en/stable/gl_objects/projects.html#project-files
|
|
138
139
|
repo_file: ProjectFile = project.files.get(
|
|
139
140
|
file_path=file, ref=branch.name
|
|
140
141
|
)
|
|
141
|
-
|
|
142
|
+
decoded_file: bytes = repo_file.decode()
|
|
143
|
+
current_content: str = decoded_file.decode("utf-8")
|
|
142
144
|
|
|
143
145
|
if current_content != new_content:
|
|
144
146
|
if configuration.get("files|" + file + "|overwrite"):
|
|
@@ -243,12 +245,9 @@ class FilesProcessor(AbstractProcessor):
|
|
|
243
245
|
# ...and protect the branch again after the operation
|
|
244
246
|
if configuration.get("branches|" + branch.name + "|protected"):
|
|
245
247
|
debug("> Protecting the branch again.")
|
|
246
|
-
project_branch: ProjectBranch = project.branches.get(
|
|
247
|
-
branch.name
|
|
248
|
-
)
|
|
249
248
|
branch_config: dict = configuration["branches"][branch.name]
|
|
250
249
|
self.branch_processor.protect_branch(
|
|
251
|
-
project,
|
|
250
|
+
project, branch.name, branch_config
|
|
252
251
|
)
|
|
253
252
|
|
|
254
253
|
else:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: gitlabform
|
|
3
|
-
Version: 4.0.
|
|
3
|
+
Version: 4.0.4
|
|
4
4
|
Summary: 🏗 Specialized configuration as a code tool for GitLab projects, groups and more using hierarchical configuration written in YAML
|
|
5
5
|
Home-page: https://gitlabform.github.io/gitlabform
|
|
6
6
|
Author: Greg Dubicki and Contributors
|
|
@@ -31,7 +31,7 @@ Requires-Dist: ruamel.yaml==0.17.21
|
|
|
31
31
|
Requires-Dist: types-requests==2.32.0.20241016
|
|
32
32
|
Requires-Dist: yamlpath==3.8.2
|
|
33
33
|
Provides-Extra: test
|
|
34
|
-
Requires-Dist: coverage==7.6.
|
|
34
|
+
Requires-Dist: coverage==7.6.8; extra == "test"
|
|
35
35
|
Requires-Dist: cryptography==43.0.3; extra == "test"
|
|
36
36
|
Requires-Dist: deepdiff==8.0.1; extra == "test"
|
|
37
37
|
Requires-Dist: mypy==1.13.0; extra == "test"
|
|
@@ -39,7 +39,7 @@ Requires-Dist: mypy-extensions==1.0.0; extra == "test"
|
|
|
39
39
|
Requires-Dist: pre-commit==2.21.0; extra == "test"
|
|
40
40
|
Requires-Dist: pytest==8.3.3; extra == "test"
|
|
41
41
|
Requires-Dist: pytest-cov==6.0.0; extra == "test"
|
|
42
|
-
Requires-Dist: pytest-rerunfailures==
|
|
42
|
+
Requires-Dist: pytest-rerunfailures==15.0; extra == "test"
|
|
43
43
|
Requires-Dist: xkcdpass==1.19.9; extra == "test"
|
|
44
44
|
Provides-Extra: docs
|
|
45
45
|
Requires-Dist: mkdocs; extra == "docs"
|
|
@@ -17,7 +17,7 @@ mkdocs
|
|
|
17
17
|
mkdocs-material
|
|
18
18
|
|
|
19
19
|
[test]
|
|
20
|
-
coverage==7.6.
|
|
20
|
+
coverage==7.6.8
|
|
21
21
|
cryptography==43.0.3
|
|
22
22
|
deepdiff==8.0.1
|
|
23
23
|
mypy==1.13.0
|
|
@@ -25,5 +25,5 @@ mypy-extensions==1.0.0
|
|
|
25
25
|
pre-commit==2.21.0
|
|
26
26
|
pytest==8.3.3
|
|
27
27
|
pytest-cov==6.0.0
|
|
28
|
-
pytest-rerunfailures==
|
|
28
|
+
pytest-rerunfailures==15.0
|
|
29
29
|
xkcdpass==1.19.9
|
|
@@ -56,7 +56,7 @@ setup(
|
|
|
56
56
|
],
|
|
57
57
|
extras_require={
|
|
58
58
|
"test": [
|
|
59
|
-
"coverage==7.6.
|
|
59
|
+
"coverage==7.6.8",
|
|
60
60
|
"cryptography==43.0.3",
|
|
61
61
|
"deepdiff==8.0.1",
|
|
62
62
|
"mypy==1.13.0",
|
|
@@ -64,7 +64,7 @@ setup(
|
|
|
64
64
|
"pre-commit==2.21.0", # not really for tests, but for development
|
|
65
65
|
"pytest==8.3.3",
|
|
66
66
|
"pytest-cov==6.0.0",
|
|
67
|
-
"pytest-rerunfailures==
|
|
67
|
+
"pytest-rerunfailures==15.0",
|
|
68
68
|
"xkcdpass==1.19.9",
|
|
69
69
|
],
|
|
70
70
|
"docs": [
|
|
@@ -60,6 +60,41 @@ class TestBranches:
|
|
|
60
60
|
assert merge_access_user_ids is None
|
|
61
61
|
assert unprotect_access_level is None
|
|
62
62
|
|
|
63
|
+
def test__protect_with_wildcard(self, project):
|
|
64
|
+
branch_wildcard = "r-*"
|
|
65
|
+
config_protect_branch = f"""
|
|
66
|
+
projects_and_groups:
|
|
67
|
+
{project.path_with_namespace}:
|
|
68
|
+
branches:
|
|
69
|
+
"{branch_wildcard}":
|
|
70
|
+
protected: true
|
|
71
|
+
push_access_level: {AccessLevel.NO_ACCESS.value}
|
|
72
|
+
merge_access_level: {AccessLevel.MAINTAINER.value}
|
|
73
|
+
unprotect_access_level: {AccessLevel.MAINTAINER.value}
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
run_gitlabform(config_protect_branch, project.path_with_namespace)
|
|
77
|
+
|
|
78
|
+
(
|
|
79
|
+
push_access_levels,
|
|
80
|
+
merge_access_levels,
|
|
81
|
+
push_access_user_ids,
|
|
82
|
+
merge_access_user_ids,
|
|
83
|
+
_,
|
|
84
|
+
_,
|
|
85
|
+
unprotect_access_level,
|
|
86
|
+
) = get_only_branch_access_levels(project, branch_wildcard)
|
|
87
|
+
assert push_access_levels == [AccessLevel.NO_ACCESS.value]
|
|
88
|
+
assert merge_access_levels == [AccessLevel.MAINTAINER.value]
|
|
89
|
+
assert push_access_user_ids == []
|
|
90
|
+
assert merge_access_user_ids == []
|
|
91
|
+
assert unprotect_access_level is AccessLevel.MAINTAINER.value
|
|
92
|
+
|
|
93
|
+
wildcard_matching_branch = project.branches.create(
|
|
94
|
+
{"branch": "r-1", "ref": "main"}
|
|
95
|
+
)
|
|
96
|
+
assert wildcard_matching_branch.protected is True
|
|
97
|
+
|
|
63
98
|
def test__config_with_access_level_names(self, project, branch):
|
|
64
99
|
config_with_access_levels_names = f"""
|
|
65
100
|
projects_and_groups:
|
|
@@ -91,6 +91,42 @@ class TestFiles:
|
|
|
91
91
|
# check if main stays protected after the file update
|
|
92
92
|
assert the_branch.protected is True
|
|
93
93
|
|
|
94
|
+
def test__does_not_commit_file_if_content_matches(self, project_for_function):
|
|
95
|
+
set_file_specific_branch = f"""
|
|
96
|
+
projects_and_groups:
|
|
97
|
+
{project_for_function.path_with_namespace}:
|
|
98
|
+
branches:
|
|
99
|
+
main:
|
|
100
|
+
protected: true
|
|
101
|
+
push_access_level: maintainer
|
|
102
|
+
merge_access_level: developer
|
|
103
|
+
unprotect_access_level: maintainer
|
|
104
|
+
files:
|
|
105
|
+
"README.md":
|
|
106
|
+
overwrite: true
|
|
107
|
+
branches:
|
|
108
|
+
- main
|
|
109
|
+
content: {DEFAULT_README}
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
run_gitlabform(
|
|
113
|
+
set_file_specific_branch, project_for_function.path_with_namespace
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
the_branch = project_for_function.branches.get("main")
|
|
117
|
+
assert not any(
|
|
118
|
+
[
|
|
119
|
+
text in the_branch.commit["message"]
|
|
120
|
+
for text in ["Automated", "made by gitlabform"]
|
|
121
|
+
]
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
project_file = project_for_function.files.get(ref="main", file_path="README.md")
|
|
125
|
+
assert project_file.decode().decode("utf-8") == DEFAULT_README
|
|
126
|
+
|
|
127
|
+
# check if main stays protected after the file update
|
|
128
|
+
assert the_branch.protected is True
|
|
129
|
+
|
|
94
130
|
def test__set_file_strongly_protected_branch(self, project, no_access_branch):
|
|
95
131
|
set_file_specific_branch = f"""
|
|
96
132
|
projects_and_groups:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/group/group_ldap_links_processor.py
RENAMED
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/group/group_members_processor.py
RENAMED
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/group/group_saml_links_processor.py
RENAMED
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/group/group_settings_processor.py
RENAMED
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/group/group_variables_processor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/deploy_keys_processor.py
RENAMED
|
File without changes
|
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/integrations_processor.py
RENAMED
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/job_token_scope_processor.py
RENAMED
|
File without changes
|
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/merge_requests_approval_rules.py
RENAMED
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/merge_requests_approvals.py
RENAMED
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/project_labels_processor.py
RENAMED
|
File without changes
|
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/project_push_rules_processor.py
RENAMED
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/project_settings_processor.py
RENAMED
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/gitlabform/processors/project/resource_groups_processor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_application_settings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_deploy_keys_all_projects.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/tests/acceptance/standard/test_group_members_groups.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/configuration/test_inheritance_break_subgroups.py
RENAMED
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/configuration/test_inheritance_break_validation.py
RENAMED
|
File without changes
|
|
File without changes
|
{gitlabform-4.0.2 → gitlabform-4.0.4}/tests/unit/configuration/test_skip_groups_skip_projects.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|