@@ -68,96 +68,100 @@ func runAuthConfigure(cmd *cobra.Command, args []string) error {
6868 return err
6969 }
7070
71- fmt .Fprintln (out , "This will:" )
71+ // Resolve bot identity early so we can show it in the banner
72+ identityLine := "app bot identity"
73+ slug , botUserID , identityErr := resolveAppIdentity ()
74+ if identityErr == nil {
75+ botName := fmt .Sprintf ("%s[bot]" , slug )
76+ botEmail := fmt .Sprintf ("%d+%s[bot]@users.noreply.github.com" , botUserID , slug )
77+ identityLine = fmt .Sprintf ("%s <%s>" , botName , botEmail )
78+ }
79+
80+ // Banner
81+ fmt .Fprintln (out , "Auth will automatically configure:" )
7282 fmt .Fprintf (out , " 1. Set git credential helper: %s\n " , helperCmd )
7383 fmt .Fprintln (out , " 2. Write github.com entry to gh hosts.yml" )
7484 fmt .Fprintln (out , " 3. Rewrite git@github.com SSH URLs to HTTPS (insteadOf)" )
85+ fmt .Fprintf (out , " 4. Set git identity to %s\n " , identityLine )
7586 fmt .Fprintln (out )
7687
77- if ! confirm (cmd , "Proceed?" ) {
78- fmt .Fprintln (out , "Aborted." )
79- return nil
88+ // Resolve gh-auth mode — this is the single gate for interactive use
89+ mode := ghAuthFlag
90+ if mode == "" {
91+ if ! isInteractive (cmd ) {
92+ mode = "none"
93+ } else {
94+ fmt .Fprintln (out , "How would you like to authenticate gh CLI commands?" )
95+ fmt .Fprintln (out , " 1. Shell function (recommended) — auto-refreshes token per invocation" )
96+ fmt .Fprintln (out , " 2. PATH binary — wrapper binary that injects token" )
97+ fmt .Fprintln (out , " 3. None — keep hosts.yml only (token expires in ~1hr)" )
98+ fmt .Fprintln (out )
99+
100+ choice := promptChoice (cmd , "Choice [1/2/3]:" , "" )
101+ switch choice {
102+ case "1" :
103+ mode = "shell-function"
104+ case "2" :
105+ mode = "path-shim"
106+ case "3" :
107+ mode = "none"
108+ default :
109+ fmt .Fprintln (out , "Skipped. Run 'ghapp auth configure' to set up later." )
110+ return nil
111+ }
112+ }
80113 }
81114
82- // Configure git credential helper
115+ // --- Execute all steps ---
116+
117+ // 1. Git credential helper
83118 gitHelper := fmt .Sprintf ("!%s credential-helper" , helperCmd )
84119 gitCmd := exec .Command ("git" , "config" , "--global" , "credential.https://github.com.helper" , gitHelper )
85120 if output , err := gitCmd .CombinedOutput (); err != nil {
86121 return fmt .Errorf ("git config: %s: %w" , strings .TrimSpace (string (output )), err )
87122 }
88123 fmt .Fprintln (out , "Git credential helper configured." )
89124
90- // Configure gh CLI (hosts.yml as baseline)
125+ // 2. gh CLI (hosts.yml as baseline)
91126 if err := configureGhHosts (); err != nil {
92127 fmt .Fprintf (out , "Warning: could not configure gh CLI: %v\n " , err )
93128 fmt .Fprintln (out , "Use: export GH_TOKEN=$(ghapp token)" )
94129 } else {
95130 fmt .Fprintln (out , "gh CLI configured." )
96131 }
97132
98- // Configure git identity as the app bot
99- if err := configureGitIdentity (cmd ); err != nil {
100- fmt .Fprintf (out , "Warning: could not configure git identity: %v\n " , err )
133+ // 3. Git identity
134+ if identityErr != nil {
135+ fmt .Fprintf (out , "Warning: could not configure git identity: %v\n " , identityErr )
136+ } else {
137+ if err := configureGitIdentity (cmd , slug , botUserID ); err != nil {
138+ fmt .Fprintf (out , "Warning: could not configure git identity: %v\n " , err )
139+ }
101140 }
102141
103- // Rewrite git@github.com SSH URLs to HTTPS
142+ // 4. SSH-to- HTTPS URL rewrite
104143 configureInsteadOf (cmd )
105144
106- // gh CLI dynamic auth setup
107- if err := configureGhAuth (cmd , helperCmd ); err != nil {
108- fmt .Fprintf (out , "Warning: gh dynamic auth: %v\n " , err )
109- }
110-
111- return nil
112- }
113-
114- // configureGhAuth handles the interactive gh auth mode selection.
115- func configureGhAuth (cmd * cobra.Command , ghappBin string ) error {
116- out := cmd .OutOrStdout ()
117-
118- mode := ghAuthFlag
119- if mode == "" {
120- // Check if interactive
121- if ! isInteractive (cmd ) {
122- fmt .Fprintln (out )
123- fmt .Fprintln (out , "Note: gh hosts.yml token expires in ~1hr." )
124- fmt .Fprintln (out , "For long sessions, use: export GH_TOKEN=$(ghapp token)" )
125- return nil
126- }
127-
128- fmt .Fprintln (out )
129- fmt .Fprintln (out , "How would you like to authenticate gh CLI commands?" )
130- fmt .Fprintln (out , " 1. Shell function (recommended) — auto-refreshes token per invocation" )
131- fmt .Fprintln (out , " 2. PATH binary — wrapper binary that injects token" )
132- fmt .Fprintln (out , " 3. None — keep hosts.yml only (token expires in ~1hr)" )
133- fmt .Fprintln (out )
134-
135- choice := promptChoice (cmd , "Choice [1/2/3]" , "1" )
136- switch choice {
137- case "1" :
138- mode = "shell-function"
139- case "2" :
140- mode = "path-shim"
141- default :
142- mode = "none"
143- }
144- }
145-
145+ // 5. gh CLI dynamic auth
146146 switch mode {
147147 case "shell-function" :
148- return configureShellFunction (cmd , ghappBin )
148+ if err := configureShellFunction (cmd , helperCmd ); err != nil {
149+ fmt .Fprintf (out , "Warning: gh dynamic auth: %v\n " , err )
150+ }
149151 case "path-shim" :
150- return configurePathShim (cmd , ghappBin )
152+ if err := configurePathShim (cmd , helperCmd ); err != nil {
153+ fmt .Fprintf (out , "Warning: gh dynamic auth: %v\n " , err )
154+ }
151155 case "none" :
152156 fmt .Fprintln (out )
153157 fmt .Fprintln (out , "Note: gh hosts.yml token expires in ~1hr." )
154158 fmt .Fprintln (out , "For long sessions, use: export GH_TOKEN=$(ghapp token)" )
155- return nil
156- default :
157- return fmt .Errorf ("unknown --gh-auth mode: %s" , mode )
158159 }
160+
161+ return nil
159162}
160163
164+
161165func configureShellFunction (cmd * cobra.Command , ghappBin string ) error {
162166 out := cmd .OutOrStdout ()
163167
@@ -427,11 +431,6 @@ func runAuthStatus(cmd *cobra.Command, args []string) error {
427431func runAuthReset (cmd * cobra.Command , args []string ) error {
428432 out := cmd .OutOrStdout ()
429433
430- if ! confirm (cmd , "Remove git credential helper and gh auth config?" ) {
431- fmt .Fprintln (out , "Aborted." )
432- return nil
433- }
434-
435434 // Remove git credential helper
436435 gitCmd := exec .Command ("git" , "config" , "--global" , "--unset" , "credential.https://github.com.helper" )
437436 if output , err := gitCmd .CombinedOutput (); err != nil {
@@ -562,31 +561,18 @@ func confirm(cmd *cobra.Command, prompt string) bool {
562561
563562// git identity management
564563
565- func configureGitIdentity (cmd * cobra.Command ) error {
564+ func configureGitIdentity (cmd * cobra.Command , slug string , botUserID int64 ) error {
566565 out := cmd .OutOrStdout ()
567566
568- // Fetch app slug + bot user ID (or use cached values)
569- slug , botUserID , err := resolveAppIdentity ()
570- if err != nil {
571- return err
572- }
573-
574567 botName := fmt .Sprintf ("%s[bot]" , slug )
575568 botEmail := fmt .Sprintf ("%d+%s[bot]@users.noreply.github.com" , botUserID , slug )
576569
577- // Check existing git identity
570+ // Backup existing identity if present
578571 existingName := gitConfigGet ("user.name" )
579572 existingEmail := gitConfigGet ("user.email" )
580-
581573 if existingName != "" || existingEmail != "" {
582- fmt .Fprintf (out , "\n Git identity already set as %q <%s>.\n " , existingName , existingEmail )
583- if ! confirm (cmd , "Switch to app bot identity?" ) {
584- return nil
585- }
586- // Backup previous identity
587574 cfg .PrevGitUserName = existingName
588575 cfg .PrevGitUserEmail = existingEmail
589- fmt .Fprintln (out , "Previous identity saved — will be restored on 'ghapp auth reset'." )
590576 }
591577
592578 // Set bot identity
0 commit comments