Skip to content

fix: handle IPv6 host URLs in parseGitLabHostURL#6

Merged
l-qing merged 1 commit into
mainfrom
fix/parse-gitlab-host-url-ipv6
Jun 13, 2026
Merged

fix: handle IPv6 host URLs in parseGitLabHostURL#6
l-qing merged 1 commit into
mainfrom
fix/parse-gitlab-host-url-ipv6

Conversation

@l-qing

@l-qing l-qing commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Problem

On IPv6 GitLab environments, make prepare-gitlab-data fails deterministically and the whole e2e suite space-runs (zero tests, empty Allure report). The failure surfaces in the downstream YAML merge:

Merging gitlab config into .../config.yaml...
Error: Failed to load ./config/users-generated.yaml: yaml: line 3: did not find expected key
make: *** [base.mk: prepare-gitlab-data] Error 1

Root cause

parseGitLabHostURL parsed host:port with a naive split:

host = strings.TrimPrefix(endpoint, "http://")     // "[2335::aa1:1415]:32336"
if strings.Contains(host, ":") {
    parts := strings.Split(host, ":")
    if len(parts) == 2 { host = parts[0]; port = parts[1] }   // only the "exactly one colon" case
}

An IPv6 host has many colons, so len(parts) != 2, the port split is skipped, and host keeps its brackets and port: [2335::aa1:1415]:32336. That value is rendered into users-generated.yaml as:

toolchains:
  gitlab:
    endpoint: http://[2335::aa1:1415]:32336
    host: [2335::aa1:1415]:32336     # value starts with '[' -> YAML flow sequence -> parse error

Because the host: value starts with [, YAML treats it as a flow sequence and the load fails with did not find expected key. IPv4 (10.161.11.29:32739) splits into exactly two parts, so it works — the bug is IPv6-only. The sibling parseGitLabSSHEndpoint in the same file already parses correctly via net/url; this function simply never got the same treatment.

Fix

Rewrite parseGitLabHostURL to parse with net/url:

  • url.Hostname() returns the bare host (IPv6 brackets stripped), so the rendered host: scalar is valid YAML (2335::aa1:1415).
  • net.JoinHostPort / explicit bracketing re-adds brackets when rebuilding the endpoint, so it stays a valid URL (http://[2335::aa1:1415]:32336).
  • Default-port-omitted endpoint behavior is preserved (80/http, 443/https omitted; non-default included).
  • Subpath GitLab (https://gitlab.example.com/gitlab) keeps its path.
  • No-scheme input (including bare IPv6, with or without a subpath) and malformed URLs fall back without corrupting the endpoint.

Tests

New internal/cli/cmd_test.go:

  • TestParseGitLabHostURL — table-driven, 15 cases: IPv6 with/without port (http+https), IPv4 with/without port, hostname, subpath (hostname and IPv6), no-scheme bare IPv6 (with and without subpath), trailing slash, malformed-URL fallback, whitespace trimming.
  • TestGeneratedHostValueIsValidYAML — regression guard tying the fix to the original failure: renders the toolchains/gitlab/{endpoint,host} snippet for the IPv6 case and asserts it round-trips through YAML.

go build ./..., go test ./..., and gofmt -l all clean.

parseGitLabHostURL split host:port with strings.Split + a len==2 check,
so an IPv6 host (many colons) skipped the port split and kept its brackets
and port, e.g. host = "[2335::aa1:1415]:32336". Rendered into the GitLab
test-data template this produced `host: [2335::aa1:1415]:32336`, whose
leading "[" makes YAML parse it as a flow sequence, failing the e2e
prepare-gitlab-data step on IPv6 environments with
"yaml: line 3: did not find expected key". IPv4 splits into two parts so
it worked; the bug was IPv6-only.

Parse with net/url instead (matching the sibling parseGitLabSSHEndpoint):
url.Hostname() returns the bare host so the rendered host: scalar is valid
YAML, and the endpoint is rebuilt with net.JoinHostPort so IPv6 stays
bracketed. Preserves the default-port-omitted endpoint contract, subpath
GitLab installs, and non-corrupting fallback for no-scheme/malformed input.

Add internal/cli/cmd_test.go: table-driven TestParseGitLabHostURL (IPv6/
IPv4/hostname, ports, subpaths, no-scheme bare IPv6, malformed fallback)
and TestGeneratedHostValueIsValidYAML as a regression guard for the
original YAML failure.
@l-qing l-qing merged commit c200bde into main Jun 13, 2026
6 checks passed
@l-qing l-qing deleted the fix/parse-gitlab-host-url-ipv6 branch June 13, 2026 05:24
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.

1 participant