Build the embedded editor with a canonical Linux compiler host
3 files changed,
+30
−36
core/tests/wasm_trap_containment.rs+7 −35internal/core/testdata/docs_core.wasmbinaryscripts/build-wasm.sh+23 −1
CI passed — run details
diff --git a/core/tests/wasm_trap_containment.rs b/core/tests/wasm_trap_containment.rs| index b0ac0d3..6732034 100644 |
| --- a/core/tests/wasm_trap_containment.rs |
| +++ b/core/tests/wasm_trap_containment.rs |
| @@ -263,42 +263,14 @@ fn build_wasm() -> Vec<u8> { |
| let workspace_root = core_dir |
| .parent() |
| .expect("core/ always has a parent (the repo root)"); |
| - // Must match scripts/build-wasm.sh's RUSTFLAGS exactly: this test |
| - // writes to the same `target/wasm32-unknown-unknown/release/ |
| - // docs_core.wasm` path the gate's `cmp` checks against the committed |
| - // testdata copy. A cargo build here with different flags (even just |
| - // "none", the default before this fix) would fingerprint-mismatch |
| - // against build-wasm.sh's build and silently overwrite that path with |
| - // differently-flagged bytes -- reintroducing embedded absolute paths |
| - // (and failing `cmp`) any time `cargo test` runs after `build-wasm.sh`. |
| - let cargo_home = std::env::var("CARGO_HOME") |
| - .map(PathBuf::from) |
| - .unwrap_or_else(|_| { |
| - PathBuf::from(std::env::var("HOME").expect("HOME must be set")).join(".cargo") |
| - }); |
| - let registry_root = cargo_home.join("registry").join("src"); |
| - let rustflags = format!( |
| - "-C strip=symbols --cfg getrandom_backend=\"custom\" --remap-path-prefix={}=/cargo-registry-src --remap-path-prefix={}=/docs-core", |
| - registry_root.display(), |
| - workspace_root.display(), |
| - ); |
| - let status = Command::new("cargo") |
| - .args([ |
| - "build", |
| - "--release", |
| - "--target", |
| - "wasm32-unknown-unknown", |
| - "--locked", |
| - "--lib", |
| - ]) |
| - .env("RUSTFLAGS", rustflags) |
| - .current_dir(&core_dir) |
| + // Use the same canonical host and flags as the committed artifact. Rebuild |
| + // current source, without recursively linting the test that invoked us. |
| + let status = Command::new("bash") |
| + .args(["scripts/build-wasm.sh", "--build-only"]) |
| + .current_dir(workspace_root) |
| .status() |
| - .expect("failed to run cargo build for wasm32-unknown-unknown"); |
| - assert!( |
| - status.success(), |
| - "cargo build --target wasm32-unknown-unknown failed" |
| - ); |
| + .expect("failed to run canonical wasm builder"); |
| + assert!(status.success(), "canonical wasm build failed"); |
| let artifact = core_dir.join("target/wasm32-unknown-unknown/release/docs_core.wasm"); |
| std::fs::read(&artifact).unwrap_or_else(|e| panic!("reading {artifact:?}: {e}")) |
| } |
diff --git a/internal/core/testdata/docs_core.wasm b/internal/core/testdata/docs_core.wasm| index a950278..4b7828f 100755 |
| Binary files a/internal/core/testdata/docs_core.wasm and b/internal/core/testdata/docs_core.wasm differ |
diff --git a/scripts/build-wasm.sh b/scripts/build-wasm.sh| index f3a6c56..012fc7f 100755 |
| --- a/scripts/build-wasm.sh |
| +++ b/scripts/build-wasm.sh |
| @@ -8,7 +8,29 @@ cd "$(dirname "$0")/.." |
| # Doc::with_client_id() both draw entropy this build has no safe source |
| # for. A doc comment alone has been wrong, or gotten around, more than |
| # once; this is the actual enforcement. |
| -cargo clippy --manifest-path core/Cargo.toml --all-targets -- -D warnings -D clippy::disallowed_methods |
| +if [[ "${1:-}" != "--build-only" ]]; then |
| + cargo clippy --manifest-path core/Cargo.toml --all-targets -- -D warnings -D clippy::disallowed_methods |
| +fi |
| +# Rust 1.98 emits different code on macOS even for the same wasm target. |
| +# The checked-in artifact and its containment tests use Linux amd64 everywhere. |
| +if [[ "$(uname -s)/$(uname -m)" != "Linux/x86_64" ]]; then |
| + command -v docker >/dev/null || { echo "build-wasm: Docker is required for the canonical Linux amd64 build" >&2; exit 1; } |
| + out="core/target/wasm32-unknown-unknown/release/docs_core.wasm" |
| + mkdir -p "$(dirname "$out")" |
| + temporary=$(mktemp "${out}.XXXXXX") |
| + trap 'rm -f "$temporary"' EXIT |
| + target_key=$(printf %s "$(pwd)" | shasum -a 256 | cut -c1-16) |
| + docker run --rm --platform linux/amd64 \ |
| + --mount "type=bind,source=$(pwd),target=/work,readonly" \ |
| + --mount "type=volume,source=oficina-docs-wasm-target-${target_key},target=/work/core/target" \ |
| + --mount type=volume,source=oficina-docs-wasm-cargo,target=/usr/local/cargo \ |
| + --mount type=volume,source=oficina-docs-wasm-rustup,target=/usr/local/rustup \ |
| + --workdir /work \ |
| + rust@sha256:8aea3a845c48caac4091a8d0e6494d213061f8f014dc2f5a5f1a88a1a8c9f301 \ |
| + bash -ec 'rustup target add wasm32-unknown-unknown >&2; ./scripts/build-wasm.sh --build-only >&2; cat core/target/wasm32-unknown-unknown/release/docs_core.wasm' > "$temporary" |
| + mv "$temporary" "$out" |
| + exit 0 |
| +fi |
| # --lib only: the wasm module shipped to wazero is the library crate. Native |
| # tooling under src/bin (e.g. emit_update, used from the host side of |
| # wire-gate.sh) is never part of that artifact and does not define the |