MCPcopy Create free account
hub / github.com/github/gh-aw / DetectRuntimeRequirements

Function DetectRuntimeRequirements

pkg/workflow/runtime_detection.go:15–97  ·  view source on GitHub ↗

DetectRuntimeRequirements analyzes workflow data to detect required runtimes

(workflowData *WorkflowData)

Source from the content-addressed store, hash-verified

13
14// DetectRuntimeRequirements analyzes workflow data to detect required runtimes
15func DetectRuntimeRequirements(workflowData *WorkflowData) []RuntimeRequirement {
16 runtimeSetupLog.Print("Detecting runtime requirements from workflow data")
17 requirements := make(map[string]*RuntimeRequirement) // map of runtime ID -> requirement
18
19 // Detect from custom steps
20 if workflowData.CustomSteps != "" {
21 detectFromCustomSteps(workflowData.CustomSteps, requirements)
22 }
23
24 // Detect from MCP server configurations
25 if workflowData.ParsedTools != nil {
26 detectFromMCPConfigs(workflowData.ParsedTools, requirements)
27 }
28 if workflowData.MCPScripts != nil {
29 detectFromMCPScripts(workflowData.MCPScripts, requirements)
30 }
31
32 // When using a custom image runner, ensure Node.js is set up.
33 // Standard GitHub-hosted runners (ubuntu-*, windows-*) have Node.js pre-installed,
34 // but custom image runners (self-hosted, enterprise runners, non-standard labels) may not.
35 // Node.js is required for gh-aw scripts such as start_safe_outputs_server.sh and
36 // start_mcp_scripts_server.sh that invoke `node` directly.
37 if isCustomImageRunner(workflowData.RunsOn) {
38 runtimeSetupLog.Printf("Custom image runner detected (%q), ensuring Node.js is set up", workflowData.RunsOn)
39 nodeRuntime := findRuntimeByID("node")
40 if nodeRuntime != nil {
41 updateRequiredRuntime(nodeRuntime, "", requirements)
42 }
43 }
44
45 // When a custom harness script is configured for an engine that currently supports
46 // harness wrappers, require Node.js runtime setup with the default version so workflows
47 // consistently execute the harness with Node 24.
48 if requiresNodeForEngineHarness(workflowData) {
49 nodeRuntime := findRuntimeByID("node")
50 if nodeRuntime != nil {
51 updateRequiredRuntime(nodeRuntime, string(constants.DefaultNodeVersion), requirements)
52 }
53 }
54
55 // Detect runtimes required by LSP server configurations.
56 // Each known LSP server declares the runtime it needs (e.g. "go" for gopls,
57 // "ruby" for solargraph). Feeding these through the runtime manager ensures
58 // the runtime is set up via a properly SHA-pinned setup action rather than
59 // relying on whatever version happens to be pre-installed on the runner.
60 if len(workflowData.LSP) > 0 {
61 detectFromLSPServers(workflowData.LSP, requirements)
62 }
63
64 // Apply runtime overrides from frontmatter
65 if workflowData.Runtimes != nil {
66 applyRuntimeOverrides(workflowData.Runtimes, requirements)
67 }
68
69 // Add Python as dependency when uv is detected (uv requires Python)
70 if _, hasUV := requirements["uv"]; hasUV {
71 if _, hasPython := requirements["python"]; !hasPython {
72 runtimeSetupLog.Print("UV detected without Python, automatically adding Python runtime")

Calls 13

SortedKeysFunction · 0.92
detectFromCustomStepsFunction · 0.85
detectFromMCPConfigsFunction · 0.85
detectFromMCPScriptsFunction · 0.85
isCustomImageRunnerFunction · 0.85
findRuntimeByIDFunction · 0.85
updateRequiredRuntimeFunction · 0.85
detectFromLSPServersFunction · 0.85
applyRuntimeOverridesFunction · 0.85
PrintMethod · 0.80
PrintfMethod · 0.45