Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions .github/workflows/editor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# The editor tools (spec/11 CP-8e): build the crate natively and as WebAssembly, run the language server's LSP tests on
# both the server and the extension's bundle, and package the VS Code extension (one .vsix for every platform) and the
# language server's npm package.
#
# Releases are by version (tooling/RELEASING.md), once the repository variable RELEASES is `on`. On main:
# - a version of tooling/rx-language-server that npm does not have is published there by trusted publishing (OIDC,
# no token), and tagged `language-server-v<version>`;
# - a version of tooling/vscode-rx without its tag `vscode-v<version>` is published to the VS Marketplace (a Microsoft
# Entra identity, or the secret VSCE_PAT) and Open VSX (the secret OVSX_PAT), and tagged.
# So a release is a version bump, merged.
name: editor

on:
push:
branches: [main]
paths: ["compiler/**", "tooling/**", ".github/workflows/editor.yml"]
pull_request:
paths: ["compiler/**", "tooling/**", ".github/workflows/editor.yml"]
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
with:
workspaces: compiler
- uses: pnpm/action-setup@v4
with:
version: 11.1.1 # solid-next's packageManager
- uses: actions/setup-node@v5
with:
node-version: 22
- name: rxc and its WebAssembly build
run: |
cargo build --release --manifest-path compiler/Cargo.toml
cargo build --lib --release --target wasm32-unknown-unknown --manifest-path compiler/Cargo.toml
- name: Solid next (the types the tests check against)
run: sh ref/scripts/solid-next.sh && npm --prefix ref install
- name: Language server tests
working-directory: tooling/rx-language-server
run: |
npm ci
node test/run.js
RXC=$GITHUB_WORKSPACE/compiler/target/release/rxc node test/run.js
- name: Package the extension
working-directory: tooling/vscode-rx
run: |
npm ci
npm run package
SERVER=dist/server.js node ../rx-language-server/test/run.js
- name: Pack the language server
working-directory: tooling/rx-language-server
run: npm pack
- uses: actions/upload-artifact@v4
with:
name: vsix
path: tooling/vscode-rx/*.vsix
- uses: actions/upload-artifact@v4
with:
name: npm
path: tooling/rx-language-server/*.tgz

# which versions are new: run on main only, after the build passed
versions:
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && vars.RELEASES == 'on'
needs: build
runs-on: ubuntu-latest
outputs:
server: ${{ steps.v.outputs.server }}
vscode: ${{ steps.v.outputs.vscode }}
steps:
- uses: actions/checkout@v5
- id: v
run: |
s=$(node -p 'const p = require("./tooling/rx-language-server/package.json"); p.name + "@" + p.version')
if [ -z "$(npm view "$s" version 2>/dev/null)" ]; then echo "server=$s" >> "$GITHUB_OUTPUT"; fi
v=$(node -p 'require("./tooling/vscode-rx/package.json").version')
if [ -z "$(git ls-remote --tags origin "refs/tags/vscode-v$v")" ]; then echo "vscode=$v" >> "$GITHUB_OUTPUT"; fi

publish-npm:
needs: versions
if: needs.versions.outputs.server != ''
runs-on: ubuntu-latest
environment: release
permissions:
id-token: write # trusted publishing: npm takes the job's OIDC token, and adds provenance
contents: write # the tag
steps:
- uses: actions/checkout@v5
- uses: actions/download-artifact@v4
with:
name: npm
- uses: actions/setup-node@v5
with:
node-version: 22
registry-url: https://registry.npmjs.org
- run: npm install -g npm@latest # trusted publishing needs npm 11.5.1 or later
- run: npm publish ./*.tgz --access public
- name: Tag
run: |
t="language-server-v${SERVER##*@}"
git tag "$t" && git push origin "$t"
env:
SERVER: ${{ needs.versions.outputs.server }}

publish-vscode:
needs: versions
if: needs.versions.outputs.vscode != ''
runs-on: ubuntu-latest
environment: release
permissions:
id-token: write # the Marketplace by Microsoft Entra, when AZURE_CLIENT_ID is set
contents: write # the tag
env: # job-wide, so that a step's `if` can see whether each is set
VSCE_PAT: ${{ secrets.VSCE_PAT }}
OVSX_PAT: ${{ secrets.OVSX_PAT }}
steps:
- uses: actions/checkout@v5
- uses: actions/download-artifact@v4
with:
name: vsix
- uses: actions/setup-node@v5
with:
node-version: 22
# the Marketplace takes a Microsoft Entra identity (no token) when the repository has AZURE_CLIENT_ID and
# AZURE_TENANT_ID, else the secret VSCE_PAT (an Azure DevOps token: global ones end 2026-12-01)
- name: Sign in to Microsoft Entra (OIDC)
if: vars.AZURE_CLIENT_ID != ''
uses: azure/login@v2
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
allow-no-subscriptions: true
- name: VS Marketplace
if: vars.AZURE_CLIENT_ID != '' || env.VSCE_PAT != ''
run: npx --yes @vscode/vsce publish --packagePath ./*.vsix ${{ vars.AZURE_CLIENT_ID != '' && '--azure-credential' || '' }}
- name: Open VSX
if: env.OVSX_PAT != ''
run: npx --yes ovsx publish ./*.vsix -p "$OVSX_PAT"
- name: Tag
if: vars.AZURE_CLIENT_ID != '' || env.VSCE_PAT != '' || env.OVSX_PAT != ''
run: git tag "vscode-v$V" && git push origin "vscode-v$V"
env:
V: ${{ needs.versions.outputs.vscode }}
3 changes: 2 additions & 1 deletion compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ publish = false
[lib]
name = "reactivescript"
path = "src/lib.rs"
# rlib for rxc; cdylib for the Node-API build (`--features node`, src/node.rs) that @reactivescript/compiler ships
# rlib for rxc; cdylib for the Node-API build (`--features node`, src/node.rs) that @reactivescript/compiler ships, and
# for the WebAssembly build the language server loads (src/wasm.rs, CP-8e)
crate-type = ["rlib", "cdylib"]

[[bin]]
Expand Down
8 changes: 8 additions & 0 deletions compiler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,25 @@ CP-1d). Both give the same answers as the reference.
| `model.rs` | `model.ts` | CP-6: regions, symbols, computations with their reads, writes and calls |
| `emit.rs`, `awaits.rs` | `ref/compile/emit.ts`, `awaits.ts` | the lowering: `__rt` calls around JSX views, and each target through Solid |
| `js.rs`, `oxc.rs` | | the lowered module as a tree, then as an Oxc program (spans: spec/11 CP-1c) |
| `spans.rs` | | what the AST's spans promise (spec/11 CP-8b), and a diagnostic's range (CP-8d) |
| `project.rs`, `prelude.ts` | `ref/types/project.ts` | the TSX projection TypeScript checks (spec/13 TY-1), with mappings onto `.rx` (CP-8c) |

The Solid pin (`solidjs-compiler` in `Cargo.toml`) must be the commit in
`ref/SOLID_NEXT`.

```sh
cargo build --release
target/release/rxc check ../examples/todo.rx # diagnostics
target/release/rxc check --json ../examples/todo.rx # … with ranges, for an editor or an agent (CP-8d)
target/release/rxc project ../examples/todo.rx # the TSX projection, with mappings onto .rx (CP-8c)
target/release/rxc model ../examples/todo.rx # the resolved model, as JSON
target/release/rxc serve # a language server's requests, a JSON line each (CP-8e)
cargo build --lib --release --target wasm32-unknown-unknown # … the same requests as WebAssembly (src/wasm.rs), what the server loads
target/release/rxc compile ../examples/todo.rx --out out # modules (dom; --target ssr|universal), source maps onto .rx, style.css
target/release/rxc app ../examples/todo.rx # the same as JSON, imports by .rx path: what the Vite front end gets
npm --prefix ../ref run crate # CP-5: the crate against ref/ on every program
npm --prefix ../ref run crate -- --project # … and the TSX projection, text for text, every mapping checked
RX_CRATE=1 npm --prefix ../ref run types # the types scenarios, on the crate's projection
npm --prefix ../ref run crate -- --lower # … and the lowered JavaScript, for every target, and its source maps
RX_CRATE=1 npm --prefix ../ref run compiled # the scenarios, run on the crate's output
RX_CRATE=1 npm --prefix ../ref run ssr # … served and hydrated from the crate's output
Expand Down
Loading
Loading