Custom url breaks submodule authentication with insteadOf rules
## Problem When a custom `url` or `clone_url` is configured in the runner, submodule cloning fails with authentication errors even though the main repository clones successfully. The issue occurs because the git `insteadOf` rules generated for credential injection only apply to the exact main repository URL, not to submodule URLs from the same domain. ### Error Example ``` fatal: could not read Username for 'https://git.mydomain.com': terminal prompts disabled fatal: clone of 'https://git.mydomain.com/marcolz/test-module' into submodule path '/builds/marcolz/test-main/submodules/test-module' failed ``` ### Root Cause The `setupExternalGitConfig()` method in `shells/abstract.go` creates `insteadOf` rules that map the full repository URL with credentials to the canonical URL: ``` url.https://gitlab-ci-token:[MASKED]@git.mydomain.com/marcolz/test-main.git.insteadOf = https://git.mydomain.com/marcolz/test-main.git ``` However, submodules reference different repository paths (e.g., `https://git.mydomain.com/marcolz/test-module`), which don't match this rule. Git then attempts to clone without credentials, resulting in authentication failures. ## Proposed Solution Add an additional base domain `insteadOf` rule that applies to all URLs under the same domain. This catch-all rule would enable credential injection for any submodule URL from the same domain: ``` url.https://gitlab-ci-token:[MASKED]@git.mydomain.com.insteadOf = https://git.mydomain.com ``` ### Implementation Details The fix mirrors the logic already present in `build_url_helper.go`'s `GetInsteadOfs()` method (see MR !5912), which handles SSH/Git protocol URL rewrites for submodules when `GitSubmoduleForceHTTPS` is enabled. In `shells/abstract.go`, the `setupExternalGitConfig()` method should be updated to: 1. Extract the base URL (scheme + host) from the full repository URL 2. Generate an additional `insteadOf` rule mapping the base URL with credentials to the base URL without credentials 3. This ensures both the main repo and all submodules from the same domain can authenticate ### Proposed Diff ```go // In setupExternalGitConfig(), after processing the full-path insteadOf rules: // Add base domain insteadOf rule for submodules baseURLWithCreds, err := url.Parse(withCreds) if err == nil && baseURLWithCreds.Host != "" { // Extract base URL (scheme + host only) baseWithCreds := fmt.Sprintf("%s://%s", baseURLWithCreds.Scheme, baseURLWithCreds.Host) baseWithoutCreds := fmt.Sprintf("%s://%s", baseURLWithCreds.Scheme, baseURLWithCreds.Host) // Replace host with auth-injected version if baseURLWithCreds.User != nil { baseWithCreds = fmt.Sprintf("%s://%s@%s", baseURLWithCreds.Scheme, baseURLWithCreds.User.String(), baseURLWithCreds.Host) } insteadOfs = append(insteadOfs, [2]string{baseWithCreds, baseWithoutCreds}) } ``` ## Related Files - `shells/abstract.go` - `setupExternalGitConfig()` method - `common/build_url_helper.go` - `GetInsteadOfs()` method (reference implementation from MR !5912) - MR !5912 - "Externalize git configuration" (merged, contains similar logic) ## Testing Test with: - A private repository with custom `clone_url` configured - Submodules from the same domain (both private and public) - Both `FF_GIT_URLS_WITHOUT_TOKENS` disabled and enabled - Verify submodule cloning succeeds with proper authentication
issue