diff --git a/.github/instructions/developer.instructions.md b/.github/instructions/developer.instructions.md index 0185cd9e8e8..239eccaf7e4 100644 --- a/.github/instructions/developer.instructions.md +++ b/.github/instructions/developer.instructions.md @@ -364,14 +364,11 @@ The custom actions build system is **entirely implemented in Go** in `pkg/cli/ac **Directory Structure**: ``` actions/ -├── setup-safe-inputs/ -│ ├── action.yml -│ ├── index.js -│ └── src/ -├── setup-safe-outputs/ -│ ├── action.yml -│ ├── index.js -│ └── src/ +└── setup/ + ├── action.yml + ├── setup.sh + ├── js/ + └── sh/ ``` **Implementation**: See specs/actions.md and `pkg/cli/actions_build_command.go` diff --git a/.gitignore b/.gitignore index bde4394300d..14da4517762 100644 --- a/.gitignore +++ b/.gitignore @@ -139,7 +139,6 @@ trivy-results.sarif # Note: If workflows fail due to missing js/ files, these may need to be committed # The js/ directories contain compiled JavaScript from pkg/workflow/js/*.cjs # and are generated by 'make actions-build' -actions/setup-safe-outputs/js/ # License compliance reports licenses.csv diff --git a/actions/README.md b/actions/README.md index 6a0da3a4aa5..519bab4772e 100644 --- a/actions/README.md +++ b/actions/README.md @@ -23,18 +23,6 @@ Copies workflow script files to the agent environment. This action embeds all ne [Documentation](./setup/README.md) -### setup-safe-outputs - -Copies safe-outputs MCP server files to the agent environment. This action embeds all necessary JavaScript files for the safe-outputs MCP server and copies them to a specified destination directory. - -[Documentation](./setup-safe-outputs/README.md) - -### setup-safe-inputs - -Copies safe-inputs MCP server files to the agent environment. This action embeds all necessary JavaScript files for the safe-inputs MCP server and copies them to a specified destination directory. - -[Documentation](./setup-safe-inputs/README.md) - ### noop Processes noop safe output - a fallback output type that logs messages for transparency without taking any GitHub API actions. @@ -264,7 +252,7 @@ Test actions locally by: 1. Creating a test workflow in `.github/workflows/` 2. Using the action with a local path: ```yaml - - uses: ./actions/setup-safe-outputs + - uses: ./actions/setup with: destination: /tmp/test ``` diff --git a/pkg/cli/actions_build_command.go b/pkg/cli/actions_build_command.go index e2d2e89275c..14dad0c1000 100644 --- a/pkg/cli/actions_build_command.go +++ b/pkg/cli/actions_build_command.go @@ -105,8 +105,8 @@ func ActionsCleanCommand() error { cleanedCount := 0 for _, actionName := range actionDirs { - // Clean index.js for actions that use it (except setup-safe-outputs and setup) - if actionName != "setup-safe-outputs" && actionName != "setup" { + // Clean index.js for actions that use it (except setup) + if actionName != "setup" { indexPath := filepath.Join(actionsDir, actionName, "index.js") if _, err := os.Stat(indexPath); err == nil { if err := os.Remove(indexPath); err != nil { @@ -117,18 +117,6 @@ func ActionsCleanCommand() error { } } - // Clean js/ directory for setup-safe-outputs - if actionName == "setup-safe-outputs" { - jsDir := filepath.Join(actionsDir, actionName, "js") - if _, err := os.Stat(jsDir); err == nil { - if err := os.RemoveAll(jsDir); err != nil { - return fmt.Errorf("failed to remove %s: %w", jsDir, err) - } - fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf(" ✓ Removed %s/js/", actionName))) - cleanedCount++ - } - } - // For setup action, both js/ and sh/ directories are source of truth (NOT generated) // Do not clean them } @@ -219,11 +207,6 @@ func buildAction(actionsDir, actionName string) error { return err } - // Special handling for setup-safe-outputs: copy files instead of embedding - if actionName == "setup-safe-outputs" { - return buildSetupSafeOutputsAction(actionsDir, actionName) - } - // Special handling for setup: build shell script with embedded files if actionName == "setup" { return buildSetupAction(actionsDir, actionName) @@ -287,43 +270,6 @@ func buildAction(actionsDir, actionName string) error { return nil } -// buildSetupSafeOutputsAction builds the setup-safe-outputs action by copying JavaScript files -func buildSetupSafeOutputsAction(actionsDir, actionName string) error { - actionPath := filepath.Join(actionsDir, actionName) - jsDir := filepath.Join(actionPath, "js") - - // Get dependencies for this action - dependencies := getActionDependencies(actionName) - fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf(" ✓ Found %d dependencies", len(dependencies)))) - - // Get all JavaScript sources - sources := workflow.GetJavaScriptSources() - - // Create js directory if it doesn't exist - if err := os.MkdirAll(jsDir, 0755); err != nil { - return fmt.Errorf("failed to create js directory: %w", err) - } - - // Copy each dependency file to the js directory - copiedCount := 0 - for _, dep := range dependencies { - if content, ok := sources[dep]; ok { - destPath := filepath.Join(jsDir, dep) - if err := os.WriteFile(destPath, []byte(content), 0644); err != nil { - return fmt.Errorf("failed to write %s: %w", dep, err) - } - fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf(" - %s", dep))) - copiedCount++ - } else { - fmt.Fprintln(os.Stderr, console.FormatWarningMessage(fmt.Sprintf(" ⚠ Warning: Could not find %s", dep))) - } - } - - fmt.Fprintln(os.Stderr, console.FormatInfoMessage(fmt.Sprintf(" ✓ Copied %d files to js/", copiedCount))) - - return nil -} - // buildSetupAction builds the setup action by checking that source files exist. // Note: Both JavaScript and shell scripts are source of truth in actions/setup/js/ and actions/setup/sh/ // They get synced to pkg/workflow/js/ and pkg/workflow/sh/ during the build process via Makefile targets. @@ -374,49 +320,5 @@ func getActionDependencies(actionName string) []string { return workflow.GetAllScriptFilenames() } - // Static dependencies for other actions - dependencyMap := map[string][]string{ - "setup-safe-outputs": { - "safe_outputs_mcp_server.cjs", - "safe_outputs_bootstrap.cjs", - "safe_outputs_tools_loader.cjs", - "safe_outputs_config.cjs", - "safe_outputs_handlers.cjs", - "mcp_server_core.cjs", - "mcp_logger.cjs", - "messages.cjs", - }, - "setup-safe-inputs": { - "safe_inputs_mcp_server.cjs", - "safe_inputs_bootstrap.cjs", - "safe_inputs_config_loader.cjs", - "safe_inputs_tool_factory.cjs", - "safe_inputs_validation.cjs", - "mcp_server_core.cjs", - "mcp_logger.cjs", - }, - "noop": { - "load_agent_output.cjs", - }, - "minimize_comment": { - "load_agent_output.cjs", - }, - "close_issue": { - "close_entity_helpers.cjs", - }, - "close_pull_request": { - "close_entity_helpers.cjs", - }, - "close_discussion": { - "generate_footer.cjs", - "get_repository_url.cjs", - "get_tracker_id.cjs", - "load_agent_output.cjs", - }, - } - - if deps, ok := dependencyMap[actionName]; ok { - return deps - } return []string{} } diff --git a/specs/actions.md b/specs/actions.md index a512ce3514f..4d590620fe0 100644 --- a/specs/actions.md +++ b/specs/actions.md @@ -94,12 +94,14 @@ Create a custom actions system that: ┌─────────────────────────────────────────────────────────┐ │ actions/ Directory │ │ ┌────────────────────────────────────────────────────┐ │ -│ │ setup-safe-inputs/ setup-safe-outputs/ │ │ -│ │ ├── action.yml ├── action.yml │ │ -│ │ ├── index.js ├── index.js │ │ -│ │ ├── src/ ├── src/ │ │ -│ │ │ └── index.js │ └── index.js │ │ -│ │ └── README.md └── README.md │ │ +│ │ setup/ │ │ +│ │ ├── action.yml │ │ +│ │ ├── setup.sh │ │ +│ │ ├── js/ │ │ +│ │ │ └── *.cjs (copied from pkg/workflow/js/) │ │ +│ │ ├── sh/ │ │ +│ │ │ └── *.sh (source of truth) │ │ +│ │ └── README.md │ │ │ └────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ ```text @@ -149,18 +151,6 @@ gh-aw/ │ │ ├── sh/ # Shell scripts (SOURCE OF TRUTH) │ │ │ └── *.sh # Manually edited shell scripts │ │ └── README.md # Action-specific docs -│ ├── setup-safe-inputs/ # Safe inputs MCP server setup -│ │ ├── action.yml # Action metadata -│ │ ├── index.js # Bundled output (committed) -│ │ ├── src/ # Source files -│ │ │ └── index.js # Source that references FILES constant -│ │ └── README.md # Action-specific docs -│ └── setup-safe-outputs/ # Safe outputs MCP server setup -│ ├── action.yml # Action metadata -│ ├── index.js # Bundled output (committed) -│ ├── src/ # Source files -│ │ └── index.js # Source that references FILES constant -│ └── README.md # Action-specific docs ├── pkg/ │ ├── cli/ │ │ └── actions_build_command.go # Build system implementation @@ -319,31 +309,12 @@ Currently uses manual mapping in `getActionDependencies()`: ```go func getActionDependencies(actionName string) []string { - dependencyMap := map[string][]string{ - "setup-safe-outputs": { - "safe_outputs_mcp_server.cjs", - "safe_outputs_bootstrap.cjs", - "safe_outputs_tools_loader.cjs", - "safe_outputs_config.cjs", - "safe_outputs_handlers.cjs", - "mcp_server_core.cjs", - "mcp_logger.cjs", - "messages.cjs", - }, - "setup-safe-inputs": { - "safe_inputs_mcp_server.cjs", - "safe_inputs_bootstrap.cjs", - "safe_inputs_config_loader.cjs", - "safe_inputs_tool_factory.cjs", - "safe_inputs_validation.cjs", - "mcp_server_core.cjs", - "mcp_logger.cjs", - }, - } - - if deps, ok := dependencyMap[actionName]; ok { - return deps + // For setup, use the dynamic script discovery + // This ensures all .cjs files are included automatically + if actionName == "setup" { + return workflow.GetAllScriptFilenames() } + return []string{} } ```text @@ -449,15 +420,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Setup Safe Inputs - uses: ./actions/setup-safe-inputs - with: - destination: /tmp/safe-inputs - - - name: Setup Safe Outputs - uses: ./actions/setup-safe-outputs + - name: Setup Workflow Scripts + uses: ./actions/setup with: - destination: /tmp/safe-outputs + destination: /tmp/scripts ```text ### Creating a New Action @@ -727,7 +693,7 @@ The custom GitHub Actions build system provides a foundation for migrating from ✅ **Go-based build system** reusing workflow bundler infrastructure ✅ **Makefile integration** for action management ✅ **CI validation** ensuring actions stay buildable -✅ **Two initial actions** (setup-safe-inputs, setup-safe-outputs) +✅ **Setup action** for workflow script management ✅ **Comprehensive documentation** for future development The system is production-ready and extensible, with clear paths for enhancement and migration of existing inline scripts.