feat(res-to-affine): land tree-sitter grammar build pipeline (Phase 2a, Refs #57) #579
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
| # SPDX-License-Identifier: MPL-2.0 | |
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Set up OCaml | |
| uses: ocaml/setup-ocaml@e32b06a3e831ff2fbc6f08cf35be2085e3918014 # v3 | |
| with: | |
| ocaml-compiler: "5.1" | |
| - name: Set up Node.js | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v4 | |
| with: | |
| node-version: "20" | |
| - name: Install dependencies | |
| run: opam install . --deps-only --with-test --with-doc | |
| - name: Build | |
| run: opam exec -- dune build | |
| - name: Run tests | |
| run: opam exec -- dune runtest | |
| - name: Run codegen WASM tests | |
| run: opam exec -- ./tools/run_codegen_wasm_tests.sh | |
| - name: Run codegen Deno-ESM tests (issue #122) | |
| # Compiles tests/codegen-deno/*.affine with the --deno-esm backend | |
| # and runs the *.harness.mjs under Node (CI has Node 20, not Deno; | |
| # the Phase 1 fixtures are pure logic so Node ESM exercises them). | |
| run: opam exec -- ./tools/run_codegen_deno_tests.sh | |
| - name: Run face-transformer regression tests | |
| run: opam exec -- ./tools/run_face_transformer_tests.sh | |
| - name: Issue #35 Phase 3 — block extension.ts regression | |
| # The vscode extension is now authored in extension.affine and | |
| # compiled to extension.cjs. Re-introducing extension.ts would | |
| # silently drift the source-of-truth back to TypeScript, which | |
| # the policy forbids. See tools/check-no-extension-ts.sh for | |
| # rationale + recovery instructions. | |
| run: ./tools/check-no-extension-ts.sh | |
| - name: Check formatting | |
| run: opam exec -- dune build @fmt | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Set up OCaml | |
| uses: ocaml/setup-ocaml@e32b06a3e831ff2fbc6f08cf35be2085e3918014 # v3 | |
| with: | |
| ocaml-compiler: "5.1" | |
| - name: Install dependencies | |
| # Match the build job: `dune build` compiles everything including | |
| # test/ (which depends on alcotest, with-test) and the @doc target | |
| # below (which depends on odoc, with-doc). Without these flags, lint | |
| # fails on missing alcotest before it ever reaches the doc step. | |
| run: opam install . --deps-only --with-test --with-doc | |
| - name: Build | |
| run: opam exec -- dune build | |
| - name: Lint with odoc | |
| run: opam exec -- dune build @doc | |
| continue-on-error: true | |
| vscode-smoke: | |
| # In-editor end-to-end smoke test for the .affine VS Code extension | |
| # (issue #139). Loads the compiled out/extension.cjs in a real VS Code | |
| # host via @vscode/test-electron and asserts: activation, command | |
| # registration + invocation, restartLsp cycling, and deactivate | |
| # teardown. The Node-based runner is a documented runtime carve-out | |
| # (see CLAUDE.md "Runtime Exemptions") because the VS Code extension | |
| # host is npm/Node-native and no Deno/JSR equivalent exists. | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v4 | |
| with: | |
| node-version: "20" | |
| - name: Install test runner dependencies | |
| working-directory: editors/vscode | |
| # The compiled out/extension.cjs is checked in (see #35 Phase 3), | |
| # so the smoke test does not need the OCaml toolchain — only the | |
| # Node-side test runner deps. peerDeps `vscode` is provided by | |
| # @vscode/test-electron at launch; the extension's runtime dep on | |
| # @hyperpolymath/affine-vscode is satisfied by npm install too. | |
| run: npm install --no-audit --no-fund | |
| - name: Run in-editor smoke (xvfb) | |
| working-directory: editors/vscode | |
| # Headless display required because @vscode/test-electron launches | |
| # the real Electron-based VS Code binary. | |
| run: xvfb-run -a npm test | |
| migration-assistant: | |
| # Build pinned tree-sitter-rescript grammar consumed by the | |
| # `.res → .affine` migration assistant (#57 Phase 2). The grammar | |
| # is manifest-vendored (`editors/tree-sitter-rescript/package.json`) | |
| # so this job exists to (a) verify the install script and pinned | |
| # commit still build cleanly and (b) gate `tools/res-to-affine/` | |
| # walker work that depends on the generated parser. | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v4 | |
| with: | |
| node-version: "20" | |
| - name: Install tree-sitter CLI | |
| # npm install of tree-sitter-cli is the fast CI path (~5 s vs. | |
| # ~5 min for `cargo install tree-sitter-cli`). The repo's | |
| # preferred local path is cargo (see editors/tree-sitter-rescript/ | |
| # README.md) — both produce the same `tree-sitter` binary that | |
| # the install script invokes via `command -v`. The version | |
| # tracks `tree-sitter-rescript`'s package.json devDependency | |
| # range. | |
| run: npm install -g tree-sitter-cli@^0.25.0 | |
| - name: Build pinned tree-sitter-rescript grammar | |
| # Direct script invocation rather than `just install-grammar` — | |
| # GitHub Actions runners do not ship `just` preinstalled, and | |
| # there is no other recipe used in this workflow that justifies | |
| # adding a setup step for it. The justfile recipe still exists | |
| # for local developer ergonomics; both call the same script. | |
| run: ./editors/tree-sitter-rescript/scripts/install.sh | |
| - name: Verify generated parser | |
| # `tree-sitter generate` is supposed to drop src/parser.c into | |
| # the cloned grammar. If it didn't, the install path is broken | |
| # and Phase-2 walker work cannot proceed; fail loudly here | |
| # rather than at the OCaml link step in a downstream PR. | |
| run: | | |
| test -f tools/vendor/tree-sitter-rescript/src/parser.c \ | |
| || { echo "error: parser.c not produced by tree-sitter generate" >&2; exit 1; } | |
| echo "parser.c size: $(wc -c < tools/vendor/tree-sitter-rescript/src/parser.c) bytes" | |
| - name: Smoke-parse a sample .res file | |
| # Sanity-check that the grammar actually parses a non-trivial | |
| # ReScript source. Picks the existing res-to-affine test fixture | |
| # so any drift in the pinned commit's syntactic surface area | |
| # surfaces here rather than at walker-rule writing time. | |
| run: | | |
| shopt -s nullglob | |
| fixtures=(tools/res-to-affine/test/fixtures/*.res) | |
| if [ ${#fixtures[@]} -eq 0 ]; then | |
| echo "no .res fixtures to smoke-parse; skipping" | |
| exit 0 | |
| fi | |
| tree-sitter parse \ | |
| --quiet \ | |
| "${fixtures[0]}" \ | |
| --paths tools/vendor/tree-sitter-rescript \ | |
| > /dev/null | |
| echo "smoke-parsed: ${fixtures[0]}" |