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
10 changes: 9 additions & 1 deletion pkg/cli/ci.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package cli

import "os"
import (
"os"

"github.com/githubnext/gh-aw/pkg/logger"
)

var ciLog = logger.New("cli:ci")

// IsRunningInCI checks if we're running in a CI environment
func IsRunningInCI() bool {
Expand All @@ -13,8 +19,10 @@ func IsRunningInCI() bool {

for _, v := range ciVars {
if os.Getenv(v) != "" {
ciLog.Printf("CI environment detected via %s", v)
return true
}
}
ciLog.Print("No CI environment detected")
return false
}
13 changes: 13 additions & 0 deletions pkg/cli/compile_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ package cli

import (
"regexp"

"github.com/githubnext/gh-aw/pkg/logger"
)

var compileConfigLog = logger.New("cli:compile_config")

// CompileConfig holds configuration options for compiling workflows
type CompileConfig struct {
MarkdownFiles []string // Files to compile (empty for all files)
Expand Down Expand Up @@ -105,18 +109,25 @@ func sanitizeErrorMessage(message string) string {
return message
}

compileConfigLog.Printf("Sanitizing error message: length=%d", len(message))

// Redact uppercase snake_case patterns (e.g., MY_SECRET_KEY, API_TOKEN)
sanitized := secretNamePattern.ReplaceAllStringFunc(message, func(match string) string {
// Don't redact common workflow keywords
if commonWorkflowKeywords[match] {
return match
}
compileConfigLog.Printf("Redacted snake_case secret pattern: %s", match)
return "[REDACTED]"
})

// Redact PascalCase patterns ending with security suffixes (e.g., GitHubToken, ApiKey)
sanitized = pascalCaseSecretPattern.ReplaceAllString(sanitized, "[REDACTED]")

if sanitized != message {
compileConfigLog.Print("Error message sanitization applied redactions")
}

return sanitized
}

Expand All @@ -129,6 +140,8 @@ func sanitizeValidationResults(results []ValidationResult) []ValidationResult {
return nil
}

compileConfigLog.Printf("Sanitizing validation results: workflow_count=%d", len(results))

sanitized := make([]ValidationResult, len(results))
for i, result := range results {
sanitized[i] = ValidationResult{
Expand Down
7 changes: 7 additions & 0 deletions pkg/cli/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ package cli
import (
"os"
"strings"

"github.com/githubnext/gh-aw/pkg/logger"
)

var githubLog = logger.New("cli:github")

// getGitHubHost returns the GitHub host URL from environment variables.
// It checks GITHUB_SERVER_URL first (GitHub Actions standard),
// then falls back to GH_HOST (gh CLI standard),
Expand All @@ -16,6 +20,9 @@ func getGitHubHost() string {
}
if host == "" {
host = "https://github.com"
githubLog.Print("Using default GitHub host: https://github.com")
} else {
githubLog.Printf("Resolved GitHub host: %s", host)
}

// Remove trailing slash for consistency
Expand Down
14 changes: 14 additions & 0 deletions pkg/cli/logs_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ import (

"github.com/githubnext/gh-aw/pkg/console"
"github.com/githubnext/gh-aw/pkg/constants"
"github.com/githubnext/gh-aw/pkg/logger"
"github.com/githubnext/gh-aw/pkg/workflow"
"github.com/spf13/cobra"
)

var logsCommandLog = logger.New("cli:logs_command")

// NewLogsCommand creates the logs command
func NewLogsCommand() *cobra.Command {
logsCmd := &cobra.Command{
Expand Down Expand Up @@ -102,8 +105,12 @@ Examples:
` + constants.CLIExtensionPrefix + ` logs --parse --json # Generate both Markdown and JSON
` + constants.CLIExtensionPrefix + ` logs weekly-research --repo owner/repo # Download logs from specific repository`,
RunE: func(cmd *cobra.Command, args []string) error {
logsCommandLog.Printf("Starting logs command: args=%d", len(args))

var workflowName string
if len(args) > 0 && args[0] != "" {
logsCommandLog.Printf("Resolving workflow name from argument: %s", args[0])

// Convert workflow ID to GitHub Actions workflow name
// First try to resolve as a workflow ID
resolvedName, err := workflow.ResolveWorkflowName(args[0])
Expand Down Expand Up @@ -161,29 +168,36 @@ Examples:
// Resolve relative dates to absolute dates for GitHub CLI
now := time.Now()
if startDate != "" {
logsCommandLog.Printf("Resolving start date: %s", startDate)
resolvedStartDate, err := workflow.ResolveRelativeDate(startDate, now)
if err != nil {
return fmt.Errorf("invalid start-date format '%s': %v", startDate, err)
}
startDate = resolvedStartDate
logsCommandLog.Printf("Resolved start date to: %s", startDate)
}
if endDate != "" {
logsCommandLog.Printf("Resolving end date: %s", endDate)
resolvedEndDate, err := workflow.ResolveRelativeDate(endDate, now)
if err != nil {
return fmt.Errorf("invalid end-date format '%s': %v", endDate, err)
}
endDate = resolvedEndDate
logsCommandLog.Printf("Resolved end date to: %s", endDate)
}

// Validate engine parameter using the engine registry
if engine != "" {
logsCommandLog.Printf("Validating engine parameter: %s", engine)
registry := workflow.GetGlobalEngineRegistry()
if !registry.IsValidEngine(engine) {
supportedEngines := registry.GetSupportedEngines()
return fmt.Errorf("invalid engine value '%s'. Must be one of: %s", engine, strings.Join(supportedEngines, ", "))
}
}

logsCommandLog.Printf("Executing logs download: workflow=%s, count=%d, engine=%s", workflowName, count, engine)

return DownloadWorkflowLogs(workflowName, count, startDate, endDate, outputDir, engine, ref, beforeRunID, afterRunID, repoOverride, verbose, toolGraph, noStaged, firewallOnly, noFirewall, parse, jsonOutput, timeout, campaignOnly, summaryFile)
},
}
Expand Down
8 changes: 8 additions & 0 deletions pkg/cli/logs_display.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,21 @@ import (
"time"

"github.com/githubnext/gh-aw/pkg/console"
"github.com/githubnext/gh-aw/pkg/logger"
"github.com/githubnext/gh-aw/pkg/timeutil"
)

var logsDisplayLog = logger.New("cli:logs_display")

// displayLogsOverview displays a summary table of workflow runs and metrics
func displayLogsOverview(processedRuns []ProcessedRun, verbose bool) {
if len(processedRuns) == 0 {
logsDisplayLog.Print("No processed runs to display")
return
}

logsDisplayLog.Printf("Displaying logs overview: runs=%d, verbose=%v", len(processedRuns), verbose)

// Prepare table data
headers := []string{"Run ID", "Workflow", "Status", "Duration", "Tokens", "Cost ($)", "Turns", "Errors", "Warnings", "Missing", "Noops", "Created", "Logs Path"}
var rows [][]string
Expand Down Expand Up @@ -176,5 +182,7 @@ func displayLogsOverview(processedRuns []ProcessedRun, verbose bool) {
TotalRow: totalRow,
}

logsDisplayLog.Printf("Rendering table: total_tokens=%d, total_cost=%.3f, total_duration=%s", totalTokens, totalCost, totalDuration)

fmt.Print(console.RenderTable(tableConfig))
}