Repository navigation
Convert eligible ref-mirror effects to useEffectEvent (bd-t18384ia) #2564
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: TS Test Suite | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - main | |
| - kyoto | |
| pull_request: | |
| branches: | |
| - main | |
| - kyoto | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.run_id || github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| PANDOC_VERSION: "3.12.1" | |
| # Typst — the Pandoc-hybrid typst leg's `L`-tier tests (typst_compile.rs) | |
| # require a real `typst` binary on PATH (TYPST_VERSION_FLOOR is 0.8+). | |
| TYPST_VERSION: "0.15.1" | |
| jobs: | |
| test-suite: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| runs-on: ${{ matrix.os }} | |
| name: Run test suite | |
| if: github.repository == 'quarto-dev/q2' | |
| steps: | |
| - name: Checkout Repo | |
| uses: actions/checkout@v6 | |
| # Fix mtimes IMMEDIATELY after checkout, before anything else | |
| - name: Restore file modification times | |
| shell: bash | |
| run: | | |
| git ls-files | while read file; do | |
| time=$(git log -1 --format='@%ct' -- "$file" 2>/dev/null || echo '@0') | |
| [ "$time" != "@0" ] && touch -d "$time" "$file" 2>/dev/null || true | |
| done | |
| - name: Set up Homebrew | |
| if: runner.os == 'macOS' | |
| id: set-up-homebrew | |
| uses: Homebrew/actions/setup-homebrew@main | |
| # Consistent Rust setup for both platforms. Use the named `@nightly` | |
| # ref (not `@master`, which hard-errors without an explicit | |
| # `toolchain:` input) — it installs the nightly toolchain; cargo | |
| # then reads the pinned dated nightly from rust-toolchain.toml | |
| # (bd-at72) at build time. Matches the existing pattern on main. | |
| - name: Set up Rust nightly | |
| uses: dtolnay/rust-toolchain@nightly | |
| with: | |
| targets: wasm32-unknown-unknown | |
| components: rust-src | |
| - name: Output rust version | |
| shell: bash | |
| run: rustup --version | |
| # # Cache Rust AFTER toolchain is set up | |
| # - name: Cache Rust dependencies | |
| # uses: Swatinem/rust-cache@v2 | |
| # with: | |
| # cache-on-failure: true | |
| # Cache cargo-nextest and insta separately to avoid reinstalling | |
| - name: Install nextest | |
| uses: taiki-e/install-action@nextest | |
| - name: Install cargo-insta | |
| uses: taiki-e/install-action@v2 | |
| with: | |
| tool: cargo-insta | |
| # Pandoc setup (pinned to match Quarto 1.9) | |
| - name: Set up Pandoc (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| curl -LO "https://github.com/jgm/pandoc/releases/download/${PANDOC_VERSION}/pandoc-${PANDOC_VERSION}-1-amd64.deb" | |
| sudo dpkg -i "pandoc-${PANDOC_VERSION}-1-amd64.deb" | |
| shell: bash | |
| - name: Set up Pandoc (macOS) | |
| if: runner.os == 'macOS' | |
| run: | | |
| curl -LO "https://github.com/jgm/pandoc/releases/download/${PANDOC_VERSION}/pandoc-${PANDOC_VERSION}-arm64-macOS.pkg" | |
| sudo installer -pkg "pandoc-${PANDOC_VERSION}-arm64-macOS.pkg" -target / | |
| shell: bash | |
| # Typst setup — the docx/pptx Pandoc-hybrid leg also has a typst | |
| # backend whose `L`-tier tests require a real binary (see TYPST_VERSION above). | |
| - name: Set up Typst (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| curl -LO "https://github.com/typst/typst/releases/download/v${TYPST_VERSION}/typst-x86_64-unknown-linux-musl.tar.xz" | |
| tar -xf "typst-x86_64-unknown-linux-musl.tar.xz" | |
| sudo mv "typst-x86_64-unknown-linux-musl/typst" /usr/local/bin/typst | |
| shell: bash | |
| - name: Set up Typst (macOS) | |
| if: runner.os == 'macOS' | |
| run: brew install typst | |
| shell: bash | |
| # tree-sitter setup | |
| - name: Set up tree-sitter CLI (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libc6-dev gcc-multilib | |
| curl -LO https://github.com/tree-sitter/tree-sitter/releases/download/v0.25.8/tree-sitter-linux-x86.gz | |
| gunzip tree-sitter-linux-x86.gz | |
| chmod +x tree-sitter-linux-x86 | |
| sudo mv tree-sitter-linux-x86 /usr/local/bin/tree-sitter | |
| - name: Set up tree-sitter CLI (macOS) | |
| if: runner.os == 'macOS' | |
| run: brew install tree-sitter-cli | |
| # TypeScript workspace build | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '24' | |
| cache: 'npm' | |
| - name: Install npm dependencies | |
| shell: bash | |
| run: npm ci | |
| # design-system.md's token/physical-prop rules are only enforced by | |
| # this script — nothing else gates them. Runs right after npm ci so | |
| # a violation fails in seconds, not after the multi-minute WASM | |
| # build. (Added after ConnectionStatusDialog.css landed with 9 | |
| # violations one day after the rule itself merged — bd-owmzraf6.) | |
| - name: Lint hub-client CSS | |
| shell: bash | |
| run: npm run lint:css -w hub-client --if-present | |
| # WASM build for hub-client (must happen before TypeScript build) | |
| - name: Set up Clang (Linux) | |
| if: runner.os == 'Linux' | |
| uses: egor-tensin/setup-clang@v2 | |
| with: | |
| version: latest | |
| platform: x64 | |
| - name: Set up LLVM (macOS) | |
| if: runner.os == 'macOS' | |
| run: brew install llvm | |
| shell: bash | |
| - name: Install wasm-bindgen-cli | |
| shell: bash | |
| run: cargo install wasm-bindgen-cli --version 0.2.108 | |
| # wasm-opt (binaryen) is `build:wasm` step 3 (live-share payload | |
| # plan Phase 1). Pinned to the version local dev uses (Homebrew | |
| # binaryen 132) so CI and dev builds produce the same bytes. | |
| - name: Install binaryen (wasm-opt) | |
| shell: bash | |
| run: npm install -g binaryen@132.0.0 | |
| - name: Build WASM module | |
| shell: bash | |
| run: | | |
| cd hub-client | |
| npm run build:all | |
| # Real-wasm pandoc-host tests (hub-client/src/pandoc/*.wasm.test.ts) need the | |
| # pinned pandoc.wasm (sha-verified against resources/pandoc-wasm.json) and the | |
| # semantic output comparer. A cache miss during a GitHub outage fails the job. | |
| - name: Cache pandoc.wasm and typst assets | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| .cache/pandoc-wasm | |
| .cache/typst-assets | |
| key: pandoc-wasm-${{ hashFiles('resources/pandoc-wasm.json', 'resources/typst-wasm.json') }} | |
| - name: Fetch pandoc.wasm | |
| shell: bash | |
| run: node scripts/fetch-pandoc-wasm.mjs --require | |
| - name: Build quarto-output-extract | |
| shell: bash | |
| run: cargo build --release -p quarto-output-extract | |
| - name: Run hub-client tests | |
| shell: bash | |
| run: | | |
| cd hub-client | |
| npm run test:ci | |
| # engine-host-node: vitest suite (harness tests + the TS<->Rust wire-parity gate) | |
| - name: Run engine-host-node tests (vitest) | |
| shell: bash | |
| run: npm run test -w @quarto/engine-host-node | |
| # Bundle freshness gate: rebuild engine-host-node.mjs from source and assert | |
| # the committed bytes are unchanged. Fails if someone edited TS but forgot | |
| # to run `npm run bundle`. build-info.json is gitignored (volatile builtAt); | |
| # the diff targets only the bundle itself. | |
| - name: Check engine-host-node bundle freshness | |
| shell: bash | |
| run: | | |
| npm run bundle -w @quarto/engine-host-node | |
| git diff --exit-code -- ts-packages/quarto-engine-host-node/dist/engine-host-node.mjs | |
| # ts-bundle: vitest suite (the rollup driver behind `q2 call build-ts-extension`) | |
| - name: Run ts-bundle tests (vitest) | |
| shell: bash | |
| run: npm run test -w @quarto/ts-bundle | |
| # Same freshness gate for the embedded ts-bundle driver: rollup and its | |
| # plugins are pinned exactly, so the bytes depend only on the sources. | |
| - name: Check ts-bundle driver freshness | |
| shell: bash | |
| run: | | |
| npm run bundle -w @quarto/ts-bundle | |
| git diff --exit-code -- ts-packages/quarto-ts-bundle/dist/ts-bundle.mjs | |
| # preview-renderer's integration tier imports wasm-quarto-hub-client | |
| # (aliased in vitest.integration.config.ts:53-55 to the committed | |
| # hub-client/wasm-quarto-hub-client symlink -> crates/.../pkg). Without it | |
| # 26 of 50 files fail on module resolution, which is why this one suite | |
| # lives here rather than in workspace-ts-suites: it must run below the | |
| # `Build WASM module` step. GH #250. | |
| - name: Run preview-renderer integration tests | |
| shell: bash | |
| run: npm run test:integration -w ts-packages/preview-renderer | |
| # quarto-hub-mcp's parser tier (CAP-11): the qmd-structure tool tests | |
| # need the wasm-qmd-parser nodejs pkg, which only a wasm32 toolchain | |
| # can build. workspace-ts-suites is deliberately toolchain-free (the | |
| # suite's global setup writes a marker and the tier skips there), so | |
| # the tier runs here alongside the other WASM-needing suites. Beyond | |
| # the qmd-* files, the tier includes: conformance.test.ts, whose | |
| # parser-gated golden cases (e.g. get_outline) skip there but must | |
| # execute somewhere; bundle.test.ts, which stages the pkg into | |
| # dist-bundle at build time and so cannot run toolchain-free at all; | |
| # and npm-pack.test.ts / mcpb-pack.test.ts (CAP-15), whose pack | |
| # scripts rebuild that bundle. | |
| # | |
| # QUARTO_QMD_PARSER_REQUIRED=1: this step has the toolchain, so a | |
| # parser build failure here means the parser does not compile. Without | |
| # it the global setup writes its skip marker and the step goes green on | |
| # skipped tests, which is how a pampa feature-gating break reached the | |
| # v0.34.0 release (bd-yt3x1gwk). | |
| - name: Install wasm-pack | |
| uses: taiki-e/install-action@wasm-pack | |
| - name: Run quarto-hub-mcp parser-tier tests | |
| shell: bash | |
| env: | |
| QUARTO_QMD_PARSER_REQUIRED: "1" | |
| run: | | |
| npm run build --if-present -w ts-packages/quarto-sync-client -w ts-packages/quarto-automerge-schema | |
| cd ts-packages/quarto-hub-mcp | |
| npx vitest run src/qmd-ast.test.ts src/qmd-outline.test.ts src/qmd-sections.test.ts src/conformance.test.ts src/bundle.test.ts src/npm-pack.test.ts src/mcpb-pack.test.ts | |
| # ── Workspace TS suites (GH #250) ──────────────────────────────────────── | |
| # | |
| # A separate job on purpose. These suites need only Node + npm ci + the | |
| # ts-packages dists — no Rust, no WASM, no pandoc/tree-sitter. Keeping | |
| # them out of `test-suite` means a red hub-client test or the | |
| # bundle-freshness gate cannot mask them, and they are not serialised behind | |
| # an uncached WASM build on both matrix legs. The one suite that does need | |
| # the WASM (preview-renderer's integration tier) lives in `test-suite`. | |
| workspace-ts-suites: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| runs-on: ${{ matrix.os }} | |
| name: Workspace TS suites | |
| if: github.repository == 'quarto-dev/q2' | |
| steps: | |
| - name: Checkout Repo | |
| uses: actions/checkout@v6 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '24' | |
| cache: 'npm' | |
| - name: Install npm dependencies | |
| shell: bash | |
| run: npm ci | |
| # quarto-sync-client, quarto-hub-mcp and annotated-qmd resolve workspace | |
| # siblings through the `"import": "./dist/index.js"` export condition, and | |
| # hub-client bundles these packages from *source*, so nothing else builds | |
| # them. Build order is irrelevant — types resolve via src/ (see | |
| # crates/xtask/src/ts_packages.rs). Same guarded loop as | |
| # hub-client-e2e.yml:144-153. | |
| - name: Build ts-packages workspaces | |
| shell: bash | |
| run: | | |
| for pkg in ts-packages/*/; do | |
| if [ -f "$pkg/package.json" ]; then | |
| npm run build --workspace "$pkg" --if-present | |
| fi | |
| done | |
| # `--help` exits 0 only after the whole ESM graph links, so a missing or | |
| # stale dependency dist fails here rather than in someone's MCP session. | |
| # This is the same smoke check cargo xtask verify step 6 runs. | |
| - name: Smoke-check quarto-hub-mcp module graph | |
| shell: bash | |
| run: node ts-packages/quarto-hub-mcp/dist/index.js --help | |
| # Suites that are green as-is (GH #250 census, 2026-08-22). Explicit | |
| # `npm test` rather than each package's `test:ci`: kanban's test:ci chains | |
| # a test:wasm leg whose glob matches zero files, and preview-runtime's | |
| # test:wasm names a config file that does not exist. | |
| - name: Run preview-renderer unit tests | |
| shell: bash | |
| run: npm test -w ts-packages/preview-renderer | |
| - name: Run preview-runtime unit tests | |
| shell: bash | |
| run: npm test -w ts-packages/preview-runtime | |
| - name: Run pdf-viewer unit tests | |
| shell: bash | |
| run: npm test -w ts-packages/pdf-viewer | |
| - name: Run pandoc-host unit tests | |
| shell: bash | |
| run: | | |
| npm run typecheck:tests -w ts-packages/pandoc-host | |
| npm test -w ts-packages/pandoc-host | |
| # typst-host runs the real typst.ts wasm (from node_modules), the default fonts | |
| # (typst-assets crate, SHA-pinned) and, for the parity test, the pdf.js build: all | |
| # three come from `fetch-pandoc-wasm.mjs`. | |
| - name: Fetch pandoc, typst and pdf.js assets | |
| shell: bash | |
| run: node scripts/fetch-pandoc-wasm.mjs --require | |
| # The browser compiler is typst 0.14.2 (resources/typst-wasm.json) while the Rust tests | |
| # above use TYPST_VERSION (0.15.1). The parity test compares the two compilers' page | |
| # count and text, so it needs a native binary of the *browser's* version, pinned here | |
| # (not brew, which is unpinned). | |
| - name: Set up native typst for browser parity (pinned) | |
| shell: bash | |
| run: | | |
| TYPST_PARITY_VERSION=$(node -p "require('./resources/typst-wasm.json').typst_version") | |
| if [ "$RUNNER_OS" = "Linux" ]; then TRIPLE=x86_64-unknown-linux-musl; else TRIPLE=aarch64-apple-darwin; fi | |
| curl -fsSL -o typst-parity.tar.xz "https://github.com/typst/typst/releases/download/v${TYPST_PARITY_VERSION}/typst-${TRIPLE}.tar.xz" | |
| mkdir typst-parity && tar -xf typst-parity.tar.xz -C typst-parity --strip-components=1 | |
| echo "TYPST_PARITY_BIN=$PWD/typst-parity/typst" >> "$GITHUB_ENV" | |
| echo "TYPST_PARITY_REQUIRED=1" >> "$GITHUB_ENV" | |
| - name: Run typst-host unit tests (includes browser/native parity) | |
| shell: bash | |
| run: | | |
| npm run typecheck:tests -w ts-packages/typst-host | |
| npm test -w ts-packages/typst-host | |
| - name: Run quarto-api tests | |
| shell: bash | |
| run: npm test -w ts-packages/quarto-api | |
| - name: Run quarto-automerge-schema tests | |
| shell: bash | |
| run: npm test -w ts-packages/quarto-automerge-schema | |
| - name: Run wasm-js-bridge tests | |
| shell: bash | |
| run: npm test -w ts-packages/wasm-js-bridge | |
| - name: Run q2-preview-spa tests | |
| shell: bash | |
| run: | | |
| npm test -w q2-preview-spa | |
| npm run test:integration -w q2-preview-spa | |
| - name: Run kanban demo tests | |
| shell: bash | |
| run: | | |
| npm test -w q2-demos/kanban | |
| npm run test:integration -w q2-demos/kanban | |
| - name: Run trace-viewer tests | |
| shell: bash | |
| run: npm test -w trace-viewer | |
| # These two resolve workspace siblings through dist/, so they need the | |
| # "Build ts-packages workspaces" step above. hub-mcp's parser tier | |
| # (qmd-*, conformance's parser-gated cases, bundle.test.ts, | |
| # npm-pack.test.ts, mcpb-pack.test.ts) skips on this toolchain-free | |
| # leg and runs in the test-suite job instead. | |
| # | |
| # --retry=2: `src/doc-inventory.test.ts > getDocInventory > reports | |
| # index, text, and binary docs with states and heads` fails | |
| # intermittently on an async peer-connection race — measured at 2 | |
| # failures in 8 local runs (~25%), which across this job's two OS legs | |
| # is a ~44% false-red rate per PR. `--retry=2` brings that to roughly 3% | |
| # while keeping all 137 tests gating. The underlying race is tracked as | |
| # bd-7hd2gzf1. | |
| - name: Run quarto-sync-client tests | |
| shell: bash | |
| run: npm test -w ts-packages/quarto-sync-client -- --retry=2 | |
| - name: Run quarto-hub-mcp tests | |
| shell: bash | |
| run: npm test -w ts-packages/quarto-hub-mcp |