Skip to content

Add Gitlab CLI integration#998

Open
Nih1tGupta wants to merge 4 commits into
mainfrom
feat/gitlab-integration
Open

Add Gitlab CLI integration#998
Nih1tGupta wants to merge 4 commits into
mainfrom
feat/gitlab-integration

Conversation

@Nih1tGupta

@Nih1tGupta Nih1tGupta commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Closes #997

Summary

  • Adds a new potpie gitlab command group for PAT-based authentication and read workflows.
  • Supports both gitlab.com and self-hosted GitLab instances with multi-instance credential storage.
  • Integrates GitLab with the existing authentication plumbing:
    • potpie auth status --verify
    • potpie auth logout
    • integration verification

Problem

Potpie already supports GitHub, Linear, Jira, and Confluence through the CLI. However, GitLab users could not:

  • Connect a GitLab instance.
  • Verify credentials.
  • List projects.
  • Browse merge requests or issues.

This was particularly problematic for self-hosted GitLab users, as there was no support for custom instance URLs or a Personal Access Token (PAT) authentication flow.


Solution

CLI Surface

potpie gitlab login [--force] [--instance <url>] [--token <pat>]
potpie gitlab logout [--instance <host>]
potpie gitlab ls
potpie gitlab repos [--instance <host>] [--limit <n>]
potpie gitlab select [--instance <host>] [--project <group/repo>] [--limit <n>]

Files Changed

New Modules

  • adapters/inbound/cli/auth/gitlab_auth.py
    • Interactive PAT login flow.
  • adapters/inbound/cli/auth/gitlab_commands.py
    • Typer command group.
  • adapters/inbound/cli/auth/gitlab_read.py
    • Project selection and MR/issue fetch workflow.
  • adapters/outbound/cli_auth/gitlab_client.py
    • URL normalization, PAT verification, and error handling.
  • adapters/outbound/cli_auth/gitlab_read_client.py
    • GitLab Projects, Merge Requests, and Issues API client.

Extended Modules

  • auth_commands.py
    • Registers the GitLab command group, status, and logout support.
  • credentials_store.py
  • credentials.py
  • Domain authentication port
    • GitLab credential lifecycle support.
  • integration_profile.py
  • integration_verify.py
    • GitLab integration records and verification.
  • provider_config.py
    • Adds the GitLab provider and related constants.

Tests

New Test Files

  • tests/unit/test_cli_gitlab.py
  • tests/unit/test_cli_gitlab_commands.py
  • tests/unit/test_gitlab_client.py
  • tests/_auth_fakes.py
    • In-memory GitLab credential fakes.

Test Plan

1. Verify GitLab unit tests

cd potpie/potpie/context-engine

python -m pytest \
  tests/unit/test_cli_gitlab.py \
  tests/unit/test_cli_gitlab_commands.py \
  tests/unit/test_gitlab_client.py \
  -q

2. Verify GitLab module coverage exceeds 80%

python -m pytest \
  tests/unit/test_cli_gitlab.py \
  tests/unit/test_cli_gitlab_commands.py \
  tests/unit/test_gitlab_client.py \
  --cov=adapters.inbound.cli.auth.gitlab_auth \
  --cov=adapters.inbound.cli.auth.gitlab_commands \
  --cov=adapters.inbound.cli.auth.gitlab_read \
  --cov=adapters.outbound.cli_auth.gitlab_client \
  --cov=adapters.outbound.cli_auth.gitlab_read_client \
  --cov-report=term-missing \
  --cov-fail-under=80

3. Verify existing provider CLI tests still pass

python -m pytest \
  tests/unit/test_github_cli_auth.py \
  tests/unit/test_cli_linear.py \
  tests/unit/test_cli_atlassian.py \
  -q

4. Manual smoke test

potpie gitlab login
potpie gitlab ls
potpie auth status --verify
potpie gitlab repos
potpie gitlab select --project <group/repo>
potpie gitlab logout

Notes

  • GitLab authentication is exposed via:

    potpie gitlab login

    rather than the deprecated:

    potpie auth gitlab
  • This PR implements Personal Access Token (PAT) authentication only. OAuth support is intentionally out of scope.

Screenshot 2026-07-06 at 6 26 43 PM

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds GitLab support to CLI auth, credential storage, verification, and read flows, with a new gitlab command group for login, logout, listing instances, browsing projects, and selecting a project context.

Changes

GitLab CLI Integration

Layer / File(s) Summary
GitLab credential contract and storage
potpie/context-engine/domain/ports/cli_auth/credentials.py, potpie/context-engine/adapters/outbound/cli_auth/credentials.py, potpie/context-engine/adapters/outbound/cli_auth/credentials_store.py, potpie/context-engine/adapters/outbound/cli_auth/integration_profile.py, potpie/context-engine/adapters/outbound/cli_auth/provider_config.py, potpie/context-engine/adapters/inbound/cli/auth/auth_commands.py
Adds GitLab credential and workspace methods, per-instance PAT persistence, metadata/status shaping, provider allowlisting, and GitLab URL/config helpers.
GitLab verification and read clients
potpie/context-engine/adapters/outbound/cli_auth/gitlab_client.py, potpie/context-engine/adapters/outbound/cli_auth/gitlab_read_client.py, potpie/context-engine/adapters/outbound/cli_auth/integration_verify.py
Adds GitLab instance and scope verification, user profile parsing, and authenticated project, merge request, and issue fetchers.
Interactive PAT auth and project selection
potpie/context-engine/adapters/inbound/cli/auth/gitlab_auth.py, potpie/context-engine/adapters/inbound/cli/auth/gitlab_read.py
Adds the interactive PAT login flow, browser-open countdown and cancellation handling, and the project selection flow that persists workspace preferences.
GitLab CLI commands and root wiring
potpie/context-engine/adapters/inbound/cli/auth/gitlab_commands.py, potpie/context-engine/adapters/inbound/cli/auth/auth_commands.py
Adds the gitlab Typer command group and wires GitLab into logout routing, integration status output, and CLI command registration.
GitLab CLI tests
potpie/context-engine/tests/_auth_fakes.py, potpie/context-engine/tests/unit/test_cli_gitlab.py, potpie/context-engine/tests/unit/test_cli_gitlab_commands.py, potpie/context-engine/tests/unit/test_gitlab_client.py
Adds in-memory GitLab fakes and unit tests for storage, verification, read flows, interactive auth, and CLI command behavior.

Possibly related PRs

  • potpie-ai/potpie#863: Modifies the same centralized integration auth CLI wiring in auth_commands.py for provider dispatch, status output, and logout routing.
  • potpie-ai/potpie#923: Updates the shared credential storage plumbing that this PR extends for GitLab PAT and workspace persistence.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes implement the linked GitLab CLI integration requirements, including PAT auth, self-hosted instances, and the requested commands.
Out of Scope Changes check ✅ Passed The added files and tests all support the GitLab CLI integration scope; no unrelated changes stand out.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title clearly summarizes the main change: adding GitLab CLI integration.
Description check ✅ Passed The description is directly related to the GitLab CLI integration and matches the changeset.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 15

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
potpie/context-engine/adapters/inbound/cli/auth/auth_commands.py (1)

499-507: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant gitlab branch — identical to else.

elif provider == "gitlab": credentials = get_integration_tokens(provider) does exactly what the trailing else already does for any non-linear/github provider. This adds branching with no behavioral difference; consider dropping the gitlab case and letting it fall through to else.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@potpie/context-engine/adapters/inbound/cli/auth/auth_commands.py` around
lines 499 - 507, The provider handling in auth_commands.py has a redundant
gitlab branch in the credential lookup logic. Update the provider selection in
the relevant auth command function so the gitlab case is removed and gitlab
falls through to the existing else path, keeping the behavior identical while
simplifying the branch structure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@potpie/context-engine/adapters/inbound/cli/auth/auth_commands.py`:
- Around line 639-643: The GitLab logout path in auth_logout() is invoking the
Typer command directly, which causes the default typer.Option value to be
treated as the instance host instead of None. Update this branch to call a plain
helper or explicitly pass None through gitlab_logout so
clear_gitlab_credentials(instance_host=instance) receives the expected value.
Use auth_logout(), gitlab_logout(), and clear_gitlab_credentials() to locate and
fix this path.

In `@potpie/context-engine/adapters/inbound/cli/auth/gitlab_auth.py`:
- Around line 26-53: The module has constants defined before the import blocks,
which triggers Ruff E402 because imports are no longer at the top of the file.
In gitlab_auth.py, move the assignments for EXIT_CANCELLED,
GITLAB_AUTO_OPEN_SECONDS, and _GITLAB_OPEN_PROMPT_PREFIX to after all adapters.*
and other module imports, or reorder the imports above those constants, so the
file keeps a clean top-level import section.
- Around line 216-266: The GitLab PAT flow is ignoring a provided --instance
unless --token is also supplied because run_gitlab_pat_auth only treats both
values as “supplied.” Update the branching in run_gitlab_pat_auth so an explicit
instance is preserved and reused when prompting for the token, instead of
falling back to _prompt_instance_url and git remote detection. Use the existing
instance_host, normalize_instance_url, _prompt_instance_url, and _prompt_pat
paths to keep the typed instance as the default target.

In `@potpie/context-engine/adapters/inbound/cli/auth/gitlab_commands.py`:
- Around line 78-97: Add a direct-call-safe GitLab logout helper so the CLI
wrapper is not used as the implementation entrypoint. The issue is that
gitlab_logout currently takes the raw typer.Option default when called directly
from auth_commands.py, and that value is passed into
clear_gitlab_credentials(instance_host=instance) instead of a real str | None.
Mirror the github_logout_impl pattern by moving the logout logic into a separate
helper, then have gitlab_logout only parse CLI options and delegate to that
helper so direct calls bypass Typer defaults cleanly.

In `@potpie/context-engine/adapters/inbound/cli/auth/gitlab_read.py`:
- Around line 55-86: The non-interactive path in run_gitlab_select_flow is
blocking use of the saved default project because the terminal check runs before
load_gitlab_read_credentials() and fetches prefs["default_project"]. Move the
guard so credentials are loaded and default_project is computed before deciding
whether stdin is a TTY, then allow the saved default_project branch to select or
synthesize the project when project_path is absent. Keep the logic centered
around run_gitlab_select_flow, load_gitlab_read_credentials, and _prompt_project
so scripted runs can use the persisted preference without requiring --project.

In `@potpie/context-engine/adapters/outbound/cli_auth/credentials_store.py`:
- Around line 1234-1253: `save_gitlab_workspace_prefs` should not create a new
metadata-only instance when the host is unknown. In
`save_gitlab_workspace_prefs`, after resolving `host` and reading `meta`, verify
that the host already exists in `instances` before updating `workspaces`; if it
does not, raise `ProviderCredentialError` instead of writing a stub entry. Keep
the existing update path for valid hosts, and reference the same metadata
helpers (`_read_gitlab_metadata`, `_norm_gitlab_host`,
`_get_active_gitlab_host`, `_write_metadata_entry`) when making the check.
- Around line 1130-1165: save_gitlab_credentials is overwriting the stored
GitLab instance record from scratch, which drops existing workspace preferences
and refreshes created_at on re-login. Update the save flow in
save_gitlab_credentials to load the current entry from _read_gitlab_metadata()
for the same inst_host, then merge the new record from
build_gitlab_integration_record with the existing one so fields like
workspaces/default_project and created_at are preserved unless explicitly
changed. Keep the final write through _write_metadata_entry using the merged
instance record.

In `@potpie/context-engine/adapters/outbound/cli_auth/gitlab_client.py`:
- Around line 30-41: normalize_instance_url currently preserves an explicit
http:// scheme, which allows the GitLab auth client to send PRIVATE-TOKEN over
cleartext. Update normalize_instance_url in gitlab_client.py so it rejects or
upgrades plain HTTP by default and only allows it when an explicit opt-in is
present for internal-only instances. Keep the HTTPS normalization path intact
and ensure any callers that rely on the returned URL from normalize_instance_url
or the GitLab client setup continue to receive an https:// URL unless HTTP is
explicitly permitted.

In `@potpie/context-engine/adapters/outbound/cli_auth/gitlab_read_client.py`:
- Around line 98-212: The three GitLab fetchers repeat the same
load-creds/request/normalize flow, so extract that shared logic into a helper
and keep the per-endpoint field mapping separate. Add a reusable internal helper
around load_gitlab_read_credentials, _api_base, _headers, and _get_json that
preserves the current “non-list response returns []” behavior, then have
fetch_gitlab_projects, fetch_gitlab_merge_requests, and fetch_gitlab_issues call
it and only transform each item into their specific dict shape.
- Around line 134-212: The GitLab read helpers do not enforce path-based project
ID encoding, so raw path_with_namespace strings can be routed incorrectly.
Update fetch_gitlab_merge_requests and fetch_gitlab_issues to normalize string
project_id values by percent-encoding them before building the
/projects/{project_id} URL, and make the contract explicit in these helpers so
future callers do not need to encode externally. After moving the encoding into
gitlab_read_client.py, remove the caller-side quote_plus handling in
gitlab_read.py to prevent double-encoding.

In `@potpie/context-engine/adapters/outbound/cli_auth/integration_verify.py`:
- Around line 118-152: The GitLab verification path in _verify_gitlab only
checks instance access via verify_instance_access, so it can succeed without the
read_api scope required by later commands. Update _verify_gitlab to also call
verify_read_api_scope (as run_gitlab_pat_auth does) after the /user check, and
return an insufficient-scopes failure when that probe fails. Keep the existing
GitLabAuthErrorKind handling and user/profile formatting intact.

In `@potpie/context-engine/tests/_auth_fakes.py`:
- Around line 228-244: The fake save_gitlab_credentials method currently stores
GitLab credentials without enforcing the same PAT check as the real
implementation. Update _auth_fakes.py’s save_gitlab_credentials to mirror the
production validation by rejecting empty or missing personal_access_token values
and raising the same ProviderCredentialError path that test_cli_gitlab.py
expects, while keeping the rest of the instance/account storage behavior
unchanged.
- Around line 273-282: Align InMemoryCredentialStore.save_gitlab_workspace_prefs
with the GitLab credential structure used by get_gitlab_credentials and
run_gitlab_select_flow. The current implementation writes prefs into
workspace_prefs["gitlab"], but get_gitlab_credentials only reads the GitLab
instance data under self.providers["gitlab"][...]["workspaces"], so the selected
default project is never seen. Update save_gitlab_workspace_prefs to persist the
default project under the GitLab provider/instance entry, or adjust
get_gitlab_credentials to merge in workspace_prefs when building the returned
credentials.

In `@potpie/context-engine/tests/unit/test_cli_gitlab.py`:
- Around line 40-53: The GitLab credentials test is too permissive because it
accepts either instance_host or provider_host, which hides regressions in the
raw credential contract. Update test_save_and_get_gitlab_credentials to assert
the specific instance_host field returned by get_gitlab_credentials, using the
existing cs.save_gitlab_credentials and cs.get_gitlab_credentials symbols to
verify the stored credential shape directly.

---

Outside diff comments:
In `@potpie/context-engine/adapters/inbound/cli/auth/auth_commands.py`:
- Around line 499-507: The provider handling in auth_commands.py has a redundant
gitlab branch in the credential lookup logic. Update the provider selection in
the relevant auth command function so the gitlab case is removed and gitlab
falls through to the existing else path, keeping the behavior identical while
simplifying the branch structure.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3e1af6f9-5359-4a2c-b246-66c73b2f8a69

📥 Commits

Reviewing files that changed from the base of the PR and between a191a5e and efded78.

📒 Files selected for processing (16)
  • potpie/context-engine/adapters/inbound/cli/auth/auth_commands.py
  • potpie/context-engine/adapters/inbound/cli/auth/gitlab_auth.py
  • potpie/context-engine/adapters/inbound/cli/auth/gitlab_commands.py
  • potpie/context-engine/adapters/inbound/cli/auth/gitlab_read.py
  • potpie/context-engine/adapters/outbound/cli_auth/credentials.py
  • potpie/context-engine/adapters/outbound/cli_auth/credentials_store.py
  • potpie/context-engine/adapters/outbound/cli_auth/gitlab_client.py
  • potpie/context-engine/adapters/outbound/cli_auth/gitlab_read_client.py
  • potpie/context-engine/adapters/outbound/cli_auth/integration_profile.py
  • potpie/context-engine/adapters/outbound/cli_auth/integration_verify.py
  • potpie/context-engine/adapters/outbound/cli_auth/provider_config.py
  • potpie/context-engine/domain/ports/cli_auth/credentials.py
  • potpie/context-engine/tests/_auth_fakes.py
  • potpie/context-engine/tests/unit/test_cli_gitlab.py
  • potpie/context-engine/tests/unit/test_cli_gitlab_commands.py
  • potpie/context-engine/tests/unit/test_gitlab_client.py

Comment thread potpie/context-engine/adapters/inbound/cli/auth/auth_commands.py
Comment thread potpie/context-engine/adapters/inbound/cli/auth/gitlab_auth.py Outdated
Comment thread potpie/context-engine/adapters/inbound/cli/auth/gitlab_auth.py
Comment thread potpie/context-engine/adapters/inbound/cli/auth/gitlab_commands.py Outdated
Comment thread potpie/context-engine/adapters/inbound/cli/auth/gitlab_commands.py
Comment thread potpie/context-engine/adapters/outbound/cli_auth/gitlab_read_client.py Outdated
Comment thread potpie/context-engine/tests/_auth_fakes.py
Comment thread potpie/context-engine/tests/_auth_fakes.py Outdated
Comment thread potpie/context-engine/tests/unit/test_cli_gitlab.py Outdated
jdyaberi-pp and others added 3 commits July 6, 2026 21:46
Address CodeRabbit feedback by hardening logout routing, preserving workspace prefs on re-login, and aligning verify/select behavior with login expectations.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
potpie/context-engine/adapters/inbound/cli/auth/gitlab_auth.py (1)

254-266: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

--token is silently dropped when --instance is omitted.

supplied requires both instance and token. If a user runs potpie gitlab login --token glpat-xxx without --instance, execution falls into the else branch, which unconditionally calls _prompt_pat() — discarding the token the user already passed and forcing them to re-enter it (plus needlessly reopening the PAT creation page). This is the same class of bug already fixed for --instance at line 260, but the symmetric case for --token remains.

🐛 Proposed fix
     else:
         git_hint = _detect_gitlab_from_git_remote()
         inst_url = normalize_instance_url(
             _prompt_instance_url(default=instance or git_hint or "")
         ) or GITLAB_DEFAULT_INSTANCE
-        if not as_json:
-            _open_gitlab_pat_page(inst_url)
-        else:
-            webbrowser.open(gitlab_pat_page_url(inst_url), new=1)
-        pat = _prompt_pat()
+        pat = (token or "").strip()
+        if not pat:
+            if not as_json:
+                _open_gitlab_pat_page(inst_url)
+            else:
+                webbrowser.open(gitlab_pat_page_url(inst_url), new=1)
+            pat = _prompt_pat()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@potpie/context-engine/adapters/inbound/cli/auth/gitlab_auth.py` around lines
254 - 266, `--token` is ignored when `--instance` is missing in the GitLab login
flow. Update the branching in `gitlab_auth.py` so a provided token is preserved
even if only one of the two flags is supplied, similar to the existing handling
around `supplied` and `_prompt_instance_url`. In the `else` path, only call
`_prompt_pat()` when `token` was not passed; otherwise reuse the trimmed `token`
value. Keep the PAT page opening behavior tied to actual prompting, and use
`_detect_gitlab_from_git_remote()`/`GITLAB_DEFAULT_INSTANCE` only for the
missing instance case.
potpie/context-engine/adapters/inbound/cli/auth/gitlab_commands.py (1)

81-105: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Scope the logout status to the target instance

get_integration_status("gitlab") only reflects the active GitLab host, not the --instance passed to logout. If a different instance is removed, the command can still print “Logged out successfully.” even when that instance had no stored credentials. Use the instance-specific GitLab record for was_authenticated when instance is set.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@potpie/context-engine/adapters/inbound/cli/auth/gitlab_commands.py` around
lines 81 - 105, The logout flow in gitlab_commands.py currently reads
authentication state only from get_integration_status("gitlab"), which can
report the wrong status when --instance is provided. Update the
was_authenticated logic in the logout command to use the instance-specific
GitLab record when instance is set, and keep the existing fallback for the
default host path. Make sure the later success message and JSON payload in the
logout handler reflect the targeted instance correctly, using the same logout
command flow around clear_gitlab_credentials, emit_error, and print_plain_line.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@potpie/context-engine/adapters/inbound/cli/auth/gitlab_auth.py`:
- Around line 254-266: `--token` is ignored when `--instance` is missing in the
GitLab login flow. Update the branching in `gitlab_auth.py` so a provided token
is preserved even if only one of the two flags is supplied, similar to the
existing handling around `supplied` and `_prompt_instance_url`. In the `else`
path, only call `_prompt_pat()` when `token` was not passed; otherwise reuse the
trimmed `token` value. Keep the PAT page opening behavior tied to actual
prompting, and use `_detect_gitlab_from_git_remote()`/`GITLAB_DEFAULT_INSTANCE`
only for the missing instance case.

In `@potpie/context-engine/adapters/inbound/cli/auth/gitlab_commands.py`:
- Around line 81-105: The logout flow in gitlab_commands.py currently reads
authentication state only from get_integration_status("gitlab"), which can
report the wrong status when --instance is provided. Update the
was_authenticated logic in the logout command to use the instance-specific
GitLab record when instance is set, and keep the existing fallback for the
default host path. Make sure the later success message and JSON payload in the
logout handler reflect the targeted instance correctly, using the same logout
command flow around clear_gitlab_credentials, emit_error, and print_plain_line.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 325804d8-359d-4701-8750-4526bfe13bf3

📥 Commits

Reviewing files that changed from the base of the PR and between efded78 and 77d300a.

📒 Files selected for processing (12)
  • potpie/context-engine/adapters/inbound/cli/auth/auth_commands.py
  • potpie/context-engine/adapters/inbound/cli/auth/gitlab_auth.py
  • potpie/context-engine/adapters/inbound/cli/auth/gitlab_commands.py
  • potpie/context-engine/adapters/inbound/cli/auth/gitlab_read.py
  • potpie/context-engine/adapters/outbound/cli_auth/credentials_store.py
  • potpie/context-engine/adapters/outbound/cli_auth/gitlab_client.py
  • potpie/context-engine/adapters/outbound/cli_auth/gitlab_read_client.py
  • potpie/context-engine/adapters/outbound/cli_auth/integration_verify.py
  • potpie/context-engine/tests/_auth_fakes.py
  • potpie/context-engine/tests/unit/test_cli_gitlab.py
  • potpie/context-engine/tests/unit/test_cli_gitlab_commands.py
  • potpie/context-engine/tests/unit/test_gitlab_client.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
potpie/context-engine/tests/_auth_fakes.py (1)

257-272: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Stale active_instance_host after clearing the active instance.

If instance_host matches the current active host and other instances remain, active_instance_host is left pointing at the removed host instead of being reassigned, unlike production clear_gitlab_credentials in credentials_store.py (which reassigns to a remaining host when the active instance is cleared). Any test relying on this fake to exercise "logout from active instance while another remains" won't reflect real behavior, since a subsequent get_gitlab_credentials() call (no explicit host) would incorrectly resolve to a dead host and appear "not connected" even though another instance is still connected.

🛠️ Proposed fix
     def clear_gitlab_credentials(
         self,
         instance_host: str | None = None,
     ) -> None:
         if instance_host:
             gitlab = dict(self.providers.get("gitlab", {}))
             instances = dict(gitlab.get("instances", {}))
             instances.pop(instance_host, None)
             if instances:
                 gitlab["instances"] = instances
+                if gitlab.get("active_instance_host") == instance_host:
+                    gitlab["active_instance_host"] = next(iter(instances))
                 self.providers["gitlab"] = gitlab
             else:
                 self.providers.pop("gitlab", None)
         else:
             self.providers.pop("gitlab", None)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@potpie/context-engine/tests/_auth_fakes.py` around lines 257 - 272, The fake
clear_gitlab_credentials method leaves active_instance_host stale when removing
the currently active GitLab host and other instances still exist. Update
clear_gitlab_credentials in _auth_fakes.py so that when instance_host matches
active_instance_host and the removed host was active, it reassigns
active_instance_host to one of the remaining instance keys before returning.
Keep the behavior aligned with the production clear_gitlab_credentials logic in
credentials_store.py, and ensure the no-host case still clears both the stored
instances and active host state.
potpie/context-engine/adapters/inbound/cli/auth/gitlab_auth.py (1)

249-264: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Supplied --token (without --instance) is silently discarded.

supplied requires both instance and token. If a user runs potpie gitlab login --token glpat-xxx (no --instance), execution falls into the else branch, which unconditionally calls _prompt_pat() — ignoring the token the user just passed — and also opens the PAT page browser prompt unnecessarily. This mirrors the previously-fixed --instance-dropped bug, but for --token.

🛠️ Proposed fix
     else:
         git_hint = _detect_gitlab_from_git_remote()
         inst_url = (
             normalize_instance_url(
                 _prompt_instance_url(default=instance or git_hint or "")
             )
             or GITLAB_DEFAULT_INSTANCE
         )
-        if not as_json:
-            _open_gitlab_pat_page(inst_url)
-        else:
-            webbrowser.open(gitlab_pat_page_url(inst_url), new=1)
-        pat = _prompt_pat()
+        pat = (token or "").strip()
+        if not pat:
+            if not as_json:
+                _open_gitlab_pat_page(inst_url)
+            else:
+                webbrowser.open(gitlab_pat_page_url(inst_url), new=1)
+            pat = _prompt_pat()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@potpie/context-engine/adapters/inbound/cli/auth/gitlab_auth.py` around lines
249 - 264, The GitLab login flow in gitlab_auth.py is dropping a supplied
--token when --instance is omitted because the current supplied check requires
both values and falls through to the interactive branch. Update the login path
around the supplied/else logic to treat token and instance independently: if a
token is provided, preserve it instead of calling _prompt_pat(), and only open
the PAT page or prompt for values that are still missing. Keep the behavior
consistent in the same auth flow that uses normalize_instance_url,
_open_gitlab_pat_page, and _prompt_pat().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@potpie/context-engine/adapters/inbound/cli/auth/gitlab_auth.py`:
- Around line 249-264: The GitLab login flow in gitlab_auth.py is dropping a
supplied --token when --instance is omitted because the current supplied check
requires both values and falls through to the interactive branch. Update the
login path around the supplied/else logic to treat token and instance
independently: if a token is provided, preserve it instead of calling
_prompt_pat(), and only open the PAT page or prompt for values that are still
missing. Keep the behavior consistent in the same auth flow that uses
normalize_instance_url, _open_gitlab_pat_page, and _prompt_pat().

In `@potpie/context-engine/tests/_auth_fakes.py`:
- Around line 257-272: The fake clear_gitlab_credentials method leaves
active_instance_host stale when removing the currently active GitLab host and
other instances still exist. Update clear_gitlab_credentials in _auth_fakes.py
so that when instance_host matches active_instance_host and the removed host was
active, it reassigns active_instance_host to one of the remaining instance keys
before returning. Keep the behavior aligned with the production
clear_gitlab_credentials logic in credentials_store.py, and ensure the no-host
case still clears both the stored instances and active host state.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4ff23865-5f11-4441-894f-ae1b7b9dc947

📥 Commits

Reviewing files that changed from the base of the PR and between 77d300a and e32169d.

📒 Files selected for processing (14)
  • potpie/context-engine/adapters/inbound/cli/auth/auth_commands.py
  • potpie/context-engine/adapters/inbound/cli/auth/gitlab_auth.py
  • potpie/context-engine/adapters/inbound/cli/auth/gitlab_commands.py
  • potpie/context-engine/adapters/inbound/cli/auth/gitlab_read.py
  • potpie/context-engine/adapters/outbound/cli_auth/credentials.py
  • potpie/context-engine/adapters/outbound/cli_auth/credentials_store.py
  • potpie/context-engine/adapters/outbound/cli_auth/gitlab_client.py
  • potpie/context-engine/adapters/outbound/cli_auth/gitlab_read_client.py
  • potpie/context-engine/adapters/outbound/cli_auth/integration_verify.py
  • potpie/context-engine/domain/ports/cli_auth/credentials.py
  • potpie/context-engine/tests/_auth_fakes.py
  • potpie/context-engine/tests/unit/test_cli_gitlab.py
  • potpie/context-engine/tests/unit/test_cli_gitlab_commands.py
  • potpie/context-engine/tests/unit/test_gitlab_client.py

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Autofix skipped. No unresolved CodeRabbit review comments with fix instructions found.

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.

[Feature]: Add GitLab CLI integration

2 participants