diff --git a/.github/workflows/ci-worker.yml b/.github/workflows/ci-worker.yml index 46bf6d7e..6c4f8e08 100755 --- a/.github/workflows/ci-worker.yml +++ b/.github/workflows/ci-worker.yml @@ -454,6 +454,7 @@ jobs: WASM_PRE_MUTATION_BUDGET_MINUTES: "40" WASM_PRIVATE_MUTATION_BUDGET_MINUTES: "20" WASM_JOB_HEADROOM_MINUTES: "5" + WASM_BINDGEN_CLI_SHA256: "064948d58e2d6c0a745216477a639ba696216d6309aaa902939d1b865b1d869d" steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -501,6 +502,31 @@ jobs: run: | cargo install wasm-pack --version 0.13.1 --locked echo "$CARGO_HOME/bin" >> "$GITHUB_PATH" + - name: install byte-bound wasm-bindgen CLI + # wasm-pack's fallback install is dependency- and host-toolchain-sensitive. + # Materialize the release binary in its completed non-dot cache layout so + # both the fallback and its disposable dot-prefixed staging are bypassed. + run: | + set -euo pipefail + version=0.2.126 + archive="$RUNNER_TEMP/wasm-bindgen-$version.tar.gz" + install_root="$WASM_PACK_CACHE/.unpacked-wasm-bindgen-cli-$version" + materialized_root="$WASM_PACK_CACHE/.materialized-wasm-bindgen-cargo-install-$version" + final_root="$WASM_PACK_CACHE/wasm-bindgen-cargo-install-$version" + rm -rf "$install_root" "$materialized_root" "$final_root" + curl --fail-with-body --silent --show-error --location \ + --retry 3 --retry-all-errors \ + "https://github.com/wasm-bindgen/wasm-bindgen/releases/download/$version/wasm-bindgen-$version-x86_64-unknown-linux-musl.tar.gz" \ + -o "$archive" + printf '%s %s\n' "$WASM_BINDGEN_CLI_SHA256" "$archive" \ + | sha256sum --check --strict + mkdir -p "$install_root" "$materialized_root" + tar --extract --gzip --strip-components=1 --file="$archive" --directory="$install_root" + mv -- "$install_root/wasm-bindgen" "$materialized_root/wasm-bindgen" + mv -- "$install_root/wasm-bindgen-test-runner" "$materialized_root/wasm-bindgen-test-runner" + mv -- "$materialized_root" "$final_root" + echo "$final_root" >> "$GITHUB_PATH" + rm -rf "$install_root" "$archive" - name: install byte-bound Binaryen Node transport run: | set -euo pipefail diff --git a/packages/colors/test/release-contract.test.mjs b/packages/colors/test/release-contract.test.mjs index 3073cfeb..3b0a9054 100644 --- a/packages/colors/test/release-contract.test.mjs +++ b/packages/colors/test/release-contract.test.mjs @@ -3582,6 +3582,61 @@ test("WASM runtime budget is one canonical self-contained exact contract", async ), "the live wasm-pack toolchain must equal the budget declaration", ); + assert.match( + wasmJob, + /WASM_BINDGEN_CLI_SHA256: "064948d58e2d6c0a745216477a639ba696216d6309aaa902939d1b865b1d869d"/u, + "the canonical wasm-bindgen release archive must be byte-bound", + ); + const expectedBindgenInstall = [ + "set -euo pipefail", + `version=${budget.toolchain.wasmBindgen}`, + 'archive="$RUNNER_TEMP/wasm-bindgen-$version.tar.gz"', + 'install_root="$WASM_PACK_CACHE/.unpacked-wasm-bindgen-cli-$version"', + 'materialized_root="$WASM_PACK_CACHE/.materialized-wasm-bindgen-cargo-install-$version"', + 'final_root="$WASM_PACK_CACHE/wasm-bindgen-cargo-install-$version"', + 'rm -rf "$install_root" "$materialized_root" "$final_root"', + "curl --fail-with-body --silent --show-error --location \\", + " --retry 3 --retry-all-errors \\", + ' "https://github.com/wasm-bindgen/wasm-bindgen/releases/download/$version/' + + 'wasm-bindgen-$version-x86_64-unknown-linux-musl.tar.gz" \\', + ' -o "$archive"', + "printf '%s %s\\n' \"$WASM_BINDGEN_CLI_SHA256\" \"$archive\" \\", + " | sha256sum --check --strict", + 'mkdir -p "$install_root" "$materialized_root"', + 'tar --extract --gzip --strip-components=1 --file="$archive" --directory="$install_root"', + 'mv -- "$install_root/wasm-bindgen" "$materialized_root/wasm-bindgen"', + 'mv -- "$install_root/wasm-bindgen-test-runner" "$materialized_root/wasm-bindgen-test-runner"', + 'mv -- "$materialized_root" "$final_root"', + 'echo "$final_root" >> "$GITHUB_PATH"', + 'rm -rf "$install_root" "$archive"', + ].join("\n"); + const assertBindgenScript = (script) => + assert.equal( + script, + expectedBindgenInstall, + "wasm-pack must find byte-bound binaries directly in its completed non-dot cache root", + ); + const bindgenInstall = workflowRunScript(ci, "name: install byte-bound wasm-bindgen CLI"); + assertBindgenScript(bindgenInstall); + for (const broken of [ + expectedBindgenInstall.replace(" | sha256sum --check --strict", ""), + expectedBindgenInstall.replace( + 'final_root="$WASM_PACK_CACHE/wasm-bindgen-cargo-install-$version"', + 'final_root="$WASM_PACK_CACHE/.wasm-bindgen-cargo-install-$version"', + ), + expectedBindgenInstall.replace( + '"$materialized_root/wasm-bindgen-test-runner"', + '"$materialized_root/bin/wasm-bindgen-test-runner"', + ), + ]) { + assert.notEqual(broken, expectedBindgenInstall, "wasm-bindgen cache mutant must bite"); + assert.throws(() => assertBindgenScript(broken)); + } + assert.ok( + ci.indexOf("name: install byte-bound wasm-bindgen CLI") < + ci.indexOf("name: repeat runtime WASM build in one toolchain-pinned CI job"), + "the byte-bound wasm-bindgen CLI must exist before wasm-pack builds the runtime", + ); assert.ok( wasmJob.includes(`targets: ${budget.toolchain.target}`), "the live WASM target must equal the budget declaration",