feat(gitlab): dynamic access levels + group and membership operations#5726
feat(gitlab): dynamic access levels + group and membership operations#5726mzxchandra wants to merge 2 commits into
Conversation
Access levels can now be bound to runtime references (e.g. a policy-table
lookup), not just picked from a static list. The three access-level fields
(accessLevel, memberAccessLevel, invitationAccessLevel) switch from dropdown
to combobox so a reference expression is accepted at Copilot save-time instead
of being rejected as an invalid enum value. The resolved value is validated at
execution time by coerceGitLabAccessLevel, which accepts an integer, a numeric
string, or a level name ("Developer"), and throws a clear error otherwise -
preserving the real safety property (no bad integer reaches GitLab) while
dropping the false one (levels must be known at design time).
Also closes demand gaps from the AskIT data:
- get_group / list_groups: resolve and list groups (provisioning critical path)
- list_user_memberships: admin GET /users/:id/memberships, gated in its
description; the non-admin path is composing list_members
The access-level enum is now a single source of truth in tools/gitlab/utils.ts
(GITLAB_ACCESS_LEVELS) that the block options and runtime coercion both derive
from, replacing three inline copies.
|
@mzxchandra is attempting to deploy a commit to the Sim Team on Vercel. A member of the Team first needs to authorize it. |
PR SummaryMedium Risk Overview Dynamic access levels: The three access-level fields ( New block operations: List Groups, Get Group, and List User Memberships (admin API) are wired through new tools, block params, filters ( Path encoding: Reviewed by Cursor Bugbot for commit 65e38db. Bugbot is set up for automated code reviews on this repo. Configure here. |
Greptile SummaryThis PR expands GitLab access and membership operations. The main changes are:
Confidence Score: 5/5This looks safe to merge.
Important Files Changed
Reviews (2): Last reviewed commit: "fix(gitlab): treat access level 0 ("No a..." | Re-trigger Greptile |
A runtime reference can resolve to the integer 0, but the block still gated access-level presence with truthiness: required ops rejected 0 as missing and optional ops silently omitted it. Add hasGitLabAccessLevel(value) (0 and '0' are provided; undefined/null/'' are not) and use it for all six presence gates so "No access" can be granted or set via a reference.
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 65e38db. Configure here.
|
closed as apart of #5743 |
Summary
Fast-follow to #5710. Fixes a blocking defect and closes two follow-up gaps in the GitLab block's access/membership surface.
1. Dynamic access levels (the core fix)
The access-level fields were
dropdownsubblocks, which the Copilot save-time validator checks against a closed enum - so binding a level to a runtime reference (<block.output>) was rejected outright withInvalid dropdown value, and the value wasn't even persisted. But access provisioning computes the grant from a (role, department) → level policy table at runtime; the level is often not a design-time constant, so this made the common case unbuildable natively.accessLevel,memberAccessLevel,invitationAccessLevel) switch fromdropdowntocombobox, which keeps the named options as a picker and accepts a reference expression at save time.coerceGitLabAccessLevel, which accepts an integer (30), a numeric string ("30"), or a level name ("Developer", case-insensitive), and throws a clear error otherwise. This preserves the real safety property (no unintended integer reaches GitLab) while dropping the false one (levels must be knowable at design time).GITLAB_ACCESS_LEVELSintools/gitlab/utils.ts) that both the block options and runtime coercion derive from, replacing three inline copies.2. Follow-up gaps closed
get_group/list_groups- resolve and list groups. A provisioning workflow must resolve the group before it can grant anything; the block hadget_projectbut no group equivalent.list_user_memberships- adminGET /users/:id/memberships, clearly gated as admin-only in its description. The non-admin path (iteratinglist_members) is already composable with shipped tools.host- verified already reference-bindable (it's ashort-input); no change needed.Deferred to separate tickets
Testing
coerceGitLabAccessLevel(name/int/numeric-string/invalid), the three new tools (URL builders +transformResponse), and block-level coercion + new-op wiring.bun run check:api-validationall clean.Invalid dropdown valuerejection), and the block coerces a name-bound reference to the correct integer at execution.🤖 Generated with Claude Code