diff --git a/pkg/cli/bootstrap_profile_actions_repo.go b/pkg/cli/bootstrap_profile_actions_repo.go index 2b5f081c9d6..c1972c80fc9 100644 --- a/pkg/cli/bootstrap_profile_actions_repo.go +++ b/pkg/cli/bootstrap_profile_actions_repo.go @@ -7,12 +7,17 @@ import ( "github.com/cli/go-gh/v2/pkg/api" "github.com/github/gh-aw/pkg/console" + "github.com/github/gh-aw/pkg/logger" "github.com/github/gh-aw/pkg/repoutil" "github.com/github/gh-aw/pkg/stringutil" ) +var bootstrapActionsRepoLog = logger.New("cli:bootstrap_profile_actions_repo") + func runBootstrapRepoVariableAction(ctx context.Context, repo string, action repositoryPackageBootstrapAction, state *bootstrapProfileExistingState) (bool, error) { + bootstrapActionsRepoLog.Printf("Running repo variable action: repo=%s, name=%s", repo, action.Name) if _, exists := state.variables[action.Name]; exists { + bootstrapActionsRepoLog.Printf("Skipping variable %s: already set on repo", action.Name) return false, nil } value, ok, err := resolveBootstrapTextValue(bootstrapRepositoryVariableEnvName(action.Name), action.Prompt, action.Description, action.Default, action.Enum, action.Optional) @@ -30,7 +35,9 @@ func runBootstrapRepoVariableAction(ctx context.Context, repo string, action rep } func runBootstrapRepoSecretAction(ctx context.Context, repo string, action repositoryPackageBootstrapAction, state *bootstrapProfileExistingState) (bool, error) { + bootstrapActionsRepoLog.Printf("Running repo secret action: repo=%s, name=%s", repo, action.Name) if _, exists := state.secrets[action.Name]; exists { + bootstrapActionsRepoLog.Printf("Skipping secret %s: already set on repo", action.Name) return false, nil } value, ok, err := resolveBootstrapSecretValue(bootstrapRepositorySecretEnvName(action.Name), action.Prompt, action.Description, action.Optional) @@ -48,7 +55,9 @@ func runBootstrapRepoSecretAction(ctx context.Context, repo string, action repos } func runBootstrapCopilotAuthAction(ctx context.Context, repo string, action repositoryPackageBootstrapAction, state *bootstrapProfileExistingState, usesActionsToken bool) (bool, error) { + bootstrapActionsRepoLog.Printf("Running Copilot auth action: repo=%s, usesActionsToken=%v", repo, usesActionsToken) if usesActionsToken { + bootstrapActionsRepoLog.Print("Skipping Copilot PAT setup: workflows already support Actions token auth") fmt.Fprintln(os.Stderr, console.FormatInfoMessage("Skipping Copilot PAT setup because selected workflows already support GitHub Actions token auth.")) return false, nil } diff --git a/pkg/cli/bootstrap_profile_git.go b/pkg/cli/bootstrap_profile_git.go index 6e057c08ecd..f0459ab4d1a 100644 --- a/pkg/cli/bootstrap_profile_git.go +++ b/pkg/cli/bootstrap_profile_git.go @@ -9,10 +9,15 @@ import ( "strings" "github.com/github/gh-aw/pkg/console" + "github.com/github/gh-aw/pkg/logger" ) +var bootstrapGitLog = logger.New("cli:bootstrap_profile_git") + func runBootstrapCommitAndPushAction(ctx context.Context, repoDir string, action repositoryPackageBootstrapAction) error { + bootstrapGitLog.Printf("Running commit-and-push action: repoDir=%q", repoDir) if repoDir == "" { + bootstrapGitLog.Print("Rejecting commit-and-push: no local checkout directory provided") return errors.New("bootstrap commit-and-push requires a local checkout directory. Example: rerun from a git checkout and then rerun gh aw add from that checkout") } @@ -21,6 +26,7 @@ func runBootstrapCommitAndPushAction(ctx context.Context, repoDir string, action return err } if !pending { + bootstrapGitLog.Print("Skipping commit-and-push: local checkout is already clean") fmt.Fprintln(os.Stderr, console.FormatInfoMessage("Skipping commit and push because the local checkout is already clean.")) return nil } @@ -35,10 +41,12 @@ func runBootstrapCommitAndPushAction(ctx context.Context, repoDir string, action if err != nil { return fmt.Errorf("failed to determine current branch for bootstrap commit-and-push: %w", err) } + bootstrapGitLog.Printf("Pushing bootstrap changes to origin: branch=%s", branch) if _, err := runBootstrapGitCommand(ctx, repoDir, "push", "-u", "origin", branch); err != nil { return err } + bootstrapGitLog.Print("Committed and pushed bootstrap changes successfully") fmt.Fprintln(os.Stderr, console.FormatSuccessMessage("Committed and pushed bootstrap changes")) return nil } @@ -52,6 +60,7 @@ func bootstrapRepoHasPendingChanges(ctx context.Context, repoDir string) (bool, } func runBootstrapGitCommand(ctx context.Context, repoDir string, args ...string) ([]byte, error) { + bootstrapGitLog.Printf("Running git command in %s: git %s", repoDir, strings.Join(args, " ")) cmd := exec.CommandContext(ctx, "git", args...) cmd.Dir = repoDir output, err := cmd.CombinedOutput() diff --git a/pkg/cli/bootstrap_profile_helpers.go b/pkg/cli/bootstrap_profile_helpers.go index 7e329057fbd..6a9417867e0 100644 --- a/pkg/cli/bootstrap_profile_helpers.go +++ b/pkg/cli/bootstrap_profile_helpers.go @@ -18,12 +18,15 @@ import ( "charm.land/huh/v2" "github.com/github/gh-aw/pkg/console" + "github.com/github/gh-aw/pkg/logger" "github.com/github/gh-aw/pkg/parser" "github.com/github/gh-aw/pkg/repoutil" "github.com/github/gh-aw/pkg/tty" "github.com/github/gh-aw/pkg/workflow" ) +var bootstrapProfileHelpersLog = logger.New("cli:bootstrap_profile_helpers") + func runBootstrapRequireOwnerType(ctx context.Context, repo string, action repositoryPackageBootstrapAction) error { owner, _, err := repoutil.SplitRepoSlug(repo) if err != nil { @@ -69,13 +72,16 @@ func parseBootstrapNames(output []byte) []string { } func resolveBootstrapTextValue(envName, title, description, defaultValue string, allowed []string, optional bool) (string, bool, error) { + bootstrapProfileHelpersLog.Printf("Resolving text value: env=%s, optional=%v, hasDefault=%v", envName, optional, defaultValue != "") if envValue := strings.TrimSpace(os.Getenv(envName)); envValue != "" { + bootstrapProfileHelpersLog.Printf("Resolved %s from environment variable", envName) if err := validateBootstrapEnumValue(envValue, allowed, optional); err != nil { return "", false, err } return envValue, true, nil } if !tty.IsStderrTerminal() { + bootstrapProfileHelpersLog.Printf("Resolving %s non-interactively (stderr is not a terminal)", envName) if defaultValue != "" { if err := validateBootstrapEnumValue(defaultValue, allowed, optional); err != nil { return "", false, err @@ -321,6 +327,7 @@ func htmlEscape(value string) string { } func openBootstrapBrowser(url string) bool { + bootstrapProfileHelpersLog.Printf("Opening browser for bootstrap URL: goos=%s", runtime.GOOS) commands := [][]string{{"gh", "browse", url}} switch runtime.GOOS { case "darwin": @@ -333,12 +340,14 @@ func openBootstrapBrowser(url string) bool { for _, args := range commands { cmd := exec.Command(args[0], args[1:]...) if err := cmd.Start(); err == nil { + bootstrapProfileHelpersLog.Printf("Launched browser via %q", args[0]) go func() { _ = cmd.Wait() }() return true } } + bootstrapProfileHelpersLog.Print("Failed to launch a browser: no launcher command succeeded") return false } diff --git a/pkg/console/timezone.go b/pkg/console/timezone.go index 546dd9e1e63..5765627d2d0 100644 --- a/pkg/console/timezone.go +++ b/pkg/console/timezone.go @@ -4,8 +4,12 @@ import ( "fmt" "sync" "time" + + "github.com/github/gh-aw/pkg/logger" ) +var timezoneLog = logger.New("console:timezone") + var ( timeLocationMu sync.RWMutex timeLocation *time.Location @@ -13,6 +17,7 @@ var ( // SetTimeLocation configures the location used when rendering time.Time values. func SetTimeLocation(location *time.Location) { + timezoneLog.Printf("Setting time location override: location=%v", location) timeLocationMu.Lock() defer timeLocationMu.Unlock() timeLocation = location @@ -35,6 +40,7 @@ func formatConfiguredTimeValue(timeVal time.Time) string { return timeVal.Format("2006-01-02 15:04:05") } + timezoneLog.Printf("Formatting time value in configured location: %v", location) localTime := timeVal.In(location) _, offsetSeconds := localTime.Zone() return fmt.Sprintf("%s UTC%s", localTime.Format("2006-01-02 15:04:05"), formatUTCOffset(offsetSeconds)) diff --git a/pkg/workflow/compiler_yaml_line_writer.go b/pkg/workflow/compiler_yaml_line_writer.go index 3f343260b16..7c9c55b7147 100644 --- a/pkg/workflow/compiler_yaml_line_writer.go +++ b/pkg/workflow/compiler_yaml_line_writer.go @@ -1,6 +1,12 @@ package workflow -import "strings" +import ( + "strings" + + "github.com/github/gh-aw/pkg/logger" +) + +var yamlLineWriterLog = logger.New("workflow:compiler_yaml_line_writer") // yamlBlockScalarState tracks whether the scanner is currently inside a YAML // literal (|) or folded (>) block scalar. It is used by appendYAMLLine to @@ -39,6 +45,7 @@ func (s *yamlBlockScalarState) update(sourceLine string) bool { s.bodyIndent = lineIndent s.active = true s.pending = false + yamlLineWriterLog.Printf("Entering block scalar payload: headerIndent=%d, bodyIndent=%d", s.headerIndent, s.bodyIndent) return true // first payload line } } @@ -46,6 +53,7 @@ func (s *yamlBlockScalarState) update(sourceLine string) bool { if lineIndent < s.bodyIndent { // Outdented non-blank line: we have left the block scalar. s.active = false + yamlLineWriterLog.Printf("Leaving block scalar payload: lineIndent=%d < bodyIndent=%d", lineIndent, s.bodyIndent) // Fall through to structural handling below. } else { return true // still inside the block scalar @@ -58,6 +66,7 @@ func (s *yamlBlockScalarState) update(sourceLine string) bool { if headerIndent, ok := blockScalarHeaderIndentForLine(trimmed); ok { s.pending = true s.headerIndent = headerIndent + yamlLineWriterLog.Printf("Detected block scalar header: headerIndent=%d", headerIndent) } } return false