Add member_role_id support to group protected branches REST API
## Context | | | |---|---| | **Phase** | 3 of 6 | | **Parallel with** | https://gitlab.com/gitlab-org/gitlab/-/work_items/594880+ <br> https://gitlab.com/gitlab-org/gitlab/-/work_items/594881+ <br> https://gitlab.com/gitlab-org/gitlab/-/work_items/594883+ <br> https://gitlab.com/gitlab-org/gitlab/-/work_items/594884+ | | **Blocked by** | https://gitlab.com/gitlab-org/gitlab/-/work_items/594877+ <br> https://gitlab.com/gitlab-org/gitlab/-/work_items/594878+ <br> https://gitlab.com/gitlab-org/gitlab/-/work_items/594879+ | | **Unblocks** | https://gitlab.com/gitlab-org/gitlab/-/work_items/594890+ | ## Summary Verify and extend group-level protected branches API support for `member_role_id`, ensuring custom roles can be set when protecting branches at the group level. ## Background The group protected branches API (`ee/lib/api/group_protected_branches.rb`) uses `use :optional_params_ee` which inherits from `ee/lib/ee/api/helpers/protected_branches_helpers.rb`. Once Issue 6 adds `member_role_id` to `shared_params`, the group API will automatically accept it in `allowed_to_push`, `allowed_to_merge`, and `allowed_to_unprotect` arrays. However, the group API's `POST` endpoint also accepts scalar `push_access_level` and `merge_access_level` integer params (for simple single-role protection). Custom roles are **not** supported via these scalar params — only via the array form. This needs to be clearly documented and validated. Additionally, group-level rules have a different namespace scoping concern: the `member_role` must belong to the same top-level group that owns the protected branch. ## Relevant files - `ee/lib/api/group_protected_branches.rb` — group API - `ee/lib/ee/api/helpers/protected_branches_helpers.rb` — shared params (updated in Issue 6) - `ee/app/models/concerns/ee/protected_branch_access.rb` — namespace validation (Issue 4) ## Changes required ### Verify `use :optional_params_ee` inheritance After Issue 6 is merged, write a quick integration test to confirm that `POST /groups/:id/protected_branches` with `allowed_to_merge: [{ member_role_id: 42 }]` correctly creates the access level row. No code change may be needed. ### Scalar param documentation The `push_access_level` and `merge_access_level` scalar integer params on the group API `POST` endpoint accept integers (e.g. `40` for Maintainer). Add a comment/documentation note that custom roles are not supported via these params; use `allowed_to_push`/`allowed_to_merge` arrays instead. ### Namespace validation The namespace validation added in Issue 4 checks `member_role.namespace_id == root_namespace.id`. For group-level protected branches, `protected_branch_group` is the group, and the root namespace is `protected_branch_group.root_ancestor`. Verify this correctly scopes to the right group in all cases (top-level group, subgroup's protected branch inherited from parent group). ### Group entity Verify that `Entities::GroupProtectedBranch` uses the same `ProtectedRefAccess` entity (updated in Issue 7) so that `member_role_id` appears in group API responses as well. ## API examples **Create group-level protected branch with custom role allowed to merge:** ``` POST /groups/:id/protected_branches { "name": "main", "allowed_to_merge": [{ "member_role_id": 42 }], "push_access_level": 40 } ``` **Response:** ```json { "id": 1, "name": "main", "merge_access_levels": [ { "access_level": 30, "access_level_description": "Lead Developer", "member_role_id": 42 } ], "push_access_levels": [ { "access_level": 40, "access_level_description": "Maintainers" } ] } ``` ## Testing - API request spec: `POST /groups/:id/protected_branches` with `allowed_to_merge: [{ member_role_id: N }]` - API request spec: `PATCH /groups/:id/protected_branches/:name` updating to add/remove custom role access - API request spec: `member_role_id` from a different namespace returns 422 - API request spec: scalar `push_access_level` param still works normally - Verify group API response includes `member_role_id` in access level objects ## Dependencies - Issue 6 (API params) — `member_role_id` must be added to `shared_params` first - Issue 7 (API entity) — entity must expose `member_role_id` in responses - Issues 3 & 4 (model) — underlying model must accept and validate `member_role_id` ## Labels
issue