From 4bd119ff070f0917bb221da3138abe2ef366679a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Mar 2026 22:20:26 +0000 Subject: [PATCH 1/2] Initial plan From 66ef3b03189d203ef90aea2c2dbec44666231793 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Mar 2026 22:35:52 +0000 Subject: [PATCH 2/2] Add --skip-secret flag to add-wizard command to skip API secret prompt Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/cli/add_interactive_engine.go | 11 ++++++++ pkg/cli/add_interactive_orchestrator.go | 6 ++-- pkg/cli/add_interactive_secrets_test.go | 37 +++++++++++++++++++++++++ pkg/cli/add_wizard_command.go | 9 ++++-- 4 files changed, 59 insertions(+), 4 deletions(-) diff --git a/pkg/cli/add_interactive_engine.go b/pkg/cli/add_interactive_engine.go index 888a246bc5f..9deb4109d49 100644 --- a/pkg/cli/add_interactive_engine.go +++ b/pkg/cli/add_interactive_engine.go @@ -139,6 +139,17 @@ func (c *AddInteractiveConfig) selectAIEngineAndKey() error { func (c *AddInteractiveConfig) collectAPIKey(engine string) error { addInteractiveLog.Printf("Collecting API key for engine: %s", engine) + // If --skip-secret flag is set, skip secrets configuration entirely. + if c.SkipSecret { + opt := constants.GetEngineOption(engine) + if opt != nil { + fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("Skipping %s secret setup (--skip-secret flag set).", opt.SecretName))) + } else { + fmt.Fprintln(os.Stderr, console.FormatInfoMessage("Skipping secret setup (--skip-secret flag set).")) + } + return nil + } + // If user doesn't have write access, skip secrets configuration. // Users without write access cannot configure repository secrets. if !c.hasWriteAccess { diff --git a/pkg/cli/add_interactive_orchestrator.go b/pkg/cli/add_interactive_orchestrator.go index d9c188901d9..b9f50107d72 100644 --- a/pkg/cli/add_interactive_orchestrator.go +++ b/pkg/cli/add_interactive_orchestrator.go @@ -24,6 +24,7 @@ type AddInteractiveConfig struct { NoStopAfter bool StopAfter string SkipWorkflowRun bool + SkipSecret bool // Skip the API secret prompt (useful when secret is set at org level) RepoOverride string // owner/repo format, if user provides it // isPublicRepo tracks whether the target repository is public @@ -48,7 +49,7 @@ type AddInteractiveConfig struct { // RunAddInteractive runs the interactive add workflow // This walks the user through adding an agentic workflow to their repository -func RunAddInteractive(ctx context.Context, workflowSpecs []string, verbose bool, engineOverride string, noGitattributes bool, workflowDir string, noStopAfter bool, stopAfter string) error { +func RunAddInteractive(ctx context.Context, workflowSpecs []string, verbose bool, engineOverride string, noGitattributes bool, workflowDir string, noStopAfter bool, stopAfter string, skipSecret bool) error { addInteractiveLog.Print("Starting interactive add workflow") // Assert this function is not running in automated unit tests or CI @@ -64,6 +65,7 @@ func RunAddInteractive(ctx context.Context, workflowSpecs []string, verbose bool WorkflowDir: workflowDir, NoStopAfter: noStopAfter, StopAfter: stopAfter, + SkipSecret: skipSecret, } // Step 1: Welcome message @@ -120,7 +122,7 @@ func RunAddInteractive(ctx context.Context, workflowSpecs []string, verbose bool // Step 8: Confirm with user var secretName, secretValue string - if config.hasWriteAccess { + if config.hasWriteAccess && !config.SkipSecret { secretName, secretValue, err = config.getSecretInfo() if err != nil { return err diff --git a/pkg/cli/add_interactive_secrets_test.go b/pkg/cli/add_interactive_secrets_test.go index 0f6e8fc4db2..80fe0a05829 100644 --- a/pkg/cli/add_interactive_secrets_test.go +++ b/pkg/cli/add_interactive_secrets_test.go @@ -132,6 +132,43 @@ func TestAddInteractiveConfig_collectAPIKey_noWriteAccess(t *testing.T) { } } +func TestAddInteractiveConfig_collectAPIKey_skipSecret(t *testing.T) { + tests := []struct { + name string + engine string + }{ + { + name: "copilot engine - skips secret setup", + engine: "copilot", + }, + { + name: "claude engine - skips secret setup", + engine: "claude", + }, + { + name: "unknown engine - skips without error", + engine: "unknown-engine", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config := &AddInteractiveConfig{ + EngineOverride: tt.engine, + RepoOverride: "owner/repo", + hasWriteAccess: true, + SkipSecret: true, + existingSecrets: make(map[string]bool), + } + + // When SkipSecret is true, collectAPIKey should return nil without + // prompting or uploading any secrets, even with write access. + err := config.collectAPIKey(tt.engine) + require.NoError(t, err, "collectAPIKey should succeed when SkipSecret is true") + }) + } +} + func TestAddInteractiveConfig_checkExistingSecrets(t *testing.T) { config := &AddInteractiveConfig{ RepoOverride: "test-owner/test-repo", diff --git a/pkg/cli/add_wizard_command.go b/pkg/cli/add_wizard_command.go index 219b965239d..9b93707e5f2 100644 --- a/pkg/cli/add_wizard_command.go +++ b/pkg/cli/add_wizard_command.go @@ -31,7 +31,8 @@ Examples: ` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/daily-repo-status # Guided setup ` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor@v1.0.0 # Guided setup with version ` + string(constants.CLIExtensionPrefix) + ` add-wizard ./my-workflow.md # Guided setup for local workflow - ` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --engine copilot # Pre-select engine + ` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --engine copilot # Pre-select engine + ` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --skip-secret # Skip secret prompt Workflow specifications: - Three parts: "owner/repo/workflow-name[@version]" (implicitly looks in workflows/ directory) @@ -56,6 +57,7 @@ Note: To create a new workflow from scratch, use the 'new' command instead.`, workflowDir, _ := cmd.Flags().GetString("dir") noStopAfter, _ := cmd.Flags().GetBool("no-stop-after") stopAfter, _ := cmd.Flags().GetString("stop-after") + skipSecret, _ := cmd.Flags().GetBool("skip-secret") addWizardLog.Printf("Starting add-wizard: workflows=%v, engine=%s, verbose=%v", workflows, engineOverride, verbose) @@ -71,7 +73,7 @@ Note: To create a new workflow from scratch, use the 'new' command instead.`, return errors.New("add-wizard requires an interactive terminal; use 'add' for non-interactive environments") } - return RunAddInteractive(cmd.Context(), workflows, verbose, engineOverride, noGitattributes, workflowDir, noStopAfter, stopAfter) + return RunAddInteractive(cmd.Context(), workflows, verbose, engineOverride, noGitattributes, workflowDir, noStopAfter, stopAfter, skipSecret) }, } @@ -90,6 +92,9 @@ Note: To create a new workflow from scratch, use the 'new' command instead.`, // Add stop-after flag cmd.Flags().String("stop-after", "", "Override stop-after value in the workflow (e.g., '+48h', '2025-12-31 23:59:59')") + // Add skip-secret flag + cmd.Flags().Bool("skip-secret", false, "Skip the API secret prompt (use when the secret is already set at the org or repo level)") + // Register completions RegisterEngineFlagCompletion(cmd) RegisterDirFlagCompletion(cmd, "dir")