From efb31a0a77e0e3b6ff0090f5753534f562e0b3ac Mon Sep 17 00:00:00 2001 From: Moritz Clasmeier Date: Tue, 30 Jun 2026 11:22:10 +0200 Subject: [PATCH 1/3] Improve in-stackrox-repo check, remove TODO --- internal/env/env.go | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/internal/env/env.go b/internal/env/env.go index 9b4c93c9..326efc64 100644 --- a/internal/env/env.go +++ b/internal/env/env.go @@ -315,20 +315,23 @@ func fetchAPIResources() ([]string, error) { } func IsInStackroxRepository() bool { - // TODO(#91): This assumes that: - // - origin is the name of the upstream remote (not true if someone cloned their fork) - // - the git transport was used - // How about instead looking for "# StackRox Kubernetes Security Platform" in README? - cmd := exec.Command("git", "remote", "get-url", "origin") - outputBytes, err := cmd.Output() + out, err := exec.Command("git", "remote", "-v").Output() if err != nil { return false } - outputLines := strings.Split(string(outputBytes), "\n") - if len(outputLines) == 0 { - return false + for _, line := range strings.Split(string(out), "\n") { + if fields := strings.Fields(line); len(fields) >= 2 && isStackRoxRepositoryRemote(fields[1]) { + return true + } } - return outputLines[0] == "git@github.com:stackrox/stackrox.git" + return false +} + +func isStackRoxRepositoryRemote(remote string) bool { + remote = strings.TrimSuffix(remote, ".git") + return remote == "git@github.com:stackrox/stackrox" || + remote == "https://github.com/stackrox/stackrox" || + remote == "ssh://git@github.com/stackrox/stackrox" } func GetStackroxRepositoryTag() (string, error) { From 9de8b01528735c42e92d5bac37a1fcd3ff786ce0 Mon Sep 17 00:00:00 2001 From: Moritz Clasmeier Date: Thu, 2 Jul 2026 09:03:27 +0200 Subject: [PATCH 2/3] transport agnostic check --- internal/env/env.go | 10 +++++----- internal/env/env_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/internal/env/env.go b/internal/env/env.go index 326efc64..77627cf3 100644 --- a/internal/env/env.go +++ b/internal/env/env.go @@ -8,6 +8,7 @@ import ( "os" "os/exec" "path/filepath" + "regexp" "strings" "sync" "time" @@ -319,7 +320,7 @@ func IsInStackroxRepository() bool { if err != nil { return false } - for _, line := range strings.Split(string(out), "\n") { + for line := range strings.SplitSeq(string(out), "\n") { if fields := strings.Fields(line); len(fields) >= 2 && isStackRoxRepositoryRemote(fields[1]) { return true } @@ -327,11 +328,10 @@ func IsInStackroxRepository() bool { return false } +var stackroxRepoPattern = regexp.MustCompile(`[/:]stackrox/stackrox(\.git)?$`) + func isStackRoxRepositoryRemote(remote string) bool { - remote = strings.TrimSuffix(remote, ".git") - return remote == "git@github.com:stackrox/stackrox" || - remote == "https://github.com/stackrox/stackrox" || - remote == "ssh://git@github.com/stackrox/stackrox" + return stackroxRepoPattern.MatchString(remote) } func GetStackroxRepositoryTag() (string, error) { diff --git a/internal/env/env_test.go b/internal/env/env_test.go index b9ccdb7c..b5cf6c1d 100644 --- a/internal/env/env_test.go +++ b/internal/env/env_test.go @@ -325,6 +325,33 @@ func TestClusterTypeString(t *testing.T) { } } +func TestIsStackRoxRepositoryRemote(t *testing.T) { + tests := []struct { + remote string + want bool + }{ + {"git@github.com:stackrox/stackrox.git", true}, + {"git@github.com:stackrox/stackrox", true}, + {"https://github.com/stackrox/stackrox.git", true}, + {"https://github.com/stackrox/stackrox", true}, + {"ssh://git@github.com/stackrox/stackrox.git", true}, + {"ssh://git@github.com/stackrox/stackrox", true}, + {"git@github.com:someone/stackrox.git", false}, + {"git@github.com:stackrox/other.git", false}, + {"git@github.com:foo-stackrox/stackrox-bar.git", false}, + {"git@github.com:foo-stackrox/stackrox.git", false}, + {"git@github.com:stackrox/stackrox-bar.git", false}, + {"", false}, + } + + for _, tt := range tests { + t.Run(tt.remote, func(t *testing.T) { + got := isStackRoxRepositoryRemote(tt.remote) + assert.Equal(t, tt.want, got, "isStackRoxRepositoryRemote(%q)", tt.remote) + }) + } +} + func TestDefaultDetector_Detect(t *testing.T) { tests := []struct { name string From acc9fee26685bb32b437376346ddb5f7f5852408 Mon Sep 17 00:00:00 2001 From: Moritz Clasmeier Date: Thu, 2 Jul 2026 13:29:27 +0200 Subject: [PATCH 3/3] Improve logging --- internal/env/env.go | 19 ++++++++++++++++--- internal/helpers/tag.go | 17 ++++++++++------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/internal/env/env.go b/internal/env/env.go index 77627cf3..48c46da4 100644 --- a/internal/env/env.go +++ b/internal/env/env.go @@ -315,16 +315,28 @@ func fetchAPIResources() ([]string, error) { return lines, nil } -func IsInStackroxRepository() bool { +func IsInStackroxRepository(log *logger.Logger) bool { out, err := exec.Command("git", "remote", "-v").Output() + if exitErr, ok := errors.AsType[*exec.ExitError](err); ok { + log.Dimf("Not a git repository, ignoring ('git remote' returned %d)", exitErr.ExitCode()) + return false + } if err != nil { + log.Dimf("Invoking 'git remote' failed: %v", err) return false } for line := range strings.SplitSeq(string(out), "\n") { - if fields := strings.Fields(line); len(fields) >= 2 && isStackRoxRepositoryRemote(fields[1]) { + fields := strings.Fields(line) + if len(fields) < 2 { + continue + } + remote := fields[1] + if isStackRoxRepositoryRemote(remote) { + log.Dimf("Identified repository as a clone of stackrox/stackrox based on the configured git remote %q", remote) return true } } + log.Dim("Repository does not seem to be a clone of stackrox/stackrox based on the configured git remotes") return false } @@ -334,11 +346,12 @@ func isStackRoxRepositoryRemote(remote string) bool { return stackroxRepoPattern.MatchString(remote) } -func GetStackroxRepositoryTag() (string, error) { +func GetStackroxRepositoryTag(log *logger.Logger) (string, error) { topLevelDir, err := getStackRoxTopLevelDir() if err != nil { return "", fmt.Errorf("getting stackrox top level directory: %w", err) } + log.Dimf("Invoking 'make tag' in directory %q", topLevelDir) cmd := exec.Command("make", "-s", "-C", topLevelDir, "tag") outputBytes, err := cmd.Output() if err != nil { diff --git a/internal/helpers/tag.go b/internal/helpers/tag.go index c7b8f692..6c2050b8 100644 --- a/internal/helpers/tag.go +++ b/internal/helpers/tag.go @@ -17,29 +17,32 @@ import ( ) func LookupMainImageTag(ctx context.Context, log *logger.Logger) (string, error) { - log.Info("Looking up main image tag") + log.Dim("Checking if main image tag is defined in the environment") if tag := os.Getenv("MAIN_IMAGE_TAG"); tag != "" { - log.Dimf("Using MAIN_IMAGE_TAG from environment: %s", tag) + log.Infof("Using MAIN_IMAGE_TAG from environment: %s", tag) return tag, nil } - if env.IsInStackroxRepository() { - tag, err := env.GetStackroxRepositoryTag() + log.Dim("Checking if current working directory is checkout of stackrox/stackrox repository") + if env.IsInStackroxRepository(log) { + tag, err := env.GetStackroxRepositoryTag(log) if err != nil { log.Dimf("Error retrieving stackrox repository tag: %v", err) return "", err } - log.Dimf("Using stackrox repository tag: %s", tag) + log.Infof("Using stackrox repository tag: %s", tag) return tag, nil } - log.Warningf("No MAIN_IMAGE_TAG found in the environment, looking up latest release tag on registry") - log.Warning("To use a different tag, set the MAIN_IMAGE_TAG environment variable") + log.Warning("No tag specific and no MAIN_IMAGE_TAG found in the environment, looking up latest release tag on registry") + log.Warning("To use a different tag, use `--tag` or set the MAIN_IMAGE_TAG environment variable") log.Warning("Alternatively, execute roxie from within the stackrox repository, in which case the currently checked out stackrox tag will be used") + log.Dim("Checking what the latest released version tag is") latestTag, err := LookupLatestTag(ctx, log) if err != nil { return "", fmt.Errorf("looking up latest release tag: %w", err) } + log.Infof("Using latest released tag %v", latestTag) return latestTag, nil }