Skip to content

Commit f2ddc40

Browse files
jketemaCopilot
andcommitted
Go: Pass proxy certificate to git via GIT_SSL_CAINFO
The extractor ran `git config --global http.sslCAInfo <temp cert>` when private `git_source` registries were configured. That permanently modified the user's global git configuration, and on non-ephemeral (e.g. self-hosted) runners it kept pointing at a temporary certificate file after the job finished, breaking later git HTTPS operations. Instead, set `GIT_SSL_CAINFO` alongside `SSL_CERT_FILE` in the environment that `ApplyProxyEnvVars` applies to `go` commands. This is picked up by the `git` processes `go` spawns, and is scoped to those subprocesses. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 1bc4e40 commit f2ddc40

2 files changed

Lines changed: 30 additions & 13 deletions

File tree

‎go/extractor/registries/registryproxy.go‎

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,14 @@ func getEnvVars() []string {
103103
slog.Error("Failed to close the temporary certificate file", slog.String("error", err.Error()))
104104
} else {
105105
proxy_cert_file = f.Name()
106-
result = append(result, fmt.Sprintf("SSL_CERT_FILE=%s", proxy_cert_file))
106+
// `SSL_CERT_FILE` is used by Go itself; `GIT_SSL_CAINFO` is used by the `git`
107+
// processes that `go` spawns to fetch `git_source` modules. Setting it here scopes
108+
// the certificate to our subprocesses instead of modifying the global git configuration.
109+
result = append(
110+
result,
111+
fmt.Sprintf("SSL_CERT_FILE=%s", proxy_cert_file),
112+
fmt.Sprintf("GIT_SSL_CAINFO=%s", proxy_cert_file),
113+
)
107114
}
108115
}
109116

@@ -160,18 +167,6 @@ func getEnvVars() []string {
160167

161168
if len(git_sources) > 0 {
162169
goprivate = append(goprivate, git_sources...)
163-
164-
if proxy_cert_file != "" {
165-
slog.Info("Configuring `git` to use proxy certificate", slog.String("path", proxy_cert_file))
166-
cmd := exec.Command("git", "config", "--global", "http.sslCAInfo", proxy_cert_file)
167-
168-
out, cmdErr := cmd.CombinedOutput()
169-
slog.Info(string(out))
170-
171-
if cmdErr != nil {
172-
slog.Error("Failed to configure `git` to accept the certificate file", slog.String("error", cmdErr.Error()))
173-
}
174-
}
175170
}
176171

177172
result = append(result, fmt.Sprintf("GOPRIVATE=%s", strings.Join(goprivate, ",")))

‎go/extractor/registries/registryproxy_test.go‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package registries
22

33
import (
4+
"os"
5+
"slices"
46
"testing"
57
)
68

@@ -131,3 +133,23 @@ func TestParseRegistryConfigsMultipleGoProxyServers(t *testing.T) {
131133
t.Fatalf("Expected `URL` to be `https://goproxy.io`, but got `%s`", second.URL)
132134
}
133135
}
136+
137+
func TestGetEnvVarsScopesCertificateToSubprocesses(t *testing.T) {
138+
t.Setenv(PROXY_HOST, "")
139+
t.Setenv(PROXY_PORT, "")
140+
t.Setenv(PROXY_URLS, "")
141+
t.Setenv(PROXY_CA_CERTIFICATE, "dummy certificate")
142+
143+
vars := getEnvVars()
144+
defer os.Remove(proxy_cert_file)
145+
146+
if proxy_cert_file == "" {
147+
t.Fatal("Expected a temporary certificate file to be created.")
148+
}
149+
150+
for _, expected := range []string{"SSL_CERT_FILE=" + proxy_cert_file, "GIT_SSL_CAINFO=" + proxy_cert_file} {
151+
if !slices.Contains(vars, expected) {
152+
t.Errorf("Expected `getEnvVars` to return %q, but got %v.", expected, vars)
153+
}
154+
}
155+
}

0 commit comments

Comments
 (0)