Skip to content

fix(ci): point SQLINK_NATIVE_BINARY at the CARGO_BUILD_TARGET dir #22

fix(ci): point SQLINK_NATIVE_BINARY at the CARGO_BUILD_TARGET dir

fix(ci): point SQLINK_NATIVE_BINARY at the CARGO_BUILD_TARGET dir #22

Workflow file for this run

name: Wasm smoke
# Builds the wasm side (cli + sqlink-loader + workspace + standalone
# extensions), encodes the produced .wasm artifacts to component
# blobs, and runs the extension-smoke native test driver against
# the freshly-encoded components.
#
# Catches the "WIT skew" failure mode: a PR widens host-spi.wit (or
# loader-bridge.wit, or a policy variant) without rebuilding the
# extension components. The native host then expects an import set
# the stale component doesn't provide; extension-smoke panics with
# "failed to convert function to given type" / "no such function".
# That used to be a "you'll discover this when you run tests
# locally" problem. This job catches it at PR time.
on:
push:
branches: [main]
pull_request:
concurrency:
# Each push to a PR cancels the prior in-flight build. Wasm-side
# CI is heavy (wasi-sdk download, cargo install wasm-tools, full
# release-mode workspace build); piling builds up on a noisy PR
# branch wastes runner minutes.
group: wasm-smoke-${{ github.ref }}
cancel-in-progress: true
env:
# Same overrides the host jobs in ci.yml set. The repo's
# .cargo/config.toml.template pins build.target = wasm32-wasip2
# for the per-crate configs; this job explicitly targets wasm
# via --target on every cargo invocation, but we still want
# native compilation of build.rs / proc-macros to use the runner
# triple. Use explicit host triple; empty string breaks `cargo install`
# ("error: target was empty"). Wasm steps pass --target wasm32-wasip2
# explicitly to override this default.
CARGO_BUILD_TARGET: x86_64-unknown-linux-gnu
CARGO_PROFILE_DEV_DEBUG: "0"
CARGO_PROFILE_TEST_DEBUG: "0"
# The vendored excel extension needs nightly features via stable
# bootstrap (per the extensions/excel/.cargo/config.toml.template
# comment + recent ef6fe7a workaround).
RUSTC_BOOTSTRAP: "1"
jobs:
wasm-smoke:
name: Build wasm side + extension-smoke
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install pinned Rust toolchain + wasm32-wasip2
run: |
if ! command -v rustup >/dev/null 2>&1; then
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
| sh -s -- -y --default-toolchain none --profile minimal
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
export PATH="$HOME/.cargo/bin:$PATH"
fi
rustup show
rustup target add wasm32-wasip2
- name: Cache cargo registry + target dir
# Distinct shared-key from any future native-side job so we
# don't poison either cache with the other's artifacts.
uses: Swatinem/rust-cache@v2
with:
shared-key: wasm-smoke-v1
# Cache the workspace target/ + standalone-extension target/s.
# rust-cache only caches workspace target/ by default; the
# standalone-extension trees rebuild fresh each run, which
# is acceptable (small handful of crates each).
cache-targets: true
- name: Install wasi-sdk (clang + sysroot for libsqlite3-sys)
# Pinned to v33 by scripts/download-wasi-sdk.sh. Installs to
# deps/wasi-sdk/. Provides the C toolchain that
# libsqlite3-sys's bundled compile needs to produce wasm.
run: bash scripts/download-wasi-sdk.sh
- name: Generate per-crate .cargo/config.toml from .template
# Substitutes __WASI_SDK_PATH__ in every .cargo/config.toml.template
# under the workspace. The generated configs are gitignored;
# this script runs once per CI invocation.
env:
WASI_SDK_PATH: ${{ github.workspace }}/deps/wasi-sdk
run: bash scripts/setup-cargo-config.sh
- name: Install wasm-tools
# Used by scripts/encode-extension-components.sh and the
# extension-smoke loader path. --locked keeps the version
# deterministic across runs (and benefits from the cargo
# cache key above).
run: cargo install --locked wasm-tools
- name: Fetch wasi-preview1 reactor adapter
# scripts/encode-extension-components.sh expects this file
# for reactor-shape artifacts. The wasmtime project ships
# the canonical adapter alongside its releases.
run: |
mkdir -p "$HOME/.cache/xtran"
curl -fsSL \
"https://github.com/bytecodealliance/wasmtime/releases/download/v25.0.0/wasi_snapshot_preview1.reactor.wasm" \
-o "$HOME/.cache/xtran/wasi_snapshot_preview1.reactor.wasm"
- name: Build standalone-workspace extensions (pre-cli-include_bytes)
# cli/src/lib.rs `include_bytes!`s the cli-family extensions'
# .component.wasm files at compile time. They must be built +
# encoded BEFORE sqlite-cli compiles. Each has its own
# [workspace] root build per-directory.
#
# cli-family (12) embedded by sqlite-cli + other standalone
# extensions (color/formats/iban/sys-compat/list/excel)
# picked up by encode-extension-components.sh.
run: |
for d in \
extensions/archive-cli extensions/bundle-cli \
extensions/core-dotcmd extensions/prefix-cli \
extensions/serialize-cli extensions/session-cli \
extensions/sha3sum-cli extensions/sqlink-meta-cli \
extensions/sqlite-utils-data extensions/sqlite-utils-fts \
extensions/sqlite-utils-maint extensions/sqlite-utils-schema \
extensions/color extensions/formats extensions/iban \
extensions/sys-compat extensions/list extensions/excel; do
if [ -f "$d/Cargo.toml" ]; then
echo "::group::build $d"
(cd "$d" && cargo build --target wasm32-wasip2 --release)
echo "::endgroup::"
fi
done
- name: Encode .wasm -> .component.wasm (pre-cli)
# cli-family .component.wasm files must exist BEFORE building
# sqlite-cli. encode-extension-components.sh is idempotent;
# this run picks up the standalone-extension .wasm files just
# produced.
run: bash scripts/encode-extension-components.sh
- name: Build wasm-side workspace members
# Explicit `-p` list (not `--workspace --exclude`). Cargo's
# workspace resolver compiles shared transitive deps even
# when their direct dependents are excluded host's tokio
# ends up compiled for wasm despite host being excluded,
# tripping tokio's `Only features sync,macros,io-util,rt,
# time are supported on wasm` compile_error. Naming the
# wasm-side packages directly avoids the shared-resolve.
#
# Runs AFTER the standalone extensions are built + encoded
# because sqlite-cli's `include_bytes!` needs the
# .component.wasm files from extensions/<X>-cli/target/
# wasm32-wasip2/release/.
run: |
cargo build --target wasm32-wasip2 --release \
-p sqlite-cli \
-p sqlink-cli-argv \
-p sqlink-parsers \
-p json1-extension \
-p csv-extension \
-p math-extension \
-p crypto-extension \
-p uuid-extension \
-p regexp-extension \
-p stats-extension
- name: Encode .wasm -> .component.wasm (post-cli)
# Second pass to encode any in-workspace extension artifacts
# the prior step produced (json1, csv, math, crypto, uuid,
# regexp, stats) plus the sqlite-cli component itself.
# Idempotent w.r.t. the earlier pass.
run: bash scripts/encode-extension-components.sh
- name: Build sqlink-native (test subprocess host)
# extension-smoke's native driver shells out to
# target/release/sqlink-native for each smoke test
# (Scenario 1: native loader running the wasm extension
# via tvm-wasmtime). Must exist before the test step runs;
# CARGO_BUILD_TARGET is set to the host triple at the
# workflow level so this build picks up the native target
# explicitly.
run: cargo build --release -p sqlink-native
- name: Run extension-smoke (native driver)
# --test-threads=1 because of a pre-existing SIGSEGV at default
# parallelism with some fixtures sharing global SQLite state.
# Documented in fix/preexisting-breakage; safe to drop once the
# underlying isolation lands.
#
# SQLINK_NATIVE_BINARY overrides the test helper's default
# `target/release/sqlink-native` lookup. CARGO_BUILD_TARGET
# is set workflow-wide to x86_64-unknown-linux-gnu, so cargo
# writes the binary under target/<triple>/release/ instead.
env:
SQLINK_NATIVE_BINARY: ${{ github.workspace }}/target/x86_64-unknown-linux-gnu/release/sqlink-native
run: cargo test -p extension-smoke --test extension_smoke_native -- --test-threads=1