Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pkg/cli/add_interactive_orchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ func RunAddInteractive(ctx context.Context, config *AddInteractiveConfig) error
addInteractiveLog.Print("Starting interactive add workflow")

// Assert this function is not running in automated unit tests or CI
if os.Getenv("GO_TEST_MODE") == "true" || os.Getenv("CI") != "" {
if os.Getenv("GO_TEST_MODE") == "true" || os.Getenv("CI") != "" { //nolint:osgetenvlibrary

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] IsRunningInCI() already exists in ci.go — using it here removes two direct env reads and their suppressions.

💡 Suggested refactor
// Before
if os.Getenv("GO_TEST_MODE") == "true" || os.Getenv("CI") != "" { (nolint/redacted):osgetenvlibrary

// After — no suppression needed
if os.Getenv("GO_TEST_MODE") == "true" || IsRunningInCI() {

This also means future CI vars added to IsRunningInCI() are automatically covered here.

@copilot please address this.

return errors.New("interactive add cannot be used in automated tests or CI environments")
}

// Set context on the config
config.Ctx = ctx

// Auto-detect GHES host from git remote if not already set
if os.Getenv("GH_HOST") == "" {
if os.Getenv("GH_HOST") == "" { //nolint:osgetenvlibrary
detectedHost := getHostFromOriginRemote()
if detectedHost != "github.com" {
addInteractiveLog.Printf("Auto-detected GHES host from git remote: %s", detectedHost)
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/add_interactive_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (c *AddInteractiveConfig) checkStatusAndOfferRun(ctx context.Context) error
}

// In Codespaces, don't offer to trigger - provide link to Actions page instead
if os.Getenv("CODESPACES") == "true" {
if os.Getenv("CODESPACES") == "true" { //nolint:osgetenvlibrary

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] isRunningInCodespace() in codespace.go encapsulates this exact check — delegating to it would remove the suppression and centralise Codespace detection.

💡 Suggested refactor
// Before
if os.Getenv("CODESPACES") == "true" { (nolint/redacted):osgetenvlibrary

// After
if isRunningInCodespace() {

The existing codespace.go already has the //nolint annotation; this avoids spreading the same check across multiple files.

@copilot please address this.

addInteractiveLog.Print("Running in Codespaces, skipping run offer and showing Actions link")
fmt.Fprintln(os.Stderr, "")
fmt.Fprintln(os.Stderr, console.FormatInfoMessage("Running in GitHub Codespaces - please trigger the workflow manually from the Actions page"))
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/add_wizard_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Note: To create a new workflow from scratch, use the 'new' command instead.`,

// add-wizard requires an interactive terminal
isTerminal := tty.IsStdoutTerminal()
isCIEnv := os.Getenv("CI") != ""
isCIEnv := os.Getenv("CI") != "" //nolint:osgetenvlibrary

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] IsRunningInCI() already encapsulates this check — use it to eliminate the suppression and avoid duplicating CI-detection logic.

💡 Suggested refactor
// Before
isCIEnv := os.Getenv("CI") != "" (nolint/redacted):osgetenvlibrary

// After
isCIEnv := IsRunningInCI()

@copilot please address this.

addWizardLog.Printf("Terminal check: is_terminal=%v, is_ci=%v", isTerminal, isCIEnv)
if !isTerminal || isCIEnv {
return errors.New("add-wizard requires an interactive terminal; use 'add' for non-interactive environments")
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func IsRunningInCI() bool {
}

for _, v := range ciVars {
if os.Getenv(v) != "" {
if os.Getenv(v) != "" { //nolint:osgetenvlibrary
ciLog.Printf("CI environment detected via %s", v)
return true
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/codespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var codespaceLog = logger.New("cli:codespace")
// by checking for the CODESPACES environment variable
func isRunningInCodespace() bool {
// GitHub Codespaces sets CODESPACES=true environment variable
isCodespace := strings.EqualFold(os.Getenv("CODESPACES"), "true")
isCodespace := strings.EqualFold(os.Getenv("CODESPACES"), "true") //nolint:osgetenvlibrary
codespaceLog.Printf("Codespace detection: is_codespace=%v", isCodespace)
return isCodespace
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/compile_orchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func CompileWorkflows(ctx context.Context, config CompileConfig) ([]*workflow.Wo
default:
}

if os.Getenv("GH_HOST") == "" {
if os.Getenv("GH_HOST") == "" { //nolint:osgetenvlibrary
if detectedHost := getHostFromOriginRemote(); detectedHost != "github.com" && detectedHost != "" {
compileOrchestratorLog.Printf("Auto-detected GHES host from git remote: %s", detectedHost)
workflow.SetDefaultGHHost(detectedHost)
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/compile_update_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func shouldRunCompileUpdateCheck(noCheckUpdate bool) bool {
compileUpdateCheckLog.Print("Update check disabled via --no-check-update flag")
return false
}
if os.Getenv(compileUpdateCheckDisableEnv) != "" {
if os.Getenv(compileUpdateCheckDisableEnv) != "" { //nolint:osgetenvlibrary
compileUpdateCheckLog.Printf("Update check disabled via %s", compileUpdateCheckDisableEnv)
return false
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/cli/engine_secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,11 +231,11 @@ func ensureSecretAvailable(req SecretRequirement, config EngineSecretConfig) err
}

// Check environment variable
envValue := os.Getenv(req.Name)
envValue := os.Getenv(req.Name) //nolint:osgetenvlibrary
if envValue == "" {
// Check alternative environment variables
for _, alt := range req.AlternativeEnvVars {
envValue = os.Getenv(alt)
envValue = os.Getenv(alt) //nolint:osgetenvlibrary
if envValue != "" {
engineSecretsLog.Printf("Found secret in alternative env var: %s", alt)
break
Expand Down Expand Up @@ -439,7 +439,7 @@ func checkOptionalSecret(req SecretRequirement, config EngineSecretConfig) error
}

// Check environment
if os.Getenv(req.Name) != "" {
if os.Getenv(req.Name) != "" { //nolint:osgetenvlibrary
if config.Verbose {
fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("Optional secret %s found in environment", req.Name)))
}
Expand Down Expand Up @@ -552,11 +552,11 @@ func GetEngineSecretNameAndValue(engine string, existingSecrets map[string]struc
envVar = opt.EnvVarName
}

value := os.Getenv(envVar)
value := os.Getenv(envVar) //nolint:osgetenvlibrary
if value == "" {
// Check alternative environment variables
for _, alt := range opt.AlternativeSecrets {
value = os.Getenv(alt)
value = os.Getenv(alt) //nolint:osgetenvlibrary
if value != "" {
engineSecretsLog.Printf("Found secret in alternative env var: %s", alt)
break
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/import_url_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ func logResponseBodyVerbose(resp *http.Response) {
}

func importAuthGHHost() string {
ghHost := os.Getenv("GH_HOST")
ghHost := os.Getenv("GH_HOST") //nolint:osgetenvlibrary
if ghHost == "" {
return ""
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/cli/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ func isGHESHost(host string) bool {
// 3. The hostname extracted from the git origin remote URL
func detectGHESDeployment() string {
// Check GITHUB_SERVER_URL first (set inside GitHub Actions runners)
if serverURL := os.Getenv("GITHUB_SERVER_URL"); serverURL != "" {
if serverURL := os.Getenv("GITHUB_SERVER_URL"); serverURL != "" { //nolint:osgetenvlibrary
// serverURL is like "https://ghes.example.com", extract just the host.
host := serverURL
for _, scheme := range []string{"https://", "http://"} {
Expand All @@ -352,7 +352,7 @@ func detectGHESDeployment() string {
}

// Check GH_HOST (set when using the gh CLI against an enterprise instance)
if ghHost := os.Getenv("GH_HOST"); ghHost != "" {
if ghHost := os.Getenv("GH_HOST"); ghHost != "" { //nolint:osgetenvlibrary
if isGHESHost(ghHost) {
initLog.Printf("Detected GHES deployment from GH_HOST: %s", ghHost)
return ghHost
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/interactive.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func CreateWorkflowInteractively(ctx context.Context, workflowName string, verbo
interactiveLog.Printf("Starting interactive workflow creation: workflowName=%s, force=%v", workflowName, force)

// Assert this function is not running in automated unit tests
if os.Getenv("GO_TEST_MODE") == "true" || os.Getenv("CI") != "" {
if os.Getenv("GO_TEST_MODE") == "true" || os.Getenv("CI") != "" { //nolint:osgetenvlibrary

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] Same pattern as add_interactive_orchestrator.go — replace the raw os.Getenv("CI") check with the existing IsRunningInCI() wrapper to keep CI-detection logic in one place.

💡 Suggested refactor
// Before
if os.Getenv("GO_TEST_MODE") == "true" || os.Getenv("CI") != "" { (nolint/redacted):osgetenvlibrary

// After
if os.Getenv("GO_TEST_MODE") == "true" || IsRunningInCI() {

Both files guard against the same conditions; centralising removes the duplication.

@copilot please address this.

return errors.New("interactive workflow creation cannot be used in automated tests or CI environments")
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/logs_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ func repoIsLocal(repo string) bool {
ownerRepo, _ := repoutil.NormalizeRepoForAPI(repo)

// Fast path: GITHUB_REPOSITORY is always the current repo in MCP server containers.
if envRepo := os.Getenv("GITHUB_REPOSITORY"); envRepo != "" {
if envRepo := os.Getenv("GITHUB_REPOSITORY"); envRepo != "" { //nolint:osgetenvlibrary
return strings.EqualFold(ownerRepo, envRepo)
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/mcp_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func getRepository(ctx context.Context) (string, error) {
}

// Try GITHUB_REPOSITORY environment variable first
repo := os.Getenv("GITHUB_REPOSITORY")
repo := os.Getenv("GITHUB_REPOSITORY") //nolint:osgetenvlibrary
if repo != "" {
mcpLog.Printf("Got repository from GITHUB_REPOSITORY: %s", repo)
mcpCache.SetRepo(repo)
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/mcp_server_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func runMCPServer(ctx context.Context, port int, cmdPath string, validateActor b
mcpServerEnv := withNonInteractiveCIEnv(nil)

// Get actor from environment variable
actor := os.Getenv("GITHUB_ACTOR")
actor := os.Getenv("GITHUB_ACTOR") //nolint:osgetenvlibrary

if validateActor {
mcpLog.Printf("Actor validation enabled (--validate-actor flag)")
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/mcp_tools_privileged.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const (
// GITHUB_REPOSITORY is forwarded to the agentic-workflows MCP server container via
// env_vars in the MCP configuration and inherited by spawned subprocesses.
func appendRepoFlagFromEnv(args []string) []string {
if repo := os.Getenv("GITHUB_REPOSITORY"); repo != "" {
if repo := os.Getenv("GITHUB_REPOSITORY"); repo != "" { //nolint:osgetenvlibrary
return append(args, "--repo", repo)
}
return args
Expand Down
4 changes: 2 additions & 2 deletions pkg/cli/mcp_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func validateServerSecrets(config parser.RegistryMCPServerConfig, verbose bool,
} else {
// Automatically try to get GitHub token for GitHub-related environment variables
if key == "GITHUB_PERSONAL_ACCESS_TOKEN" || key == "GITHUB_TOKEN" || key == "GH_TOKEN" {
if actualValue := os.Getenv(key); actualValue == "" {
if actualValue := os.Getenv(key); actualValue == "" { //nolint:osgetenvlibrary
// Try to automatically get the GitHub token
if token, err := parser.GetGitHubToken(); err == nil {
config.Env[key] = token
Expand All @@ -114,7 +114,7 @@ func validateServerSecrets(config parser.RegistryMCPServerConfig, verbose bool,
} else {
// For backward compatibility: check if environment variable with this name exists
// This preserves the original behavior for existing tests
if actualValue := os.Getenv(key); actualValue == "" {
if actualValue := os.Getenv(key); actualValue == "" { //nolint:osgetenvlibrary
return fmt.Errorf("environment variable '%s' not set", key)
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/secret_set_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func normalizeSecretSetAPIHost(apiBase string) string {

func resolveSecretValueForSet(fromEnv, fromFlag string) (string, error) {
if fromEnv != "" {
v := os.Getenv(fromEnv)
v := os.Getenv(fromEnv) //nolint:osgetenvlibrary
if v == "" {
return "", fmt.Errorf("environment variable %s is not set or empty", fromEnv)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func extractSecretsFromConfig(config parser.RegistryMCPServerConfig) []SecretInf
func checkSecretsAvailability(secrets []SecretInfo, useActionsSecrets bool) []SecretInfo {
for i := range secrets {
// First check if it's in environment variables
if value := os.Getenv(secrets[i].Name); value != "" {
if value := os.Getenv(secrets[i].Name); value != "" { //nolint:osgetenvlibrary
secrets[i].Available = true
secrets[i].Source = "env"
secrets[i].Value = value
Expand Down
12 changes: 6 additions & 6 deletions pkg/cli/shell_completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,21 @@ func DetectShell() ShellType {
shellCompletionLog.Print("Detecting current shell")

// Check shell-specific version variables first (most reliable)
if os.Getenv("ZSH_VERSION") != "" {
if os.Getenv("ZSH_VERSION") != "" { //nolint:osgetenvlibrary
shellCompletionLog.Print("Detected zsh from ZSH_VERSION")
return ShellZsh
}
if os.Getenv("BASH_VERSION") != "" {
if os.Getenv("BASH_VERSION") != "" { //nolint:osgetenvlibrary
shellCompletionLog.Print("Detected bash from BASH_VERSION")
return ShellBash
}
if os.Getenv("FISH_VERSION") != "" {
if os.Getenv("FISH_VERSION") != "" { //nolint:osgetenvlibrary
shellCompletionLog.Print("Detected fish from FISH_VERSION")
return ShellFish
}

// Fall back to $SHELL environment variable
shell := os.Getenv("SHELL")
shell := os.Getenv("SHELL") //nolint:osgetenvlibrary
if shell == "" {
shellCompletionLog.Print("SHELL environment variable not set, checking platform")
// On Windows, check for PowerShell
Expand Down Expand Up @@ -143,7 +143,7 @@ func installBashCompletion(verbose bool, cmd *cobra.Command) error {
// Try to determine the best location for bash completions
if runtime.GOOS == "darwin" {
// macOS with Homebrew
brewPrefix := os.Getenv("HOMEBREW_PREFIX")
brewPrefix := os.Getenv("HOMEBREW_PREFIX") //nolint:osgetenvlibrary
if brewPrefix == "" {
// Try common locations
for _, prefix := range []string{constants.HomebrewPrefix, constants.UsrLocalPrefix} {
Expand Down Expand Up @@ -425,7 +425,7 @@ func uninstallBashCompletion(verbose bool) error {

// macOS with Homebrew
if runtime.GOOS == "darwin" {
brewPrefix := os.Getenv("HOMEBREW_PREFIX")
brewPrefix := os.Getenv("HOMEBREW_PREFIX") //nolint:osgetenvlibrary
if brewPrefix == "" {
for _, prefix := range []string{constants.HomebrewPrefix, constants.UsrLocalPrefix} {
if fileutil.DirExists(filepath.Join(prefix, "etc", "bash_completion.d")) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/update_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func shouldCheckForUpdate(noCheckUpdate bool) bool {
// This is a heuristic - we can't reliably detect this, so we're conservative
func isRunningAsMCPServer() bool {
// Check for MCP_SERVER environment variable that could be set by the MCP server
return os.Getenv("GH_AW_MCP_SERVER") != ""
return os.Getenv("GH_AW_MCP_SERVER") != "" //nolint:osgetenvlibrary
Comment on lines 76 to +77
}

var (
Expand Down
2 changes: 1 addition & 1 deletion pkg/workflow/process_env_lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ import "os"
func lookupProcessEnv(key string) string {
// Intentionally ignore the existence flag to preserve os.Getenv semantics:
// missing variables and explicitly empty variables are both treated as "".
value, _ := os.LookupEnv(key)
value, _ := os.LookupEnv(key) //nolint:osgetenvlibrary
return value
}
Loading