Skip to content

Commit 9fbbceb

Browse files
Copilotpelikhan
andauthored
Add --skip-secret flag to add-wizard to bypass API key prompt (#20598)
* Initial plan * Add --skip-secret flag to add-wizard command to skip API secret prompt Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> Co-authored-by: Peli de Halleux <pelikhan@users.noreply.github.com>
1 parent 61398e7 commit 9fbbceb

4 files changed

Lines changed: 59 additions & 4 deletions

File tree

pkg/cli/add_interactive_engine.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,17 @@ func (c *AddInteractiveConfig) selectAIEngineAndKey() error {
139139
func (c *AddInteractiveConfig) collectAPIKey(engine string) error {
140140
addInteractiveLog.Printf("Collecting API key for engine: %s", engine)
141141

142+
// If --skip-secret flag is set, skip secrets configuration entirely.
143+
if c.SkipSecret {
144+
opt := constants.GetEngineOption(engine)
145+
if opt != nil {
146+
fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("Skipping %s secret setup (--skip-secret flag set).", opt.SecretName)))
147+
} else {
148+
fmt.Fprintln(os.Stderr, console.FormatInfoMessage("Skipping secret setup (--skip-secret flag set)."))
149+
}
150+
return nil
151+
}
152+
142153
// If user doesn't have write access, skip secrets configuration.
143154
// Users without write access cannot configure repository secrets.
144155
if !c.hasWriteAccess {

pkg/cli/add_interactive_orchestrator.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type AddInteractiveConfig struct {
2424
NoStopAfter bool
2525
StopAfter string
2626
SkipWorkflowRun bool
27+
SkipSecret bool // Skip the API secret prompt (useful when secret is set at org level)
2728
RepoOverride string // owner/repo format, if user provides it
2829

2930
// isPublicRepo tracks whether the target repository is public
@@ -48,7 +49,7 @@ type AddInteractiveConfig struct {
4849

4950
// RunAddInteractive runs the interactive add workflow
5051
// This walks the user through adding an agentic workflow to their repository
51-
func RunAddInteractive(ctx context.Context, workflowSpecs []string, verbose bool, engineOverride string, noGitattributes bool, workflowDir string, noStopAfter bool, stopAfter string) error {
52+
func RunAddInteractive(ctx context.Context, workflowSpecs []string, verbose bool, engineOverride string, noGitattributes bool, workflowDir string, noStopAfter bool, stopAfter string, skipSecret bool) error {
5253
addInteractiveLog.Print("Starting interactive add workflow")
5354

5455
// 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
6465
WorkflowDir: workflowDir,
6566
NoStopAfter: noStopAfter,
6667
StopAfter: stopAfter,
68+
SkipSecret: skipSecret,
6769
}
6870

6971
// Step 1: Welcome message
@@ -120,7 +122,7 @@ func RunAddInteractive(ctx context.Context, workflowSpecs []string, verbose bool
120122

121123
// Step 8: Confirm with user
122124
var secretName, secretValue string
123-
if config.hasWriteAccess {
125+
if config.hasWriteAccess && !config.SkipSecret {
124126
secretName, secretValue, err = config.getSecretInfo()
125127
if err != nil {
126128
return err

pkg/cli/add_interactive_secrets_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,43 @@ func TestAddInteractiveConfig_collectAPIKey_noWriteAccess(t *testing.T) {
132132
}
133133
}
134134

135+
func TestAddInteractiveConfig_collectAPIKey_skipSecret(t *testing.T) {
136+
tests := []struct {
137+
name string
138+
engine string
139+
}{
140+
{
141+
name: "copilot engine - skips secret setup",
142+
engine: "copilot",
143+
},
144+
{
145+
name: "claude engine - skips secret setup",
146+
engine: "claude",
147+
},
148+
{
149+
name: "unknown engine - skips without error",
150+
engine: "unknown-engine",
151+
},
152+
}
153+
154+
for _, tt := range tests {
155+
t.Run(tt.name, func(t *testing.T) {
156+
config := &AddInteractiveConfig{
157+
EngineOverride: tt.engine,
158+
RepoOverride: "owner/repo",
159+
hasWriteAccess: true,
160+
SkipSecret: true,
161+
existingSecrets: make(map[string]bool),
162+
}
163+
164+
// When SkipSecret is true, collectAPIKey should return nil without
165+
// prompting or uploading any secrets, even with write access.
166+
err := config.collectAPIKey(tt.engine)
167+
require.NoError(t, err, "collectAPIKey should succeed when SkipSecret is true")
168+
})
169+
}
170+
}
171+
135172
func TestAddInteractiveConfig_checkExistingSecrets(t *testing.T) {
136173
config := &AddInteractiveConfig{
137174
RepoOverride: "test-owner/test-repo",

pkg/cli/add_wizard_command.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ Examples:
3131
` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/daily-repo-status # Guided setup
3232
` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor@v1.0.0 # Guided setup with version
3333
` + string(constants.CLIExtensionPrefix) + ` add-wizard ./my-workflow.md # Guided setup for local workflow
34-
` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --engine copilot # Pre-select engine
34+
` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --engine copilot # Pre-select engine
35+
` + string(constants.CLIExtensionPrefix) + ` add-wizard githubnext/agentics/ci-doctor --skip-secret # Skip secret prompt
3536
3637
Workflow specifications:
3738
- 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.`,
5657
workflowDir, _ := cmd.Flags().GetString("dir")
5758
noStopAfter, _ := cmd.Flags().GetBool("no-stop-after")
5859
stopAfter, _ := cmd.Flags().GetString("stop-after")
60+
skipSecret, _ := cmd.Flags().GetBool("skip-secret")
5961

6062
addWizardLog.Printf("Starting add-wizard: workflows=%v, engine=%s, verbose=%v", workflows, engineOverride, verbose)
6163

@@ -71,7 +73,7 @@ Note: To create a new workflow from scratch, use the 'new' command instead.`,
7173
return errors.New("add-wizard requires an interactive terminal; use 'add' for non-interactive environments")
7274
}
7375

74-
return RunAddInteractive(cmd.Context(), workflows, verbose, engineOverride, noGitattributes, workflowDir, noStopAfter, stopAfter)
76+
return RunAddInteractive(cmd.Context(), workflows, verbose, engineOverride, noGitattributes, workflowDir, noStopAfter, stopAfter, skipSecret)
7577
},
7678
}
7779

@@ -90,6 +92,9 @@ Note: To create a new workflow from scratch, use the 'new' command instead.`,
9092
// Add stop-after flag
9193
cmd.Flags().String("stop-after", "", "Override stop-after value in the workflow (e.g., '+48h', '2025-12-31 23:59:59')")
9294

95+
// Add skip-secret flag
96+
cmd.Flags().Bool("skip-secret", false, "Skip the API secret prompt (use when the secret is already set at the org or repo level)")
97+
9398
// Register completions
9499
RegisterEngineFlagCompletion(cmd)
95100
RegisterDirFlagCompletion(cmd, "dir")

0 commit comments

Comments
 (0)