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

Function runProcess

actions/setup/js/process_runner.cjs:68–145  ·  view source on GitHub ↗

* Run a command with the given arguments, transparently forwarding stdin/stdout/stderr. * Also collects combined stdout+stderr output for error pattern detection. * * The child process is spawned with `cwd` set to `process.env.GH_AW_ENGINE_CWD` when * available, falling back to `process.env.GITH

({ command, args, attempt, log, logArgs, env })

Source from the content-addressed store, hash-verified

66 * @returns {Promise<{exitCode: number, output: string, hasOutput: boolean, durationMs: number}>}
67 */
68function runProcess({ command, args, attempt, log, logArgs, env }) {
69 return new Promise(resolve => {
70 const startTime = Date.now();
71 // Guard against the promise being settled more than once. On some systems Node
72 // emits 'close' after 'error' (or vice-versa); only the first terminal event should
73 // log and resolve so callers receive a deterministic result.
74 let settled = false;
75 /** @param {{exitCode: number, output: string, hasOutput: boolean, durationMs: number}} result */
76 function settle(result) {
77 if (settled) return;
78 settled = true;
79 resolve(result);
80 }
81
82 const argsForLog = logArgs ?? args;
83 log(`attempt ${attempt + 1}: spawning: ${command} ${argsForLog.join(" ").substring(0, 200)}`);
84
85 const child = spawn(command, args, {
86 stdio: ["inherit", "pipe", "pipe"],
87 env: env ?? process.env,
88 cwd: process.env.GH_AW_ENGINE_CWD || process.env.GITHUB_WORKSPACE || undefined,
89 });
90
91 log(`attempt ${attempt + 1}: process started (pid=${child.pid ?? "unknown"})`);
92
93 let collectedOutput = "";
94 let hasOutput = false;
95 let stdoutBytes = 0;
96 let stderrBytes = 0;
97
98 child.stdout.on(
99 "data",
100 /** @param {Buffer} data */ data => {
101 hasOutput = true;
102 stdoutBytes += data.length;
103 collectedOutput += data.toString();
104 process.stdout.write(data);
105 }
106 );
107
108 child.stderr.on(
109 "data",
110 /** @param {Buffer} data */ data => {
111 hasOutput = true;
112 stderrBytes += data.length;
113 collectedOutput += data.toString();
114 process.stderr.write(data);
115 }
116 );
117
118 child.on("exit", (code, signal) => {
119 log(`attempt ${attempt + 1}: process exit event` + ` exitCode=${code ?? 1}` + (signal ? ` signal=${signal}` : ""));
120 });
121
122 // Resolve on 'close', not 'exit', to ensure stdio streams are fully drained.
123 child.on("close", (code, signal) => {
124 const durationMs = Date.now() - startTime;
125 const exitCode = code ?? 1;

Callers 4

mainFunction · 0.85
mainFunction · 0.85
mainFunction · 0.85

Calls 3

settleFunction · 0.85
logFunction · 0.70
formatDurationFunction · 0.70

Tested by

no test coverage detected