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/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"), ) diff --git a/tests/functional/api/test_variables.py b/tests/functional/api/test_variables.py index eeed51da7..48c532dce 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 is None + 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()