Merge pull request #21252 from github/mbg/go/private-registry-diagnostic

Go: Add diagnostic for private registry usage
This commit is contained in:
Michael B. Gale
2026-02-03 14:36:19 +00:00
committed by GitHub
8 changed files with 121 additions and 6 deletions

View File

@@ -568,3 +568,25 @@ func EmitExtractionFailedForProjects(path []string) {
noLocation,
)
}
func EmitPrivateRegistryUsed(writer DiagnosticsWriter, configs []string) {
n := len(configs)
lines := make([]string, n)
for i := range configs {
lines[i] = 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 registr%s:\n\n%s\n",
plural(n, "y", "ies"),
strings.Join(lines, "\n")),
severityNote,
fullVisibility,
noLocation,
)
}

View File

@@ -83,3 +83,46 @@ 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_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{
"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))
assert.Contains(t, d.MarkdownMessage, "following private package registries")
for i := range testItems {
assert.Contains(t, d.MarkdownMessage, testItems[i])
}
}

17
go/extractor/registries/BUILD.bazel generated Normal file
View File

@@ -0,0 +1,17 @@
# 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"],
deps = ["//go/extractor/diagnostics"],
)
go_test(
name = "registries_test",
srcs = ["registryproxy_test.go"],
embed = [":registries"],
)

View File

@@ -1,4 +1,4 @@
package util
package registries
import (
"encoding/json"
@@ -8,6 +8,8 @@ import (
"os"
"os/exec"
"strings"
"github.com/github/codeql-go/extractor/diagnostics"
)
const PROXY_HOST = "CODEQL_PROXY_HOST"
@@ -22,6 +24,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,24 +112,40 @@ func getEnvVars() []string {
if err != nil {
slog.Error("Unable to parse proxy configurations", slog.String("error", err.Error()))
} else {
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.
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))
}
}
}
// 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 {

View File

@@ -1,4 +1,4 @@
package util
package registries
import (
"testing"

View File

@@ -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(

View File

@@ -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
}

View File

@@ -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",
],