gitlabform 5.5.6__tar.gz → 6.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 (270) hide show
  1. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/workflows/_releases.yml +2 -2
  2. {gitlabform-5.5.6 → gitlabform-6.0.0}/PKG-INFO +3 -4
  3. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/changelog.md +16 -0
  4. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/upgrade.md +19 -0
  5. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/__init__.py +21 -14
  6. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/configuration/core.py +0 -4
  7. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/configuration/transform.py +12 -11
  8. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/output.py +2 -3
  9. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/__init__.py +2 -2
  10. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/project_variables_processor.py +19 -13
  11. gitlabform-6.0.0/gitlabform/util.py +47 -0
  12. {gitlabform-5.5.6 → gitlabform-6.0.0}/pyproject.toml +3 -9
  13. {gitlabform-5.5.6 → gitlabform-6.0.0}/tbump.toml +1 -1
  14. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_files_templates.py +1 -1
  15. gitlabform-6.0.0/tests/unit/configuration/test_yaml_version.py +63 -0
  16. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/configuration/transform/test_access_level_transformer.py +3 -11
  17. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/configuration/transform/test_group_transformer.py +1 -7
  18. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/configuration/transform/test_implicit_name_transformer.py +2 -3
  19. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/configuration/transform/test_user_and_group_transformers.py +1 -19
  20. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/configuration/transform/test_user_transformer.py +6 -17
  21. {gitlabform-5.5.6 → gitlabform-6.0.0}/uv.lock +9 -127
  22. gitlabform-5.5.6/gitlabform/util.py +0 -7
  23. gitlabform-5.5.6/tests/unit/configuration/test_yaml_version.py +0 -36
  24. {gitlabform-5.5.6 → gitlabform-6.0.0}/.coveragerc +0 -0
  25. {gitlabform-5.5.6 → gitlabform-6.0.0}/.dockerignore +0 -0
  26. {gitlabform-5.5.6 → gitlabform-6.0.0}/.git-blame-ignore-revs +0 -0
  27. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/CODEOWNERS +0 -0
  28. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  29. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  30. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/ISSUE_TEMPLATE/question-or-other-issue.md +0 -0
  31. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/actions/setup-uv-local/README.md +0 -0
  32. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/actions/setup-uv-local/action.yml +0 -0
  33. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/dependabot.yml +0 -0
  34. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/workflows/_main.yml +0 -0
  35. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/workflows/build.yml +0 -0
  36. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/workflows/pr-ci-workflow.yml +0 -0
  37. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/workflows/prs-entrypoint-forks.yml +0 -0
  38. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/workflows/prs-entrypoint-main.yml +0 -0
  39. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/workflows/static-analysis.yml +0 -0
  40. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/workflows/tests-acceptance.yml +0 -0
  41. {gitlabform-5.5.6 → gitlabform-6.0.0}/.github/workflows/tests-unit.yml +0 -0
  42. {gitlabform-5.5.6 → gitlabform-6.0.0}/.gitignore +0 -0
  43. {gitlabform-5.5.6 → gitlabform-6.0.0}/.lgtm.yml +0 -0
  44. {gitlabform-5.5.6 → gitlabform-6.0.0}/.mypy.ini +0 -0
  45. {gitlabform-5.5.6 → gitlabform-6.0.0}/.overrides/gitlabform-logo-favicon.png +0 -0
  46. {gitlabform-5.5.6 → gitlabform-6.0.0}/.overrides/gitlabform-logo-favicon.svg +0 -0
  47. {gitlabform-5.5.6 → gitlabform-6.0.0}/.python-version +0 -0
  48. {gitlabform-5.5.6 → gitlabform-6.0.0}/CONTRIBUTING.md +0 -0
  49. {gitlabform-5.5.6 → gitlabform-6.0.0}/Dockerfile +0 -0
  50. {gitlabform-5.5.6 → gitlabform-6.0.0}/LICENSE +0 -0
  51. {gitlabform-5.5.6 → gitlabform-6.0.0}/README.md +0 -0
  52. {gitlabform-5.5.6 → gitlabform-6.0.0}/codecov.yml +0 -0
  53. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/__init__.py +0 -0
  54. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/common.py +0 -0
  55. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/docker.py +0 -0
  56. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/docs.py +0 -0
  57. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/env.py +0 -0
  58. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/gitlab/await-healthy.sh +0 -0
  59. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/gitlab/gitlab.rb +0 -0
  60. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/gitlab/healthcheck-and-setup.sh +0 -0
  61. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/gitlab/run_gitlab_in_docker.sh +0 -0
  62. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/gitlab/tests.Dockerfile +0 -0
  63. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/infra.py +0 -0
  64. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/main.py +0 -0
  65. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/package.py +0 -0
  66. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/qa.py +0 -0
  67. {gitlabform-5.5.6 → gitlabform-6.0.0}/dev/release.py +0 -0
  68. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/automation.md +0 -0
  69. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/contrib/coding_guidelines.md +0 -0
  70. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/contrib/implementation_design.md +0 -0
  71. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/contrib/index.md +0 -0
  72. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/contrib/local_development.md +0 -0
  73. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/contrib/releases.md +0 -0
  74. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/contrib/workflows.md +0 -0
  75. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/features.md +0 -0
  76. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/images/Opencast-logo.png +0 -0
  77. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/images/egnyte-logo.svg +0 -0
  78. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/images/elastic-path-logo.svg +0 -0
  79. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/images/gitlabform-logo-square.png +0 -0
  80. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/images/gitlabform-logo.png +0 -0
  81. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/images/gitlabform-logo.svg +0 -0
  82. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/images/group-ldap-links-provider.png +0 -0
  83. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/images/liquidlight-logo.svg +0 -0
  84. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/images/roche-logo.png +0 -0
  85. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/images/stroeer-online-marketing-logo.svg +0 -0
  86. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/index.md +0 -0
  87. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/installation.md +0 -0
  88. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/archive_unarchive.md +0 -0
  89. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/avatar.md +0 -0
  90. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/badges.md +0 -0
  91. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/ci_cd_variables.md +0 -0
  92. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/deploy_keys.md +0 -0
  93. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/files.md +0 -0
  94. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/group_ldap_links.md +0 -0
  95. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/group_saml_links.md +0 -0
  96. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/index.md +0 -0
  97. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/integrations.md +0 -0
  98. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/job_token_scope.md +0 -0
  99. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/labels.md +0 -0
  100. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/members.md +0 -0
  101. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/merge_requests.md +0 -0
  102. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/pipeline_schedules.md +0 -0
  103. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/project_security_settings.md +0 -0
  104. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/project_transfer.md +0 -0
  105. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/protected_branches.md +0 -0
  106. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/protected_environments.md +0 -0
  107. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/push_mirrors.md +0 -0
  108. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/push_rules.md +0 -0
  109. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/resource_groups.md +0 -0
  110. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/settings.md +0 -0
  111. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/tags_protection.md +0 -0
  112. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/reference/webhooks.md +0 -0
  113. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/requirements.md +0 -0
  114. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/running.md +0 -0
  115. {gitlabform-5.5.6 → gitlabform-6.0.0}/docs/similar_apps.md +0 -0
  116. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlab-config/config.yml +0 -0
  117. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlab-config/gitlab-config.md +0 -0
  118. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/configuration/__init__.py +0 -0
  119. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/configuration/common.py +0 -0
  120. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/configuration/groups.py +0 -0
  121. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/configuration/projects.py +0 -0
  122. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/constants.py +0 -0
  123. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/__init__.py +0 -0
  124. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/commits.py +0 -0
  125. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/core.py +0 -0
  126. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/group_badges.py +0 -0
  127. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/group_ldap_links.py +0 -0
  128. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/groups.py +0 -0
  129. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/merge_requests.py +0 -0
  130. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/pipelines.py +0 -0
  131. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/project_badges.py +0 -0
  132. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/project_deploy_keys.py +0 -0
  133. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/project_merge_requests_approvals.py +0 -0
  134. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/project_protected_environments.py +0 -0
  135. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/projects.py +0 -0
  136. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/python_gitlab.py +0 -0
  137. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/gitlab/variables.py +0 -0
  138. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/lists/__init__.py +0 -0
  139. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/lists/filter.py +0 -0
  140. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/lists/groups.py +0 -0
  141. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/lists/projects.py +0 -0
  142. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/__init__.py +0 -0
  143. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/abstract_processor.py +0 -0
  144. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/application/__init__.py +0 -0
  145. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/application/application_settings_processor.py +0 -0
  146. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/defining_keys.py +0 -0
  147. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/group/__init__.py +0 -0
  148. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/group/group_badges_processor.py +0 -0
  149. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/group/group_hooks_processor.py +0 -0
  150. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/group/group_labels_processor.py +0 -0
  151. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/group/group_ldap_links_processor.py +0 -0
  152. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/group/group_members_processor.py +0 -0
  153. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/group/group_protected_branches_processor.py +0 -0
  154. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/group/group_push_rules_processor.py +0 -0
  155. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/group/group_saml_links_processor.py +0 -0
  156. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/group/group_settings_processor.py +0 -0
  157. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/group/group_variables_processor.py +0 -0
  158. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/multiple_entities_processor.py +0 -0
  159. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/badges_processor.py +0 -0
  160. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/branches_processor.py +0 -0
  161. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/deploy_keys_processor.py +0 -0
  162. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/files_processor.py +0 -0
  163. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/hooks_processor.py +0 -0
  164. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/integrations_processor.py +0 -0
  165. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/job_token_scope_processor.py +0 -0
  166. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/members_processor.py +0 -0
  167. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/merge_requests_approval_rules.py +0 -0
  168. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/merge_requests_approvals.py +0 -0
  169. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/project_labels_processor.py +0 -0
  170. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/project_processor.py +0 -0
  171. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/project_push_rules_processor.py +0 -0
  172. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/project_security_settings.py +0 -0
  173. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/project_settings_processor.py +0 -0
  174. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/remote_mirrors_processor.py +0 -0
  175. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/resource_groups_processor.py +0 -0
  176. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/schedules_processor.py +0 -0
  177. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/project/tags_processor.py +0 -0
  178. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/shared/__init__.py +0 -0
  179. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/shared/protected_environments_processor.py +0 -0
  180. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/util/__init__.py +0 -0
  181. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/util/branch_protection.py +0 -0
  182. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/util/decorators.py +0 -0
  183. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/util/difference_logger.py +0 -0
  184. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/util/labels_processor.py +0 -0
  185. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/processors/util/variables_processor.py +0 -0
  186. {gitlabform-5.5.6 → gitlabform-6.0.0}/gitlabform/run.py +0 -0
  187. {gitlabform-5.5.6 → gitlabform-6.0.0}/mkdocs.yml +0 -0
  188. {gitlabform-5.5.6 → gitlabform-6.0.0}/prek.toml +0 -0
  189. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/__init__.py +0 -0
  190. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/__init__.py +0 -0
  191. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/conftest.py +0 -0
  192. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/premium/test_branches.py +0 -0
  193. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/premium/test_branches_users_case_insensitive.py +0 -0
  194. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/premium/test_group_ldap_links.py +0 -0
  195. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/premium/test_group_protected_branches.py +0 -0
  196. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/premium/test_group_push_rules.py +0 -0
  197. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/premium/test_group_saml_links.py +0 -0
  198. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/premium/test_group_settings.py +0 -0
  199. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/premium/test_group_variables.py +0 -0
  200. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/premium/test_merge_request_approval_rules.py +0 -0
  201. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/premium/test_merge_request_approvals_settings.py +0 -0
  202. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/premium/test_protected_environments.py +0 -0
  203. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/premium/test_push_rules.py +0 -0
  204. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/premium/test_tags.py +0 -0
  205. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/__init__.py +0 -0
  206. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_application_settings.py +0 -0
  207. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_archive_project.py +0 -0
  208. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_badges.py +0 -0
  209. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_branches.py +0 -0
  210. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_deploy_keys.py +0 -0
  211. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_deploy_keys_all_projects.py +0 -0
  212. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_files.py +0 -0
  213. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_group_avatar.py +0 -0
  214. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_group_badges.py +0 -0
  215. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_group_hooks.py +0 -0
  216. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_group_labels.py +0 -0
  217. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_group_members_case_insensitive.py +0 -0
  218. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_group_members_groups.py +0 -0
  219. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_group_members_users.py +0 -0
  220. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_group_settings.py +0 -0
  221. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_group_variables.py +0 -0
  222. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_hooks.py +0 -0
  223. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_integrations.py +0 -0
  224. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_job_token_scope.py +0 -0
  225. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_members.py +0 -0
  226. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_members_add_group.py +0 -0
  227. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_members_enforce.py +0 -0
  228. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_project_avatar.py +0 -0
  229. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_project_group_members_case_insensitive.py +0 -0
  230. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_project_labels.py +0 -0
  231. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_project_members_case_insensitve.py +0 -0
  232. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_project_settings.py +0 -0
  233. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_project_variables.py +0 -0
  234. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_remote_mirrors.py +0 -0
  235. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_resource_groups.py +0 -0
  236. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_running.py +0 -0
  237. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_scheduled_for_deletion_project.py +0 -0
  238. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_schedules.py +0 -0
  239. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_tags.py +0 -0
  240. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_token_from_config.py +0 -0
  241. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/standard/test_transfer_project.py +0 -0
  242. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/ultimate/test_group_members.py +0 -0
  243. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/ultimate/test_group_settings.py +0 -0
  244. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/ultimate/test_members.py +0 -0
  245. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/ultimate/test_project_security_settings.py +0 -0
  246. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/acceptance/ultimate/test_project_settings.py +0 -0
  247. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/__init__.py +0 -0
  248. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/configuration/__init__.py +0 -0
  249. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/configuration/test_case_sensitivity.py +0 -0
  250. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/configuration/test_inheritance_break_projects_and_groups.py +0 -0
  251. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/configuration/test_inheritance_break_subgroups.py +0 -0
  252. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/configuration/test_inheritance_break_validation.py +0 -0
  253. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/configuration/test_projects_and_groups.py +0 -0
  254. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/configuration/test_skip_groups_skip_projects.py +0 -0
  255. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/configuration/test_subgroups.py +0 -0
  256. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/gitlab/test_core.py +0 -0
  257. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/gitlab/test_python_gitlab.py +0 -0
  258. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/processors/__init__.py +0 -0
  259. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/processors/test_abstract_processor.py +0 -0
  260. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/processors/test_abstract_processors.py +0 -0
  261. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/processors/test_branches_processor.py +0 -0
  262. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/processors/test_difference_logger.py +0 -0
  263. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/processors/test_files_processor.py +0 -0
  264. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/processors/test_group_protected_branches_processor.py +0 -0
  265. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/processors/test_schedules_processor_extended_cron_pattern.py +0 -0
  266. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/test_access_levels.py +0 -0
  267. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/test_non_empty_configs_provider.py +0 -0
  268. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/test_parse_args.py +0 -0
  269. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/test_projects_provider.py +0 -0
  270. {gitlabform-5.5.6 → gitlabform-6.0.0}/tests/unit/test_utils.py +0 -0
@@ -165,12 +165,12 @@ jobs:
165
165
  uses: actions/checkout@v6
166
166
  with:
167
167
  ref: ${{ needs.prep-release.outputs.semver_tag }}
168
- - name: Get the version from the tag
169
- run: echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV
170
168
  - name: Docker metadata
171
169
  id: metadata
172
170
  uses: docker/metadata-action@v6
173
171
  with:
172
+ # Get the ref and the sha from the checked out context - e.g. semver tag rather than triggering branch
173
+ context: git
174
174
  images: |
175
175
  ghcr.io/gitlabform/gitlabform
176
176
  flavor: |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitlabform
3
- Version: 5.5.6
3
+ Version: 6.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
  Project-URL: Homepage, https://gitlabform.github.io/gitlabform/
6
6
  Project-URL: Repository, https://github.com/gitlabform/gitlabform.git
@@ -21,7 +21,6 @@ Classifier: Topic :: Software Development :: Version Control :: Git
21
21
  Requires-Python: >=3.12.0
22
22
  Requires-Dist: certifi==2026.5.20
23
23
  Requires-Dist: cli-ui==0.19.0
24
- Requires-Dist: ez-yaml==1.2.0
25
24
  Requires-Dist: jinja2==3.1.6
26
25
  Requires-Dist: luddite==1.0.4
27
26
  Requires-Dist: markupsafe==3.0.3
@@ -30,8 +29,8 @@ Requires-Dist: packaging==26.2
30
29
  Requires-Dist: python-gitlab[graphql]==8.4.0
31
30
  Requires-Dist: requests==2.34.2
32
31
  Requires-Dist: rich==15.0.0
33
- Requires-Dist: ruamel-yaml==0.17.21
34
- Requires-Dist: yamlpath==3.8.2
32
+ Requires-Dist: ruamel-yaml==0.19.1
33
+ Requires-Dist: yamlpath==3.9.1
35
34
  Description-Content-Type: text/markdown
36
35
 
37
36
  [![version](https://badge.fury.io/gh/gitlabform%2Fgitlabform.svg)](https://badge.fury.io/gh/gitlabform%2Fgitlabform)
@@ -6,6 +6,22 @@ For details on how to migrate between major versions, please refer to the [upgra
6
6
 
7
7
  ---
8
8
 
9
+ ## 6.0.0
10
+
11
+ ### Breaking Changes
12
+
13
+ **Drops default support for YAML 1.1 by upgrading dependency major versions:** [#1309](https://github.com/gitlabform/gitlabform/pull/1309). ([timknight01](https://github.com/TimKnight01))
14
+ * Drops DeepDiff and ez_yaml dependencies
15
+ * Upgrades ruamel.yaml and yamlpath to their latest versions
16
+
17
+ See [upgrade guide](upgrade.md) for important upgrade instructions and migration details.
18
+
19
+ ## 5.5.7
20
+
21
+ ### Build
22
+
23
+ * Fix an issue where the incorrect `ref` was used in docker/metadata-action preventing publishing to GHCR on a Tag. ([timknight01](https://github.com/TimKnight01))
24
+
9
25
  ## 5.5.6
10
26
 
11
27
  ### Documentation
@@ -2,6 +2,25 @@
2
2
 
3
3
  Some of these changes between major application versions may affect the effective configuration that would be applied if you run the application. Therefore to do the upgrade safely please follow this procedure.
4
4
 
5
+ ## From 5.\* to 6.\*
6
+
7
+ We have upgraded to new major versions of underlying YAML libraries `ezyaml`, `yamlpath` and `ruamel.yaml`.
8
+
9
+ This results in GitLabForm no longer defaulting to `yaml 1.1` support when parsing YAML configuration files.
10
+
11
+ In order to retain `yaml 1.1` configuration you **must** add the `%YAML` directive to the top of your configuration file, for example:
12
+
13
+ ```yaml
14
+ %YAML 1.1
15
+ ---
16
+ projects_and_groups:
17
+ some_group/*:
18
+ project_settings:
19
+ foo: yes
20
+ ```
21
+
22
+ Alternatively update your YAML to be compatible with `yaml 1.2` specification, for example by replacing `yes` with `true` in the above example, and any instances of `no` with `false`.
23
+
5
24
  ## From 4.\* to 5.\*
6
25
 
7
26
  ### Update `config_version`
@@ -68,8 +68,9 @@ class GitLabForm:
68
68
  self.only_sections = "all"
69
69
  self.exclude_sections = []
70
70
  self.recurse_subgroups = recurse_subgroups
71
+ self.log_level = logging.DEBUG
71
72
 
72
- self._configure_output(tests=True)
73
+ self._configure_logging()
73
74
  else:
74
75
  # normal mode
75
76
 
@@ -94,7 +95,16 @@ class GitLabForm:
94
95
  self.recurse_subgroups,
95
96
  ) = self._parse_args()
96
97
 
97
- self._configure_output()
98
+ if self.debug:
99
+ level = logging.DEBUG
100
+ elif self.verbose:
101
+ level = logging.INFO
102
+ else:
103
+ level = logging.WARNING
104
+
105
+ self.log_level = level
106
+
107
+ self._configure_logging()
98
108
 
99
109
  self._show_version(self.skip_version_check)
100
110
  if self.just_show_version:
@@ -108,7 +118,7 @@ class GitLabForm:
108
118
 
109
119
  self.application_processors = ApplicationProcessors(self.gitlab, self.configuration, self.strict)
110
120
  self.group_processors = GroupProcessors(self.gitlab, self.configuration, self.strict)
111
- self.project_processors = ProjectProcessors(self.gitlab, self.configuration, self.strict)
121
+ self.project_processors = ProjectProcessors(self.gitlab, self.configuration, self.strict, self.log_level)
112
122
  self.groups_provider = GroupsProvider(
113
123
  self.gitlab,
114
124
  self.configuration,
@@ -323,27 +333,24 @@ class GitLabForm:
323
333
  args.recurse_subsgroups,
324
334
  )
325
335
 
326
- def _configure_output(self, tests=False) -> None:
336
+ def _configure_logging(self) -> None:
327
337
  """
328
338
  Configures the application output using logging, based on debug and verbose flags:
329
339
 
330
340
  * normal mode - logging only WARNING logs
331
341
  * verbose mode - logging INFO level and above
332
342
  * debug / tests mode - logging DEBUG level and above, along with rich exception tracebacks (may expose secrets)
333
-
334
- :param tests: True if we are running in tests mode
335
343
  """
336
344
  rich_tracebacks = False
337
- if tests or self.debug:
338
- level = logging.DEBUG
345
+
346
+ if self.log_level == logging.DEBUG:
339
347
  rich_tracebacks = True
340
- elif self.verbose:
341
- level = logging.INFO
342
- else:
343
- level = logging.WARNING
344
348
 
345
349
  logging.basicConfig(
346
- level=level, format="%(message)s", datefmt="[%X]", handlers=[RichHandler(rich_tracebacks=rich_tracebacks)]
350
+ level=self.log_level,
351
+ format="%(message)s",
352
+ datefmt="[%X]",
353
+ handlers=[RichHandler(rich_tracebacks=rich_tracebacks)],
347
354
  )
348
355
 
349
356
  def _initialize_configuration_and_gitlab(self) -> Tuple[GitLab, Configuration]:
@@ -362,7 +369,7 @@ class GitLabForm:
362
369
  gitlab = GitLab(config_path=self.config)
363
370
  configuration = gitlab.get_configuration()
364
371
 
365
- configuration_transformers = ConfigurationTransformers(gitlab)
372
+ configuration_transformers = ConfigurationTransformers(gitlab, self.log_level)
366
373
  configuration_transformers.transform(configuration)
367
374
 
368
375
  except ConfigFileNotFoundException as e:
@@ -93,10 +93,6 @@ class ConfigurationCore(ABC):
93
93
 
94
94
  yaml = Parsers.get_yaml_editor()
95
95
 
96
- # for better backward compatibility with PyYAML (that supports only YAML 1.1) used in the previous
97
- # GitLabForm versions, let's force ruamel.yaml to use YAML version 1.1 by default too
98
- yaml.version = (1, 1)
99
-
100
96
  if config_string:
101
97
  config = textwrap.dedent(source)
102
98
  info("Reading config from the provided string.")
@@ -1,15 +1,13 @@
1
1
  import sys
2
- from logging import debug, info, critical
2
+ from logging import debug, info, critical, DEBUG
3
3
  from abc import ABC, abstractmethod
4
- from ez_yaml import ez_yaml
5
- from ruamel.yaml import YAML
6
4
  from types import SimpleNamespace
7
-
8
5
  from ruamel.yaml.comments import CommentedMap
9
6
  from yamlpath import Processor
10
7
  from yamlpath.exceptions import YAMLPathException
11
8
  from yamlpath.wrappers import ConsolePrinter
12
9
 
10
+ from gitlabform import util
13
11
  from gitlabform.constants import EXIT_INVALID_INPUT, APPROVAL_RULE_NAME
14
12
  from gitlabform.configuration import Configuration
15
13
  from gitlabform.gitlab import AccessLevel
@@ -24,23 +22,26 @@ from gitlabform.gitlab import GitLab
24
22
 
25
23
 
26
24
  class ConfigurationTransformers:
27
- def __init__(self, gitlab: GitLab):
25
+ def __init__(self, gitlab: GitLab, log_level: int):
28
26
  self.user_transformer = UserTransformer(gitlab)
29
27
  self.group_transformer = GroupTransformer(gitlab)
30
28
  self.implicit_name_transformer = ImplicitNameTransformer(gitlab)
31
29
  self.access_level_transformer = AccessLevelsTransformer(gitlab)
30
+ self.log_level = log_level
32
31
 
33
32
  def transform(self, configuration: Configuration) -> None:
34
- config_before = ez_yaml.to_string(obj=configuration.config, options={})
35
- debug(f"Config BEFORE transformations:\n{config_before}")
33
+ if self.log_level == DEBUG:
34
+ config_before = util.yaml_config_to_string(configuration.config)
35
+ debug(f"Config BEFORE transformations:\n{config_before}")
36
36
 
37
37
  self.user_transformer.transform(configuration)
38
38
  self.group_transformer.transform(configuration)
39
39
  self.implicit_name_transformer.transform(configuration)
40
40
  self.access_level_transformer.transform(configuration, last=True)
41
41
 
42
- config_after = ez_yaml.to_string(obj=configuration.config, options={})
43
- debug(f"Config AFTER transformations:\n{config_after}")
42
+ if self.log_level == DEBUG:
43
+ config_after = util.yaml_config_to_string(configuration.config)
44
+ debug(f"Config AFTER transformations:\n{config_after}")
44
45
 
45
46
 
46
47
  class ConfigurationTransformer(ABC):
@@ -58,9 +59,9 @@ class ConfigurationTransformer(ABC):
58
59
  # we needed complex ruamel.yaml's types like ordereddict and CommentedSeq
59
60
  # for transformations, but at the end convert them to simple dict and lists
60
61
  # for easier to understand debug output and tests
62
+ config_yaml_string = util.yaml_config_to_string(configuration.config)
61
63
 
62
- config_yaml_string = ez_yaml.to_string(obj=configuration.config, options={})
63
- simple_yaml_loader = YAML(typ="safe", pure=True)
64
+ simple_yaml_loader = util.configure_ruamel_yaml_loader(typ="safe", pure=True)
64
65
  configuration.config = simple_yaml_loader.load(config_yaml_string)
65
66
 
66
67
 
@@ -1,8 +1,7 @@
1
1
  import sys
2
2
  from logging import debug, critical, info
3
3
 
4
- import ez_yaml
5
-
4
+ from gitlabform import util
6
5
  from gitlabform.constants import EXIT_INVALID_INPUT, EXIT_PROCESSING_ERROR
7
6
 
8
7
 
@@ -38,7 +37,7 @@ class EffectiveConfigurationFile:
38
37
  def write_to_file(self):
39
38
  if self.output_file:
40
39
  try:
41
- yaml_configuration = ez_yaml.to_string(self.config)
40
+ yaml_configuration = util.yaml_config_to_string(self.config)
42
41
  self.output_file.write(yaml_configuration)
43
42
  self.output_file.close()
44
43
  except Exception as e:
@@ -47,7 +47,7 @@ from gitlabform.processors.project.remote_mirrors_processor import RemoteMirrors
47
47
 
48
48
 
49
49
  class ProjectProcessors(AbstractProcessors):
50
- def __init__(self, gitlab: GitLab, config: Configuration, strict: bool):
50
+ def __init__(self, gitlab: GitLab, config: Configuration, strict: bool, log_level: int):
51
51
  super().__init__(gitlab, config, strict)
52
52
  self.processors: List[AbstractProcessor] = [
53
53
  # Order of processors matter. GitLabForm will process config sections
@@ -64,7 +64,7 @@ class ProjectProcessors(AbstractProcessors):
64
64
  ProjectLabelsProcessor(gitlab),
65
65
  JobTokenScopeProcessor(gitlab),
66
66
  DeployKeysProcessor(gitlab),
67
- ProjectVariablesProcessor(gitlab),
67
+ ProjectVariablesProcessor(gitlab, log_level),
68
68
  BranchesProcessor(gitlab, strict),
69
69
  TagsProcessor(gitlab, strict),
70
70
  IntegrationsProcessor(gitlab),
@@ -1,12 +1,13 @@
1
1
  from typing import Dict, Any, List, cast
2
- from logging import warning, info
2
+ from logging import warning, info, INFO
3
3
 
4
4
  import copy
5
5
  import textwrap
6
- import ez_yaml
7
6
 
8
7
  from gitlab.exceptions import GitlabGetError
9
8
  from gitlab.v4.objects import Project, ProjectVariable
9
+
10
+ from gitlabform import util
10
11
  from gitlabform.gitlab import GitLab
11
12
  from gitlabform.processors.util.difference_logger import hide
12
13
  from gitlabform.processors.abstract_processor import AbstractProcessor
@@ -14,8 +15,9 @@ from gitlabform.processors.util.variables_processor import VariablesProcessor
14
15
 
15
16
 
16
17
  class ProjectVariablesProcessor(AbstractProcessor):
17
- def __init__(self, gitlab: GitLab):
18
+ def __init__(self, gitlab: GitLab, log_level: int):
18
19
  super().__init__("variables", gitlab)
20
+ self.log_level = log_level
19
21
  self._variables_processor = VariablesProcessor(self._needs_update)
20
22
 
21
23
  def _process_configuration(self, project_and_group: str, configuration: Dict[str, Any]) -> None:
@@ -65,12 +67,14 @@ class ProjectVariablesProcessor(AbstractProcessor):
65
67
  variables_list.append(var_dict)
66
68
 
67
69
  info(f"Variables for {project_and_group} in GitLab:")
68
- info(
69
- textwrap.indent(
70
- ez_yaml.to_string(variables_list),
71
- " ",
70
+ if self.log_level == INFO:
71
+ yaml = util.yaml_config_to_string(variables_list)
72
+ info(
73
+ textwrap.indent(
74
+ yaml,
75
+ " ",
76
+ )
72
77
  )
73
- )
74
78
  except GitlabGetError:
75
79
  info(f"Variables for {project_and_group} in GitLab cannot be checked.")
76
80
 
@@ -86,9 +90,11 @@ class ProjectVariablesProcessor(AbstractProcessor):
86
90
  for key in configured_variables.keys():
87
91
  configured_variables[key]["value"] = hide(configured_variables[key]["value"])
88
92
 
89
- info(
90
- textwrap.indent(
91
- ez_yaml.to_string(configured_variables),
92
- " ",
93
+ if self.log_level == INFO:
94
+ yaml = util.yaml_config_to_string(configured_variables)
95
+ info(
96
+ textwrap.indent(
97
+ "",
98
+ " ",
99
+ )
93
100
  )
94
- )
@@ -0,0 +1,47 @@
1
+ import json
2
+ from io import StringIO
3
+
4
+ from ruamel.yaml import YAML
5
+
6
+
7
+ def to_str(a_dict: dict) -> str:
8
+ # arguably the most readable form of a dict in a single line
9
+ # is JSON with sorted keys
10
+ return json.dumps(a_dict, sort_keys=True, default=str)
11
+
12
+
13
+ def yaml_config_to_string(yaml) -> str:
14
+ """
15
+ Provides a convenience wrapper around ruamel.yaml to output to a string
16
+ ez_yaml used to perform this task but in v2.2 they seem to have over complicated the implementation and it is
17
+ breaking in ruamel.yaml when parsing the yaml, with no way for us to configure it.
18
+ We can provide a simple native implementation around ruamel.yaml to configure it consistently.
19
+ :param yaml:
20
+ :return:
21
+ """
22
+ yaml_loader = configure_ruamel_yaml_loader()
23
+
24
+ # dump to StringIO
25
+ string_stream = StringIO()
26
+ yaml_loader.dump(yaml, string_stream)
27
+ config_yaml_string = string_stream.getvalue()
28
+ string_stream.close()
29
+
30
+ return config_yaml_string
31
+
32
+
33
+ def configure_ruamel_yaml_loader(typ=None, pure=False, output=None, plug_ins=None) -> YAML:
34
+ """
35
+ Takes inputs matching ruamel.yaml __init__ and configures with indentation, duplicate key allowance and null representor
36
+ :return: instance of ruamel.yaml
37
+ """
38
+ yaml_loader = YAML(typ=typ, pure=pure, output=output, plug_ins=plug_ins)
39
+ yaml_loader.indent(mapping=3, sequence=2, offset=0)
40
+ yaml_loader.allow_duplicate_keys = True
41
+ yaml_loader.explicit_start = False
42
+ # show null
43
+ yaml_loader.representer.add_representer(
44
+ type(None),
45
+ lambda self, data: self.represent_scalar("tag:yaml.org,2002:null", "null"),
46
+ )
47
+ return yaml_loader
@@ -10,7 +10,7 @@ packages = ["gitlabform"]
10
10
 
11
11
  [project]
12
12
  name = "gitlabform"
13
- version = "5.5.6"
13
+ version = "6.0.0"
14
14
  requires-python = ">=3.12.0"
15
15
  authors = [{ name = "Greg Dubicki and Contributors" }]
16
16
  description = "🏗 Specialized configuration as a code tool for GitLab projects, groups and more using hierarchical configuration written in YAML"
@@ -33,8 +33,6 @@ classifiers = [
33
33
  dependencies = [
34
34
  "certifi==2026.5.20",
35
35
  "cli-ui==0.19.0",
36
- # ez_yaml >1.2.0 changes imports and also uses ruamel.yaml tied to 1.2 so wouldn't support "yes" as True
37
- "ez-yaml==1.2.0",
38
36
  "jinja2==3.1.6",
39
37
  "luddite==1.0.4",
40
38
  "markupsafe==3.0.3",
@@ -43,11 +41,8 @@ dependencies = [
43
41
  "python-gitlab[graphql]==8.4.0",
44
42
  "requests==2.34.2",
45
43
  "rich==15.0.0",
46
- # yamlpath and ruamel and tightly coupled, currently 0.19.1 of ruamel and 3.9.0 of yamlpath break support for
47
- # yaml 1.1 "yes" -> True conversion. If we want to upgrade we'd need to make a breaking-change and drop support for
48
- # unannotated yaml 1.1
49
- "ruamel.yaml==0.17.21",
50
- "yamlpath==3.8.2",
44
+ "ruamel.yaml==0.19.1",
45
+ "yamlpath==3.9.1",
51
46
  ]
52
47
 
53
48
  # PEP 735 Dependency Groups.
@@ -65,7 +60,6 @@ dev = [
65
60
  test = [
66
61
  "coverage==7.14.1",
67
62
  "cryptography==49.0.0",
68
- "deepdiff==9.1.0",
69
63
  "pytest==9.1.0",
70
64
  "pytest-cov==7.1.0",
71
65
  "pytest-rerunfailures==16.3",
@@ -2,7 +2,7 @@
2
2
  github_url = "https://github.com/gitlabform/gitlabform/"
3
3
 
4
4
  [version]
5
- current = "5.5.6"
5
+ current = "6.0.0"
6
6
 
7
7
  # Example of a semver regexp.
8
8
  # Make sure this matches current_version before
@@ -81,7 +81,7 @@ class TestFilesTemplates:
81
81
  "README.md":
82
82
  overwrite: true
83
83
  branches: all
84
- template: no
84
+ template: false
85
85
  content: |
86
86
  This is a text containing literals: {{{{ group }}}}/{{{{ project }}}}
87
87
  """
@@ -0,0 +1,63 @@
1
+ import pytest
2
+
3
+ from gitlabform.configuration import Configuration
4
+
5
+
6
+ @pytest.fixture
7
+ def yaml11_configuration_with_yes():
8
+ config_yaml = """
9
+ ---
10
+ projects_and_groups:
11
+ some_group/*:
12
+ project_settings:
13
+ foo: yes # in YAML 1.1 this should be interpreted as boolean true
14
+ """
15
+ return Configuration(config_string=config_yaml)
16
+
17
+
18
+ @pytest.fixture
19
+ def yaml12_configuration():
20
+ config_yaml = """
21
+ %YAML 1.2
22
+ ---
23
+ projects_and_groups:
24
+ some_group/*:
25
+ project_settings:
26
+ foo: true
27
+ """
28
+ return Configuration(config_string=config_yaml)
29
+
30
+
31
+ @pytest.fixture
32
+ def yaml11_annotated_configuration_with_yes():
33
+ config_yaml = """
34
+ %YAML 1.1
35
+ ---
36
+ projects_and_groups:
37
+ some_group/*:
38
+ project_settings:
39
+ foo: yes # in YAML 1.1 this should be interpreted as boolean true
40
+ """
41
+ return Configuration(config_string=config_yaml)
42
+
43
+
44
+ def test__unannotated_yaml_11(yaml11_configuration_with_yes):
45
+ """
46
+ By default, in v6.+ we use YAML 1.2, so the "yes" value is not interpreted as a boolean.
47
+ This test validates that without annotation, the YAML file is treated as v1.2, and "yes" is just a string, not a boolean.
48
+ """
49
+ assert yaml11_configuration_with_yes.get("projects_and_groups|some_group/*|project_settings") == {"foo": "yes"}
50
+
51
+
52
+ def test__annotated_yaml_11(yaml11_annotated_configuration_with_yes):
53
+ """
54
+ By default, in v6.+ we use YAML 1.2, so the "yes" value is not interpreted as a boolean, unless annotated as such.
55
+ This test validates the annotation can correctly set a YAML file to v1.1
56
+ """
57
+ assert yaml11_annotated_configuration_with_yes.get("projects_and_groups|some_group/*|project_settings") == {
58
+ "foo": True
59
+ }
60
+
61
+
62
+ def test__yaml_12(yaml12_configuration):
63
+ assert yaml12_configuration.get("projects_and_groups|some_group/*|project_settings") == {"foo": True}
@@ -1,11 +1,6 @@
1
- from unittest import TestCase
2
-
3
- import ez_yaml
4
1
  import pytest
5
- from deepdiff import DeepDiff
6
2
  from unittest.mock import MagicMock
7
3
 
8
- from gitlabform.constants import APPROVAL_RULE_NAME
9
4
  from gitlabform import EXIT_INVALID_INPUT
10
5
  from gitlabform.configuration import Configuration
11
6
  from gitlabform.configuration.transform import (
@@ -86,8 +81,7 @@ def test__config__with_access_level_names__branches():
86
81
  """
87
82
  configuration_with_numbers = Configuration(config_string=config_with_numbers)
88
83
 
89
- ddiff = DeepDiff(configuration.config, configuration_with_numbers.config)
90
- assert not ddiff
84
+ assert configuration.config == configuration_with_numbers.config
91
85
 
92
86
 
93
87
  def test__config__with_access_level_names__group_ldap_links():
@@ -128,8 +122,7 @@ def test__config__with_access_level_names__group_ldap_links():
128
122
  """
129
123
  configuration_with_numbers = Configuration(config_string=config_with_numbers)
130
124
 
131
- ddiff = DeepDiff(configuration.config, configuration_with_numbers.config)
132
- assert not ddiff
125
+ assert configuration_with_numbers.config == configuration_with_numbers.config
133
126
 
134
127
 
135
128
  def test__config__with_access_level_names__branches_premium_syntax():
@@ -174,8 +167,7 @@ def test__config__with_access_level_names__branches_premium_syntax():
174
167
  """
175
168
  configuration_with_numbers = Configuration(config_string=config_with_numbers)
176
169
 
177
- ddiff = DeepDiff(configuration.config, configuration_with_numbers.config)
178
- assert not ddiff
170
+ assert configuration.config == configuration_with_numbers.config
179
171
 
180
172
 
181
173
  def test__config__with_access_level_names__invalid_name():
@@ -1,4 +1,3 @@
1
- from deepdiff import DeepDiff
2
1
  from unittest.mock import MagicMock
3
2
 
4
3
  from gitlabform.configuration import Configuration
@@ -29,10 +28,6 @@ def test__transform_for_merge_request_approvals() -> None:
29
28
 
30
29
  assert gitlab_mock._get_group_id.call_count == 1
31
30
 
32
- # effective_config_yaml_str = ez_yaml.to_string(obj=configuration.config, options={})
33
- # print("!!!")
34
- # print(effective_config_yaml_str)
35
-
36
31
  expected_transformed_config_yaml = f"""
37
32
  projects_and_groups:
38
33
  "foo/bar":
@@ -45,6 +40,5 @@ def test__transform_for_merge_request_approvals() -> None:
45
40
  """
46
41
 
47
42
  expected_transformed_config = Configuration(config_string=expected_transformed_config_yaml)
48
- transformer.convert_to_simple_types(expected_transformed_config)
49
43
 
50
- assert not DeepDiff(configuration.config, expected_transformed_config.config)
44
+ assert configuration.config == expected_transformed_config.config
@@ -1,4 +1,3 @@
1
- from deepdiff import DeepDiff
2
1
  from unittest.mock import MagicMock
3
2
 
4
3
  from gitlabform.configuration import Configuration
@@ -31,7 +30,7 @@ def test__transform_for_protected_environments():
31
30
 
32
31
  expected_transformed_config = Configuration(config_string=expected_transformed_config_yaml)
33
32
 
34
- assert not DeepDiff(configuration.config, expected_transformed_config.config)
33
+ assert configuration.config == expected_transformed_config.config
35
34
 
36
35
 
37
36
  def test__transform_for_protected_environments_sanity_check():
@@ -47,4 +46,4 @@ def test__transform_for_protected_environments_sanity_check():
47
46
 
48
47
  expected_transformed_config = Configuration(config_string=expected_transformed_config_yaml)
49
48
 
50
- assert DeepDiff(configuration.config, expected_transformed_config.config)
49
+ assert configuration.config != expected_transformed_config.config
@@ -1,6 +1,3 @@
1
- import ez_yaml
2
- from deepdiff import DeepDiff
3
- from pprint import pprint
4
1
  from unittest.mock import MagicMock
5
2
 
6
3
  from gitlabform.configuration import Configuration
@@ -35,7 +32,6 @@ def test__transform_for_merge_request_approvals() -> None:
35
32
  gitlab_mock = MagicMock(GitLab)
36
33
  gitlab_mock._get_group_id = MagicMock(side_effect=[1])
37
34
  gitlab_mock._get_user_id = MagicMock(side_effect=[2])
38
- # gitlab_mock._get_branch_id = MagicMock(side_effect=[3])
39
35
 
40
36
  ut = UserTransformer(gitlab_mock)
41
37
  ut.transform(configuration)
@@ -43,13 +39,6 @@ def test__transform_for_merge_request_approvals() -> None:
43
39
  gt = GroupTransformer(gitlab_mock)
44
40
  gt.transform(configuration, last=True)
45
41
 
46
- # ut = UserTransformer(gitlab_mock)
47
- # ut.transform(configuration)
48
-
49
- effective_config_yaml_str = ez_yaml.to_string(obj=configuration.config, options={})
50
- print("!!!BEFORE:")
51
- print(effective_config_yaml_str)
52
-
53
42
  expected_transformed_config_yaml = f"""
54
43
  projects_and_groups:
55
44
 
@@ -70,11 +59,4 @@ def test__transform_for_merge_request_approvals() -> None:
70
59
 
71
60
  expected_transformed_config = Configuration(config_string=expected_transformed_config_yaml)
72
61
 
73
- ut.convert_to_simple_types(expected_transformed_config)
74
-
75
- effective_config_yaml_str = ez_yaml.to_string(obj=expected_transformed_config.config, options={})
76
- print("!!!After:")
77
- print(effective_config_yaml_str)
78
-
79
- difference = DeepDiff(configuration.config, expected_transformed_config.config)
80
- assert not difference
62
+ assert configuration.config == expected_transformed_config.config