X Tutup
Skip to content

feat(api): add support for project feature flags and feature flag user lists#3366

Open
amimas wants to merge 10 commits intopython-gitlab:mainfrom
amimas:issue-3350
Open

feat(api): add support for project feature flags and feature flag user lists#3366
amimas wants to merge 10 commits intopython-gitlab:mainfrom
amimas:issue-3350

Conversation

@amimas
Copy link
Contributor

@amimas amimas commented Mar 9, 2026

Changes

This change introduces support for managing Project Feature Flags and Feature Flag User Lists via the API and CLI.

It adds the ProjectFeatureFlag and ProjectFeatureFlagUserList objects and their corresponding managers, which are exposed on the Project object as project.feature_flags and project.feature_flags_user_lists.

To support the specific data formats required by these GitLab APIs, this change also introduces:

  • JsonAttribute: A new attribute type to handle the strategies field, which is sent as a JSON object.
  • CommaSeparatedStringAttribute: A new attribute type to handle the user_xids field, which is sent as a comma-separated string.

Additionally, a custom save() method has been implemented for ProjectFeatureFlag to correctly handle renaming, as the flag's name is also its unique identifier.

The implementation includes:

  • API object and manager definitions.
  • Functional API tests.
  • Functional CLI tests.
  • Unit tests for the new attribute types and the custom renaming logic.

Documentation and testing

Please consider whether this PR needs documentation and tests. This is not required, but highly appreciated:

Documentation updates:

  • Added new documentation pages for Project Feature Flags and Feature Flag User Lists.
  • Renamed the existing features.rst to gitlab_features.rst and updated its content to clearly distinguish that this API/feature is for admin-only GitLab Development Feature Flags - not for project-level feature flags.

References:

Support for following API is being included in this PR

Documentation changed/clarified related to following existing feature in python-gitlab

amimas added 9 commits March 9, 2026 18:58
Add support for the Project Feature Flags API.

- Add `ProjectFeatureFlag` and `ProjectFeatureFlagManager`.
- Add `project.feature_flags` manager.
- Add functional tests for API and CLI.
- Handle JSON parsing for `strategies` attribute in
CLI commands by overriding create/update methods in the manager.
Add `JsonAttribute` to `gitlab.types` to handle JSON parsing for CLI
arguments.

Update `ProjectFeatureFlagManager` to use `JsonAttribute` for the
`strategies` attribute, replacing custom `create` and `update` overrides.
This adds support for managing user lists for project feature flags.
It introduces the `ProjectFeatureFlagUserList` object and manager,
and exposes it via `project.feature_flags_user_lists`.

New type `CommaSeparatedStringAttribute` is added to handle
comma-separated string values in API requests.
Add functional tests to ensure that feature flag strategies and scopes
can be removed using the `_destroy` flag in the update payload, as
supported by the GitLab API.
The `ProjectFeatureFlag` object uses `name` as its ID attribute.
Previously, modifying the `name` of a flag object and calling `save()`
would fail because the library would attempt to send a PUT request to
the *new* name, which does not yet exist, resulting in a 404 error.

This change overrides the `save()` method in `ProjectFeatureFlag` to
correctly handle renaming. It now detects when the `name` attribute has
been modified and uses the original name for the API request URL, while
sending the new name in the request body.

This makes renaming feature flags more intuitive and consistent with the
behavior of other objects in the library.
This adds the documentation for Project Feature Flags and Feature Flag
User Lists.

It includes:
- New documentation pages for Feature Flags and User Lists.
- Updates to the Project documentation to reference the new managers.
The existing documentation for `features.rst` covered the API for
managing GitLab's internal development feature flags, which requires
administrator access. This was easily confused with the newly added
project-level feature flags API.

To prevent ambiguity for users, this commit refactors the documentation by:
- Renaming `features.rst` to `gitlab_features.rst`.
- Updating the title and adding a note to clarify its specific,
  admin-only purpose.
- Adding a cross-reference to the new project-level feature flag
  documentation.
This adds unit tests for the new logic introduced with the feature
flags API.

- Verifies the custom `save()` method in `ProjectFeatureFlag` correctly
  handles renaming by using the old name in the URL and the new name
  in the request body.
- Verifies the `CommaSeparatedStringAttribute` correctly converts a
  Python list to a comma-separated string for API calls.
- Verifies the `JsonAttribute` correctly handles JSON string parsing.
The title overline in `docs/gl_objects/project_feature_flag_user_lists.rst`
was shorter than the title text, causing a Sphinx warning.
@codecov
Copy link

codecov bot commented Mar 10, 2026

Codecov Report

❌ Patch coverage is 96.87500% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.76%. Comparing base (cb09624) to head (aa156b0).

Files with missing lines Patch % Lines
gitlab/v4/objects/feature_flags.py 93.93% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3366      +/-   ##
==========================================
+ Coverage   95.75%   95.76%   +0.01%     
==========================================
  Files          98      100       +2     
  Lines        6054     6117      +63     
==========================================
+ Hits         5797     5858      +61     
- Misses        257      259       +2     
Flag Coverage Δ
api_func_v4 83.63% <92.18%> (+0.08%) ⬆️
cli_func_v4 78.63% <75.00%> (-0.05%) ⬇️
unit 90.24% <95.31%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
gitlab/types.py 98.46% <100.00%> (+0.21%) ⬆️
gitlab/utils.py 98.59% <100.00%> (ø)
gitlab/v4/objects/__init__.py 100.00% <100.00%> (ø)
gitlab/v4/objects/feature_flag_user_lists.py 100.00% <100.00%> (ø)
gitlab/v4/objects/projects.py 98.95% <100.00%> (+0.01%) ⬆️
gitlab/v4/objects/feature_flags.py 93.93% <93.93%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for managing Project Feature Flags and Feature Flag User Lists in python-gitlab, enabling users to interact with the GitLab Feature Flags API and Feature Flag User Lists API via both the Python API client and CLI.

Changes:

  • Adds two new API object files (feature_flags.py and feature_flag_user_lists.py) with custom save() logic in ProjectFeatureFlag to support renaming via the original name in the URL
  • Introduces two new GitlabAttribute types: JsonAttribute (for parsing/sending JSON from the CLI) and CommaSeparatedStringAttribute (for transforming lists to CSV strings in POST/PUT bodies), plus a transform_in_post hook in utils._transform_types
  • Adds unit tests for the new attribute types and renaming logic, functional API tests, functional CLI tests, and updated/new documentation pages

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
gitlab/v4/objects/feature_flags.py New ProjectFeatureFlag and ProjectFeatureFlagManager with custom save/rename logic
gitlab/v4/objects/feature_flag_user_lists.py New ProjectFeatureFlagUserList and ProjectFeatureFlagUserListManager
gitlab/v4/objects/__init__.py Adds exports for the two new object modules
gitlab/v4/objects/projects.py Attaches the two new managers to Project
gitlab/types.py New JsonAttribute and CommaSeparatedStringAttribute types
gitlab/utils.py Extended _transform_types with transform_in_post support
tests/unit/test_types.py Unit tests for the two new attribute types
tests/unit/objects/test_project_feature_flags.py Unit test for rename save behavior
tests/unit/objects/test_project_feature_flag_user_lists.py Unit test for list→CSV transformation in POST body
tests/functional/api/test_project_feature_flags.py Functional API tests (CRUD + rename + strategy/scope deletion)
tests/functional/api/test_project_feature_flag_user_lists.py Functional API tests (CRUD + search)
tests/functional/cli/test_cli_project_feature_flags.py Functional CLI tests (CRUD + strategy creation)
tests/functional/cli/test_cli_project_feature_flag_user_lists.py Functional CLI tests (CRUD)
docs/gl_objects/project_feature_flags.rst New documentation page for feature flags
docs/gl_objects/project_feature_flag_user_lists.rst New documentation page for user lists
docs/gl_objects/gitlab_features.rst Renamed/clarified admin-only GitLab dev features doc
docs/gl_objects/projects.rst Added references to the two new documentation pages
docs/api-objects.rst Updated ToC to reference renamed and new docs

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

assert o.get_for_api(key="spam") == ("spam", "foo")


# JSONAttribute tests
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says # JSONAttribute tests but the class is named JsonAttribute (not JSONAttribute). The comment should match the actual class name.

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +15
@pytest.fixture
def project():
gl = Gitlab("http://localhost", private_token="private_token", api_version="4")
return gl.projects.get(1, lazy=True)
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both test_project_feature_flags.py and test_project_feature_flag_user_lists.py define a local project fixture that creates a Gitlab instance directly. This duplicates the shared project fixture from tests/unit/conftest.py (which is available to all unit tests), and is missing the ssl_verify=True argument used in the shared fixture. The local fixtures should be removed and the shared one (from conftest) should be used instead.

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +14
@pytest.fixture
def project():
gl = Gitlab("http://localhost", private_token="private_token", api_version="4")
return gl.projects.get(1, lazy=True)
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This local project fixture duplicates the shared one from tests/unit/conftest.py and is missing the ssl_verify=True argument. The local fixture should be removed in favour of the shared conftest fixture.

Copilot uses AI. Check for mistakes.
This commit refactors the unit tests for `ProjectFeatureFlag` and
`ProjectFeatureFlagUserList` to use the shared `project` fixture from
`conftest.py`.

This change removes duplicated local fixture definitions, improving
code consistency and maintainability, and addresses feedback from
the pull request review.
@amimas
Copy link
Contributor Author

amimas commented Mar 10, 2026

/rerun-workflow "Test / functional (cli_func_v4)"

@amimas
Copy link
Contributor Author

amimas commented Mar 10, 2026

/rerun-workflow "Test / functional (api_func_v4)"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

X Tutup