c0rey.sc0tt
07/10/2026, 4:42 PMcloudposse/github-action-setup-atmos@v3, our atmos terraform deploy and atmos terraform apply commands in GitHub Actions started completing instantly (0 seconds, exit code 0) with no terraform output — no init, no plan, no apply.
The install path changed from /home/runner/work/_actions/cloudposse/github-action-setup-atmos/atmos to /opt/hostedtoolcache/atmos-wrapper/1.222.0/x64. Actions runs using the old path on July 3 worked fine (5-minute deploys); runs using the new wrapper path on July 4+ silently no-op.
Workaround: Setting install-wrapper: "false" resolves it — deploy commands run terraform as expected.
Are we missing a configuration step for the wrapper, or is this a known issue with the latest release? Happy to provide workflow snippets or run logs if helpful. Thanks!Erik Osterman (Cloud Posse)
07/10/2026, 5:06 PMErik Osterman (Cloud Posse)
07/10/2026, 5:06 PMErik Osterman (Cloud Posse)
07/10/2026, 5:07 PMc0rey.sc0tt
07/10/2026, 5:08 PMErik Osterman (Cloud Posse)
07/10/2026, 5:08 PMErik Osterman (Cloud Posse)
07/10/2026, 5:08 PMc0rey.sc0tt
07/10/2026, 5:09 PMErik Osterman (Cloud Posse)
07/10/2026, 8:09 PMErik Osterman (Cloud Posse)
07/10/2026, 8:09 PMc0rey.sc0tt
07/10/2026, 8:19 PMc0rey.sc0tt
07/10/2026, 9:06 PM# Test workflow for cloudposse/github-action-setup-atmos wrapper no-op regression
# Two modes:
# - "reproduce-bug": uses @v3 with default wrapper (should no-op)
# - "test-fix": uses PR #115 branch with wrapper enabled (should work)
name: "Test: Atmos Wrapper Fix"
on:
workflow_dispatch:
inputs:
mode:
description: "Test mode"
required: true
type: choice
options:
- reproduce-bug
- test-fix
permissions:
contents: read
id-token: write
jobs:
test-wrapper:
name: "${{ inputs.mode }}"
runs-on: ubuntu-latest
defaults:
run:
working-directory: infra/
steps:
- uses: actions/checkout@v6
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: ${{ vars.AWS_ROLE_ARN }}
aws-region: ${{ vars.AWS_REGION }}
- uses: hashicorp/setup-terraform@v4
# --- Reproduce bug: @v3 with wrapper ENABLED (default) ---
- name: "Setup Atmos (buggy: @v3 default wrapper)"
if: inputs.mode == 'reproduce-bug'
uses: cloudposse/github-action-setup-atmos@v3
# --- Test fix: PR #115 branch with wrapper ENABLED (default) ---
- name: "Setup Atmos (fix: PR #115 branch)"
if: inputs.mode == 'test-fix'
uses: cloudposse/github-action-setup-atmos<@U0719661QCD>/wrapper-noop-bug
- name: Diagnostics
run: |
echo "=== Atmos diagnostics ==="
echo "which atmos: $(which atmos)"
echo "atmos version: $(atmos version)"
echo "ATMOS_CLI_PATH: ${ATMOS_CLI_PATH:-not set}"
ls -la "$(which atmos)"
echo ""
- name: "Plan component"
id: plan
run: |
echo "=== Starting plan at $(date -u) ==="
START=$(date +%s)
OUTPUT=$(atmos terraform plan <your-component> -s <your-stack> 2>&1) || true
EXIT_CODE=$?
END=$(date +%s)
DURATION=$((END - START))
echo "$OUTPUT"
echo ""
echo "=== Plan completed ==="
echo "Exit code: $EXIT_CODE"
echo "Duration: ${DURATION}s"
echo "Output length: ${#OUTPUT} chars"
echo "plan_duration=$DURATION" >> "$GITHUB_OUTPUT"
echo "plan_output_length=${#OUTPUT}" >> "$GITHUB_OUTPUT"
echo "plan_exit_code=$EXIT_CODE" >> "$GITHUB_OUTPUT"
- name: "Deploy component"
id: deploy
run: |
echo "=== Starting deploy at $(date -u) ==="
START=$(date +%s)
OUTPUT=$(atmos terraform deploy <your-component> -s <your-stack> 2>&1) || true
EXIT_CODE=$?
END=$(date +%s)
DURATION=$((END - START))
echo "$OUTPUT"
echo ""
echo "=== Deploy completed ==="
echo "Exit code: $EXIT_CODE"
echo "Duration: ${DURATION}s"
echo "Output length: ${#OUTPUT} chars"
echo "deploy_duration=$DURATION" >> "$GITHUB_OUTPUT"
echo "deploy_output_length=${#OUTPUT}" >> "$GITHUB_OUTPUT"
echo "deploy_exit_code=$EXIT_CODE" >> "$GITHUB_OUTPUT"
- name: "Destroy component (cleanup)"
if: always()
run: |
echo "=== Starting destroy at $(date -u) ==="
atmos terraform destroy <your-component> -s <your-stack> -- -auto-approve 2>&1 || true
echo "=== Destroy completed ==="
- name: "Validate results"
run: |
echo "=== Results Summary ==="
echo "Plan: duration=${{ steps.plan.outputs.plan_duration }}s output=${{ steps.plan.outputs.plan_output_length }} chars exit=${{ steps.plan.outputs.plan_exit_code }}"
echo "Deploy: duration=${{ steps.deploy.outputs.deploy_duration }}s output=${{ steps.deploy.outputs.deploy_output_length }} chars exit=${{ steps.deploy.outputs.deploy_exit_code
}}"
echo ""
PLAN_LEN=${{ steps.plan.outputs.plan_output_length }}
DEPLOY_LEN=${{ steps.deploy.outputs.deploy_output_length }}
if [ "${{ inputs.mode }}" = "reproduce-bug" ]; then
echo "MODE: reproduce-bug"
echo "Expected: near-zero output and instant completion (the no-op bug)"
if [ "$PLAN_LEN" -lt 100 ] && [ "$DEPLOY_LEN" -lt 100 ]; then
echo "✅ Bug reproduced — both plan and deploy produced minimal/no output"
else
echo "⚠️ Bug NOT reproduced — commands produced real output (${PLAN_LEN} / ${DEPLOY_LEN} chars)"
echo " The wrapper may have been fixed upstream since @v3 tag was updated"
fi
else
echo "MODE: test-fix (PR #115)"
echo "Expected: real terraform output and multi-second duration"
if [ "$PLAN_LEN" -gt 100 ] && [ "$DEPLOY_LEN" -gt 100 ]; then
echo "✅ Fix confirmed — both plan and deploy produced real terraform output"
else
echo "❌ Fix NOT working — commands still producing minimal output (${PLAN_LEN} / ${DEPLOY_LEN} chars)"
exit 1
fi
fi
Results:
PR #115 resolves the wrapper no-op completely — plan, deploy, and destroy all execute real terraform through the same /opt/hostedtoolcache/atmos-wrapper/1.222.0/x64 path. The fix (replacing the require.main === module guard with a realpath comparison) works, confirmed for plan, apply and destroy in a real GHA deployment.c0rey.sc0tt
07/30/2026, 7:48 PMErik Osterman (Cloud Posse)
07/30/2026, 8:14 PM