Skip to content

Commit

Permalink
Fix output malformed when wrapper enabled (#367)
Browse files Browse the repository at this point in the history
* Fix output malformed when wrapper enabled

Presently using a command such as `terraform output -json | jq` does not
work with the wrapper enabled, as it is by default.

In order to consume terraform's output having set it up with this
Action, it is necessary either to disable the wrapper (`with:
terraform_wrapper: false`) or run it in its own Actions step with an
explicit `id` (e.g. `id: foo`) so that it can be referred to and consumed
(`${{steps.foo.outputs.stdout}}` et al.) in later steps.

This seems to be the result of much confusion (issues passim) and is not
at all easy (#338) to debug/diagnose and come to the realisation that
it's due to the wrapper, or even that such a thing exists.

@austinvalle identified the issue as being due to the `@actions/exec`
package writing the spawned command to stdout (along with then its
actual stdout). This has previously been reported upstream in
actions/toolkit#649; I've proposed actions/toolkit#1573 to fix it.

This commit aims to address the issue for `setup-terraform` in the
meantime by silencing `@actions/exec` and then writing out to stdout &
stderr from the listener buffers, which it writes to without this
additional logging.

Closes #20, #80, #85, #149, #338, and probably more.

* add test for stdout with jq

* update test name

* remove debug lines and add changelog

* add additional note about the bug fix to wrapper

---------

Co-authored-by: Austin Valle <austinvalle@gmail.com>
  • Loading branch information
OJFord and austinvalle committed Oct 27, 2023
1 parent 4c41f96 commit 4dff81d
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 15 deletions.
5 changes: 5 additions & 0 deletions .changes/unreleased/BUG FIXES-20231027-092614.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: BUG FIXES
body: Fixed malformed stdout when wrapper is enabled
time: 2023-10-27T09:26:14.675402-04:00
custom:
Issue: "367"
10 changes: 10 additions & 0 deletions .changes/unreleased/NOTES-20231027-134331.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
kind: NOTES
body: The wrapper around the installed Terraform binary has been fixed to return the
exact STDOUT and STDERR from Terraform when executing commands. Previous versions
of setup-terraform may have required workarounds to process the STDOUT in bash,
such as filtering out the first line or selectively parsing STDOUT with jq. These
workarounds may need to be adjusted with `v3.0.0`, which will now return just the
STDOUT/STDERR from Terraform with no errant characters/statements.
time: 2023-10-27T13:43:31.430759-04:00
custom:
Issue: "367"
8 changes: 4 additions & 4 deletions .github/workflows/data/local/main.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
resource "null_resource" "null" {
triggers = {
value = timestamp()
}
resource "random_pet" "pet" {}

output "pet" {
value = random_pet.pet.id
}
69 changes: 68 additions & 1 deletion .github/workflows/setup-terraform.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: 'Setup Terraform'
name: 'setup-terraform tests'

on:
push:
Expand Down Expand Up @@ -303,3 +303,70 @@ jobs:
- name: Terraform Plan
id: plan
run: terraform plan


terraform-stdout-wrapper:
name: 'Terraform STDOUT'
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
defaults:
run:
shell: bash
working-directory: ./.github/workflows/data/local
steps:
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0

- name: Setup Terraform
uses: ./
with:
terraform_wrapper: true

- name: Terraform Init
run: terraform init

- name: Terraform Format
run: terraform fmt -check

- name: Terraform Apply
id: apply
run: terraform apply -auto-approve

- name: Terraform Output to JQ
id: output
run: terraform output -json | jq '.pet.value'

terraform-stdout-no-wrapper:
name: 'Terraform STDOUT No Wrapper'
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
defaults:
run:
shell: bash
working-directory: ./.github/workflows/data/local
steps:
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0

- name: Setup Terraform
uses: ./
with:
terraform_wrapper: false

- name: Terraform Init
run: terraform init

- name: Terraform Format
run: terraform fmt -check

- name: Terraform Apply
id: apply
run: terraform apply -auto-approve

- name: Terraform Output to JQ
id: output
run: terraform output -json | jq '.pet.value'
11 changes: 6 additions & 5 deletions dist/index1.js
Original file line number Diff line number Diff line change
Expand Up @@ -27221,13 +27221,14 @@ async function checkTerraform () {
const args = process.argv.slice(2);
const options = {
listeners,
ignoreReturnCode: true
ignoreReturnCode: true,
silent: true, // avoid printing command in stdout: https://github.com/actions/toolkit/issues/649
};
const exitCode = await exec(pathToCLI, args, options);
core.debug(`Terraform exited with code ${exitCode}.`);
core.debug(`stdout: ${stdout.contents}`);
core.debug(`stderr: ${stderr.contents}`);
core.debug(`exitcode: ${exitCode}`);

// Pass-through stdout/err as `exec` won't due to `silent: true` option
process.stdout.write(stdout.contents);
process.stderr.write(stderr.contents);

// Set outputs, result, exitcode, and stderr
core.setOutput('stdout', stdout.contents);
Expand Down
11 changes: 6 additions & 5 deletions wrapper/terraform.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@ async function checkTerraform () {
const args = process.argv.slice(2);
const options = {
listeners,
ignoreReturnCode: true
ignoreReturnCode: true,
silent: true, // avoid printing command in stdout: https://github.com/actions/toolkit/issues/649
};
const exitCode = await exec(pathToCLI, args, options);
core.debug(`Terraform exited with code ${exitCode}.`);
core.debug(`stdout: ${stdout.contents}`);
core.debug(`stderr: ${stderr.contents}`);
core.debug(`exitcode: ${exitCode}`);

// Pass-through stdout/err as `exec` won't due to `silent: true` option
process.stdout.write(stdout.contents);
process.stderr.write(stderr.contents);

// Set outputs, result, exitcode, and stderr
core.setOutput('stdout', stdout.contents);
Expand Down

0 comments on commit 4dff81d

Please sign in to comment.