From 419d00903a58a45598c5d03b28e3c1d97df1007c Mon Sep 17 00:00:00 2001 From: Viwat Vchirawongkwin Date: Sat, 1 Aug 2026 09:49:54 +0700 Subject: [PATCH 1/2] [red] Reproduce Bash 3 smoke failure Signed-off-by: Viwat Vchirawongkwin --- tools/web/src/test/vps-deployment-contract.test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/web/src/test/vps-deployment-contract.test.ts b/tools/web/src/test/vps-deployment-contract.test.ts index caeb7d7..62f8d9d 100644 --- a/tools/web/src/test/vps-deployment-contract.test.ts +++ b/tools/web/src/test/vps-deployment-contract.test.ts @@ -119,6 +119,10 @@ describe("Cloudflare-fronted VPS deployment", () => { expect(script).toContain("/social/pyble-beta-og-1200x630.png"); expect(script).toContain("/social/pyble-beta-og-1200x630.svg"); expect(script).toContain("retired_public_asset_methods=( GET HEAD )"); + expect(script).toContain( + '--request "${retired_public_asset_method}"', + ); + expect(script).not.toContain("retired_public_asset_curl_mode"); expect(script).toMatch(/retired_public_asset_status[\s\S]*?!= 404/); expect(script).toContain("Cache-Control: *no-store"); }); @@ -469,6 +473,12 @@ describe("Cloudflare-fronted VPS deployment", () => { expect(firmwareNotFoundSmoke).toContain( "firmware_not_found_methods=( GET HEAD )", ); + expect(firmwareNotFoundSmoke).toContain( + '--request "${firmware_not_found_method}"', + ); + expect(firmwareNotFoundSmoke).not.toContain( + "firmware_not_found_curl_mode", + ); expect(firmwareNotFoundSmoke).toContain("esp32-c3-4mb/manifest.json"); expect(firmwareNotFoundSmoke).toContain("--dump-header"); expect(firmwareNotFoundSmoke).toContain("--write-out '%{http_code}'"); From de3c3d6e2db3844b4d3f21c9143e41bf1c94270e Mon Sep 17 00:00:00 2001 From: Viwat Vchirawongkwin Date: Sat, 1 Aug 2026 09:50:26 +0700 Subject: [PATCH 2/2] [green] Make deployment smoke Bash 3 compatible Signed-off-by: Viwat Vchirawongkwin --- tools/web/deploy/vps/deploy.sh | 12 ++---------- tools/web/src/test/vps-deployment-contract.test.ts | 8 ++------ 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/tools/web/deploy/vps/deploy.sh b/tools/web/deploy/vps/deploy.sh index c39af24..d0e8262 100755 --- a/tools/web/deploy/vps/deploy.sh +++ b/tools/web/deploy/vps/deploy.sh @@ -1166,14 +1166,10 @@ retired_public_asset_index=0 for retired_public_asset_path in "${retired_public_asset_paths[@]}"; do for retired_public_asset_method in "${retired_public_asset_methods[@]}"; do retired_public_asset_headers="${smoke_root}/retired-public-asset-${retired_public_asset_index}-${retired_public_asset_method}.headers" - retired_public_asset_curl_mode=() - if [[ "${retired_public_asset_method}" == HEAD ]]; then - retired_public_asset_curl_mode=( --head ) - fi retired_public_asset_status=$( curl --silent --show-error --max-time 30 \ --location --max-redirs 0 --proto '=https' \ - "${retired_public_asset_curl_mode[@]}" \ + --request "${retired_public_asset_method}" \ --dump-header "${retired_public_asset_headers}" \ --output /dev/null \ --write-out '%{http_code}' \ @@ -1217,14 +1213,10 @@ firmware_not_found_index=0 for firmware_not_found_path in "${firmware_not_found_paths[@]}"; do for firmware_not_found_method in "${firmware_not_found_methods[@]}"; do firmware_not_found_headers="${smoke_root}/firmware-not-found-${firmware_not_found_index}-${firmware_not_found_method}.headers" - firmware_not_found_curl_mode=() - if [[ "${firmware_not_found_method}" == HEAD ]]; then - firmware_not_found_curl_mode=( --head ) - fi firmware_not_found_status=$( curl --silent --show-error --max-time 30 \ --location --max-redirs 0 --proto '=https' \ - "${firmware_not_found_curl_mode[@]}" \ + --request "${firmware_not_found_method}" \ --dump-header "${firmware_not_found_headers}" \ --output /dev/null \ --write-out '%{http_code}' \ diff --git a/tools/web/src/test/vps-deployment-contract.test.ts b/tools/web/src/test/vps-deployment-contract.test.ts index 62f8d9d..0188b0b 100644 --- a/tools/web/src/test/vps-deployment-contract.test.ts +++ b/tools/web/src/test/vps-deployment-contract.test.ts @@ -119,9 +119,7 @@ describe("Cloudflare-fronted VPS deployment", () => { expect(script).toContain("/social/pyble-beta-og-1200x630.png"); expect(script).toContain("/social/pyble-beta-og-1200x630.svg"); expect(script).toContain("retired_public_asset_methods=( GET HEAD )"); - expect(script).toContain( - '--request "${retired_public_asset_method}"', - ); + expect(script).toContain('--request "${retired_public_asset_method}"'); expect(script).not.toContain("retired_public_asset_curl_mode"); expect(script).toMatch(/retired_public_asset_status[\s\S]*?!= 404/); expect(script).toContain("Cache-Control: *no-store"); @@ -476,9 +474,7 @@ describe("Cloudflare-fronted VPS deployment", () => { expect(firmwareNotFoundSmoke).toContain( '--request "${firmware_not_found_method}"', ); - expect(firmwareNotFoundSmoke).not.toContain( - "firmware_not_found_curl_mode", - ); + expect(firmwareNotFoundSmoke).not.toContain("firmware_not_found_curl_mode"); expect(firmwareNotFoundSmoke).toContain("esp32-c3-4mb/manifest.json"); expect(firmwareNotFoundSmoke).toContain("--dump-header"); expect(firmwareNotFoundSmoke).toContain("--write-out '%{http_code}'");