Skip to content

feat(gitlab): dynamic access levels + group & membership ops + full group filters#5743

Merged
waleedlatif1 merged 4 commits into
stagingfrom
feature/gitlab-groups-filters-followup
Jul 17, 2026
Merged

feat(gitlab): dynamic access levels + group & membership ops + full group filters#5743
waleedlatif1 merged 4 commits into
stagingfrom
feature/gitlab-groups-filters-followup

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

Supersedes and bundles #5726, adding the full documented filter surface for group listing on top. Everything ships as one reviewable change.

Dynamic access levels (from #5726)

  • The three access-level fields (accessLevel, memberAccessLevel, invitationAccessLevel) are combobox (not dropdown), so a level can be bound to a runtime reference or picked by name. The resolved value is validated at execution time by coerceGitLabAccessLevel (accepts integer, numeric string, or case-insensitive name).
  • GITLAB_ACCESS_LEVELS in tools/gitlab/utils.ts is the single source of truth for the enum; block options and runtime coercion both derive from it.

Group & membership operations (from #5726)

  • get_group / list_groups — resolve and list groups (GET /groups/:id, GET /groups).
  • list_user_memberships — admin-only GET /users/:id/memberships, clearly gated in its description.

New in this PR — full group-listing filters + audit hardening

  • list_groups now supports every documented GET /groups filter: visibility, min_access_level, all_available, plus order_by/sort — all surfaced in the block (advanced mode) and forwarded in params.
  • order_by widened to include GitLab's documented similarity value (requires a search term).
  • min_access_level reuses the access-level enum for the block dropdown (drops No access); the tool guard rejects 0 since GitLab's floor is 5.
  • Enum label Minimal AccessMinimal access to match GitLab verbatim.

Validation

  • Every new tool and the access-level change were audited by parallel agents against GitLab's live API docs — zero correctness issues; all findings fixed.
  • All 9 access levels verified name+integer against docs (incl. 15 Planner, 25 Security Manager).

Type of Change

  • New feature

Testing

  • Vitest: 46 GitLab tests pass (coercion name/int/numeric-string/invalid/level-0, three new tools, block coercion + new-op + filter mapping).
  • Biome and tsc --noEmit clean.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

mzxchandra and others added 3 commits July 16, 2026 19:12
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.
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.
- list_groups: add visibility, min_access_level, and all_available filters (documented on GET /groups) plus order_by/sort, now surfaced in the block and forwarded in params
- order_by widened to include GitLab's documented 'similarity' value
- access-level enum label 'Minimal Access' -> 'Minimal access' to match GitLab verbatim; coercion already case-insensitive
- min_access_level guard rejects 0 (GitLab floor is 5); reuse the access-level enum for the block dropdown (drops 'No access')
- tests: out-of-enum numeric-string coercion case + full list_groups filter mapping
@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 17, 2026 8:37pm

Request Review

@cursor

cursor Bot commented Jul 17, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes membership and access-request parameter handling and can alter who gets which GitLab role when workflows bind dynamic levels; new admin-only membership API is gated but misconfigured tokens could surprise operators.

Overview
Extends the GitLab block and tools with group listing/detail, admin user memberships, and runtime-friendly access levels for membership and SAML flows.

Access levels move from fixed dropdowns to comboboxes backed by a shared GITLAB_ACCESS_LEVELS enum in utils. At run time, hasGitLabAccessLevel / coerceGitLabAccessLevel accept integer, numeric string, or role name (e.g. Developer), treat 0 ("No access") as a real value instead of omitting it, and throw on invalid levels. Invitation updates still omit level when left unchanged.

New operations: list_groups (full GET /groups filters: visibility, min access level, all available, top-level, similarity ordering with search guard), get_group, and list_user_memberships (admin GET /users/:id/memberships with optional Project/Namespace filter). The block wires UI filters, pagination, and param mapping; tools are registered in the GitLab index and registry.

Hardening: encodeGitLabResourceId avoids double-encoding pre-encoded group/project paths; coerceGitLabMinAccessLevel rejects 0 for group list filters. Vitest coverage expands for coercion, block routing, and the three new tools.

Reviewed by Cursor Bugbot for commit 160aaaa. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR expands the GitLab integration with dynamic access levels and group operations. The main changes are:

  • Runtime coercion and validation for named or numeric access levels.
  • Tools for getting groups, listing groups, and listing user memberships.
  • Full filtering, ordering, and pagination options for group listings.
  • Block registration, response types, and tests for the new operations.

Confidence Score: 5/5

This looks safe to merge.

  • Invalid minimum access levels are rejected before request construction.
  • Similarity ordering now requires the same trimmed search term sent to GitLab.
  • Focused tests cover the corrected inputs and valid request paths.

Important Files Changed

Filename Overview
apps/sim/tools/gitlab/list_groups.ts Adds group listing filters and now validates access levels and similarity-order prerequisites before sending requests.
apps/sim/tools/gitlab/utils.ts Defines the shared access-level catalog and runtime coercion helpers.
apps/sim/blocks/blocks/gitlab.ts Exposes the new GitLab operations, dynamic access-level inputs, and group filters in the block.
apps/sim/tools/gitlab/get_group.ts Adds a tool for retrieving a GitLab group by ID or path.
apps/sim/tools/gitlab/list_user_memberships.ts Adds the administrator-only user membership listing tool.

Reviews (2): Last reviewed commit: "fix(gitlab): validate list_groups min-ac..." | Re-trigger Greptile

Comment thread apps/sim/tools/gitlab/list_groups.ts Outdated
Comment thread apps/sim/tools/gitlab/list_groups.ts Outdated
…ering at execution time

Greptile round 1 (both P1):
- min_access_level: coerce via the shared access-level enum (coerceGitLabMinAccessLevel) and throw on out-of-enum values (31, 999) or 0, so a direct tool call fails loudly instead of sending an invalid filter to GitLab
- order_by=similarity now requires a non-empty search term (GitLab ignores similarity ordering without one); throws a clear error otherwise
- tests for both validations
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ 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 160aaaa. Configure here.

@waleedlatif1
waleedlatif1 merged commit fb86b49 into staging Jul 17, 2026
15 checks passed
@waleedlatif1
waleedlatif1 deleted the feature/gitlab-groups-filters-followup branch July 17, 2026 20:40
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