From 188c96283dc0b49ca354952c5ea2f4fc519d28cc Mon Sep 17 00:00:00 2001 From: Philip Nelson Date: Wed, 25 Mar 2026 16:06:18 -0600 Subject: [PATCH 1/5] test: add test for hidden variables --- .gitignore | 1 + tests/functional/api/test_variables.py | 48 ++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/.gitignore b/.gitignore index 849ca6e85..3a1338bb3 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ docs/_build .tox .venv/ venv/ +.mypy_cache/ # Include tracked hidden files and directories in search and diff tools !.dockerignore diff --git a/tests/functional/api/test_variables.py b/tests/functional/api/test_variables.py index eeed51da7..44f23cf6f 100644 --- a/tests/functional/api/test_variables.py +++ b/tests/functional/api/test_variables.py @@ -43,3 +43,51 @@ def test_project_variables(project): assert variable.value == "new_value1" variable.delete() + + +def test_hidden_instance_variables(gl): + variable = gl.variables.create( + {"key": "key1", "value": "secret_value", "masked_and_hidden": True} + ) + assert variable.value == "secret_value" + assert variable.description is None + assert variable in gl.variables.list() + + variable.description = "new_description" + variable.save() + variable = gl.variables.get(variable.key) + assert variable.description == "new_description" + + variable.delete() + + +def test_hidden_group_variables(group): + variable = group.variables.create( + {"key": "key1", "value": "secret_value", "masked_and_hidden": True} + ) + assert variable.value is None + assert variable.description is None + assert variable in group.variables.list() + + variable.description = "new_description" + variable.save() + variable = group.variables.get(variable.key) + assert variable.description == "new_description" + + variable.delete() + + +def test_hidden_project_variables(project): + variable = project.variables.create( + {"key": "key1", "value": "secret_value", "masked_and_hidden": True} + ) + assert variable.value is None + assert variable.description is None + assert variable in project.variables.list() + + variable.description = "new_description" + variable.save() + variable = project.variables.get(variable.key) + assert variable.description == "new_description" + + variable.delete() From 7f312424cb6f74a6bf0d7fcb01d88e18619d07aa Mon Sep 17 00:00:00 2001 From: Philip Nelson Date: Wed, 25 Mar 2026 15:38:05 -0600 Subject: [PATCH 2/5] feat(api): add 'masked_and_hidden' to the optional variable create attrs fix(api): make 'value' an optional variable update attr --- gitlab/v4/objects/variables.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/gitlab/v4/objects/variables.py b/gitlab/v4/objects/variables.py index bae2be22b..b5c3bc47b 100644 --- a/gitlab/v4/objects/variables.py +++ b/gitlab/v4/objects/variables.py @@ -27,10 +27,11 @@ class VariableManager(CRUDMixin[Variable]): _path = "/admin/ci/variables" _obj_cls = Variable _create_attrs = RequiredOptional( - required=("key", "value"), optional=("protected", "variable_type", "masked") + required=("key", "value"), + optional=("protected", "variable_type", "masked", "masked_and_hidden"), ) _update_attrs = RequiredOptional( - required=("key", "value"), optional=("protected", "variable_type", "masked") + required=("key",), optional=("value", "protected", "variable_type", "masked") ) @@ -43,10 +44,11 @@ class GroupVariableManager(CRUDMixin[GroupVariable]): _obj_cls = GroupVariable _from_parent_attrs = {"group_id": "id"} _create_attrs = RequiredOptional( - required=("key", "value"), optional=("protected", "variable_type", "masked") + required=("key", "value"), + optional=("protected", "variable_type", "masked", "masked_and_hidden"), ) _update_attrs = RequiredOptional( - required=("key", "value"), optional=("protected", "variable_type", "masked") + required=("key",), optional=("value", "protected", "variable_type", "masked") ) @@ -60,9 +62,15 @@ class ProjectVariableManager(CRUDMixin[ProjectVariable]): _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional( required=("key", "value"), - optional=("protected", "variable_type", "masked", "environment_scope"), + optional=( + "protected", + "variable_type", + "masked", + "environment_scope", + "masked_and_hidden", + ), ) _update_attrs = RequiredOptional( - required=("key", "value"), - optional=("protected", "variable_type", "masked", "environment_scope"), + required=("key",), + optional=("value", "protected", "variable_type", "masked", "environment_scope"), ) From 4ea4cc0442b794796de04cf76d1d313b372d119d Mon Sep 17 00:00:00 2001 From: Philip Nelson Date: Mon, 20 Apr 2026 13:06:18 -0600 Subject: [PATCH 3/5] fixup! feat(api): add 'masked_and_hidden' to the optional variable create attrs remove hidden_and_masked from admin vars api --- gitlab/v4/objects/variables.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gitlab/v4/objects/variables.py b/gitlab/v4/objects/variables.py index b5c3bc47b..2dcbf1583 100644 --- a/gitlab/v4/objects/variables.py +++ b/gitlab/v4/objects/variables.py @@ -27,8 +27,7 @@ class VariableManager(CRUDMixin[Variable]): _path = "/admin/ci/variables" _obj_cls = Variable _create_attrs = RequiredOptional( - required=("key", "value"), - optional=("protected", "variable_type", "masked", "masked_and_hidden"), + required=("key", "value"), optional=("protected", "variable_type", "masked") ) _update_attrs = RequiredOptional( required=("key",), optional=("value", "protected", "variable_type", "masked") From d47e03f22013556c9440b726855a564d0e7b6b93 Mon Sep 17 00:00:00 2001 From: Philip Nelson Date: Mon, 20 Apr 2026 13:23:10 -0600 Subject: [PATCH 4/5] fixup! feat(api): add 'masked_and_hidden' to the optional variable create attrs add missing optional attributes --- gitlab/v4/objects/variables.py | 52 ++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/gitlab/v4/objects/variables.py b/gitlab/v4/objects/variables.py index 2dcbf1583..afb42bda3 100644 --- a/gitlab/v4/objects/variables.py +++ b/gitlab/v4/objects/variables.py @@ -27,10 +27,19 @@ class VariableManager(CRUDMixin[Variable]): _path = "/admin/ci/variables" _obj_cls = Variable _create_attrs = RequiredOptional( - required=("key", "value"), optional=("protected", "variable_type", "masked") + required=("key", "value"), + optional=("description", "masked", "protected", "raw", "variable_type"), ) _update_attrs = RequiredOptional( - required=("key",), optional=("value", "protected", "variable_type", "masked") + required=("key",), + optional=( + "description", + "masked", + "protected", + "raw", + "value", + "variable_type", + ), ) @@ -44,10 +53,27 @@ class GroupVariableManager(CRUDMixin[GroupVariable]): _from_parent_attrs = {"group_id": "id"} _create_attrs = RequiredOptional( required=("key", "value"), - optional=("protected", "variable_type", "masked", "masked_and_hidden"), + optional=( + "description", + "environment_scope", + "masked", + "masked_and_hidden", + "protected", + "raw", + "variable_type", + ), ) _update_attrs = RequiredOptional( - required=("key",), optional=("value", "protected", "variable_type", "masked") + required=("key",), + optional=( + "description", + "environment_scope", + "masked", + "protected", + "raw", + "value", + "variable_type", + ), ) @@ -62,14 +88,24 @@ class ProjectVariableManager(CRUDMixin[ProjectVariable]): _create_attrs = RequiredOptional( required=("key", "value"), optional=( - "protected", - "variable_type", - "masked", + "description", "environment_scope", + "masked", "masked_and_hidden", + "protected", + "raw", + "variable_type", ), ) _update_attrs = RequiredOptional( required=("key",), - optional=("value", "protected", "variable_type", "masked", "environment_scope"), + optional=( + "description", + "environment_scope", + "masked", + "protected", + "raw", + "value", + "variable_type", + ), ) From 5c0652deebef7505f46ed39a4cebf5cb2a7ff3e0 Mon Sep 17 00:00:00 2001 From: Philip Nelson Date: Mon, 20 Apr 2026 14:29:49 -0600 Subject: [PATCH 5/5] fixup! test: add test for hidden variables Remove instance test becasue it does not support masked_and_hidden --- tests/functional/api/test_variables.py | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/tests/functional/api/test_variables.py b/tests/functional/api/test_variables.py index 44f23cf6f..bed26c1d0 100644 --- a/tests/functional/api/test_variables.py +++ b/tests/functional/api/test_variables.py @@ -45,26 +45,12 @@ def test_project_variables(project): variable.delete() -def test_hidden_instance_variables(gl): - variable = gl.variables.create( - {"key": "key1", "value": "secret_value", "masked_and_hidden": True} - ) - assert variable.value == "secret_value" - assert variable.description is None - assert variable in gl.variables.list() - - variable.description = "new_description" - variable.save() - variable = gl.variables.get(variable.key) - assert variable.description == "new_description" - - variable.delete() - - def test_hidden_group_variables(group): variable = group.variables.create( {"key": "key1", "value": "secret_value", "masked_and_hidden": True} ) + + variable = group.variables.get(variable.key) assert variable.value is None assert variable.description is None assert variable in group.variables.list() @@ -81,6 +67,8 @@ def test_hidden_project_variables(project): variable = project.variables.create( {"key": "key1", "value": "secret_value", "masked_and_hidden": True} ) + + variable = project.variables.get(variable.key) assert variable.value is None assert variable.description is None assert variable in project.variables.list()