Skip to content

Commit

Permalink
utils: add new execute utility
Browse files Browse the repository at this point in the history
This new function is similar to `run` except that it requires that the
arguments be passed properly quoted and pre-split through an array.  It
also will not permit the prefixing a command for execution.  The major
difference between `run` and `execute` is that `execute` will not go
through a shell, so parameter expansion, variable substitution, etc do
not occur.  Additionally, because there is no shell involved, a single
process is created rather than two processes (one for the shell, and the
actual process being invoked).  This is required to enable using this
action on Windows, where the process redirection does not work as the
shell used is different.
  • Loading branch information
compnerd committed May 9, 2021
1 parent e4dadc1 commit d79e32f
Showing 1 changed file with 39 additions and 1 deletion.
40 changes: 39 additions & 1 deletion src/utils/action.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
const { execSync } = require("child_process");
const { execSync, spawnSync } = require("child_process");

const core = require("@actions/core");

const RUN_OPTIONS_DEFAULTS = { dir: null, ignoreErrors: false, prefix: "" };
const EXECUTE_OPTIONS_DEFAULTS = { dir: null, ignoreErrors: false };

/**
* Returns the value for an environment variable. If the variable is required but doesn't have a
Expand Down Expand Up @@ -72,7 +73,44 @@ function run(cmd, options) {
}
}

/**
* Executes the provided binary with the given arguments.
* @param {string} command - binary to execute
* @param {{dir: string, ignoreErrors: boolean}} [options] - {@see EXECUTE_OPTIONS_DEFAULTS}
* @returns {{status: number, stdout: string, stderr: string}} - Output of the command
*/
function execute(command, args, options) {
const optionsWithDefaults = {
...EXECUTE_OPTIONS_DEFAULTS,
...options,
};

core.debug(`${command} ${args.filter(e => e).join(" ")}`);

const process = spawnSync(command, args.filter(e => e), {
cwd: optionsWithDefaults.dir,
encoding: "utf-8",
maxBuffer: 20 * 1024 * 1024,
});

const output = {
status: process.status,
stdout: process.stdout.trim(),
stderr: process.stderr.trim(),
};

core.debug(`Exit code: ${output.status}`);
core.debug(`Stdout: ${output.stdout}`);
core.debug(`Stderr: ${output.stderr}`);

if (!optionsWithDefaults.ignoreErrors && child.status != 0) {
throw child.error;
}
return output;
}

module.exports = {
execute,
getEnv,
run,
};

0 comments on commit d79e32f

Please sign in to comment.