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
2 changes: 1 addition & 1 deletion .github/workflows/test-dispatcher.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 26 additions & 5 deletions pkg/workflow/dispatch_workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package workflow

import (
"encoding/json"
"os"
"path/filepath"
"testing"
Expand Down Expand Up @@ -368,14 +369,34 @@ This workflow dispatches to different workflow types.
workflowData, err := compiler.ParseWorkflowFile("dispatcher.md")
require.NoError(t, err, "Failed to parse workflow")

// Generate filtered tools JSON to populate WorkflowFiles
_, err = generateFilteredToolsJSON(workflowData, dispatcherFile)
require.NoError(t, err, "Failed to generate tools JSON")
// Populate workflow files (this is what the fix does)
populateDispatchWorkflowFiles(workflowData, dispatcherFile)

// Verify WorkflowFiles map has correct extensions
require.NotNil(t, workflowData.SafeOutputs.DispatchWorkflow.WorkflowFiles)
// Verify WorkflowFiles map has correct extensions after populate
require.NotNil(t, workflowData.SafeOutputs.DispatchWorkflow.WorkflowFiles,
"WorkflowFiles should be populated after populateDispatchWorkflowFiles")
assert.Equal(t, ".lock.yml", workflowData.SafeOutputs.DispatchWorkflow.WorkflowFiles["lock-test"],
"lock-test should use .lock.yml extension")
assert.Equal(t, ".yml", workflowData.SafeOutputs.DispatchWorkflow.WorkflowFiles["yml-test"],
"yml-test should use .yml extension")

// Generate safe outputs config to verify workflow_files is included
configJSON := generateSafeOutputsConfig(workflowData)
require.NotEmpty(t, configJSON, "Config JSON should not be empty")

// Parse config to verify workflow_files is present
var config map[string]any
err = json.Unmarshal([]byte(configJSON), &config)
require.NoError(t, err, "Config JSON should be valid")

dispatchWorkflowConfig, ok := config["dispatch_workflow"].(map[string]any)
require.True(t, ok, "dispatch_workflow should be in config")

workflowFiles, ok := dispatchWorkflowConfig["workflow_files"].(map[string]any)
require.True(t, ok, "workflow_files should be in dispatch_workflow config")

assert.Equal(t, ".lock.yml", workflowFiles["lock-test"],
"lock-test extension should be in workflow_files")
assert.Equal(t, ".yml", workflowFiles["yml-test"],
"yml-test extension should be in workflow_files")
}
4 changes: 4 additions & 0 deletions pkg/workflow/mcp_setup_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ func (c *Compiler) generateMCPSetup(yaml *strings.Builder, tools map[string]any,
mcpTools = append(mcpTools, "safe-inputs")
}

// Populate dispatch-workflow file mappings before generating config
// This ensures workflow_files is available in the config.json
populateDispatchWorkflowFiles(workflowData, c.markdownPath)

// Generate safe-outputs configuration once to avoid duplicate computation
var safeOutputConfig string
if HasSafeOutputsEnabled(workflowData.SafeOutputs) {
Expand Down
43 changes: 43 additions & 0 deletions pkg/workflow/safe_outputs_config_generation.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,49 @@ import (
// Safe Output Configuration Generation
// ========================================

// populateDispatchWorkflowFiles populates the WorkflowFiles map for dispatch-workflow configuration.
// This must be called before generateSafeOutputsConfig to ensure workflow file extensions are available.
func populateDispatchWorkflowFiles(data *WorkflowData, markdownPath string) {
if data.SafeOutputs == nil || data.SafeOutputs.DispatchWorkflow == nil {
return
}

if len(data.SafeOutputs.DispatchWorkflow.Workflows) == 0 {
return
}

safeOutputsConfigLog.Printf("Populating workflow files for %d dispatch workflows", len(data.SafeOutputs.DispatchWorkflow.Workflows))

// Initialize WorkflowFiles map if not already initialized
if data.SafeOutputs.DispatchWorkflow.WorkflowFiles == nil {
data.SafeOutputs.DispatchWorkflow.WorkflowFiles = make(map[string]string)
}

for _, workflowName := range data.SafeOutputs.DispatchWorkflow.Workflows {
// Find the workflow file
fileResult, err := findWorkflowFile(workflowName, markdownPath)
if err != nil {
safeOutputsConfigLog.Printf("Warning: error finding workflow %s: %v", workflowName, err)
continue
}

// Determine which file to use - priority: .lock.yml > .yml
var extension string
if fileResult.lockExists {
extension = ".lock.yml"
} else if fileResult.ymlExists {
extension = ".yml"
} else {
safeOutputsConfigLog.Printf("Warning: workflow file not found for %s (only .md exists, needs compilation)", workflowName)
continue
}

// Store the file extension for runtime use
data.SafeOutputs.DispatchWorkflow.WorkflowFiles[workflowName] = extension
safeOutputsConfigLog.Printf("Mapped workflow %s to extension %s", workflowName, extension)
}
}

func generateSafeOutputsConfig(data *WorkflowData) string {
// Pass the safe-outputs configuration for validation
if data.SafeOutputs == nil {
Expand Down
Loading