Skip to content

Commit

Permalink
feat: allow command output to be hidden (#26)
Browse files Browse the repository at this point in the history
This is used for the Terraform show command as it can
contain sensitive data in plain text.

Also includes a fix to properly handle mutli-line input for
the Terraform init args.
  • Loading branch information
patheard authored Jun 29, 2021
1 parent eaa3ff4 commit 75496d5
Show file tree
Hide file tree
Showing 9 changed files with 252 additions and 138 deletions.
38 changes: 29 additions & 9 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14845,14 +14845,28 @@ const action = async () => {
const octokit = token !== "false" ? github.getOctokit(token) : undefined;

const commands = [
{ key: "init", exec: `${binary} init ${terraformInit}` },
{ key: "validate", exec: `${binary} validate` },
{ key: "fmt", exec: `${binary} fmt --check` },
{
key: "init",
exec: `${binary} init ${terraformInit ? terraformInit.join(" ") : ""}`,
},
{
key: "validate",
exec: `${binary} validate`,
},
{
key: "fmt",
exec: `${binary} fmt --check`,
},
{
key: "plan",
exec: `${binary} plan -no-color -input=false -out=plan.tfplan`,
},
{ key: "show", exec: `${binary} show -json plan.tfplan`, depends: "plan" },
{
key: "show",
exec: `${binary} show -json plan.tfplan`,
depends: "plan",
output: false,
},
];
let results = {};
let isError = false;
Expand All @@ -14866,7 +14880,7 @@ const action = async () => {
// Exec commands
for (let command of commands) {
if (!command.depends || results[command.depends].isSuccess) {
results[command.key] = execCommand(command.exec, directory);
results[command.key] = execCommand(command, directory);
} else {
results[command.key] = { isSuccess: false };
}
Expand Down Expand Up @@ -14913,7 +14927,7 @@ const proc = __nccwpck_require__(3129);

/**
* Executes a command in a given directory
* @param {String} command The command (and args) to execute
* @param {Object} command The command to execute
* @param {String} directory The directory to execute the command in
* @returns {Object} Results object with the command output and if the command was successful
*/
Expand All @@ -14922,17 +14936,23 @@ const execCommand = (command, directory) => {
exitCode = 0;

try {
console.log("🧪 \x1b[36m%s\x1b[0m\n", command);
console.log("🧪 \x1b[36m%s\x1b[0m\n", command.exec);
output = proc
.execSync(command, { cwd: directory, maxBuffer: 1024 * 5000 })
.execSync(command.exec, {
cwd: directory,
maxBuffer: 1024 * 5000,
})
.toString("utf8");
} catch (error) {
exitCode = error.status;
output = error.stderr.toString("utf8");
console.log(`Command failed with exit code ${exitCode}`);
}

console.log(output);
if (command.output !== false) {
console.log(output);
}

return {
isSuccess: exitCode === 0,
output: output,
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
"main": "dist/index.js",
"scripts": {
"build": "ncc build src/index.js --source-map --license licenses.txt",
"format:check": "prettier --check src",
"format:write": "prettier --write src",
"lint": "eslint src",
"format:check": "prettier --check src test",
"format:write": "prettier --write src test",
"lint": "eslint src test",
"policy": "./src/policy/build.sh",
"prepare": "husky install",
"pre-commit": "npm run policy && npm run format:write && npm run build",
Expand Down
24 changes: 19 additions & 5 deletions src/action.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,28 @@ const action = async () => {
const octokit = token !== "false" ? github.getOctokit(token) : undefined;

const commands = [
{ key: "init", exec: `${binary} init ${terraformInit}` },
{ key: "validate", exec: `${binary} validate` },
{ key: "fmt", exec: `${binary} fmt --check` },
{
key: "init",
exec: `${binary} init ${terraformInit ? terraformInit.join(" ") : ""}`,
},
{
key: "validate",
exec: `${binary} validate`,
},
{
key: "fmt",
exec: `${binary} fmt --check`,
},
{
key: "plan",
exec: `${binary} plan -no-color -input=false -out=plan.tfplan`,
},
{ key: "show", exec: `${binary} show -json plan.tfplan`, depends: "plan" },
{
key: "show",
exec: `${binary} show -json plan.tfplan`,
depends: "plan",
output: false,
},
];
let results = {};
let isError = false;
Expand All @@ -44,7 +58,7 @@ const action = async () => {
// Exec commands
for (let command of commands) {
if (!command.depends || results[command.depends].isSuccess) {
results[command.key] = execCommand(command.exec, directory);
results[command.key] = execCommand(command, directory);
} else {
results[command.key] = { isSuccess: false };
}
Expand Down
14 changes: 10 additions & 4 deletions src/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const proc = require("child_process");

/**
* Executes a command in a given directory
* @param {String} command The command (and args) to execute
* @param {Object} command The command to execute
* @param {String} directory The directory to execute the command in
* @returns {Object} Results object with the command output and if the command was successful
*/
Expand All @@ -14,17 +14,23 @@ const execCommand = (command, directory) => {
exitCode = 0;

try {
console.log("🧪 \x1b[36m%s\x1b[0m\n", command);
console.log("🧪 \x1b[36m%s\x1b[0m\n", command.exec);
output = proc
.execSync(command, { cwd: directory, maxBuffer: 1024 * 5000 })
.execSync(command.exec, {
cwd: directory,
maxBuffer: 1024 * 5000,
})
.toString("utf8");
} catch (error) {
exitCode = error.status;
output = error.stderr.toString("utf8");
console.log(`Command failed with exit code ${exitCode}`);
}

console.log(output);
if (command.output !== false) {
console.log(output);
}

return {
isSuccess: exitCode === 0,
output: output,
Expand Down
92 changes: 78 additions & 14 deletions test/action.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,52 @@ describe("action", () => {
when(core.getInput).calledWith("directory").mockReturnValue("foo");
when(core.getMultilineInput)
.calledWith("terraform-init")
.mockReturnValue("-backend-config='bucket=some-bucket'");
.mockReturnValue([
"-backend-config='bucket=some-bucket'",
"-backend-config='region=ca-central-1'",
]);

await action();

expect(execCommand.mock.calls.length).toBe(5);
expect(execCommand.mock.calls).toEqual([
["terraform init -backend-config='bucket=some-bucket'", "foo"],
["terraform validate", "foo"],
["terraform fmt --check", "foo"],
["terraform plan -no-color -input=false -out=plan.tfplan", "foo"],
["terraform show -json plan.tfplan", "foo"],
[
{
key: "init",
exec: "terraform init -backend-config='bucket=some-bucket' -backend-config='region=ca-central-1'",
},
"foo",
],
[
{
key: "validate",
exec: "terraform validate",
},
"foo",
],
[
{
key: "fmt",
exec: "terraform fmt --check",
},
"foo",
],
[
{
key: "plan",
exec: "terraform plan -no-color -input=false -out=plan.tfplan",
},
"foo",
],
[
{
key: "show",
exec: "terraform show -json plan.tfplan",
depends: "plan",
output: false,
},
"foo",
],
]);
expect(addComment.mock.calls.length).toBe(0);
expect(deleteComment.mock.calls.length).toBe(0);
Expand All @@ -43,20 +78,49 @@ describe("action", () => {
test("terragrunt flow", async () => {
execCommand.mockReturnValue({ isSuccess: true, output: "{}" });
when(core.getInput).calledWith("directory").mockReturnValue("bar");
when(core.getMultilineInput)
.calledWith("terraform-init")
.mockReturnValue("");
when(core.getBooleanInput).calledWith("terragrunt").mockReturnValue(true);

await action();

expect(execCommand.mock.calls.length).toBe(5);
expect(execCommand.mock.calls).toEqual([
["terragrunt init ", "bar"],
["terragrunt validate", "bar"],
["terragrunt fmt --check", "bar"],
["terragrunt plan -no-color -input=false -out=plan.tfplan", "bar"],
["terragrunt show -json plan.tfplan", "bar"],
[
{
key: "init",
exec: "terragrunt init ",
},
"bar",
],
[
{
key: "validate",
exec: "terragrunt validate",
},
"bar",
],
[
{
key: "fmt",
exec: "terragrunt fmt --check",
},
"bar",
],
[
{
key: "plan",
exec: "terragrunt plan -no-color -input=false -out=plan.tfplan",
},
"bar",
],
[
{
key: "show",
exec: "terragrunt show -json plan.tfplan",
depends: "plan",
output: false,
},
"bar",
],
]);
expect(getPlanChanges.mock.calls.length).toBe(1);
expect(addComment.mock.calls.length).toBe(0);
Expand Down
Loading

0 comments on commit 75496d5

Please sign in to comment.