gitlabform 4.7.0__tar.gz → 5.0.0__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.
Files changed (92) hide show
  1. {gitlabform-4.7.0 → gitlabform-5.0.0}/PKG-INFO +10 -10
  2. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/__init__.py +2 -4
  3. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/configuration/__init__.py +0 -1
  4. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/configuration/core.py +4 -4
  5. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/configuration/transform.py +0 -94
  6. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/__init__.py +0 -6
  7. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/core.py +40 -0
  8. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/projects.py +0 -6
  9. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/lists/filter.py +0 -1
  10. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/abstract_processor.py +2 -4
  11. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/group/group_saml_links_processor.py +5 -4
  12. gitlabform-5.0.0/gitlabform/processors/group/group_variables_processor.py +26 -0
  13. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/__init__.py +2 -2
  14. gitlabform-5.0.0/gitlabform/processors/project/branches_processor.py +438 -0
  15. gitlabform-5.0.0/gitlabform/processors/project/project_security_settings.py +68 -0
  16. gitlabform-5.0.0/gitlabform/processors/project/project_variables_processor.py +95 -0
  17. gitlabform-5.0.0/gitlabform/processors/util/variables_processor.py +144 -0
  18. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform.egg-info/PKG-INFO +10 -10
  19. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform.egg-info/SOURCES.txt +3 -4
  20. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform.egg-info/requires.txt +8 -8
  21. {gitlabform-4.7.0 → gitlabform-5.0.0}/pyproject.toml +10 -10
  22. gitlabform-4.7.0/gitlabform/gitlab/group_variables.py +0 -51
  23. gitlabform-4.7.0/gitlabform/gitlab/project_security_settings.py +0 -22
  24. gitlabform-4.7.0/gitlabform/processors/group/group_variables_processor.py +0 -17
  25. gitlabform-4.7.0/gitlabform/processors/project/branches_processor.py +0 -141
  26. gitlabform-4.7.0/gitlabform/processors/project/project_security_settings.py +0 -12
  27. gitlabform-4.7.0/gitlabform/processors/project/variables_processor.py +0 -70
  28. {gitlabform-4.7.0 → gitlabform-5.0.0}/LICENSE +0 -0
  29. {gitlabform-4.7.0 → gitlabform-5.0.0}/README.md +0 -0
  30. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/configuration/common.py +0 -0
  31. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/configuration/groups.py +0 -0
  32. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/configuration/projects.py +0 -0
  33. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/constants.py +0 -0
  34. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/commits.py +0 -0
  35. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/group_badges.py +0 -0
  36. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/group_ldap_links.py +0 -0
  37. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/groups.py +0 -0
  38. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/merge_requests.py +0 -0
  39. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/pipelines.py +0 -0
  40. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/project_badges.py +0 -0
  41. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/project_deploy_keys.py +0 -0
  42. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/project_merge_requests_approvals.py +0 -0
  43. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/project_protected_environments.py +0 -0
  44. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/python_gitlab.py +0 -0
  45. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/gitlab/variables.py +0 -0
  46. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/lists/__init__.py +0 -0
  47. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/lists/groups.py +0 -0
  48. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/lists/projects.py +0 -0
  49. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/output.py +0 -0
  50. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/__init__.py +0 -0
  51. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/application/__init__.py +0 -0
  52. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/application/application_settings_processor.py +0 -0
  53. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/defining_keys.py +0 -0
  54. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/group/__init__.py +0 -0
  55. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/group/group_badges_processor.py +0 -0
  56. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/group/group_hooks_processor.py +0 -0
  57. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/group/group_labels_processor.py +0 -0
  58. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/group/group_ldap_links_processor.py +0 -0
  59. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/group/group_members_processor.py +0 -0
  60. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/group/group_push_rules_processor.py +0 -0
  61. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/group/group_settings_processor.py +0 -0
  62. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/multiple_entities_processor.py +0 -0
  63. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/badges_processor.py +0 -0
  64. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/deploy_keys_processor.py +0 -0
  65. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/files_processor.py +0 -0
  66. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/hooks_processor.py +0 -0
  67. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/integrations_processor.py +0 -0
  68. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/job_token_scope_processor.py +0 -0
  69. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/members_processor.py +0 -0
  70. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/merge_requests_approval_rules.py +0 -0
  71. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/merge_requests_approvals.py +0 -0
  72. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/project_labels_processor.py +0 -0
  73. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/project_processor.py +0 -0
  74. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/project_push_rules_processor.py +0 -0
  75. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/project_settings_processor.py +0 -0
  76. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/remote_mirrors_processor.py +0 -0
  77. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/resource_groups_processor.py +0 -0
  78. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/schedules_processor.py +0 -0
  79. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/project/tags_processor.py +0 -0
  80. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/shared/__init__.py +0 -0
  81. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/shared/protected_environments_processor.py +0 -0
  82. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/single_entity_processor.py +0 -0
  83. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/util/__init__.py +0 -0
  84. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/util/decorators.py +0 -0
  85. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/util/difference_logger.py +0 -0
  86. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/processors/util/labels_processor.py +0 -0
  87. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/run.py +0 -0
  88. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform/util.py +0 -0
  89. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform.egg-info/dependency_links.txt +0 -0
  90. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform.egg-info/entry_points.txt +0 -0
  91. {gitlabform-4.7.0 → gitlabform-5.0.0}/gitlabform.egg-info/top_level.txt +0 -0
  92. {gitlabform-4.7.0 → gitlabform-5.0.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitlabform
3
- Version: 4.7.0
3
+ Version: 5.0.0
4
4
  Summary: 🏗 Specialized configuration as a code tool for GitLab projects, groups and more using hierarchical configuration written in YAML
5
5
  Author: Greg Dubicki and Contributors
6
6
  Project-URL: Homepage, https://gitlabform.github.io/gitlabform/
@@ -8,7 +8,7 @@ Project-URL: Repository, https://github.com/gitlabform/gitlabform.git
8
8
  Project-URL: Issues, https://github.com/gitlabform/gitlabform/issues
9
9
  Project-URL: Changelog, https://gitlabform.github.io/gitlabform/changelog/
10
10
  Keywords: cli,yaml,gitlab,configuration-as-code
11
- Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Programming Language :: Python :: 3.14
12
12
  Classifier: Development Status :: 5 - Production/Stable
13
13
  Classifier: Intended Audience :: Information Technology
14
14
  Classifier: Intended Audience :: System Administrators
@@ -20,24 +20,22 @@ Classifier: Topic :: Software Development :: Version Control :: Git
20
20
  Requires-Python: >=3.12.0
21
21
  Description-Content-Type: text/markdown
22
22
  License-File: LICENSE
23
- Requires-Dist: certifi==2026.1.4
23
+ Requires-Dist: certifi==2026.2.25
24
24
  Requires-Dist: cli-ui==0.19.0
25
25
  Requires-Dist: ez-yaml==1.2.0
26
26
  Requires-Dist: Jinja2==3.1.6
27
27
  Requires-Dist: luddite==1.0.4
28
28
  Requires-Dist: MarkupSafe==3.0.3
29
29
  Requires-Dist: mergedeep==1.3.4
30
- Requires-Dist: packaging==25.0
31
- Requires-Dist: python-gitlab==7.1.0
32
- Requires-Dist: python-gitlab[graphql]==7.1.0
30
+ Requires-Dist: packaging==26.0
31
+ Requires-Dist: python-gitlab==8.0.0
32
+ Requires-Dist: python-gitlab[graphql]==8.0.0
33
33
  Requires-Dist: requests==2.32.5
34
34
  Requires-Dist: ruamel.yaml==0.17.21
35
- Requires-Dist: types-requests==2.32.4.20260107
36
- Requires-Dist: types-setuptools==80.9.0.20251223
37
35
  Requires-Dist: yamlpath==3.8.2
38
36
  Provides-Extra: test
39
- Requires-Dist: coverage==7.13.1; extra == "test"
40
- Requires-Dist: cryptography==46.0.3; extra == "test"
37
+ Requires-Dist: coverage==7.13.4; extra == "test"
38
+ Requires-Dist: cryptography==46.0.5; extra == "test"
41
39
  Requires-Dist: deepdiff==8.6.1; extra == "test"
42
40
  Requires-Dist: mypy==1.19.1; extra == "test"
43
41
  Requires-Dist: mypy-extensions==1.1.0; extra == "test"
@@ -45,6 +43,8 @@ Requires-Dist: pre-commit==2.21.0; extra == "test"
45
43
  Requires-Dist: pytest==9.0.2; extra == "test"
46
44
  Requires-Dist: pytest-cov==7.0.0; extra == "test"
47
45
  Requires-Dist: pytest-rerunfailures==16.1; extra == "test"
46
+ Requires-Dist: types-requests==2.32.4.20260107; extra == "test"
47
+ Requires-Dist: types-setuptools==82.0.0.20260210; extra == "test"
48
48
  Requires-Dist: xkcdpass==1.30.0; extra == "test"
49
49
  Provides-Extra: docs
50
50
  Requires-Dist: mkdocs; extra == "docs"
@@ -143,8 +143,7 @@ class GitLabForm:
143
143
  :return: a tuple with all the arguments that have been parsed
144
144
  """
145
145
  parser = argparse.ArgumentParser(
146
- description=textwrap.dedent(
147
- f"""
146
+ description=textwrap.dedent(f"""
148
147
  🏗 Specialized configuration as a code tool for GitLab projects, groups and more
149
148
  using hierarchical configuration written in YAML.
150
149
 
@@ -152,8 +151,7 @@ class GitLabForm:
152
151
  * 0 - on success,
153
152
  * {EXIT_INVALID_INPUT} - on invalid input errors (f.e. bad syntax in the config file) ~ "it's your fault". 😅
154
153
  * {EXIT_PROCESSING_ERROR} - if there were backend processing errors (f.e. when requests to GitLab fail) ~ "it's not your fault". 😎
155
- """
156
- ),
154
+ """),
157
155
  formatter_class=Formatter,
158
156
  )
159
157
 
@@ -2,7 +2,6 @@ from gitlabform.configuration.common import ConfigurationCommon
2
2
  from gitlabform.configuration.groups import ConfigurationGroups
3
3
  from gitlabform.configuration.projects import ConfigurationProjects
4
4
 
5
-
6
5
  #
7
6
  # This the only external interface for operating on the configuration from a given YAML file
8
7
  # (or an input string in case of tests).
@@ -52,9 +52,9 @@ class ConfigurationCore(ABC):
52
52
  exit_code=EXIT_INVALID_INPUT,
53
53
  )
54
54
 
55
- if self.config.get("config_version", 1) != 3:
55
+ if self.config.get("config_version", 1) != 4:
56
56
  fatal(
57
- "This version of GitLabForm requires 'config_version: 3' entry in the config. "
57
+ "This version of GitLabForm requires 'config_version: 4' entry in the config. "
58
58
  "This ensures that if the application behavior changes in a backward-incompatible way,"
59
59
  " you won't apply unwanted configuration to your GitLab instance.\n"
60
60
  "Please follow this guide: https://gitlabform.github.io/gitlabform/upgrade/\n",
@@ -101,11 +101,11 @@ class ConfigurationCore(ABC):
101
101
  if config_string:
102
102
  config = textwrap.dedent(source)
103
103
  verbose("Reading config from the provided string.")
104
- (yaml_data, doc_loaded) = Parsers.get_yaml_data(yaml, log, config, literal=True)
104
+ yaml_data, doc_loaded = Parsers.get_yaml_data(yaml, log, config, literal=True)
105
105
  else:
106
106
  config_path = source
107
107
  verbose(f"Reading config from file: {config_path}")
108
- (yaml_data, doc_loaded) = Parsers.get_yaml_data(yaml, log, config_path)
108
+ yaml_data, doc_loaded = Parsers.get_yaml_data(yaml, log, config_path)
109
109
 
110
110
  if doc_loaded:
111
111
  debug("Config parsed successfully as YAML.")
@@ -15,7 +15,6 @@ from gitlabform.configuration import Configuration
15
15
  from gitlabform.gitlab import AccessLevel
16
16
  from gitlabform.gitlab import GitLab
17
17
 
18
-
19
18
  # Configuration transformers are classes which take the input configuration as YAML and change it
20
19
  # to from the more user-friendly input to an output that is more applicable to passing to GitLab
21
20
  # over its API.
@@ -26,7 +25,6 @@ from gitlabform.gitlab import GitLab
26
25
 
27
26
  class ConfigurationTransformers:
28
27
  def __init__(self, gitlab: GitLab):
29
- self.merge_request_approvals_transformer = MergeRequestApprovalsTransformer(gitlab)
30
28
  self.user_transformer = UserTransformer(gitlab)
31
29
  self.group_transformer = GroupTransformer(gitlab)
32
30
  self.implicit_name_transformer = ImplicitNameTransformer(gitlab)
@@ -36,10 +34,6 @@ class ConfigurationTransformers:
36
34
  config_before = ez_yaml.to_string(obj=configuration.config, options={})
37
35
  debug(f"Config BEFORE transformations:\n{config_before}")
38
36
 
39
- # this needs to run before user and group transformer as it may contain users and group
40
- # names to convert to ids
41
- self.merge_request_approvals_transformer.transform(configuration)
42
-
43
37
  self.user_transformer.transform(configuration)
44
38
  self.group_transformer.transform(configuration)
45
39
  self.implicit_name_transformer.transform(configuration)
@@ -263,91 +257,3 @@ class AccessLevelsTransformer(ConfigurationTransformer):
263
257
  # this just means that we haven't found any keys in YAML
264
258
  # under the given path
265
259
  pass
266
-
267
-
268
- #
269
- # TODO: remove below code in v4.x
270
- #
271
-
272
-
273
- class MergeRequestApprovalsTransformer(ConfigurationTransformer):
274
- def __init__(self, gitlab: GitLab):
275
- # this transformer doesn't need to call gitlab
276
- pass
277
-
278
- def _do_transform(self, configuration: Configuration) -> None:
279
- logging_args = SimpleNamespace(quiet=False, verbose=False, debug=False)
280
- processor = Processor(ConsolePrinter(logging_args), configuration.config)
281
-
282
- try:
283
- for node_coordinate in processor.get_nodes(
284
- "projects_and_groups.*.merge_requests",
285
- mustexist=True,
286
- ):
287
- old_syntax_found = False
288
-
289
- where_to_add_new_syntax = node_coordinate.parent
290
-
291
- old_syntax = node_coordinate.node
292
-
293
- approvals_required_guessed = True
294
- approvals_required = 2
295
-
296
- # approvals configurations
297
- if "approvals" in old_syntax:
298
- old_syntax_found = True
299
-
300
- if "approvals_before_merge" in old_syntax["approvals"]:
301
- # this setting is now moved inside the approval rules, so remove it from here
302
- # but store it for adding there
303
- approvals_required = old_syntax["approvals"]["approvals_before_merge"]
304
- approvals_required_guessed = False
305
- old_syntax["approvals"].pop("approvals_before_merge")
306
-
307
- if old_syntax["approvals"]:
308
- # add the settings, if there are left any after removing 'approvals_before_merge'
309
- where_to_add_new_syntax["merge_requests_approvals"] = old_syntax["approvals"]
310
-
311
- # approval rules
312
- if "approvers" in old_syntax or "approver_groups" in old_syntax or not approvals_required_guessed:
313
- old_syntax_found = True
314
-
315
- where_to_add_new_syntax["merge_requests_approval_rules"] = {
316
- "legacy": {
317
- "approvals_required": approvals_required,
318
- "name": APPROVAL_RULE_NAME,
319
- }
320
- }
321
-
322
- if "approvers" in old_syntax:
323
- where_to_add_new_syntax["merge_requests_approval_rules"]["legacy"]["users"] = old_syntax[
324
- "approvers"
325
- ]
326
- if "approver_groups" in old_syntax:
327
- where_to_add_new_syntax["merge_requests_approval_rules"]["legacy"]["groups"] = old_syntax[
328
- "approver_groups"
329
- ]
330
-
331
- if "remove_other_approval_rules" in old_syntax and old_syntax["remove_other_approval_rules"]:
332
- old_syntax_found = True
333
- where_to_add_new_syntax["merge_requests_approval_rules"]["enforce"] = True
334
-
335
- if old_syntax_found:
336
- where_to_add_new_syntax.pop("merge_requests")
337
-
338
- warning(
339
- "The 'merge_requests' configuration section syntax works but is deprecated and will be removed "
340
- "in the next major version of GitLabForm. "
341
- "Please migrate to the new syntax using the 'merge_requests_approvals' "
342
- "and the 'merge_requests_approval_rules' sections."
343
- )
344
- if approvals_required_guessed:
345
- warning(
346
- "'approvals_before_merge' not found in the old 'merge_requests' configuration section",
347
- "- assuming that it is set to 2.",
348
- )
349
-
350
- except YAMLPathException:
351
- # this just means that we haven't found any keys in YAML
352
- # under the given path
353
- pass
@@ -8,7 +8,6 @@ from gitlab import Gitlab as GitlabClient, GraphQL
8
8
  from gitlabform.gitlab.commits import GitLabCommits
9
9
  from gitlabform.gitlab.group_badges import GitLabGroupBadges
10
10
  from gitlabform.gitlab.group_ldap_links import GitLabGroupLDAPLinks
11
- from gitlabform.gitlab.group_variables import GitLabGroupVariables
12
11
  from gitlabform.gitlab.merge_requests import GitLabMergeRequests
13
12
  from gitlabform.gitlab.pipelines import GitLabPipelines
14
13
  from gitlabform.gitlab.project_badges import GitLabProjectBadges
@@ -20,8 +19,6 @@ from gitlabform.gitlab.project_merge_requests_approvals import (
20
19
  GitLabProjectMergeRequestsApprovals,
21
20
  )
22
21
  from gitlabform.gitlab.python_gitlab import PythonGitlab
23
- from gitlabform.gitlab.variables import GitLabVariables
24
- from gitlabform.gitlab.project_security_settings import GitlabProjectSecuritySettings
25
22
 
26
23
 
27
24
  @enum.unique
@@ -55,14 +52,11 @@ class GitLab(
55
52
  GitLabMergeRequests,
56
53
  GitLabGroupLDAPLinks,
57
54
  GitLabGroupBadges,
58
- GitLabGroupVariables,
59
55
  GitLabPipelines,
60
56
  GitLabProjectBadges,
61
57
  GitLabProjectDeployKeys,
62
58
  GitLabProjectProtectedEnvironments,
63
59
  GitLabProjectMergeRequestsApprovals,
64
- GitLabVariables,
65
- GitlabProjectSecuritySettings,
66
60
  ):
67
61
  pass
68
62
 
@@ -1,8 +1,12 @@
1
1
  import functools
2
2
  import os
3
+ import re
3
4
  from logging import debug
5
+ from typing import Union
4
6
  from urllib import parse
5
7
 
8
+ from packaging import version
9
+
6
10
  from importlib.metadata import version as package_version
7
11
  import requests
8
12
 
@@ -90,6 +94,42 @@ class GitLabCore:
90
94
  def get_project(self, project_and_group_or_id):
91
95
  return self._make_requests_to_api("projects/%s", project_and_group_or_id)
92
96
 
97
+ def is_version_at_least(self, min_version: Union[str, version.Version]) -> bool:
98
+ """
99
+ Check if GitLab server version is at least the specified version
100
+
101
+ Args:
102
+ min_version: Version string like "15.4.0" or "16.0", or a Version object
103
+
104
+ Returns:
105
+ bool: True if server version is >= min_version, False otherwise
106
+ """
107
+ current_version = "0.0.0"
108
+
109
+ if self.version != "unknown":
110
+ sem_ver_regex = "^\d*\.\d*\.\d*"
111
+ # Get the pure semantic version from self.version, for example Gitlab will return 18.2.1-ee
112
+ match = re.search(sem_ver_regex, self.version)
113
+ if match:
114
+ current_version = match.group()
115
+
116
+ if isinstance(min_version, str):
117
+ min_version = version.parse(min_version)
118
+
119
+ return version.parse(current_version) >= min_version
120
+
121
+ def is_version_less_than(self, max_version: Union[str, version.Version]) -> bool:
122
+ """
123
+ Check if GitLab server version is less than the specified version
124
+ Args:
125
+ max_version: Version string like "15.4.0" or "16.0", or a Version object
126
+
127
+ Returns:
128
+ bool: True if server version is < max_version, False otherwise
129
+ """
130
+
131
+ return not self.is_version_at_least(max_version)
132
+
93
133
  @functools.lru_cache()
94
134
  def _get_user_id(self, username: str) -> int:
95
135
  users = self._make_requests_to_api("users?username=%s", username, "GET")
@@ -116,12 +116,6 @@ class GitLabProjects(GitLabCore):
116
116
  except NotFoundException:
117
117
  return []
118
118
 
119
- def get_project_settings(self, project_and_group_name):
120
- try:
121
- return self._make_requests_to_api("projects/%s", project_and_group_name)
122
- except NotFoundException:
123
- return dict()
124
-
125
119
  def get_groups_from_project(self, project_and_group_name):
126
120
  # couldn't find an API call that was giving me directly
127
121
  # the shared groups, so I'm using directly the GET /projects/:id call
@@ -5,7 +5,6 @@ from cli_ui import fatal
5
5
  from gitlabform.constants import EXIT_INVALID_INPUT
6
6
  from gitlabform.lists import OmissionReason, Groups, Projects
7
7
 
8
-
9
8
  # Groups and projects filters jobs is to omit some groups and projects that GitLabForm is requested
10
9
  # to process for a speed-up.
11
10
  #
@@ -43,10 +43,8 @@ class AbstractProcessor(ABC):
43
43
  project_transfer_source = ""
44
44
  try:
45
45
  project_transfer_source = configuration["project"]["transfer_from"]
46
- verbose(
47
- f"""Project {project_or_project_and_group} is configured to be transferred,
48
- diffing config from transfer source project {project_transfer_source}."""
49
- )
46
+ verbose(f"""Project {project_or_project_and_group} is configured to be transferred,
47
+ diffing config from transfer source project {project_transfer_source}.""")
50
48
  except KeyError:
51
49
  pass
52
50
 
@@ -1,5 +1,6 @@
1
- from logging import debug
1
+ from logging import debug, warning
2
2
  from typing import List
3
+ from cli_ui import info
3
4
 
4
5
  from gitlabform.gitlab import GitLab
5
6
  from gitlab.v4.objects import Group, GroupSAMLGroupLink
@@ -9,13 +10,13 @@ from gitlabform.processors.abstract_processor import AbstractProcessor
9
10
  class GroupSAMLLinksProcessor(AbstractProcessor):
10
11
 
11
12
  def __init__(self, gitlab: GitLab):
12
- super().__init__("saml_group_links", gitlab)
13
+ super().__init__("group_saml_links", gitlab)
13
14
 
14
15
  def _process_configuration(self, group_path: str, configuration: dict) -> None:
15
16
  """Process the SAML links configuration for a group."""
16
17
 
17
- configured_links = configuration.get("saml_group_links", {})
18
- enforce_links = configuration.get("saml_group_links|enforce", False)
18
+ configured_links = configuration.get("group_saml_links", {})
19
+ enforce_links = configuration.get("group_saml_links|enforce", False)
19
20
 
20
21
  group: Group = self.gl.get_group_by_path_cached(group_path)
21
22
  existing_links: List[GroupSAMLGroupLink] = group.saml_group_links.list(get_all=True)
@@ -0,0 +1,26 @@
1
+ from typing import Any, Dict
2
+ from cli_ui import debug as verbose
3
+ from gitlabform.gitlab import GitLab
4
+ from gitlab.v4.objects import Group
5
+
6
+ from gitlabform.processors.abstract_processor import AbstractProcessor
7
+ from gitlabform.processors.util.variables_processor import VariablesProcessor
8
+
9
+
10
+ class GroupVariablesProcessor(AbstractProcessor):
11
+ def __init__(self, gitlab: GitLab):
12
+ super().__init__("group_variables", gitlab)
13
+ self._variables_processor = VariablesProcessor(self._needs_update)
14
+
15
+ def _process_configuration(self, project_and_group: str, configuration: Dict[str, Any]) -> None:
16
+ group: Group = self.gl.get_group_by_path_cached(project_and_group)
17
+
18
+ configured_variables = configuration.get("group_variables", {})
19
+ enforce_mode: bool = configured_variables.get("enforce", False)
20
+
21
+ if enforce_mode:
22
+ verbose(f"Enforce mode enabled for variables in {project_and_group}")
23
+ # Remove 'enforce' key from the config so that it's not treated as a variable
24
+ configured_variables.pop("enforce")
25
+
26
+ self._variables_processor.process_variables(group, configured_variables, enforce_mode)
@@ -35,7 +35,7 @@ from gitlabform.processors.project.resource_groups_processor import (
35
35
  )
36
36
  from gitlabform.processors.project.schedules_processor import SchedulesProcessor
37
37
  from gitlabform.processors.project.tags_processor import TagsProcessor
38
- from gitlabform.processors.project.variables_processor import VariablesProcessor
38
+ from gitlabform.processors.project.project_variables_processor import ProjectVariablesProcessor
39
39
  from gitlabform.processors.shared.protected_environments_processor import (
40
40
  ProtectedEnvironmentsProcessor,
41
41
  )
@@ -64,7 +64,7 @@ class ProjectProcessors(AbstractProcessors):
64
64
  ProjectLabelsProcessor(gitlab),
65
65
  JobTokenScopeProcessor(gitlab),
66
66
  DeployKeysProcessor(gitlab),
67
- VariablesProcessor(gitlab),
67
+ ProjectVariablesProcessor(gitlab),
68
68
  BranchesProcessor(gitlab, strict),
69
69
  TagsProcessor(gitlab, strict),
70
70
  IntegrationsProcessor(gitlab),