From 16a249f007852df2493a5110e5645ae5c06ec018 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 16 May 2026 04:39:44 +0000 Subject: [PATCH] Add debug logging to 5 workflow compiler files Adds strategic debug log calls at function entry, mode-selection branches, and previously unlogged exit paths to improve troubleshooting visibility during workflow compilation. Uses the existing shared package loggers (checkoutManagerLog, mcpRendererLog, maintenanceLog, strictModeValidationLog) so log namespaces stay coherent with neighbouring files. Files touched: - pkg/workflow/checkout_step_generator.go - pkg/workflow/mcp_renderer_github.go - pkg/workflow/side_repo_maintenance.go - pkg/workflow/strict_mode_network_validation.go - pkg/workflow/strict_mode_steps_validation.go Co-Authored-By: Claude Opus 4.7 (1M context) --- pkg/workflow/checkout_step_generator.go | 5 +++++ pkg/workflow/mcp_renderer_github.go | 5 +++++ pkg/workflow/side_repo_maintenance.go | 4 ++++ pkg/workflow/strict_mode_network_validation.go | 6 ++++++ pkg/workflow/strict_mode_steps_validation.go | 3 +++ 5 files changed, 23 insertions(+) diff --git a/pkg/workflow/checkout_step_generator.go b/pkg/workflow/checkout_step_generator.go index c70a7e79601..bbbfed0f5f5 100644 --- a/pkg/workflow/checkout_step_generator.go +++ b/pkg/workflow/checkout_step_generator.go @@ -11,6 +11,7 @@ import ( // If the repository already ends with ".wiki" it is returned unchanged to prevent double-suffixing. func wikiRepository(repository string) string { if repository == "" { + checkoutManagerLog.Print("Wiki checkout using default current repository") return "${{ github.repository }}.wiki" } if strings.HasSuffix(repository, ".wiki") { @@ -27,6 +28,7 @@ func wikiRepository(repository string) string { // The step ID for each checkout is "checkout-app-token-{index}" where index is // the position in the ordered checkout list. func (cm *CheckoutManager) GenerateCheckoutAppTokenSteps(c *Compiler, permissions *Permissions) []string { + checkoutManagerLog.Printf("Building app token minting steps for %d checkout entries", len(cm.ordered)) var steps []string for i, entry := range cm.ordered { if entry.githubApp == nil { @@ -54,6 +56,7 @@ func (cm *CheckoutManager) GenerateCheckoutAppTokenSteps(c *Compiler, permission // The tokens were minted in the agent job and are referenced via // steps.checkout-app-token-{index}.outputs.token. func (cm *CheckoutManager) GenerateCheckoutAppTokenInvalidationSteps(c *Compiler) []string { + checkoutManagerLog.Printf("Building app token invalidation steps for %d checkout entries", len(cm.ordered)) var steps []string for i, entry := range cm.ordered { if entry.githubApp == nil { @@ -320,8 +323,10 @@ func checkoutStepName(key checkoutKey) string { func fetchRefToRefspec(pattern string) string { switch pattern { case "*": + checkoutManagerLog.Print("Fetch refspec: wildcard expanded to all branches") return "+refs/heads/*:refs/remotes/origin/*" case "refs/pulls/open/*": + checkoutManagerLog.Print("Fetch refspec: open PRs pattern expanded") return "+refs/pull/*/head:refs/remotes/origin/pull/*/head" default: // Treat as branch name or glob: map to remote tracking ref diff --git a/pkg/workflow/mcp_renderer_github.go b/pkg/workflow/mcp_renderer_github.go index 5971fead2b6..2c8028ac5de 100644 --- a/pkg/workflow/mcp_renderer_github.go +++ b/pkg/workflow/mcp_renderer_github.go @@ -47,6 +47,7 @@ func (r *MCPConfigRendererUnified) RenderGitHubMCP(yaml *strings.Builder, github githubType, readOnly, lockdown, hasGitHubLockdownExplicitlySet(githubTool), shouldUseStepOutputForGuardPolicy, toolsets, r.options.Format) if r.options.Format == "toml" { + mcpRendererLog.Print("GitHub MCP format=toml, dispatching to renderGitHubTOML") r.renderGitHubTOML(yaml, githubTool, workflowData) return } @@ -55,6 +56,7 @@ func (r *MCPConfigRendererUnified) RenderGitHubMCP(yaml *strings.Builder, github // Check if remote mode is enabled (type: remote) if githubType == "remote" { + mcpRendererLog.Printf("GitHub MCP remote mode selected: copilot_fields=%t", r.options.IncludeCopilotFields) // Determine authorization value based on engine requirements // Copilot uses MCP passthrough syntax: "Bearer \${GITHUB_PERSONAL_ACCESS_TOKEN}" // Other engines use shell variable: "Bearer $GITHUB_MCP_SERVER_TOKEN" @@ -80,6 +82,8 @@ func (r *MCPConfigRendererUnified) RenderGitHubMCP(yaml *strings.Builder, github githubDockerImageVersion := getGitHubDockerImageVersion(githubTool) customArgs := getGitHubCustomArgs(githubTool) + mcpRendererLog.Printf("GitHub MCP local docker mode: image_version=%s, custom_args=%d", githubDockerImageVersion, len(customArgs)) + RenderGitHubMCPDockerConfig(yaml, GitHubMCPDockerOptions{ ReadOnly: readOnly, Lockdown: lockdown, @@ -149,6 +153,7 @@ func (r *MCPConfigRendererUnified) renderGitHubTOML(yaml *strings.Builder, githu // Check if remote mode is enabled if githubType == "remote" { + mcpRendererLog.Printf("GitHub MCP TOML remote mode: readonly_endpoint=%t", readOnly) // Remote mode - use hosted GitHub MCP server with streamable HTTP // Use readonly endpoint if read-only mode is enabled if readOnly { diff --git a/pkg/workflow/side_repo_maintenance.go b/pkg/workflow/side_repo_maintenance.go index 16f405bf5d9..4e16ecc0877 100644 --- a/pkg/workflow/side_repo_maintenance.go +++ b/pkg/workflow/side_repo_maintenance.go @@ -38,6 +38,7 @@ type SideRepoTarget struct { // preferred over an empty one so that the generated workflow uses the custom // token rather than falling back to GH_AW_GITHUB_TOKEN. func collectSideRepoTargets(workflowDataList []*WorkflowData) []SideRepoTarget { + maintenanceLog.Printf("Scanning %d workflows for side-repo targets", len(workflowDataList)) // Use a map to accumulate the best token seen for each slug. // Order slice preserves first-seen repository discovery order for stable output; // tokens may be upgraded to non-empty values from later occurrences. @@ -99,6 +100,7 @@ func generateAllSideRepoMaintenanceWorkflows( minExpiresDays int, ) error { targets := collectSideRepoTargets(workflowDataList) + maintenanceLog.Printf("Generating maintenance workflows for %d side-repo target(s): hasExpires=%t, minExpiresDays=%d", len(targets), hasExpires, minExpiresDays) // Track which side-repo maintenance files we (re-)generate so we can identify // and remove stale files from previous runs when target repos are renamed or removed. @@ -163,6 +165,7 @@ func generateSideRepoMaintenanceWorkflow( ) error { token := effectiveSideRepoToken(target) repoSlug := target.Repository + maintenanceLog.Printf("Building side-repo workflow content: repo=%s, actionMode=%s, hasExpires=%t", repoSlug, actionMode, hasExpires) var yaml strings.Builder @@ -243,6 +246,7 @@ jobs: // Add close-expired-entities job only when any workflow uses expires. if hasExpires { + maintenanceLog.Printf("Including close-expired-entities job for %s (cron=%s)", repoSlug, cronSchedule) closeExpiredCondition := buildNotForkAndScheduled() yaml.WriteString(` close-expired-entities: if: ${{ ` + RenderCondition(closeExpiredCondition) + ` }} diff --git a/pkg/workflow/strict_mode_network_validation.go b/pkg/workflow/strict_mode_network_validation.go index 4d883b02198..a01cc5679fc 100644 --- a/pkg/workflow/strict_mode_network_validation.go +++ b/pkg/workflow/strict_mode_network_validation.go @@ -45,16 +45,19 @@ func (c *Compiler) validateStrictMCPNetwork(frontmatter map[string]any, networkP // Check mcp-servers section (new format) mcpServersValue, exists := frontmatter["mcp-servers"] if !exists { + strictModeValidationLog.Print("No mcp-servers section, skipping MCP network validation") return nil } mcpServersMap, ok := mcpServersValue.(map[string]any) if !ok { + strictModeValidationLog.Print("mcp-servers is not a map, skipping MCP network validation") return nil } // Check if top-level network configuration exists hasTopLevelNetwork := networkPermissions != nil && len(networkPermissions.Allowed) > 0 + strictModeValidationLog.Printf("Checking %d MCP servers for container network requirements: hasTopLevelNetwork=%t", len(mcpServersMap), hasTopLevelNetwork) // Check each MCP server for containers for serverName, serverValue := range mcpServersMap { @@ -88,17 +91,20 @@ func (c *Compiler) validateStrictTools(frontmatter map[string]any) error { // Check tools section toolsValue, exists := frontmatter["tools"] if !exists { + strictModeValidationLog.Print("No tools section, skipping strict tools validation") return nil } toolsMap, ok := toolsValue.(map[string]any) if !ok { + strictModeValidationLog.Print("tools is not a map, skipping strict tools validation") return nil } // Check if cache-memory is configured with scope: repo cacheMemoryValue, hasCacheMemory := toolsMap["cache-memory"] if hasCacheMemory { + strictModeValidationLog.Print("Checking cache-memory scope in strict mode") // Helper function to check scope in a cache entry checkScope := func(cacheMap map[string]any) error { if scope, hasScope := cacheMap["scope"]; hasScope { diff --git a/pkg/workflow/strict_mode_steps_validation.go b/pkg/workflow/strict_mode_steps_validation.go index 964825c5505..7e21e7d98f8 100644 --- a/pkg/workflow/strict_mode_steps_validation.go +++ b/pkg/workflow/strict_mode_steps_validation.go @@ -32,6 +32,7 @@ import ( // in other fields (run, etc.) are errors. // In non-strict mode a warning is emitted for all secrets. func (c *Compiler) validateStepsSecrets(frontmatter map[string]any) error { + strictModeValidationLog.Printf("Validating secrets across steps sections: strictMode=%t", c.strictMode) for _, sectionName := range []string{"pre-steps", "steps", "pre-agent-steps", "post-steps"} { if err := c.validateStepsSectionSecrets(frontmatter, sectionName); err != nil { return err @@ -62,6 +63,7 @@ func (c *Compiler) validateStepsSectionSecrets(frontmatter map[string]any, secti // Separate secrets found in safe bindings (env: maps, with: maps in uses: // action steps) from secrets found in other fields (unsafe, potential leak). + strictModeValidationLog.Printf("Classifying secrets in %s section: %d step(s)", sectionName, len(steps)) var unsafeSecretRefs []string var safeSecretRefs []string for _, step := range steps { @@ -107,6 +109,7 @@ func (c *Compiler) validateStepsSectionSecrets(frontmatter map[string]any, secti // Non-strict mode: emit a warning for all secrets. allSecretRefs = sliceutil.Deduplicate(allSecretRefs) sort.Strings(allSecretRefs) + strictModeValidationLog.Printf("Emitting non-strict warning for %d unique secret reference(s) in %s section", len(allSecretRefs), sectionName) warningMsg := fmt.Sprintf( "Warning: secrets expressions detected in '%s' section may be leaked to the agent job. Found: %s. "+ "Consider moving operations requiring secrets to a separate job outside the agent job.",