diff --git a/scripts/git-incremental-deploy.ps1 b/scripts/git-incremental-deploy.ps1 index de5fde4..67c57b5 100644 --- a/scripts/git-incremental-deploy.ps1 +++ b/scripts/git-incremental-deploy.ps1 @@ -1050,7 +1050,7 @@ if [ "$SKIP_DEPLOY" != "1" ]; then fi ok "Production image revision label matches $COMMIT_SHA" - PROD_PAYLOAD="$(cat <<'PROD_SCRIPT' + IFS= read -r -d '' PROD_PAYLOAD <<'PROD_SCRIPT' || true set -Eeuo pipefail TARGET="$1" @@ -3669,7 +3669,6 @@ fi abort_after_uncertain_switch "Consumed bootstrap handoff permissions could not be secured" } PROD_SCRIPT -)" printf '%s' "$PROD_PAYLOAD" | prod_ssh_script \ "$TARGET" "$CONTAINER_NAME" "$PORT" "$REGISTRY_COMMIT" "$EXPECTED_IMAGE_ID" "$COMMIT_SHA" \ diff --git a/scripts/git-incremental-deploy.test.mjs b/scripts/git-incremental-deploy.test.mjs new file mode 100644 index 0000000..ee68e03 --- /dev/null +++ b/scripts/git-incremental-deploy.test.mjs @@ -0,0 +1,18 @@ +import assert from 'node:assert/strict' +import { readFileSync } from 'node:fs' +import { spawnSync } from 'node:child_process' +import test from 'node:test' + +test('generated remote deployment payload is valid bash', () => { + const source = readFileSync(new URL('./git-incremental-deploy.ps1', import.meta.url), 'utf8') + const match = source.match(/\$remoteTemplate = @'\r?\n([\s\S]*?)\r?\n'@\r?\n\r?\nWrite-Step/) + assert.ok(match, 'remote deployment template should be present') + + const payload = match[1].replace(/__[A-Z0-9_]+__/g, "''") + const result = spawnSync('bash', ['-n'], { + input: payload, + encoding: 'utf8', + }) + + assert.equal(result.status, 0, result.stderr || result.stdout) +})