name: WAI Studio # WAI Studio on the web (wai/wai-studio): one front end, its core in WebAssembly, served by # `wai dev` at /_wai/ and hosted by the WAI site. # # - catalogue · linux: Studio's actions hold to the operation catalogue (scripts/actions.mjs # --check: an action with no operation, an operation placed for the browser with no action, # a mismatched name), the unit tests that need no core build (the generation and every rule # of the drift check broken in a copy, the palette, the local core's calls), and the core's # own tests and clippy (core/, wai-studio-core, on the http-conformance vectors); # - browser · macos: e2e/run.sh builds wai, the relay, the room service, the core, the room # client's packages, the quantum engine, Quantum Studio and Studio; runs every unit test, # the core's calls among them, and the drift check; then e2e/studio.e2e.mjs against a # `wai dev` stack in Chromium and Firefox: each panel on both hosts, Inspect and Verify on # conformance vectors with the results their cases expect, a room joined as a viewer, the # palette, axe (WCAG 2.2 A and AA), no console error or failed request; # - webkit · linux: the same in WebKit, in the browser image of the Playwright release # package-lock.json pins (by digest). The macOS runner is started from SSH, and a process of # an SSH session there cannot open WebKit's helper processes: WebKit never launches. # # `wai dev`'s side (/_wai/ on its origin, nothing listening beyond loopback) is tested in the # WAI conformance workflow's quickstart step (tests/cli_studio.rs and the binary's own tests). # # Push filters match the push's delta, so every path Studio builds on is listed. concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true on: push: branches: [main] paths: - 'wai/wai-studio/**' - 'wai/wai-rs/**' - 'wai/catalogue/**' - 'wai/quantum-studio/**' - 'wai/wai-web/**' - 'wai/wai-quantum/**' - 'wai/wai-ops/**' - 'wai/wai-live-web/**' - 'wai/quickstart/build-web.sh' - 'wai/http-conformance/**' - 'wai/pack-conformance/stills/**' - 'joule-code/joule-code-rs/crates/joule-moq-web/**' - 'joule-code/joule-code-rs/crates/joule-moq-relay/**' - 'joule-code/joule-code-rs/crates/joule-moq-room/**' - 'rust-toolchain.toml' - '.github/workflows/wai-studio.yml' pull_request: paths: - 'wai/wai-studio/**' - 'wai/wai-rs/**' - 'wai/catalogue/**' - 'wai/quantum-studio/**' - 'wai/wai-web/**' - 'wai/wai-quantum/**' - 'wai/wai-ops/**' - 'wai/wai-live-web/**' - 'wai/quickstart/build-web.sh' - 'wai/http-conformance/**' - 'wai/pack-conformance/stills/**' - 'joule-code/joule-code-rs/crates/joule-moq-web/**' - 'joule-code/joule-code-rs/crates/joule-moq-relay/**' - 'joule-code/joule-code-rs/crates/joule-moq-room/**' - 'rust-toolchain.toml' - '.github/workflows/wai-studio.yml' jobs: # The path filters gate the trigger; this job gates the work from the pull request's own # diff (scripts/pr-touches-paths.py, reading the list above), as wai-pack.yml explains. relevant: name: does this change touch it runs-on: linux-arm64 outputs: run: ${{ steps.gate.outputs.run }} steps: - uses: actions/checkout@v5 with: fetch-depth: 0 - id: gate run: | set -euo pipefail r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-studio.yml \ "${{ github.event.pull_request.base.sha }}" \ "${{ github.event.pull_request.head.sha }}") echo "this change touches WAI Studio: $r" echo "run=$r" >> "$GITHUB_OUTPUT" catalogue: name: the catalogue's actions, the unit tests and the core · linux needs: relevant if: needs.relevant.outputs.run == 'true' runs-on: linux timeout-minutes: 60 steps: - uses: actions/checkout@v5 - name: Install Rust 1.98.0 shell: bash run: | export PATH="$HOME/.cargo/bin:$PATH" command -v rustup >/dev/null 2>&1 || \ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.98.0 rustup toolchain install 1.98.0 --profile minimal --component clippy rustup default 1.98.0 echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - uses: actions/setup-node@v4 with: node-version: '22' - name: Studio's actions hold to the catalogue working-directory: wai/wai-studio run: node scripts/actions.mjs --check # The core's calls (test/core.test.mjs) need the core built for the web; the browser # job runs them. These need nothing built. - name: Unit tests shell: bash working-directory: wai/wai-studio run: | set -euo pipefail node --test --test-reporter=tap test/actions.test.mjs test/palette.test.mjs test/local-core.test.mjs 2>&1 | tee "$RUNNER_TEMP/unit.log" grep -qE '^# pass [1-9]' "$RUNNER_TEMP/unit.log" && grep -qE '^# fail 0$' "$RUNNER_TEMP/unit.log" || { echo "::error::no unit test ran, or one failed"; exit 1; } - name: The core's tests and clippy shell: bash working-directory: wai/wai-studio/core run: | set -euo pipefail cargo test --locked 2>&1 | tee "$RUNNER_TEMP/core.log" grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$RUNNER_TEMP/core.log" || { echo "::error::no test ran"; exit 1; } cargo clippy --locked --all-targets -- -D warnings browser: name: Studio in Chromium and Firefox · macos needs: relevant if: needs.relevant.outputs.run == 'true' runs-on: macos timeout-minutes: 120 steps: - uses: actions/checkout@v5 # launchd's PATH omits cargo and node on the macOS host runner. - name: Put cargo and node on PATH shell: bash run: | echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" echo "/opt/homebrew/bin" >> "$GITHUB_PATH" - name: wasm32 target and wasm-bindgen CLI 0.2.127 shell: bash run: | rustup target add wasm32-unknown-unknown command -v wasm-bindgen >/dev/null && wasm-bindgen --version | grep -q ' 0\.2\.127$' || cargo install --locked wasm-bindgen-cli --version 0.2.127 - name: The browsers Playwright drives shell: bash working-directory: wai/wai-studio run: | set -euo pipefail npm ci --ignore-scripts --no-audit --no-fund npx playwright install chromium firefox - name: Build everything, the unit tests, the drift check, and Studio in Chromium and Firefox shell: bash env: STUDIO_OUT: ${{ runner.temp }}/wai-studio-e2e run: nice -n 10 bash wai/wai-studio/e2e/run.sh --browsers chromium,firefox webkit: name: Studio in WebKit · linux needs: relevant if: needs.relevant.outputs.run == 'true' runs-on: linux timeout-minutes: 150 # Playwright 1.60.0's image (package-lock.json pins 1.60.0): Node, and WebKit with every # library it needs. container: image: mcr.microsoft.com/playwright@sha256:9bd26ad900bb5e0f4dee75839e957a89ae89c2b7ab1e76050e559790e946b948 steps: - uses: actions/checkout@v5 # The floor's zstd is C, compiled for wasm32 by clang and archived by llvm-ar. - name: Rust 1.98.0 with the wasm32 target, clang and llvm, wasm-bindgen CLI 0.2.127 shell: bash run: | set -euo pipefail apt-get update -qq apt-get install -y -qq --no-install-recommends curl ca-certificates build-essential pkg-config clang llvm python3 git > /dev/null curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.98.0 "$HOME/.cargo/bin/rustup" target add wasm32-unknown-unknown "$HOME/.cargo/bin/cargo" install --locked wasm-bindgen-cli --version 0.2.127 echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - name: Build everything, the unit tests, the drift check, and Studio in WebKit shell: bash env: STUDIO_OUT: ${{ runner.temp }}/wai-studio-e2e run: bash wai/wai-studio/e2e/run.sh --browsers webkit