open-standards/.github/workflows/wai-quantum-editors.yml
Transaction Science 770f3b3039 wai/tools/wai-quantum-editor: the debugger, in the extension and the other editors
The extension contributes breakpoints for OpenQASM and a `wai-quantum`
debugger whose launch settings (program, stopOnEntry, inputs, noise, method,
outcomes) are the ones `wai-quantum dap` reads; it starts the adapter as the
command line's dap verb, and "Debug the program" debugs the file in the
editor. The Lua configuration registers the adapter with the debug adapter
plugin, and languages.toml declares it with a launch template. test/check.mjs
holds the manifest to the adapter's source and checks the client starts it;
the editors workflow runs the debugger's module tests and tests/dap.rs on
Linux and macOS.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-27 23:44:27 -04:00

204 lines
10 KiB
YAML

name: wai-quantum editors
# The engine in editors:
# - the language service (wai/wai-quantum/src/engine/editor): its unit tests,
# each module by name, on Linux and macOS;
# - the language server, `wai-quantum lsp`, driven over standard input and
# output by a scripted session from initialize to exit (tests/lsp.rs), on
# Linux and macOS;
# - the debugger (wai/wai-quantum/src/engine/debug.rs, with the visual edits
# and the statistical tests beside it), each module by name, and the debug
# adapter, `wai-quantum dap`, driven by scripted sessions from initialize
# to disconnect (tests/dap.rs), on Linux and macOS;
# - `wai-quantum fmt` on every program in the repository: formatting the
# formatted program changes nothing, and the engine draws the same circuit;
# - the tree-sitter grammar (wai/tools/tree-sitter-openqasm): regenerated
# with the pinned command line and identical to the committed parser, its
# corpus and highlighting tests, and every program in the repository's
# conformance material and examples parsed with no error;
# - the editor extension (wai/tools/wai-quantum-editor): built, packaged as a
# .vsix with the pinned packaging tool, and checked (its manifest against
# the server, its highlighting, its message when the command line is
# missing, the other editors' configurations, and the package's files);
# - the extension for editors with WebAssembly extensions, built for
# wasm32-wasip2.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
branches: [main]
paths:
- 'wai/wai-quantum/**'
- 'wai/wai-quantum-cli/**'
- 'wai/tools/tree-sitter-openqasm/**'
- 'wai/tools/wai-quantum-editor/**'
- 'wai/quantum-studio/src/examples.js'
- 'wai/quantum-ops-conformance/**'
- 'rust-toolchain.toml'
- '.github/workflows/wai-quantum-editors.yml'
pull_request:
paths:
- 'wai/wai-quantum/**'
- 'wai/wai-quantum-cli/**'
- 'wai/tools/tree-sitter-openqasm/**'
- 'wai/tools/wai-quantum-editor/**'
- 'wai/quantum-studio/src/examples.js'
- 'wai/quantum-ops-conformance/**'
- 'rust-toolchain.toml'
- '.github/workflows/wai-quantum-editors.yml'
jobs:
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-quantum-editors.yml \
"${{ github.event.pull_request.base.sha }}" \
"${{ github.event.pull_request.head.sha }}")
echo "this change touches the editors' support: $r"
echo "run=$r" >> "$GITHUB_OUTPUT"
editors-linux:
name: editors · linux
needs: relevant
if: needs.relevant.outputs.run == 'true'
runs-on: linux
timeout-minutes: 60
# The grammar's tree-sitter command (from npm, a prebuilt binary) needs glibc
# 2.39, which the runner's default image (act-22.04, glibc 2.35) lacks; this
# image has it, as wai-neural-e2e.yml's job does for its libraries.
container:
image: catthehacker/ubuntu:act-24.04
steps:
- uses: actions/checkout@v5
- name: Install Rust 1.98.0 with the wasm32-wasip2 target
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
rustup default 1.98.0
rustup target add --toolchain 1.98.0 wasm32-wasip2
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- uses: actions/setup-node@v4
with:
node-version: '22'
# The filters are module paths, and a filter that matches nothing passes, so
# each module must show a test that passed.
- name: The language service's tests
shell: bash
working-directory: wai/wai-quantum
run: |
set -euo pipefail
cargo test --locked --features full --lib engine::editor:: 2>&1 | tee "$RUNNER_TEMP/service.log"
for m in lex index gates format tests; do
grep -qE "^test engine::editor::$m::.* \.\.\. ok$" "$RUNNER_TEMP/service.log" || { echo "::error::no test of engine::editor::$m ran"; exit 1; }
done
grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$RUNNER_TEMP/service.log"
- name: The language server over standard input and output, and the verbs' parsing
shell: bash
working-directory: wai/wai-quantum-cli
run: |
set -euo pipefail
cargo test --locked --release --test lsp 2>&1 | tee "$RUNNER_TEMP/lsp.log"
grep -qE '^test result: ok\. 2 passed; 0 failed' "$RUNNER_TEMP/lsp.log" || { echo "::error::the protocol session did not pass"; exit 1; }
cargo test --locked --release --bin wai-quantum -- lsp:: the_command_line_parses_as_documented 2>&1 | tee "$RUNNER_TEMP/unit.log"
grep -qE '^test result: ok\. 4 passed; 0 failed' "$RUNNER_TEMP/unit.log" || { echo "::error::the server's unit tests did not all run"; exit 1; }
cargo build --locked --release
- name: The debugger's tests, and the debug adapter over standard input and output
shell: bash
run: |
set -euo pipefail
cd wai/wai-quantum
cargo test --locked --features full --lib -- engine::debug:: engine::visual:: engine::stats:: 2>&1 | tee "$RUNNER_TEMP/debug.log"
for m in debug visual stats; do
grep -qE "^test engine::$m::.* \.\.\. ok$" "$RUNNER_TEMP/debug.log" || { echo "::error::no test of engine::$m ran"; exit 1; }
done
grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$RUNNER_TEMP/debug.log"
cd ../wai-quantum-cli
cargo test --locked --release --test dap 2>&1 | tee "$RUNNER_TEMP/dap.log"
grep -qE '^test result: ok\. 2 passed; 0 failed' "$RUNNER_TEMP/dap.log" || { echo "::error::the debug adapter's sessions did not pass"; exit 1; }
- name: The grammar, regenerated as committed; its corpus, its highlighting, and every program in the repository
shell: bash
working-directory: wai/tools/tree-sitter-openqasm
run: |
set -euo pipefail
npm ci --no-audit --no-fund
npx tree-sitter generate --abi 14
git diff --exit-code -- src || { echo "::error::src/ is not what grammar.js generates: regenerate and commit it"; exit 1; }
npx tree-sitter test
node script/check-programs.mjs --out "$RUNNER_TEMP/programs"
- name: wai-quantum fmt on every program in the repository
shell: bash
run: |
set -euo pipefail
w="$PWD/wai/wai-quantum-cli/target/release/wai-quantum"
n=0
for f in "$RUNNER_TEMP"/programs/*.qasm; do
"$w" fmt "$f" > "$RUNNER_TEMP/once.qasm"
"$w" fmt "$RUNNER_TEMP/once.qasm" > "$RUNNER_TEMP/twice.qasm"
cmp -s "$RUNNER_TEMP/once.qasm" "$RUNNER_TEMP/twice.qasm" || { echo "::error::formatting $f again changed it"; diff "$RUNNER_TEMP/once.qasm" "$RUNNER_TEMP/twice.qasm" || true; exit 1; }
# The engine draws the formatted program as it draws the program, or refuses
# both (a refusal names a line, which formatting may move).
args=(); grep -qE '^\s*input\s+u?int' "$f" && args=(--input n=5)
a_out=$("$w" "${args[@]}" draw < "$f" 2>/dev/null) && a=0 || a=$?
b_out=$("$w" "${args[@]}" draw < "$RUNNER_TEMP/once.qasm" 2>/dev/null) && b=0 || b=$?
[ "$a" = "$b" ] || { echo "::error::the engine reads $f (status $a) and its formatted form (status $b) differently"; exit 1; }
[ "$a" != 0 ] || [ "$a_out" = "$b_out" ] || { echo "::error::the engine draws the formatted $f differently"; diff <(echo "$a_out") <(echo "$b_out") || true; exit 1; }
n=$((n + 1))
done
[ "$n" -ge 20 ] || { echo "::error::only $n programs were formatted"; exit 1; }
echo "fmt: $n programs, each stable, each drawn the same or refused alike"
- name: The editor extension, packaged and checked
shell: bash
working-directory: wai/tools/wai-quantum-editor
run: |
set -euo pipefail
npm ci --no-audit --no-fund
npm run package < /dev/null
WAI_QUANTUM_BIN="$GITHUB_WORKSPACE/wai/wai-quantum-cli/target/release/wai-quantum" node test/check.mjs --vsix wai-quantum.vsix
- name: The extension for editors with WebAssembly extensions, for wasm32-wasip2
shell: bash
working-directory: wai/tools/wai-quantum-editor/editors/extension
run: cargo build --locked --release --target wasm32-wasip2
editors-macos:
name: editors · macos
needs: relevant
if: needs.relevant.outputs.run == 'true'
runs-on: macos
timeout-minutes: 60
steps:
- uses: actions/checkout@v5
# launchd's PATH omits cargo on the macOS host runner.
- name: Put cargo on PATH
shell: bash
run: echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: The language service's tests
shell: bash
working-directory: wai/wai-quantum
run: |
set -euo pipefail
nice -n 10 cargo test --locked --features full --lib engine::editor:: 2>&1 | tee "$RUNNER_TEMP/service.log"
grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$RUNNER_TEMP/service.log"
- name: The language server over standard input and output
shell: bash
working-directory: wai/wai-quantum-cli
run: |
set -euo pipefail
nice -n 10 cargo test --locked --release --test lsp 2>&1 | tee "$RUNNER_TEMP/lsp.log"
grep -qE '^test result: ok\. 2 passed; 0 failed' "$RUNNER_TEMP/lsp.log" || { echo "::error::the protocol session did not pass"; exit 1; }
nice -n 10 cargo test --locked --release --test dap 2>&1 | tee "$RUNNER_TEMP/dap.log"
grep -qE '^test result: ok\. 2 passed; 0 failed' "$RUNNER_TEMP/dap.log" || { echo "::error::the debug adapter's sessions did not pass"; exit 1; }