diff --git a/.github/workflows/publish-wasm-extension-artifact.yml b/.github/workflows/publish-wasm-extension-artifact.yml index 3b93b8e6..398e92f7 100644 --- a/.github/workflows/publish-wasm-extension-artifact.yml +++ b/.github/workflows/publish-wasm-extension-artifact.yml @@ -9,10 +9,6 @@ on: - '.github/workflows/publish-wasm-extension-artifact.yml' workflow_dispatch: inputs: - playground-ref: - description: 'wordpress-playground branch/tag/SHA to build against' - required: false - default: 'trunk' retention-days: description: 'Actions artifact retention in days' required: false @@ -26,47 +22,13 @@ concurrency: cancel-in-progress: true jobs: - base-image: - name: Build shared Playground base image - runs-on: ubuntu-latest - timeout-minutes: 20 - - steps: - - name: Check out wordpress-playground - uses: actions/checkout@v4 - with: - repository: WordPress/wordpress-playground - ref: ${{ github.event.inputs.playground-ref || 'trunk' }} - path: wordpress-playground - sparse-checkout: | - packages/php-wasm/compile/base-image - - - name: Build Playground base image - run: | - docker build \ - -f wordpress-playground/packages/php-wasm/compile/base-image/Dockerfile \ - --tag playground-php-wasm:base \ - wordpress-playground/packages/php-wasm/compile/base-image - - - name: Save Playground base image - run: docker save --output "${RUNNER_TEMP}/playground-php-wasm-base.tar" playground-php-wasm:base - - - name: Upload Playground base image - uses: actions/upload-artifact@v4 - with: - name: playground-php-wasm-base-image - path: ${{ runner.temp }}/playground-php-wasm-base.tar - if-no-files-found: error - retention-days: 1 - build: name: Build wp_mysql_parser.so (PHP ${{ matrix.php }}) - needs: base-image runs-on: ubuntu-latest timeout-minutes: 60 strategy: fail-fast: false - max-parallel: 6 + max-parallel: 1 matrix: # The Rust WASM path uses ext-php-rs 0.15, which depends on PHP 8 # Zend APIs. PHP 7.4 cannot be added here by extending the matrix. @@ -78,66 +40,17 @@ jobs: with: path: sqlite-database-integration - - name: Check out wordpress-playground - uses: actions/checkout@v4 - with: - repository: WordPress/wordpress-playground - ref: ${{ github.event.inputs.playground-ref || 'trunk' }} - path: wordpress-playground - sparse-checkout-cone-mode: false - sparse-checkout: | - /package.json - /package-lock.json - /nx.json - /tsconfig.base.json - /packages/meta/ - /packages/nx-extensions/ - /packages/php-wasm/cli-util/ - /packages/php-wasm/compile-extension/ - /packages/php-wasm/compile/ - /packages/php-wasm/fs-journal/ - /packages/php-wasm/logger/ - /packages/php-wasm/node/ - /packages/php-wasm/node-builds/8-0/ - /packages/php-wasm/node-builds/8-1/ - /packages/php-wasm/node-builds/8-2/ - /packages/php-wasm/node-builds/8-3/ - /packages/php-wasm/node-builds/8-4/ - /packages/php-wasm/node-builds/8-5/ - /packages/php-wasm/progress/ - /packages/php-wasm/scopes/ - /packages/php-wasm/stream-compression/ - /packages/php-wasm/universal/ - /packages/php-wasm/util/ - - name: Set up Node uses: actions/setup-node@v4 with: node-version: '24' - cache: 'npm' - cache-dependency-path: wordpress-playground/package-lock.json - - - name: Download Playground base image - uses: actions/download-artifact@v4 - with: - name: playground-php-wasm-base-image - path: ${{ runner.temp }}/playground-base-image - - - name: Load Playground base image - run: docker load --input "${RUNNER_TEMP}/playground-base-image/playground-php-wasm-base.tar" - - - name: Install Playground deps - working-directory: wordpress-playground - run: npm ci --ignore-scripts - name: Build wp_mysql_parser side module working-directory: sqlite-database-integration/packages/php-ext-wp-mysql-parser/wasm-spike env: PHP_VERSION: ${{ matrix.php }} ASYNC_MODE: jspi - COMPILE_EXTENSION_PACKAGE: '@php-wasm/compile-extension@3.1.27' - PLAYGROUND_REPO: ${{ github.workspace }}/wordpress-playground - SKIP_BASE_IMAGE_BUILD: '1' + COMPILE_EXTENSION_PACKAGE: '@php-wasm/compile-extension@3.1.28' run: bash build-in-docker-rust.sh - name: Verify side module exists diff --git a/.github/workflows/wasm-spike.yml b/.github/workflows/wasm-spike.yml index 7dc15d4b..14f3451a 100644 --- a/.github/workflows/wasm-spike.yml +++ b/.github/workflows/wasm-spike.yml @@ -12,54 +12,15 @@ on: - 'packages/php-ext-wp-mysql-parser/**' - '.github/workflows/wasm-spike.yml' workflow_dispatch: - inputs: - playground-ref: - description: 'wordpress-playground branch/tag/SHA to build against' - required: false - default: 'trunk' jobs: - base-image: - name: Build shared Playground base image - runs-on: ubuntu-latest - timeout-minutes: 20 - - steps: - - name: Check out wordpress-playground - uses: actions/checkout@v4 - with: - repository: WordPress/wordpress-playground - ref: ${{ github.event.inputs.playground-ref || 'trunk' }} - path: wordpress-playground - sparse-checkout: | - packages/php-wasm/compile/base-image - - - name: Build Playground base image - run: | - docker build \ - -f wordpress-playground/packages/php-wasm/compile/base-image/Dockerfile \ - --tag playground-php-wasm:base \ - wordpress-playground/packages/php-wasm/compile/base-image - - - name: Save Playground base image - run: docker save --output "${RUNNER_TEMP}/playground-php-wasm-base.tar" playground-php-wasm:base - - - name: Upload Playground base image - uses: actions/upload-artifact@v4 - with: - name: playground-php-wasm-base-image - path: ${{ runner.temp }}/playground-php-wasm-base.tar - if-no-files-found: error - retention-days: 1 - build-and-load: - name: Build wp_mysql_parser.so and load it in Playground (PHP ${{ matrix.php }}) - needs: base-image + name: Build wp_mysql_parser.so and load it in PHP.wasm (PHP ${{ matrix.php }}) runs-on: ubuntu-latest timeout-minutes: 60 strategy: fail-fast: false - max-parallel: 6 + max-parallel: 1 matrix: # The Rust WASM path uses ext-php-rs 0.15, which depends on PHP 8 # Zend APIs. PHP 7.4 cannot be added here by extending the matrix. @@ -72,66 +33,17 @@ jobs: with: path: sqlite-database-integration - - name: Check out wordpress-playground - uses: actions/checkout@v4 - with: - repository: WordPress/wordpress-playground - ref: ${{ github.event.inputs.playground-ref || 'trunk' }} - path: wordpress-playground - sparse-checkout-cone-mode: false - sparse-checkout: | - /package.json - /package-lock.json - /nx.json - /tsconfig.base.json - /packages/meta/ - /packages/nx-extensions/ - /packages/php-wasm/cli-util/ - /packages/php-wasm/compile-extension/ - /packages/php-wasm/compile/ - /packages/php-wasm/fs-journal/ - /packages/php-wasm/logger/ - /packages/php-wasm/node/ - /packages/php-wasm/node-builds/8-0/ - /packages/php-wasm/node-builds/8-1/ - /packages/php-wasm/node-builds/8-2/ - /packages/php-wasm/node-builds/8-3/ - /packages/php-wasm/node-builds/8-4/ - /packages/php-wasm/node-builds/8-5/ - /packages/php-wasm/progress/ - /packages/php-wasm/scopes/ - /packages/php-wasm/stream-compression/ - /packages/php-wasm/universal/ - /packages/php-wasm/util/ - - name: Set up Node uses: actions/setup-node@v4 with: node-version: '24' - cache: 'npm' - cache-dependency-path: wordpress-playground/package-lock.json - - - name: Download Playground base image - uses: actions/download-artifact@v4 - with: - name: playground-php-wasm-base-image - path: ${{ runner.temp }}/playground-base-image - - - name: Load Playground base image - run: docker load --input "${RUNNER_TEMP}/playground-base-image/playground-php-wasm-base.tar" - - - name: Install Playground deps - working-directory: wordpress-playground - run: npm ci --ignore-scripts - name: Build wp_mysql_parser side module working-directory: sqlite-database-integration/packages/php-ext-wp-mysql-parser/wasm-spike env: PHP_VERSION: ${{ matrix.php }} ASYNC_MODE: ${{ matrix.async-mode }} - COMPILE_EXTENSION_PACKAGE: '@php-wasm/compile-extension@3.1.27' - PLAYGROUND_REPO: ${{ github.workspace }}/wordpress-playground - SKIP_BASE_IMAGE_BUILD: '1' + COMPILE_EXTENSION_PACKAGE: '@php-wasm/compile-extension@3.1.28' run: bash build-in-docker-rust.sh - name: Verify build artifacts exist @@ -153,12 +65,15 @@ jobs: test -f "dist/$SOURCE_PATH" node -e "const artifact = require('./dist/manifest.json').artifacts[0]; if ('file' in artifact || 'sha256' in artifact) { throw new Error('manifest uses retired artifact fields'); }" - - name: Load the extension in Playground and parse a query + - name: Install PHP.wasm runtime deps + working-directory: sqlite-database-integration/packages/php-ext-wp-mysql-parser/wasm-spike + run: npm install --no-save --package-lock=false --no-audit --no-fund @php-wasm/node@3.1.28 @php-wasm/universal@3.1.28 + + - name: Load the extension in PHP.wasm and parse a query working-directory: sqlite-database-integration/packages/php-ext-wp-mysql-parser/wasm-spike env: - PLAYGROUND_REPO: ${{ github.workspace }}/wordpress-playground PHP_VERSION: ${{ matrix.php }} - run: node run-spike.mjs + run: node --experimental-wasm-jspi run-spike.mjs - name: Upload artifacts on success if: success() diff --git a/packages/php-ext-wp-mysql-parser/wasm-spike/Dockerfile.rust b/packages/php-ext-wp-mysql-parser/wasm-spike/Dockerfile.rust index 188b47dc..20eb14f1 100644 --- a/packages/php-ext-wp-mysql-parser/wasm-spike/Dockerfile.rust +++ b/packages/php-ext-wp-mysql-parser/wasm-spike/Dockerfile.rust @@ -1,5 +1,5 @@ # Layer that adds rustup + the wasm32-unknown-emscripten target on top of -# Playground's compile-extension image. +# PHP.wasm's compile-extension image. # # Base image is the one produced by `@php-wasm/compile-extension`'s # Dockerfile.ext, tagged as @@ -61,7 +61,7 @@ RUN set -eux; \ /usr/local/bin/php-host-info -i | grep -q "PHP API => ${HOST_PHP_API_VERSION}" # Set PHP_CONFIG explicitly so bindgen uses the wasm PHP headers from the -# Playground compile-extension image, not any host PHP package that apt may +# PHP.wasm compile-extension image, not any host PHP package that apt may # provide as a transitive dependency. ENV PHP_CONFIG=/usr/local/bin/php-config \ PHP=/usr/local/bin/php-host-info diff --git a/packages/php-ext-wp-mysql-parser/wasm-spike/RESULT.md b/packages/php-ext-wp-mysql-parser/wasm-spike/RESULT.md index 51360d21..c6cca2b8 100644 --- a/packages/php-ext-wp-mysql-parser/wasm-spike/RESULT.md +++ b/packages/php-ext-wp-mysql-parser/wasm-spike/RESULT.md @@ -2,10 +2,10 @@ ## Current status -The spike now builds and loads `wp_mysql_parser` in Playground across every +The spike now builds and loads `wp_mysql_parser` in PHP.wasm across every PHP version supported by the current `ext-php-rs` binding layer: 8.0 through 8.5, all JSPI. CI verifies each generated side module by loading its manifest -through Playground's compile-extension test harness and running a native lexer +through the released `@php-wasm/node` runtime and running a native lexer smoke test. PHP 7.4 is outside this Rust path because `ext-php-rs` 0.15 depends on PHP 8 Zend APIs and does not compile against PHP 7.4 headers. @@ -19,12 +19,11 @@ struct fields. The build uses the published `@php-wasm/compile-extension` CLI for the phpize side-module build, static archive force-linking, wasm-opt pass, and manifest -generation. A sparse Playground checkout is still required for the -`packages/php-wasm/compile` Docker assets and for CI's Playground load test. -The CLI is installed into an isolated temporary npm prefix before it is run; -the sparse Playground workspace also contains an unbuilt local -`@php-wasm/compile-extension` package, so relying on workspace `.bin` links -would bypass the published package. +generation. The CLI is installed into an isolated temporary npm prefix before +it is run and lazily fetches the PHP.wasm Docker assets it needs from the +matching Playground npm release. CI no longer checks out +`WordPress/wordpress-playground` for Docker assets or for the loader smoke +test. The local glue that remains is Rust-specific: build `libwp_mysql_parser.a` with the same Emscripten/PHP.wasm ABI and patch the vendored `ext-php-rs` registry copy so it can run as a PHP.wasm side module. @@ -108,31 +107,22 @@ extension build and manifest machinery. | Path | What it is | | --- | --- | -| `Dockerfile.rust` | Rust/nightly/host-PHP layer on top of Playground's compile-extension image. | +| `Dockerfile.rust` | Rust/nightly/host-PHP layer on top of the PHP.wasm compile-extension image. | | `build-in-docker-rust.sh` | Builds the Rust staticlib, then calls the published `@php-wasm/compile-extension` CLI. | | `write-extension-manifest.mjs` | Writes the combined all-version artifact manifest for the publish workflow. | | `shim/config.m4` | Minimal phpize wrapper. | | `shim/wp_mysql_parser_shim.c` | Pulls the Rust `get_module()` symbol into the side-module link. | -| `run-spike.mjs` | Loads the generated manifest in Playground and verifies the native lexer. | +| `run-spike.mjs` | Loads the generated manifest in `@php-wasm/node` and verifies the native lexer. | ## Reproduce ```bash cd packages/php-ext-wp-mysql-parser/wasm-spike -PLAYGROUND_REPO=/abs/path/to/wordpress-playground \ - bash build-in-docker-rust.sh +bash build-in-docker-rust.sh -PLAYGROUND_REPO=/abs/path/to/wordpress-playground PHP_VERSION=8.4 \ - node run-spike.mjs -``` - -The workflow still uses a sparse checkout of `WordPress/wordpress-playground` -for `packages/php-wasm/compile` Docker assets and the Playground loader smoke -test, while the extension compile itself runs through an isolated install of -the published npm CLI. +npm install --no-save --package-lock=false --no-audit --no-fund \ + @php-wasm/node@3.1.28 @php-wasm/universal@3.1.28 -Follow-up for Playground: make `@php-wasm/compile-extension` self-contained so -external extension projects do not need to shallow or sparse checkout -`WordPress/wordpress-playground` just to access Docker assets or test harness -files. +PHP_VERSION=8.4 node --experimental-wasm-jspi run-spike.mjs +``` diff --git a/packages/php-ext-wp-mysql-parser/wasm-spike/build-in-docker-rust.sh b/packages/php-ext-wp-mysql-parser/wasm-spike/build-in-docker-rust.sh index f18d0e39..04104a8a 100755 --- a/packages/php-ext-wp-mysql-parser/wasm-spike/build-in-docker-rust.sh +++ b/packages/php-ext-wp-mysql-parser/wasm-spike/build-in-docker-rust.sh @@ -4,7 +4,7 @@ # # 1. cargo build --release --target wasm32-unknown-emscripten # inside playground-php-wasm-ext-rust:-, which -# layers rustup + ext-php-rs build metadata on top of the Playground +# layers rustup + ext-php-rs build metadata on top of the PHP.wasm # compile-extension image. # 2. Hand the resulting libwp_mysql_parser.a + C shim + config.m4 to # `@php-wasm/compile-extension`, which owns phpize, emconfigure, @@ -21,22 +21,32 @@ ASYNC_MODE="${ASYNC_MODE:-jspi}" SPIKE_DIR="$(cd "$(dirname "$0")" && pwd)" CRATE_DIR="$(cd "$SPIKE_DIR/.." && pwd)" OUT_DIR="${OUT_DIR:-$SPIKE_DIR/dist}" -COMPILE_EXTENSION_PACKAGE="${COMPILE_EXTENSION_PACKAGE:-@php-wasm/compile-extension@3.1.27}" -PLAYGROUND_REPO="${PLAYGROUND_REPO:-$(cd "$SPIKE_DIR/../../../../wordpress-playground" 2>/dev/null && pwd || true)}" +COMPILE_EXTENSION_PACKAGE="${COMPILE_EXTENSION_PACKAGE:-@php-wasm/compile-extension@3.1.28}" +CLI_STAGE="$(mktemp -d)" +SRC_STAGE="" +COMPILE_EXTENSION_CLI="$CLI_STAGE/node_modules/@php-wasm/compile-extension/cli.js" mkdir -p "$OUT_DIR" +cleanup() { + if [ -n "$SRC_STAGE" ]; then + rm -rf "$SRC_STAGE" + fi + rm -rf "$CLI_STAGE" +} +trap cleanup EXIT + if [ "$ASYNC_MODE" != "jspi" ]; then echo "Unsupported ASYNC_MODE: $ASYNC_MODE. @php-wasm/compile-extension is JSPI-only." >&2 exit 1 fi case "$PHP_VERSION" in - 8.0) PHP_API_VERSION=20200930; PHP_RELEASE=8.0.30 ;; - 8.1) PHP_API_VERSION=20210902; PHP_RELEASE=8.1.34 ;; - 8.2) PHP_API_VERSION=20220829; PHP_RELEASE=8.2.30 ;; - 8.3) PHP_API_VERSION=20230831; PHP_RELEASE=8.3.30 ;; - 8.4) PHP_API_VERSION=20240924; PHP_RELEASE=8.4.20 ;; - 8.5) PHP_API_VERSION=20250925; PHP_RELEASE=8.5.5 ;; + 8.0) PHP_API_VERSION=20200930 ;; + 8.1) PHP_API_VERSION=20210902 ;; + 8.2) PHP_API_VERSION=20220829 ;; + 8.3) PHP_API_VERSION=20230831 ;; + 8.4) PHP_API_VERSION=20240924 ;; + 8.5) PHP_API_VERSION=20250925 ;; 7.4) echo "Unsupported PHP_VERSION: 7.4" >&2 echo "The WASM Rust build uses ext-php-rs 0.15, which depends on PHP 8 Zend APIs and does not compile against PHP 7.4 headers." >&2 @@ -49,71 +59,16 @@ case "$PHP_VERSION" in ;; esac -if [ -z "$PLAYGROUND_REPO" ] || [ ! -f "$PLAYGROUND_REPO/packages/php-wasm/compile/Makefile" ] || [ ! -f "$PLAYGROUND_REPO/packages/php-wasm/compile-extension/docker/Dockerfile.ext" ]; then - echo "PLAYGROUND_REPO must point at a wordpress-playground checkout with packages/php-wasm/compile and packages/php-wasm/compile-extension/docker." >&2 - exit 1 -fi - -patch_compile_extension_cli() { - local cli_path="$1" - - # The npm CLI currently rebuilds the Docker images itself. This script has - # already prepared those exact images in Stage 0, so patch the pinned CLI to - # reuse them and fail loudly if the installed package changes shape. - node --input-type=module - "$cli_path" <<'NODE' -import { readFileSync, writeFileSync } from 'node:fs'; - -const cliPath = process.argv[2]; -let source = readFileSync(cliPath, 'utf8'); - -const replacements = [ - [ - 'async function k(e){await p("make",["base-image"],{cwd:e.compileRoot})}', - 'async function k(e){if(process.env.COMPILE_EXTENSION_SKIP_IMAGE_BUILD==="1"){await p("docker",["image","inspect","playground-php-wasm:base"],{stdio:"ignore"});console.log("Skipping compile-extension base image build; using existing playground-php-wasm:base");return}await p("make",["base-image"],{cwd:e.compileRoot})}', - ], - [ - 'async function j(e){const t=$(e);return await p("docker",["build","-f","compile-extension/docker/Dockerfile.ext",".",`--tag=${t}`,"--progress=plain","--build-arg",`PHP_VERSION=${e.phpRelease}`,"--build-arg","JSPI=yes"],{cwd:e.phpWasmRoot}),t}', - 'async function j(e){const t=$(e);if(process.env.COMPILE_EXTENSION_SKIP_IMAGE_BUILD==="1"){await p("docker",["image","inspect",t],{stdio:"ignore"});console.log(`Skipping compile-extension image build; using existing ${t}`);return t}return await p("docker",["build","-f","compile-extension/docker/Dockerfile.ext",".",`--tag=${t}`,"--progress=plain","--build-arg",`PHP_VERSION=${e.phpRelease}`,"--build-arg","JSPI=yes"],{cwd:e.phpWasmRoot}),t}', - ], -]; - -for (const [from, to] of replacements) { - if (!source.includes(from)) { - throw new Error(`Unable to patch @php-wasm/compile-extension CLI. Missing pattern: ${from}`); - } - source = source.replace(from, to); -} - -writeFileSync(cliPath, source); -NODE - - grep -q 'COMPILE_EXTENSION_SKIP_IMAGE_BUILD' "$cli_path" -} - RUST_IMAGE="playground-php-wasm-ext-rust:${PHP_VERSION}-${ASYNC_MODE}" BASE_IMAGE="playground-php-wasm:compile-extension-php${PHP_VERSION//./-}-${ASYNC_MODE}" -echo "==> Stage 0: preparing $BASE_IMAGE via Playground compile-extension tooling" -if [ "${SKIP_BASE_IMAGE_BUILD:-}" = "1" ]; then - if ! docker image inspect playground-php-wasm:base >/dev/null 2>&1; then - echo "SKIP_BASE_IMAGE_BUILD=1 requires a preloaded playground-php-wasm:base image." >&2 - exit 1 - fi - echo "==> Stage 0: using preloaded playground-php-wasm:base" -else - BASE_IMAGE_DIR="$PLAYGROUND_REPO/packages/php-wasm/compile/base-image" - docker build \ - -f "$BASE_IMAGE_DIR/Dockerfile" \ - --tag="playground-php-wasm:base" \ - "$BASE_IMAGE_DIR" -fi -docker build \ - -f "$PLAYGROUND_REPO/packages/php-wasm/compile-extension/docker/Dockerfile.ext" \ - --tag="$BASE_IMAGE" \ - --progress=plain \ - --build-arg "PHP_VERSION=$PHP_RELEASE" \ - --build-arg "JSPI=yes" \ - "$PLAYGROUND_REPO/packages/php-wasm" +npm install --prefix "$CLI_STAGE" --no-audit --no-fund --ignore-scripts "$COMPILE_EXTENSION_PACKAGE" + +echo "==> Stage 0: preparing $BASE_IMAGE via @php-wasm/compile-extension" +node "$COMPILE_EXTENSION_CLI" \ + --prepare-image \ + --php-versions "$PHP_VERSION" \ + --jobs 1 echo "==> Stage 0: building $RUST_IMAGE" docker build \ @@ -301,30 +256,21 @@ EOF echo "==> Stage 2: phpize + emconfigure + emmake (@php-wasm/compile-extension)" SRC_STAGE="$(mktemp -d)" -CLI_STAGE="$(mktemp -d)" -trap 'rm -rf "$SRC_STAGE" "$CLI_STAGE"' EXIT cp "$SPIKE_DIR/shim/config.m4" "$SRC_STAGE/" cp "$SPIKE_DIR/shim/wp_mysql_parser_shim.c" "$SRC_STAGE/" cp "$OUT_DIR/libwp_mysql_parser.a" "$SRC_STAGE/" ARTIFACT="wp_mysql_parser-php${PHP_VERSION}-${ASYNC_MODE}.so" -COMPILE_EXTENSION_CLI="$CLI_STAGE/node_modules/@php-wasm/compile-extension/cli.js" - -npm install --prefix "$CLI_STAGE" --no-audit --no-fund --ignore-scripts "$COMPILE_EXTENSION_PACKAGE" -patch_compile_extension_cli "$COMPILE_EXTENSION_CLI" -( - cd "$PLAYGROUND_REPO" - COMPILE_EXTENSION_SKIP_IMAGE_BUILD=1 node "$COMPILE_EXTENSION_CLI" \ - --source "$SRC_STAGE" \ - --name wp_mysql_parser \ - --php-versions "$PHP_VERSION" \ - --out "$OUT_DIR" \ - --jobs 1 \ - --extra-ldflags "/build/libwp_mysql_parser.a" -) +node "$COMPILE_EXTENSION_CLI" \ + --source "$SRC_STAGE" \ + --name wp_mysql_parser \ + --php-versions "$PHP_VERSION" \ + --out "$OUT_DIR" \ + --jobs 1 \ + --extra-ldflags "/build/libwp_mysql_parser.a" rm -rf "$SRC_STAGE" -trap - EXIT +SRC_STAGE="" echo "==> Built $OUT_DIR/$ARTIFACT" diff --git a/packages/php-ext-wp-mysql-parser/wasm-spike/run-spike.mjs b/packages/php-ext-wp-mysql-parser/wasm-spike/run-spike.mjs index 27c74a0c..22552bed 100644 --- a/packages/php-ext-wp-mysql-parser/wasm-spike/run-spike.mjs +++ b/packages/php-ext-wp-mysql-parser/wasm-spike/run-spike.mjs @@ -1,18 +1,17 @@ -// Headless Playground runner for the wasm-spike. Uses the stock -// load-built-extension.mjs harness shipped with @php-wasm/compile-extension. -// We feed it our manifest and a snippet of PHP that pokes the Rust parser, -// then assert the output. +// Headless PHP.wasm runner for the wasm-spike. It feeds the generated +// extension manifest to the released @php-wasm/node runtime, then runs a +// snippet of PHP that pokes the Rust parser and asserts the output. // // Run with: -// node packages/php-ext-wp-mysql-parser/wasm-spike/run-spike.mjs +// node --experimental-wasm-jspi packages/php-ext-wp-mysql-parser/wasm-spike/run-spike.mjs // -// Optional env: PLAYGROUND_REPO=/path/to/wordpress-playground checkout. - -import { spawnSync } from 'node:child_process'; import { existsSync } from 'node:fs'; import { dirname, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; +import { loadNodeRuntime } from '@php-wasm/node'; +import { PHP } from '@php-wasm/universal'; + const here = dirname(fileURLToPath(import.meta.url)); const SPIKE_DIR = here; const MANIFEST = resolve(SPIKE_DIR, 'dist/manifest.json'); @@ -23,15 +22,6 @@ if (!existsSync(MANIFEST)) { process.exit(2); } -const PLAYGROUND_REPO = - process.env.PLAYGROUND_REPO || - resolve(here, '../../../../wordpress-playground-spike'); - -if (!existsSync(resolve(PLAYGROUND_REPO, 'package.json'))) { - console.error(`[spike] PLAYGROUND_REPO not found at ${PLAYGROUND_REPO}`); - process.exit(2); -} - const PHP_CODE = `count(); const EXPECTED = 'COUNT=5'; -// Probe JSPI up front: loadNodeRuntime asks wasm-feature-detect for it, and -// custom extensions only load under JSPI. If the probe fails here we know -// the harness will reject the side module before the runtime ever tries. -const probe = spawnSync( - process.execPath, - [ - '--experimental-wasm-jspi', - '-e', - "import('wasm-feature-detect').then(async ({ jspi }) => { process.exit((await jspi()) ? 0 : 42); })", +console.error('[spike] loading manifest in @php-wasm/node:', MANIFEST); +const runtime = await loadNodeRuntime(PHP_VERSION, { + extensions: [ + { + source: { + format: 'manifest', + manifestUrl: MANIFEST, + }, + }, ], - { cwd: PLAYGROUND_REPO, stdio: 'inherit' } -); -if (probe.status !== 0) { - console.error( - `[spike] wasm-feature-detect/jspi probe failed (exit ${probe.status}). ` + - `Node ${process.version} cannot enable JSPI; aborting before runtime.` - ); - process.exit(probe.status || 1); -} - -const cmd = [ - '--experimental-wasm-jspi', - '--experimental-strip-types', - '--experimental-transform-types', - '--disable-warning=ExperimentalWarning', - '--import', - resolve( - PLAYGROUND_REPO, - 'packages/meta/src/node-es-module-loader/register.mts' - ), - resolve( - PLAYGROUND_REPO, - 'packages/php-wasm/compile-extension/tests/load-built-extension.mjs' - ), - MANIFEST, - PHP_VERSION, - PHP_CODE, - EXPECTED, -]; - -console.error('[spike] running load-built-extension.mjs against', MANIFEST); -const result = spawnSync(process.execPath, cmd, { - cwd: PLAYGROUND_REPO, - stdio: 'inherit', }); -process.exit(result.status ?? 1); +const php = new PHP(runtime); + +try { + const response = await php.run({ code: PHP_CODE }); + if (response.exitCode !== 0) { + console.error(response.errors); + console.error(response.text); + process.exit(response.exitCode || 1); + } + if (response.text !== EXPECTED) { + console.error(`[spike] Expected ${JSON.stringify(EXPECTED)}, got ${JSON.stringify(response.text)}.`); + process.exit(1); + } + console.log(response.text); +} finally { + php.exit(); +} diff --git a/packages/php-ext-wp-mysql-parser/wasm-spike/shim/config.m4 b/packages/php-ext-wp-mysql-parser/wasm-spike/shim/config.m4 index c0cbb7dd..0c334fed 100644 --- a/packages/php-ext-wp-mysql-parser/wasm-spike/shim/config.m4 +++ b/packages/php-ext-wp-mysql-parser/wasm-spike/shim/config.m4 @@ -1,4 +1,4 @@ -dnl C shim that lets the Playground compile-extension Docker pipeline (phpize + +dnl C shim that lets the PHP.wasm compile-extension Docker pipeline (phpize + dnl emconfigure + emmake) build a side module whose actual code is a dnl pre-compiled Rust staticlib produced by `cargo build --target dnl wasm32-unknown-emscripten --release`.