Skip to content

fix(credentials): preserve non-default SSH ports in remote URLs#5945

Open
immanuwell wants to merge 1 commit into
flipt-io:v2from
immanuwell:fix/ssh-remote-nondefault-port
Open

fix(credentials): preserve non-default SSH ports in remote URLs#5945
immanuwell wants to merge 1 commit into
flipt-io:v2from
immanuwell:fix/ssh-remote-nondefault-port

Conversation

@immanuwell
Copy link
Copy Markdown
Contributor

@immanuwell immanuwell commented May 30, 2026

Small follow-up to #5130.

When Flipt normalizes ssh://git@host:2222/group/repo.git, it rewrites it to git@host:2222:group/repo.git.
That changes the meaning of the remote, so Git no longer uses port 2222 and sync can fail

Fix is pretty small:

  • keep SCP style for the default SSH port
  • keep ssh:// form for non-default ports

Repro

  1. Configure a Git environment with SSH creds and remote: ssh://git@gitlab.example.com:2222/group/repo.git
  2. Start Flipt or trigger a remote sync
  3. Before this patch, the remote gets normalized to git@gitlab.example.com:2222:group/repo.git
  4. Git treats that as SCP style, not an SSH URL with port 2222, so the sync goes to the wrong port and blows up

Tests: go test ./...

closes #5946

Signed-off-by: immanuwell <pchpr.00@list.ru>
@immanuwell immanuwell requested a review from a team as a code owner May 30, 2026 09:02
@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label May 30, 2026
@dosubot
Copy link
Copy Markdown

dosubot Bot commented May 30, 2026

Related Knowledge

1 document with suggested updates is ready for review.

flipt

Flipt SCM Providers and Git Integration
View Suggested Changes
@@ -47,7 +47,7 @@
 
 **SSH Remote URL Normalization and Port Handling:**
 
-When using SSH credentials, Flipt automatically normalizes the configured remote URL to the correct SCP-style format (`git@host:path`). Flipt supports SSH URLs with non-standard ports, such as `git@host:2222:owner/repo.git` or `ssh://git@host:2222/owner/repo.git`. The port is preserved in the normalized SCP-style URL for all SSH operations.
+When using SSH credentials, Flipt automatically normalizes the configured remote URL for SSH operations. For the default SSH port (22), Flipt uses SCP-style format (`git@host:path`). For non-default ports, Flipt preserves the `ssh://` protocol URL format (e.g., `ssh://git@host:2222/owner/repo.git`) to maintain correct port semantics. This ensures Git connects to the correct port during sync operations.
 
 You may specify the remote as HTTPS, HTTP, `ssh://`, SCP-style, or host/path format. Flipt will convert it as needed for Git operations. If the SSH user in your credentials differs from the user in the remote URL, Flipt will raise an error to prevent misconfiguration.
 
@@ -217,10 +217,11 @@
 - SSH protocol: `ssh://git@github.com/org/repo.git`
 - SSH protocol with port: `ssh://git@github.com:2222/org/repo.git`
 - SCP-style: `git@github.com:org/repo.git`
-- SCP-style with port: `git@github.com:2222:org/repo.git`
 - Host/path: `github.com/org/repo.git`
 
-Flipt will automatically normalize the URL to the correct SCP-style format required for SSH operations, preserving any non-standard port. The SSH user is taken from your credentials configuration (defaults to `git` if not specified). If the remote URL already contains a user (e.g., `deploy@github.com:org/repo.git`), it must match the user in your credentials, otherwise Flipt will fail to start with an error indicating the conflict.
+Flipt will automatically normalize the URL for SSH operations. For the default SSH port (22), Flipt converts URLs to SCP-style format (`git@host:path`). For non-default ports, Flipt preserves the `ssh://` protocol URL format to maintain correct port semantics and prevent sync failures. This prevents ambiguity with the SCP-style path separator.
+
+The SSH user is taken from your credentials configuration (defaults to `git` if not specified). If the remote URL already contains a user (e.g., `deploy@github.com:org/repo.git`), it must match the user in your credentials, otherwise Flipt will fail to start with an error indicating the conflict.
 
 **Examples:**
 
@@ -228,14 +229,13 @@
 |------------------------------------------------|------------------------|-------------------------------------------|
 | `https://github.com/org/repo.git`              | `git`                  | `git@github.com:org/repo.git`             |
 | `ssh://deploy@gitlab.com/group/repo.git`       | `deploy`               | `deploy@gitlab.com:group/repo.git`        |
-| `ssh://git@localhost:6022/root/demo.git`       | `git`                  | `git@localhost:6022:root/demo.git`        |
+| `ssh://git@localhost:6022/root/demo.git`       | `git`                  | `ssh://git@localhost:6022/root/demo.git`  |
 | `git@github.com:org/repo.git`                  | `git`                  | `git@github.com:org/repo.git`             |
-| `git@localhost:2222:owner/repo.git`            | `git`                  | `git@localhost:2222:owner/repo.git`       |
 | `github.com/org/repo.git`                      | *(empty)*              | `git@github.com:org/repo.git`             |
 
 If you see an error about conflicting SSH users, ensure that the user in your credentials matches the user in the remote URL, or remove the user from the URL and let Flipt insert it automatically.
 
-This normalization is handled automatically by Flipt; you do not need to manually convert URLs for SSH usage. Non-standard ports are preserved in all SSH operations.
+This normalization is handled automatically by Flipt; you do not need to manually convert URLs for SSH usage.
 
 ### 3. Configure Environments
 Reference your storage backend in the environments section and specify a directory for each environment.

[Accept] [Edit] [Decline]

How did I do? Any feedback?  Join Discord

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Verdict: approve

Clean, focused fix for a real bug. The change correctly preserves ssh:// format for non-default SSH ports instead of incorrectly converting them to SCP-style (git@host:port:path), which Git misinterprets. Tests cover both the with-user and without-user cases for non-default ports, and existing port-22 behavior is unchanged.

🤖 Automated review by the Flipt PR review agent.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.28%. Comparing base (e93418b) to head (031034a).

Additional details and impacted files
@@           Coverage Diff           @@
##               v2    #5945   +/-   ##
=======================================
  Coverage   61.28%   61.28%           
=======================================
  Files         141      141           
  Lines       14208    14208           
=======================================
  Hits         8707     8707           
  Misses       4772     4772           
  Partials      729      729           
Flag Coverage Δ
integrationtests 34.50% <0.00%> (ø)
unittests 52.37% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@erka
Copy link
Copy Markdown
Contributor

erka commented May 30, 2026

related to #5298.

@erka
Copy link
Copy Markdown
Contributor

erka commented May 30, 2026

I've tried to investigate your issue with my setup, but I couldn't replicate it using Flipt v2.9.0 and GitLab 19.0. This is the log entries I captured:

DEBUG	pushing to remote	{"server": "grpc", "git_storage_type": "memory", "remoteName": "origin", "remoteURLs": ["git@git.lan:6022:root/flipt-features.git"], "refSpec": "refs/heads/main:refs/heads/main"}
DEBUG	setting remote tracking reference	{"server": "grpc", "git_storage_type": "memory", "reference": "refs/remotes/origin/main", "hash": "5675e05a47d3ea629940b83af263ff48f326cf98"}
DEBUG	update and push completed successfully	{"server": "grpc", "git_storage_type": "memory", "branch": "main", "hash": "5675e05a47d3ea629940b83af263ff48f326cf98"}

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

Labels

size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Trouble connecting to Gitlab instance

2 participants