Skip to content

fix(clients): default GitLab clones to HTTPS - #24612

Open
juliusmarminge wants to merge 6 commits into
mainfrom
takeover/pr-13351
Open

juliusmarminge wants to merge 6 commits into
mainfrom
takeover/pr-13351

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

GitLab repositories selected through Add Project → Clone now start with the host’s HTTPS/web URL. Explicit SSH URLs remain available through Git URL; other forge defaults are unchanged. Updated servers already recover some SSH failures through HTTPS fallback; this skips that first SSH attempt and supports older servers without the fallback. SSH-only private repositories require the explicit SSH path. Self-hosted HTTP URLs remain HTTP.

Fixes #13350.

Original description by @Mnigos

Fixes #13350.

Choosing a GitLab repository through Add Project → Clone used SSH even after signing in with glab over HTTPS. Without a registered SSH key, lookup succeeded but cloning failed.

GitLab's host definition now defaults to HTTPS, using the same shared clone-selection path as other HTTPS hosts. Web, desktop, and mobile inherit that choice; pasted URLs and other providers keep their existing behavior. Self-hosted GitLab still needs credentials configured for its host.

The existing shared regression test uses GitLab's actual web-URL shape. It fails with the SSH default and passes with the fix; all 18 project-operation tests pass. Client-runtime and GitLab package typechecks and targeted lint also pass. Private-repository credential-helper authentication was not exercised; this change only selects the clone URL.

Original fix and reproduction by @Mnigos in #13351. Maintainer takeover by Claude Opus 5.5 and Claude Fable 5.1 through T3 Code, independently reviewed by Claude Opus 5.5 and GPT-6.1-Sol through the Codex harness.

Takeover

Original fix and reproduction by @Mnigos in #13351. Rebuilt on current main because the forge definition moved to shared/; the one-field implementation is retained, and the tests use current shared clone selection.
No GitLab special cases were added outside the forge package. No scratch scripts or captures are committed. Pixel-diff amplification driver is uploaded separately.

Evidence

Full fixture matrix · capture index, traces and all drivers · reproduction recipe · proof audit

Matrix rows Verification
G1/G2 Real GitLab picker: before SSH rejection → HTTPS fallback success; after direct HTTPS success
C1 Real GitHub picker: HTTPS success on both
C2 Explicit GitLab SSH submitted unchanged on both; real SSH rejection/fallback, after DNS failure and recorded Retry success
P1 Tracked clone exercised, including Retry
G3/G4/C3/C4/S2 Helper fixtures, focused tests and source; nested/custom-host URLs and exact HTTP scheme disclosed
P2/E1/S1 Older-server path, additional entry/gate paths and direct-service protocols source-only
M1/M2 Native iOS and Android unverified

Recordings: enter repository → lookup → choose destination → clone → terminal outcome. Timestamped steps and actual submitted URLs are narrated in the linked clips; complete timeline. GitLab’s official SSH endpoint on port 443 was used because port 22 hangs on this VM.

Flow Before After Settled / recovery
G1-G2 Before After Before settled / After settled
C1 Before After —
C2 Before After Real Retry

Environment: real web app, Chromium 148 / Playwright 1.60, Xvfb, 1280×900, DPR 1, dark, reduced motion, fixed relative-time clock, DejaVu Sans fallback. Fresh sandbox home, seeding disabled; live userdata untouched.

What else changed in the captures: original GitLab interaction clips ended with stale Git metadata; the separate settled clips and primary images supersede those endpoints. Corrected GitLab and GitHub frames are pixel-identical. C2 input has a faint blurred background label difference (1,427 pixels, max channel delta 9/255); its after outcome shows a real DNS failure, retained with separate successful Retry. No private-authentication or successful SSH-authentication claim is made.

Fixture, 1280×900 dark Before: 3cc31ed27c After: 589c61891b Diff 0, 32× Diff 16/255
G1-G2 input before-G1-G2-input.png after-G1-G2-input.png diff-G1-G2-input-t0-amplified32.png diff-G1-G2-input-t16.png
G1-G2 confirm before-G1-G2-confirm.png after-G1-G2-confirm.png diff-G1-G2-confirm-t0-amplified32.png diff-G1-G2-confirm-t16.png
G1-G2 outcome before-G1-G2-outcome.png after-G1-G2-outcome.png diff-G1-G2-outcome-t0-amplified32.png diff-G1-G2-outcome-t16.png
C1 input before-C1-input.png after-C1-input.png diff-C1-input-t0-amplified32.png diff-C1-input-t16.png
C1 confirm before-C1-confirm.png after-C1-confirm.png diff-C1-confirm-t0-amplified32.png diff-C1-confirm-t16.png
C1 outcome before-C1-outcome.png after-C1-outcome.png diff-C1-outcome-t0-amplified32.png diff-C1-outcome-t16.png
C2 input before-C2-input.png after-C2-input.png diff-C2-input-t0-amplified32.png diff-C2-input-t16.png
C2 confirm before-C2-confirm.png after-C2-confirm.png diff-C2-confirm-t0-amplified32.png diff-C2-confirm-t16.png
C2 outcome before-C2-outcome.png after-C2-outcome.png diff-C2-outcome-t0-amplified32.png diff-C2-outcome-t16.png
Verification log
  • Tests: project-operation file 6 → 7; GitLab regression fails with SSH and passes with HTTPS. 48 focused tests across projects, forge definition and registry passed. Targeted lint/format, GitLab and client-runtime typechecks passed.
  • Reviews: round 1 MERGE / FIX_FIRST; SSH-only picker objection resolved against the authorized HTTPS default and explicit SSH path. Round 2 MERGE / MERGE. No added regex/parser or dependencies.
  • Proof audit: SUFFICIENT; inspected all primary images, 27 diffs and 15 recordings. Independent real HTTPS clone succeeded; reproduced input delta 681 pixels, max 2/255, none above 16.
  • Final head / main integration: e8f29cc13c merges 843f4e3529 without rebasing. All 48 scoped tests pass on this head. The captured web, shared clone runtime, GitLab package and mobile project-flow blobs are unchanged from captured after revision; main additions are outside those paths.
  • CI: At handoff, 8 checks successful, 19 pending, 0 failing on final head; no bot comments yet. CI/review monitoring returns to the dispatcher because this is a delegated child task. Original-fork checks are not claimed for this replacement.
  • Unverified: native iOS/Android, separate Electron shell, light/narrow viewports, private-repository authentication, authenticated SSH, older-server blocking clone, direct service/MCP protocols, relay/tunnel and multiple environments. Only the web capture and source/shared tests are claimed.
  • All owned capture/audit processes stopped; temporary worktree and scratch removed before handoff.
  • Implementation/tests: Claude Opus 5.5 through T3 Code; independent review: GPT-6.1-Sol (Codex) and Claude Opus 5.5; capture/proof audit: GPT-6.1-Sol through Codex.

Fixes #13350

@github-actions github-actions Bot added the vouch:trusted Author is trusted by repo permissions or the VOUCHED list. label Oct 24, 2026
@github-actions github-actions Bot added the size:XS 0-9 changed lines (additions + deletions). label Oct 24, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 19d07ef

Macroscope's review found this PR approvable — The specified revisions have no net changes. GitLab cloning still defaults to SSH, so this comparison introduces no product-default change or additional risk.

Notes:

  • No code objects were reviewed. Approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 5.0 KiB 5.0 KiB 0 B (0.0%) 6.8 KiB ✅
Codex Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.2 KiB 1.2 KiB 0 B (0.0%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 21.5 KiB 21.5 KiB 0 B (0.0%) 24.4 KiB ✅
Codex Live turn messages 1 1 0 (0.0%) 8 ✅
Claude Total thread wire 5.0 KiB 5.0 KiB 0 B (0.0%) 6.8 KiB ✅
Claude Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.2 KiB 1.2 KiB 0 B (0.0%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 21.9 KiB 21.9 KiB 0 B (0.0%) 24.4 KiB ✅
Claude Live turn messages 1 1 0 (0.0%) 8 ✅

Other scenarios

All 64 scenario measurements match main.

All 64 scenario measurements
Provider Scenario Metric Main baseline This PR Impact PR ceiling
Codex short turn resume WebSocket decoded 10.5 KiB 10.5 KiB 0 B (0.0%) 12.7 KiB ✅
Codex short turn resume WebSocket messages 2 2 0 (0.0%) 2 ✅
Codex long turn running, cold open HTTP decoded 281.7 KiB 281.7 KiB 0 B (0.0%) 302.7 KiB ✅
Codex long turn running, cold open rows 75 75 0 (0.0%) 75 ✅
Codex long turn running, history page HTTP decoded 92.4 KiB 92.4 KiB 0 B (0.0%) 107.4 KiB ✅
Codex long turn running, history page rows 75 75 0 (0.0%) 75 ✅
Codex long turn finished, cold open HTTP decoded 381.5 KiB 381.5 KiB 0 B (0.0%) 410.2 KiB ✅
Codex long turn finished, cold open rows 151 151 0 (0.0%) 151 ✅
Codex long turn finished, socket cold open WebSocket decoded 381.6 KiB 381.6 KiB 0 B (0.0%) 410.2 KiB ✅
Codex long turn finished, socket cold open WebSocket messages 2 2 0 (0.0%) 2 ✅
Codex long turn finished, socket cold open rows 151 151 0 (0.0%) 151 ✅
Codex long turn finished, work page HTTP decoded 186.2 KiB 186.2 KiB 0 B (0.0%) 200.2 KiB ✅
Codex long turn finished, work page rows 150 150 0 (0.0%) 150 ✅
Codex idle thread resume WebSocket decoded 65 B 65 B 0 B (0.0%) 200 B ✅
Codex idle thread resume WebSocket messages 1 1 0 (0.0%) 1 ✅
Codex fleet shell snapshot HTTP decoded 42.4 KiB 42.4 KiB 0 B (0.0%) 53.7 KiB ✅
Codex fleet shell snapshot rows 27 27 0 (0.0%) 27 ✅
Codex fleet shell subscribe WebSocket decoded 65 B 65 B 0 B (0.0%) 200 B ✅
Codex fleet shell subscribe WebSocket messages 1 1 0 (0.0%) 1 ✅
Codex fleet shell resume check HTTP decoded 18 B 18 B 0 B (0.0%) 100 B ✅
Codex fleet shell resume check rows 0 0 0 0 ✅
Codex stale shell reload HTTP decoded 42.4 KiB 42.4 KiB 0 B (0.0%) 53.7 KiB ✅
Codex stale shell reload rows 27 27 0 (0.0%) 27 ✅
Codex stale shell resume WebSocket decoded 140 B 140 B 0 B (0.0%) 400 B ✅
Codex stale shell resume WebSocket messages 2 2 0 (0.0%) 2 ✅
Codex stale todo list cold open HTTP decoded 72.4 KiB 72.4 KiB 0 B (0.0%) 83.0 KiB ✅
Codex stale todo list cold open rows 75 75 0 (0.0%) 75 ✅
Codex stale todo list cold open nodes 2 2 0 (0.0%) 4 ✅
Codex stale todo list cold open subagents 2 2 0 (0.0%) 4 ✅
Codex stale todo list cold open plans 1 1 0 (0.0%) 2 ✅
Codex stale todo list cold open providerTurns 1 1 0 (0.0%) 2 ✅
Codex stale todo list cold open checkpoints 1 1 0 (0.0%) 2 ✅
Claude short turn resume WebSocket decoded 10.6 KiB 10.6 KiB 0 B (0.0%) 12.7 KiB ✅
Claude short turn resume WebSocket messages 2 2 0 (0.0%) 2 ✅
Claude long turn running, cold open HTTP decoded 283.3 KiB 283.3 KiB 0 B (0.0%) 302.7 KiB ✅
Claude long turn running, cold open rows 75 75 0 (0.0%) 75 ✅
Claude long turn running, history page HTTP decoded 93.4 KiB 93.4 KiB 0 B (0.0%) 107.4 KiB ✅
Claude long turn running, history page rows 75 75 0 (0.0%) 75 ✅
Claude long turn finished, cold open HTTP decoded 384.2 KiB 384.2 KiB 0 B (0.0%) 410.2 KiB ✅
Claude long turn finished, cold open rows 151 151 0 (0.0%) 151 ✅
Claude long turn finished, socket cold open WebSocket decoded 384.3 KiB 384.3 KiB 0 B (0.0%) 410.2 KiB ✅
Claude long turn finished, socket cold open WebSocket messages 2 2 0 (0.0%) 2 ✅
Claude long turn finished, socket cold open rows 151 151 0 (0.0%) 151 ✅
Claude long turn finished, work page HTTP decoded 188.1 KiB 188.1 KiB 0 B (0.0%) 200.2 KiB ✅
Claude long turn finished, work page rows 150 150 0 (0.0%) 150 ✅
Claude idle thread resume WebSocket decoded 66 B 66 B 0 B (0.0%) 200 B ✅
Claude idle thread resume WebSocket messages 1 1 0 (0.0%) 1 ✅
Claude fleet shell snapshot HTTP decoded 42.9 KiB 42.9 KiB 0 B (0.0%) 53.7 KiB ✅
Claude fleet shell snapshot rows 27 27 0 (0.0%) 27 ✅
Claude fleet shell subscribe WebSocket decoded 66 B 66 B 0 B (0.0%) 200 B ✅
Claude fleet shell subscribe WebSocket messages 1 1 0 (0.0%) 1 ✅
Claude fleet shell resume check HTTP decoded 18 B 18 B 0 B (0.0%) 100 B ✅
Claude fleet shell resume check rows 0 0 0 0 ✅
Claude stale shell reload HTTP decoded 42.9 KiB 42.9 KiB 0 B (0.0%) 53.7 KiB ✅
Claude stale shell reload rows 27 27 0 (0.0%) 27 ✅
Claude stale shell resume WebSocket decoded 140 B 140 B 0 B (0.0%) 400 B ✅
Claude stale shell resume WebSocket messages 2 2 0 (0.0%) 2 ✅
Claude stale todo list cold open HTTP decoded 73.4 KiB 73.4 KiB 0 B (0.0%) 83.0 KiB ✅
Claude stale todo list cold open rows 75 75 0 (0.0%) 75 ✅
Claude stale todo list cold open nodes 2 2 0 (0.0%) 4 ✅
Claude stale todo list cold open subagents 2 2 0 (0.0%) 4 ✅
Claude stale todo list cold open plans 1 1 0 (0.0%) 2 ✅
Claude stale todo list cold open providerTurns 1 1 0 (0.0%) 2 ✅
Claude stale todo list cold open checkpoints 1 1 0 (0.0%) 2 ✅

Baseline: 0bc993a · PR result: c6f8a19 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@juliusmarminge juliusmarminge added bugfix Fix PR opened by an issue lead; enters the PR loop pr:gate-failed A land gate failed pr:in-progress A lead is working on this PR labels Oct 24, 2026
@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

Walkthrough

GitLab’s default clone transport changes from SSH to HTTPS. A test checks that getDefaultCloneUrl returns the GitLab HTTPS URL when an SSH URL is also supplied.

Changes: Clone transport selection

Layer / File(s) Summary
GitLab default and URL selection tests
packages/source-control-gitlab/src/shared/definition.ts, packages/client-runtime/src/operations/projects.test.ts
GitLab’s default clone transport changes to HTTPS. A test checks that GitLab URL selection returns HTTPS when an SSH URL is also supplied.

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: macroscopeapp

Merge Risk: Low · previous review c6f8a

GitLab clones through Add Project → Clone now default to the project's web URL over HTTPS. This is the intended behavior and should work on standard GitLab hosts. There is a small residual risk on instances that expose a separate HTTP clone endpoint, so the author should confirm the behavior on one such instance.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title names the main change: GitLab clones made through Add Project → Clone now default to HTTPS. It uses a conventional commit prefix and is specific to the changeset. The title is short, single-…
Description check Passed The description follows the repository template. It has a clear problem statement, a change explanation, a scope section that links issue #13350 and states the bug, and a verification section with tes…
Linked Issues check Passed The only direct linked issue is #13350. Its coding requirement is that GitLab clones selected through Add Project → Clone use HTTPS, so the glab credential helper can authenticate without an SSH key. …
Out of Scope Changes check Passed The whole-PR diff touches two files. definition.ts changes one GitLab field and adds a comment explaining the HTTPS credential-helper rationale. projects.test.ts adds one GitLab regression asserti…
Full details: Title check

Explanation

The title names the main change: GitLab clones made through Add Project → Clone now default to HTTPS. It uses a conventional commit prefix and is specific to the changeset. The title is short, single-sentence, and not vague.

Full details: Description check

Explanation

The description follows the repository template. It has a clear problem statement, a change explanation, a scope section that links issue #13350 and states the bug, and a verification section with tests, typechecks, lint, and recordings. The template's Problem section is only implied by the opening paragraph and the original description, and the Scope section does not explicitly justify the absence of an issue, but the issue is linked. The description is mostly complete and is lengthy, with heavy media content and an unusually large evidence section. The template asks for concise verification and the description spends most of its length on evidence links and image tables, but the required information is present.

Full details: Linked Issues check

Explanation

The only direct linked issue is #13350. Its coding requirement is that GitLab clones selected through Add Project → Clone use HTTPS, so the glab credential helper can authenticate without an SSH key. The whole-PR diff (base to head) changes defaultCloneTransport in packages/source-control-gitlab/src/shared/definition.ts from "ssh" to "https". The shared getDefaultCloneUrl in packages/client-runtime/src/operations/projects.ts then selects repository.url for GitLab. The added assertion in projects.test.ts checks that a GitLab provider with url: "https://gitlab.com/group/subgroup/project" and an SSH URL returns the HTTPS URL. This covers the issue's suggested minimum fix (include GitLab in the HTTPS default). The issue's optional git_protocol discovery is not implemented, and the issue does not require it as a minimum. Private-repository authentication is not tested, which the issue does not require as a coding test. The apps/mobile impact is covered by the shared clone-selection path, which the PR does not modify separately.

Full details: Out of Scope Changes check

Explanation

The whole-PR diff touches two files. definition.ts changes one GitLab field and adds a comment explaining the HTTPS credential-helper rationale. projects.test.ts adds one GitLab regression assertion to the existing shared clone-selection test. Both changes implement #13350. No unrelated source, configuration, or dependency changes appear in the diff. The PR description's claims about self-hosted HTTP URLs and explicit SSH entry through Git URL concern existing behavior that the diff does not alter.

Finishing Touches

Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

@juliusmarminge juliusmarminge added pr:needs-julius Needs Julius: route gate, unverifiable surface, or blocked pr:in-progress A lead is working on this PR pr:gate-failed A land gate failed and removed pr:in-progress A lead is working on this PR pr:needs-julius Needs Julius: route gate, unverifiable surface, or blocked pr:gate-failed A land gate failed labels Oct 24, 2026
# Conflicts:
#	packages/source-control-gitlab/src/shared/definition.ts
…nfig

AI-assisted; verified with the tests and tools listed above.
Clients send GitLab's SSH URL without a protocol, so a refused key or an
unverified host key is already retried over HTTPS with the glab credential
helper. Defaulting to HTTPS gives no SSH retry, so it breaks GitLab users who
only have SSH access.

AI-assisted; verified with the tests and tools listed above.

@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.

Additional comments: 1

packages/source-control-gitlab/src/shared/definition.ts-46-46: 1

46-46: Major · Data Integrity & Integration · Heavy lift

Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

Use GitLab’s HTTP clone URL

This change selects repository.url, but GitLabCli.ts maps that field from web_url and discards http_url_to_repo. GitLab supports a separate HTTP(S) clone endpoint. If only that endpoint accepts Git traffic, provider-selected clones now fail. Preserve the clone URL through the repository contract and select it here. (raw.githubusercontent.com)

Review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between e8f29cc and c6f8a19.

Files selected for processing: 2

  • packages/client-runtime/src/operations/projects.test.ts
  • packages/source-control-gitlab/src/shared/definition.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 4 remain after this review.

@juliusmarminge

Copy link
Copy Markdown
Member Author

The automated pipeline stopped on this pull request and will not merge it:

in the real app the problem is still there, and the rework changed nothing:

No code change: the proof result shows the reported bug is already fixed. On both commits, with glab set up for HTTPS and no SSH key (the setup in issue #13350), the GitLab picker sent the SSH URL and the clone finished with an HTTPS origin. The issue was that the clone failed; it now succeeds because main's clone fallback (#30142) retries a refused SSH key or untrusted host key over HTTPS with the glab credential helper. The proof treats the SSH-first request as the problem, but HTTPS-first is exactly what the previous review rejected as worse than main: clones run with terminal prompts off and nothing retries HTTPS as SSH, so users with only SSH access would break. Keeping SSH first is deliberate. The pasted git@ URL staying unchanged is the intended behavior on both commits and was never in scope. The branch has no net diff against main and should be closed as superseded, with #13350 marked fixed by #30142. Making GitLab HTTPS-first anyway would need an HTTPS-to-SSH retry in the same change, and that is a maintainer decision.

It stays open for a person to finish or close.

This branch has not been deployed

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

Labels

bugfix Fix PR opened by an issue lead; enters the PR loop pr:needs-julius Needs Julius: route gate, unverifiable surface, or blocked size:XS 0-9 changed lines (additions + deletions). vouch:trusted Author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: GitLab clones default to SSH even when glab is configured for HTTPS

1 participant