Skip to content

Commit fccb7d7

Browse files
Add debug logging to 5 additional Go files (#4037)
1 parent 0009250 commit fccb7d7

5 files changed

Lines changed: 86 additions & 1 deletion

File tree

pkg/cli/update_command.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,14 @@ import (
1010

1111
"github.com/githubnext/gh-aw/pkg/console"
1212
"github.com/githubnext/gh-aw/pkg/constants"
13+
"github.com/githubnext/gh-aw/pkg/logger"
1314
"github.com/githubnext/gh-aw/pkg/parser"
1415
"github.com/githubnext/gh-aw/pkg/workflow"
1516
"github.com/spf13/cobra"
1617
)
1718

19+
var updateLog = logger.New("cli:update_command")
20+
1821
// NewUpdateCommand creates the update command
1922
func NewUpdateCommand(validateEngine func(string) error) *cobra.Command {
2023
cmd := &cobra.Command{
@@ -118,6 +121,8 @@ func checkExtensionUpdate(verbose bool) error {
118121
// 2. Update workflows from source repositories (compiles each workflow after update)
119122
// 3. Optionally create a PR
120123
func UpdateWorkflowsWithExtensionCheck(workflowNames []string, allowMajor, force, verbose bool, engineOverride string, createPR bool, workflowsDir string, noStopAfter bool, stopAfter string) error {
124+
updateLog.Printf("Starting update process: workflows=%v, allowMajor=%v, force=%v, createPR=%v", workflowNames, allowMajor, force, createPR)
125+
121126
// Step 1: Check for gh-aw extension updates
122127
if err := checkExtensionUpdate(verbose); err != nil {
123128
return fmt.Errorf("extension update check failed: %w", err)
@@ -224,6 +229,8 @@ func createUpdatePR(verbose bool) error {
224229

225230
// UpdateWorkflows updates workflows from their source repositories
226231
func UpdateWorkflows(workflowNames []string, allowMajor, force, verbose bool, engineOverride string, workflowsDir string, noStopAfter bool, stopAfter string) error {
232+
updateLog.Printf("Scanning for workflows with source field: dir=%s, filter=%v", workflowsDir, workflowNames)
233+
227234
// Use provided workflows directory or default
228235
if workflowsDir == "" {
229236
workflowsDir = getWorkflowsDir()
@@ -235,6 +242,8 @@ func UpdateWorkflows(workflowNames []string, allowMajor, force, verbose bool, en
235242
return err
236243
}
237244

245+
updateLog.Printf("Found %d workflows with source field", len(workflows))
246+
238247
if len(workflows) == 0 {
239248
if len(workflowNames) > 0 {
240249
return fmt.Errorf("no workflows found matching the specified names with source field")
@@ -394,12 +403,15 @@ func findWorkflowsWithSource(workflowsDir string, filterNames []string, verbose
394403

395404
// resolveLatestRef resolves the latest ref for a workflow source
396405
func resolveLatestRef(repo, currentRef string, allowMajor, verbose bool) (string, error) {
406+
updateLog.Printf("Resolving latest ref: repo=%s, currentRef=%s, allowMajor=%v", repo, currentRef, allowMajor)
407+
397408
if verbose {
398409
fmt.Fprintln(os.Stderr, console.FormatVerboseMessage(fmt.Sprintf("Resolving latest ref for %s (current: %s)", repo, currentRef)))
399410
}
400411

401412
// Check if current ref is a tag (looks like a semantic version)
402413
if isSemanticVersionTag(currentRef) {
414+
updateLog.Print("Current ref is semantic version tag, resolving latest release")
403415
return resolveLatestRelease(repo, currentRef, allowMajor, verbose)
404416
}
405417

@@ -414,10 +426,12 @@ func resolveLatestRef(repo, currentRef string, allowMajor, verbose bool) (string
414426
}
415427

416428
if isBranch {
429+
updateLog.Printf("Current ref is branch: %s", currentRef)
417430
return resolveBranchHead(repo, currentRef, verbose)
418431
}
419432

420433
// Otherwise, use default branch
434+
updateLog.Print("Using default branch for ref resolution")
421435
return resolveDefaultBranchHead(repo, verbose)
422436
}
423437

@@ -546,6 +560,8 @@ func resolveDefaultBranchHead(repo string, verbose bool) (string, error) {
546560

547561
// updateWorkflow updates a single workflow from its source
548562
func updateWorkflow(wf *workflowWithSource, allowMajor, force, verbose bool, engineOverride string, noStopAfter bool, stopAfter string) error {
563+
updateLog.Printf("Updating workflow: name=%s, source=%s, force=%v", wf.Name, wf.SourceSpec, force)
564+
549565
if verbose {
550566
fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("\nUpdating workflow: %s", wf.Name)))
551567
fmt.Fprintln(os.Stderr, console.FormatVerboseMessage(fmt.Sprintf("Source: %s", wf.SourceSpec)))
@@ -554,6 +570,7 @@ func updateWorkflow(wf *workflowWithSource, allowMajor, force, verbose bool, eng
554570
// Parse source spec
555571
sourceSpec, err := parseSourceSpec(wf.SourceSpec)
556572
if err != nil {
573+
updateLog.Printf("Failed to parse source spec: %v", err)
557574
return fmt.Errorf("failed to parse source spec: %w", err)
558575
}
559576

@@ -576,6 +593,8 @@ func updateWorkflow(wf *workflowWithSource, allowMajor, force, verbose bool, eng
576593

577594
// Check if update is needed
578595
if !force && currentRef == latestRef {
596+
updateLog.Printf("Workflow already at latest ref: %s, checking for local modifications", currentRef)
597+
579598
// Download the source content to check if local file has been modified
580599
sourceContent, err := downloadWorkflowContent(sourceSpec.Repo, sourceSpec.Path, currentRef, verbose)
581600
if err != nil {
@@ -595,11 +614,13 @@ func updateWorkflow(wf *workflowWithSource, allowMajor, force, verbose bool, eng
595614

596615
// Check if local file differs from source
597616
if hasLocalModifications(string(sourceContent), string(currentContent), wf.SourceSpec, verbose) {
617+
updateLog.Printf("Local modifications detected in workflow: %s", wf.Name)
598618
fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("Workflow %s is already up to date (%s)", wf.Name, currentRef)))
599619
fmt.Fprintln(os.Stderr, console.FormatWarningMessage(fmt.Sprintf("⚠️ Local copy of %s has been modified from source", wf.Name)))
600620
return nil
601621
}
602622

623+
updateLog.Printf("Workflow %s is up to date with no local modifications", wf.Name)
603624
fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf("Workflow %s is already up to date (%s)", wf.Name, currentRef)))
604625
return nil
605626
}
@@ -631,11 +652,17 @@ func updateWorkflow(wf *workflowWithSource, allowMajor, force, verbose bool, eng
631652
}
632653

633654
// Perform 3-way merge using git merge-file
655+
updateLog.Printf("Performing 3-way merge for workflow: %s", wf.Name)
634656
mergedContent, hasConflicts, err := MergeWorkflowContent(string(baseContent), string(currentContent), string(newContent), wf.SourceSpec, latestRef, verbose)
635657
if err != nil {
658+
updateLog.Printf("Merge failed for workflow %s: %v", wf.Name, err)
636659
return fmt.Errorf("failed to merge workflow content: %w", err)
637660
}
638661

662+
if hasConflicts {
663+
updateLog.Printf("Merge conflicts detected in workflow: %s", wf.Name)
664+
}
665+
639666
// Handle stop-after field modifications
640667
if noStopAfter {
641668
// Remove stop-after field if requested
@@ -675,10 +702,13 @@ func updateWorkflow(wf *workflowWithSource, allowMajor, force, verbose bool, eng
675702
return nil // Not an error, but user needs to resolve conflicts
676703
}
677704

705+
updateLog.Printf("Successfully updated workflow %s from %s to %s", wf.Name, currentRef, latestRef)
678706
fmt.Fprintln(os.Stderr, console.FormatSuccessMessage(fmt.Sprintf("Updated %s from %s to %s", wf.Name, currentRef, latestRef)))
679707

680708
// Compile the updated workflow with refreshStopTime enabled
709+
updateLog.Printf("Compiling updated workflow: %s", wf.Name)
681710
if err := compileWorkflowWithRefresh(wf.Path, verbose, engineOverride, true); err != nil {
711+
updateLog.Printf("Compilation failed for workflow %s: %v", wf.Name, err)
682712
return fmt.Errorf("failed to compile updated workflow: %w", err)
683713
}
684714

pkg/parser/github_urls.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ import (
66
"path/filepath"
77
"strconv"
88
"strings"
9+
10+
"github.com/githubnext/gh-aw/pkg/logger"
911
)
1012

13+
var urlLog = logger.New("parser:github_urls")
14+
1115
// GitHubURLType represents the type of GitHub URL
1216
type GitHubURLType string
1317

@@ -45,9 +49,11 @@ type GitHubURLComponents struct {
4549
// - Raw content: https://raw.githubusercontent.com/owner/repo/main/path/to/file.md
4650
// - Enterprise URLs: https://github.example.com/owner/repo/...
4751
func ParseGitHubURL(urlStr string) (*GitHubURLComponents, error) {
52+
urlLog.Printf("Parsing GitHub URL: %s", urlStr)
4853
// Parse the URL
4954
parsedURL, err := url.Parse(urlStr)
5055
if err != nil {
56+
urlLog.Printf("Failed to parse URL: %v", err)
5157
return nil, fmt.Errorf("invalid URL: %w", err)
5258
}
5359

@@ -57,8 +63,11 @@ func ParseGitHubURL(urlStr string) (*GitHubURLComponents, error) {
5763
return nil, fmt.Errorf("URL must include a host")
5864
}
5965

66+
urlLog.Printf("Detected host: %s", host)
67+
6068
// Handle raw.githubusercontent.com specially
6169
if host == "raw.githubusercontent.com" {
70+
urlLog.Print("Detected raw.githubusercontent.com URL")
6271
return parseRawGitHubContentURL(parsedURL)
6372
}
6473

@@ -81,23 +90,27 @@ func ParseGitHubURL(urlStr string) (*GitHubURLComponents, error) {
8190
// Determine the type based on path structure
8291
if len(pathParts) >= 4 {
8392
urlType := pathParts[2]
93+
urlLog.Printf("Detected URL type segment: %s for %s/%s", urlType, owner, repo)
8494

8595
switch urlType {
8696
case "actions":
8797
// Pattern: /owner/repo/actions/runs/12345678
8898
if len(pathParts) >= 5 && pathParts[3] == "runs" {
99+
urlLog.Print("Parsing GitHub Actions run URL")
89100
return parseRunURL(host, owner, repo, pathParts[4:])
90101
}
91102

92103
case "runs":
93104
// Pattern: /owner/repo/runs/12345678 (short form)
94105
if len(pathParts) >= 4 {
106+
urlLog.Print("Parsing GitHub Actions run URL (short form)")
95107
return parseRunURL(host, owner, repo, pathParts[3:])
96108
}
97109

98110
case "pull":
99111
// Pattern: /owner/repo/pull/123
100112
if len(pathParts) >= 4 {
113+
urlLog.Print("Parsing pull request URL")
101114
prNumber, err := strconv.ParseInt(pathParts[3], 10, 64)
102115
if err != nil {
103116
return nil, fmt.Errorf("invalid PR number: %s", pathParts[3])
@@ -130,6 +143,7 @@ func ParseGitHubURL(urlStr string) (*GitHubURLComponents, error) {
130143
case "blob", "tree", "raw":
131144
// Pattern: /owner/repo/{blob|tree|raw}/ref/path/to/file
132145
if len(pathParts) >= 5 {
146+
urlLog.Printf("Parsing file URL (type=%s)", urlType)
133147
ref := pathParts[3]
134148
filePath := strings.Join(pathParts[4:], "/")
135149

@@ -143,6 +157,7 @@ func ParseGitHubURL(urlStr string) (*GitHubURLComponents, error) {
143157
urlTypeEnum = URLTypeRaw
144158
}
145159

160+
urlLog.Printf("Parsed file URL: ref=%s, path=%s", ref, filePath)
146161
return &GitHubURLComponents{
147162
Host: host,
148163
Owner: owner,

pkg/parser/mcp.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ func ExtractMCPConfigurations(frontmatter map[string]any, serverFilter string) (
9696

9797
// Check for safe-outputs configuration first (built-in MCP)
9898
if safeOutputsSection, hasSafeOutputs := frontmatter["safe-outputs"]; hasSafeOutputs {
99+
mcpLog.Print("Found safe-outputs configuration")
99100
// Apply server filter if specified
100101
if serverFilter == "" || strings.Contains(constants.SafeOutputsMCPServerID, strings.ToLower(serverFilter)) {
101102
config := MCPServerConfig{
@@ -142,6 +143,7 @@ func ExtractMCPConfigurations(frontmatter map[string]any, serverFilter string) (
142143

143144
// Check for top-level safe-jobs configuration
144145
if safeJobsSection, hasSafeJobs := frontmatter["safe-jobs"]; hasSafeJobs {
146+
mcpLog.Print("Found safe-jobs configuration")
145147
// Apply server filter if specified
146148
if serverFilter == "" || strings.Contains(constants.SafeOutputsMCPServerID, strings.ToLower(serverFilter)) {
147149
// Find existing safe-outputs config or create new one
@@ -176,6 +178,7 @@ func ExtractMCPConfigurations(frontmatter map[string]any, serverFilter string) (
176178
// Get mcp-servers section from frontmatter
177179
mcpServersSection, hasMCPServers := frontmatter["mcp-servers"]
178180
if !hasMCPServers {
181+
mcpLog.Print("No mcp-servers section found, checking for built-in tools")
179182
// Also check tools section for built-in MCP tools (github, playwright)
180183
toolsSection, hasTools := frontmatter["tools"]
181184
if hasTools {
@@ -188,12 +191,14 @@ func ExtractMCPConfigurations(frontmatter map[string]any, serverFilter string) (
188191
return nil, err
189192
}
190193
if config != nil {
194+
mcpLog.Printf("Added built-in MCP tool: %s", toolName)
191195
configs = append(configs, *config)
192196
}
193197
}
194198
}
195199
}
196200
}
201+
mcpLog.Printf("Extracted %d MCP configurations total", len(configs))
197202
return configs, nil // No mcp-servers configured, but we might have safe-outputs and built-in tools
198203
}
199204

@@ -222,6 +227,7 @@ func ExtractMCPConfigurations(frontmatter map[string]any, serverFilter string) (
222227
}
223228

224229
// Process custom MCP servers from mcp-servers section
230+
mcpLog.Printf("Processing %d custom MCP servers", len(mcpServers))
225231
for serverName, serverValue := range mcpServers {
226232
// Apply server filter if specified
227233
if serverFilter != "" && !strings.Contains(strings.ToLower(serverName), strings.ToLower(serverFilter)) {
@@ -239,9 +245,11 @@ func ExtractMCPConfigurations(frontmatter map[string]any, serverFilter string) (
239245
return nil, fmt.Errorf("failed to parse MCP config for %s: %w", serverName, err)
240246
}
241247

248+
mcpLog.Printf("Parsed custom MCP server: %s (type=%s)", serverName, config.Type)
242249
configs = append(configs, config)
243250
}
244251

252+
mcpLog.Printf("Extracted %d MCP configurations total", len(configs))
245253
return configs, nil
246254
}
247255

@@ -512,10 +520,13 @@ func ParseMCPConfig(toolName string, mcpSection any, toolConfig map[string]any)
512520
// Infer type from presence of fields
513521
if _, hasURL := mcpConfig["url"]; hasURL {
514522
config.Type = "http"
523+
mcpLog.Printf("Inferred MCP type 'http' for tool %s based on url field", toolName)
515524
} else if _, hasCommand := mcpConfig["command"]; hasCommand {
516525
config.Type = "stdio"
526+
mcpLog.Printf("Inferred MCP type 'stdio' for tool %s based on command field", toolName)
517527
} else if _, hasContainer := mcpConfig["container"]; hasContainer {
518528
config.Type = "stdio"
529+
mcpLog.Printf("Inferred MCP type 'stdio' for tool %s based on container field", toolName)
519530
} else {
520531
return config, fmt.Errorf("unable to determine MCP type for tool '%s': missing type, url, command, or container", toolName)
521532
}
@@ -531,11 +542,13 @@ func ParseMCPConfig(toolName string, mcpSection any, toolConfig map[string]any)
531542
}
532543

533544
// Extract configuration based on type
545+
mcpLog.Printf("Extracting %s configuration for tool: %s", config.Type, toolName)
534546
switch config.Type {
535547
case "stdio":
536548
// Handle container field (simplified Docker run)
537549
if container, hasContainer := mcpConfig["container"]; hasContainer {
538550
if containerStr, ok := container.(string); ok {
551+
mcpLog.Printf("Tool %s uses container: %s", toolName, containerStr)
539552
config.Container = containerStr
540553
config.Command = "docker"
541554
config.Args = []string{"run", "--rm", "-i"}

pkg/workflow/threat_detection.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ import (
66
"strings"
77

88
"github.com/githubnext/gh-aw/pkg/constants"
9+
"github.com/githubnext/gh-aw/pkg/logger"
910
)
1011

12+
var threatLog = logger.New("workflow:threat_detection")
13+
1114
//go:embed templates/threat_detection.md
1215
var defaultThreatDetectionPrompt string
1316

@@ -22,12 +25,15 @@ type ThreatDetectionConfig struct {
2225
// parseThreatDetectionConfig handles threat-detection configuration
2326
func (c *Compiler) parseThreatDetectionConfig(outputMap map[string]any) *ThreatDetectionConfig {
2427
if configData, exists := outputMap["threat-detection"]; exists {
28+
threatLog.Print("Found threat-detection configuration")
2529
// Handle boolean values
2630
if boolVal, ok := configData.(bool); ok {
2731
if !boolVal {
32+
threatLog.Print("Threat detection explicitly disabled")
2833
// When explicitly disabled, return nil
2934
return nil
3035
}
36+
threatLog.Print("Threat detection enabled with default settings")
3137
// When enabled as boolean, return empty config
3238
return &ThreatDetectionConfig{}
3339
}
@@ -38,6 +44,7 @@ func (c *Compiler) parseThreatDetectionConfig(outputMap map[string]any) *ThreatD
3844
if enabled, exists := configMap["enabled"]; exists {
3945
if enabledBool, ok := enabled.(bool); ok {
4046
if !enabledBool {
47+
threatLog.Print("Threat detection disabled via enabled field")
4148
// When explicitly disabled, return nil
4249
return nil
4350
}
@@ -66,36 +73,43 @@ func (c *Compiler) parseThreatDetectionConfig(outputMap map[string]any) *ThreatD
6673
// Handle boolean false to disable AI engine
6774
if engineBool, ok := engine.(bool); ok {
6875
if !engineBool {
76+
threatLog.Print("Threat detection AI engine disabled")
6977
// engine: false means no AI engine steps
7078
threatConfig.EngineConfig = nil
7179
threatConfig.EngineDisabled = true
7280
}
7381
} else if engineStr, ok := engine.(string); ok {
82+
threatLog.Printf("Threat detection engine set to: %s", engineStr)
7483
// Handle string format
7584
threatConfig.EngineConfig = &EngineConfig{ID: engineStr}
7685
} else if engineObj, ok := engine.(map[string]any); ok {
86+
threatLog.Print("Parsing threat detection engine configuration")
7787
// Handle object format - use extractEngineConfig logic
7888
_, engineConfig := c.ExtractEngineConfig(map[string]any{"engine": engineObj})
7989
threatConfig.EngineConfig = engineConfig
8090
}
8191
}
8292

93+
threatLog.Printf("Threat detection configured with custom prompt: %v, custom steps: %v", threatConfig.Prompt != "", len(threatConfig.Steps) > 0)
8394
return threatConfig
8495
}
8596
}
8697

8798
// Default behavior: enabled if any safe-outputs are configured
99+
threatLog.Print("Using default threat detection configuration")
88100
return &ThreatDetectionConfig{}
89101
}
90102

91103
// buildThreatDetectionJob creates the detection job
92104
func (c *Compiler) buildThreatDetectionJob(data *WorkflowData, mainJobName string) (*Job, error) {
105+
threatLog.Printf("Building threat detection job for main job: %s", mainJobName)
93106
if data.SafeOutputs == nil || data.SafeOutputs.ThreatDetection == nil {
94107
return nil, fmt.Errorf("threat detection is not enabled")
95108
}
96109

97110
// Build steps using a more structured approach
98111
steps := c.buildThreatDetectionSteps(data, mainJobName)
112+
threatLog.Printf("Generated %d steps for threat detection job", len(steps))
99113

100114
// Generate agent concurrency configuration (same as main agent job)
101115
agentConcurrency := GenerateJobConcurrencyConfig(data)

0 commit comments

Comments
 (0)