From a57c6cde309d8d6d908ae1fc4e36087b5081f215 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 2 Feb 2026 14:39:27 +0000 Subject: [PATCH 1/7] Add `EmitPrivateRegistryUsed` --- go/extractor/diagnostics/diagnostics.go | 21 ++++++++++++++++++++ go/extractor/diagnostics/diagnostics_test.go | 21 ++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/go/extractor/diagnostics/diagnostics.go b/go/extractor/diagnostics/diagnostics.go index a91a9efac0d1..b40b31c15f3e 100644 --- a/go/extractor/diagnostics/diagnostics.go +++ b/go/extractor/diagnostics/diagnostics.go @@ -568,3 +568,24 @@ func EmitExtractionFailedForProjects(path []string) { noLocation, ) } + +func EmitPrivateRegistryUsed(writer DiagnosticsWriter, configs []string) { + lines := []string{} + + for i := range configs { + lines = append(lines, fmt.Sprintf("* %s", configs[i])) + } + + emitDiagnosticTo( + writer, + "go/autobuilder/analysis-using-private-registries", + "Go extraction used private package registries", + fmt.Sprintf( + "Go was extracted using the following private package registrie%s:\n\n%s\n", + plural(len(lines), "", "s"), + strings.Join(lines, "\n")), + severityNote, + fullVisibility, + noLocation, + ) +} diff --git a/go/extractor/diagnostics/diagnostics_test.go b/go/extractor/diagnostics/diagnostics_test.go index f2b560004bae..1582923fb559 100644 --- a/go/extractor/diagnostics/diagnostics_test.go +++ b/go/extractor/diagnostics/diagnostics_test.go @@ -83,3 +83,24 @@ func Test_EmitCannotFindPackages_Actions(t *testing.T) { // Custom build command suggestion assert.Contains(t, d.MarkdownMessage, "If any of the packages are already present in the repository") } + +func Test_EmitPrivateRegistryUsed(t *testing.T) { + writer := newMemoryDiagnosticsWriter() + + testItems := []string{ + "* https://github.com/github/example (Git Source)", + "* https://example.com/goproxy (GOPROXY Server)", + } + + EmitPrivateRegistryUsed(writer, testItems) + + assert.Len(t, writer.diagnostics, 1, "Expected one diagnostic to be emitted") + + d := writer.diagnostics[0] + assert.Equal(t, d.Source.Id, "go/autobuilder/analysis-using-private-registries") + assert.Equal(t, d.Severity, string(severityNote)) + + for i := range testItems { + assert.Contains(t, d.MarkdownMessage, testItems[i]) + } +} From 29930fa6bf98828af43ac93378ef9637b52ef385 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 2 Feb 2026 14:40:08 +0000 Subject: [PATCH 2/7] Track active proxy configurations --- go/extractor/util/registryproxy.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/go/extractor/util/registryproxy.go b/go/extractor/util/registryproxy.go index 1f20832e8d81..600c05a5af11 100644 --- a/go/extractor/util/registryproxy.go +++ b/go/extractor/util/registryproxy.go @@ -22,6 +22,19 @@ type RegistryConfig struct { URL string `json:"url"` } +func (config *RegistryConfig) Pretty() string { + pretty_type := "other" + + switch config.Type { + case GIT_SOURCE: + pretty_type = "Git Source" + case GOPROXY_SERVER: + pretty_type = "GOPROXY Server" + } + + return fmt.Sprintf("`%s` (%s)", config.URL, pretty_type) +} + // The address of the proxy including protocol and port (e.g. http://localhost:1234) var proxy_address string @@ -97,18 +110,22 @@ func getEnvVars() []string { if err != nil { slog.Error("Unable to parse proxy configurations", slog.String("error", err.Error())) } else { + activeConfigs := []RegistryConfig{} + // We only care about private registry configurations that are relevant to Go and // filter others out at this point. for _, cfg := range val { if cfg.Type == GOPROXY_SERVER { goproxy_servers = append(goproxy_servers, cfg.URL) slog.Info("Found GOPROXY server", slog.String("url", cfg.URL)) + activeConfigs = append(activeConfigs, cfg) } else if cfg.Type == GIT_SOURCE { parsed, err := url.Parse(cfg.URL) if err == nil && parsed.Hostname() != "" { git_source := parsed.Hostname() + parsed.Path + "*" git_sources = append(git_sources, git_source) slog.Info("Found Git source", slog.String("source", git_source)) + activeConfigs = append(activeConfigs, cfg) } else { slog.Warn("Not a valid URL for Git source", slog.String("url", cfg.URL)) } From 6d67e419ffc705deb5033bbb07f82ef80b3a8bd3 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 2 Feb 2026 14:45:06 +0000 Subject: [PATCH 3/7] Move private registry sources out of `util` package --- go/extractor/registries/BUILD.bazel | 16 ++++++++++++++++ .../{util => registries}/registryproxy.go | 2 +- .../{util => registries}/registryproxy_test.go | 2 +- go/extractor/toolchain/BUILD.bazel | 5 ++++- go/extractor/toolchain/toolchain.go | 3 ++- go/extractor/util/BUILD.bazel | 2 -- 6 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 go/extractor/registries/BUILD.bazel rename go/extractor/{util => registries}/registryproxy.go (99%) rename go/extractor/{util => registries}/registryproxy_test.go (99%) diff --git a/go/extractor/registries/BUILD.bazel b/go/extractor/registries/BUILD.bazel new file mode 100644 index 000000000000..8c002f20db28 --- /dev/null +++ b/go/extractor/registries/BUILD.bazel @@ -0,0 +1,16 @@ +# generated running `bazel run //go/gazelle`, do not edit + +load("@rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "registries", + srcs = ["registryproxy.go"], + importpath = "github.com/github/codeql-go/extractor/registries", + visibility = ["//visibility:public"], +) + +go_test( + name = "registries_test", + srcs = ["registryproxy_test.go"], + embed = [":registries"], +) diff --git a/go/extractor/util/registryproxy.go b/go/extractor/registries/registryproxy.go similarity index 99% rename from go/extractor/util/registryproxy.go rename to go/extractor/registries/registryproxy.go index 600c05a5af11..793bec5a41db 100644 --- a/go/extractor/util/registryproxy.go +++ b/go/extractor/registries/registryproxy.go @@ -1,4 +1,4 @@ -package util +package registries import ( "encoding/json" diff --git a/go/extractor/util/registryproxy_test.go b/go/extractor/registries/registryproxy_test.go similarity index 99% rename from go/extractor/util/registryproxy_test.go rename to go/extractor/registries/registryproxy_test.go index ef63bd9d3f87..c564040ff1b6 100644 --- a/go/extractor/util/registryproxy_test.go +++ b/go/extractor/registries/registryproxy_test.go @@ -1,4 +1,4 @@ -package util +package registries import ( "testing" diff --git a/go/extractor/toolchain/BUILD.bazel b/go/extractor/toolchain/BUILD.bazel index 583749993239..16c591f2a96a 100644 --- a/go/extractor/toolchain/BUILD.bazel +++ b/go/extractor/toolchain/BUILD.bazel @@ -7,7 +7,10 @@ go_library( srcs = ["toolchain.go"], importpath = "github.com/github/codeql-go/extractor/toolchain", visibility = ["//visibility:public"], - deps = ["//go/extractor/util"], + deps = [ + "//go/extractor/registries", + "//go/extractor/util", + ], ) go_test( diff --git a/go/extractor/toolchain/toolchain.go b/go/extractor/toolchain/toolchain.go index 01b3ab813bd5..fb9d5512cd83 100644 --- a/go/extractor/toolchain/toolchain.go +++ b/go/extractor/toolchain/toolchain.go @@ -10,6 +10,7 @@ import ( "path/filepath" "strings" + "github.com/github/codeql-go/extractor/registries" "github.com/github/codeql-go/extractor/util" ) @@ -140,7 +141,7 @@ func SupportsWorkspaces() bool { // Constructs a `*exec.Cmd` for `go` with the specified arguments. func GoCommand(arg ...string) *exec.Cmd { cmd := exec.Command("go", arg...) - util.ApplyProxyEnvVars(cmd) + registries.ApplyProxyEnvVars(cmd) return cmd } diff --git a/go/extractor/util/BUILD.bazel b/go/extractor/util/BUILD.bazel index ee090607ced5..ccebf5ebd865 100644 --- a/go/extractor/util/BUILD.bazel +++ b/go/extractor/util/BUILD.bazel @@ -8,7 +8,6 @@ go_library( "extractvendordirs.go", "logging.go", "overlays.go", - "registryproxy.go", "semver.go", "util.go", ], @@ -21,7 +20,6 @@ go_test( name = "util_test", srcs = [ "logging_test.go", - "registryproxy_test.go", "semver_test.go", "util_test.go", ], From 30b30d65c832a2a14a7f64834f532156d4e223c0 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 2 Feb 2026 14:47:25 +0000 Subject: [PATCH 4/7] Emit the new diagnostic --- go/extractor/registries/BUILD.bazel | 1 + go/extractor/registries/registryproxy.go | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/go/extractor/registries/BUILD.bazel b/go/extractor/registries/BUILD.bazel index 8c002f20db28..7947556ee5d8 100644 --- a/go/extractor/registries/BUILD.bazel +++ b/go/extractor/registries/BUILD.bazel @@ -7,6 +7,7 @@ go_library( srcs = ["registryproxy.go"], importpath = "github.com/github/codeql-go/extractor/registries", visibility = ["//visibility:public"], + deps = ["//go/extractor/diagnostics"], ) go_test( diff --git a/go/extractor/registries/registryproxy.go b/go/extractor/registries/registryproxy.go index 793bec5a41db..1bb5995e27ab 100644 --- a/go/extractor/registries/registryproxy.go +++ b/go/extractor/registries/registryproxy.go @@ -8,6 +8,8 @@ import ( "os" "os/exec" "strings" + + "github.com/github/codeql-go/extractor/diagnostics" ) const PROXY_HOST = "CODEQL_PROXY_HOST" @@ -132,6 +134,18 @@ func getEnvVars() []string { } } + // Emit a diagnostic to make it easy for users to see that private registry + // configurations were picked up by the Go analysis. + if len(activeConfigs) > 0 { + prettyConfigs := []string{} + for i := range activeConfigs { + prettyConfigs = append(prettyConfigs, activeConfigs[i].Pretty()) + } + + diagnostics.EmitPrivateRegistryUsed(diagnostics.DefaultWriter, prettyConfigs) + } + + // Assemble environment variables for Go. goprivate := []string{} if len(goproxy_servers) > 0 { From cbbc057dd313144605650f4d59d23f220247194a Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 2 Feb 2026 16:15:36 +0000 Subject: [PATCH 5/7] Fix singular/plural wording and add test --- go/extractor/diagnostics/diagnostics.go | 4 ++-- go/extractor/diagnostics/diagnostics_test.go | 24 +++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/go/extractor/diagnostics/diagnostics.go b/go/extractor/diagnostics/diagnostics.go index b40b31c15f3e..1deff68aa955 100644 --- a/go/extractor/diagnostics/diagnostics.go +++ b/go/extractor/diagnostics/diagnostics.go @@ -581,8 +581,8 @@ func EmitPrivateRegistryUsed(writer DiagnosticsWriter, configs []string) { "go/autobuilder/analysis-using-private-registries", "Go extraction used private package registries", fmt.Sprintf( - "Go was extracted using the following private package registrie%s:\n\n%s\n", - plural(len(lines), "", "s"), + "Go was extracted using the following private package registr%s:\n\n%s\n", + plural(len(lines), "y", "ies"), strings.Join(lines, "\n")), severityNote, fullVisibility, diff --git a/go/extractor/diagnostics/diagnostics_test.go b/go/extractor/diagnostics/diagnostics_test.go index 1582923fb559..1817610868fc 100644 --- a/go/extractor/diagnostics/diagnostics_test.go +++ b/go/extractor/diagnostics/diagnostics_test.go @@ -84,7 +84,28 @@ func Test_EmitCannotFindPackages_Actions(t *testing.T) { assert.Contains(t, d.MarkdownMessage, "If any of the packages are already present in the repository") } -func Test_EmitPrivateRegistryUsed(t *testing.T) { +func Test_EmitPrivateRegistryUsed_Single(t *testing.T) { + writer := newMemoryDiagnosticsWriter() + + testItems := []string{ + "* https://github.com/github/example (Git Source)", + } + + EmitPrivateRegistryUsed(writer, testItems) + + assert.Len(t, writer.diagnostics, 1, "Expected one diagnostic to be emitted") + + d := writer.diagnostics[0] + assert.Equal(t, d.Source.Id, "go/autobuilder/analysis-using-private-registries") + assert.Equal(t, d.Severity, string(severityNote)) + assert.Contains(t, d.MarkdownMessage, "following private package registry") + + for i := range testItems { + assert.Contains(t, d.MarkdownMessage, testItems[i]) + } +} + +func Test_EmitPrivateRegistryUsed_Multiple(t *testing.T) { writer := newMemoryDiagnosticsWriter() testItems := []string{ @@ -99,6 +120,7 @@ func Test_EmitPrivateRegistryUsed(t *testing.T) { d := writer.diagnostics[0] assert.Equal(t, d.Source.Id, "go/autobuilder/analysis-using-private-registries") assert.Equal(t, d.Severity, string(severityNote)) + assert.Contains(t, d.MarkdownMessage, "following private package registries") for i := range testItems { assert.Contains(t, d.MarkdownMessage, testItems[i]) From d079671ec8b56014eb484419c1253474105dbe8b Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Mon, 2 Feb 2026 16:17:22 +0000 Subject: [PATCH 6/7] Align `testItems` with what `getEnvVars` does --- go/extractor/diagnostics/diagnostics_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go/extractor/diagnostics/diagnostics_test.go b/go/extractor/diagnostics/diagnostics_test.go index 1817610868fc..3c28a57d4b5b 100644 --- a/go/extractor/diagnostics/diagnostics_test.go +++ b/go/extractor/diagnostics/diagnostics_test.go @@ -88,7 +88,7 @@ func Test_EmitPrivateRegistryUsed_Single(t *testing.T) { writer := newMemoryDiagnosticsWriter() testItems := []string{ - "* https://github.com/github/example (Git Source)", + "https://github.com/github/example (Git Source)", } EmitPrivateRegistryUsed(writer, testItems) @@ -109,8 +109,8 @@ func Test_EmitPrivateRegistryUsed_Multiple(t *testing.T) { writer := newMemoryDiagnosticsWriter() testItems := []string{ - "* https://github.com/github/example (Git Source)", - "* https://example.com/goproxy (GOPROXY Server)", + "https://github.com/github/example (Git Source)", + "https://example.com/goproxy (GOPROXY Server)", } EmitPrivateRegistryUsed(writer, testItems) From d5c4a19efa878c8c6b134c987cee5edd3ec921b0 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Tue, 3 Feb 2026 10:29:15 +0000 Subject: [PATCH 7/7] Apply suggestions from code review Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> --- go/extractor/diagnostics/diagnostics.go | 7 ++++--- go/extractor/registries/registryproxy.go | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/go/extractor/diagnostics/diagnostics.go b/go/extractor/diagnostics/diagnostics.go index 1deff68aa955..e7ff86cb878b 100644 --- a/go/extractor/diagnostics/diagnostics.go +++ b/go/extractor/diagnostics/diagnostics.go @@ -570,10 +570,11 @@ func EmitExtractionFailedForProjects(path []string) { } func EmitPrivateRegistryUsed(writer DiagnosticsWriter, configs []string) { - lines := []string{} + n := len(configs) + lines := make([]string, n) for i := range configs { - lines = append(lines, fmt.Sprintf("* %s", configs[i])) + lines[i] = fmt.Sprintf("* %s", configs[i]) } emitDiagnosticTo( @@ -582,7 +583,7 @@ func EmitPrivateRegistryUsed(writer DiagnosticsWriter, configs []string) { "Go extraction used private package registries", fmt.Sprintf( "Go was extracted using the following private package registr%s:\n\n%s\n", - plural(len(lines), "y", "ies"), + plural(n, "y", "ies"), strings.Join(lines, "\n")), severityNote, fullVisibility, diff --git a/go/extractor/registries/registryproxy.go b/go/extractor/registries/registryproxy.go index 1bb5995e27ab..39578af476be 100644 --- a/go/extractor/registries/registryproxy.go +++ b/go/extractor/registries/registryproxy.go @@ -112,7 +112,7 @@ func getEnvVars() []string { if err != nil { slog.Error("Unable to parse proxy configurations", slog.String("error", err.Error())) } else { - activeConfigs := []RegistryConfig{} + activeConfigs := make([]RegistryConfig, 0, len(val)) // We only care about private registry configurations that are relevant to Go and // filter others out at this point.