From 0aef3607a002178b6a1c463bc672ef83e900f302 Mon Sep 17 00:00:00 2001 From: JKRT Date: Wed, 8 Jul 2026 20:17:24 +0200 Subject: [PATCH 1/5] Build standalone binaries for macOS and Windows in release CI The existing release only ships a Linux x64 binary, so downstream consumers (e.g. OMEdit's CMake bundling) have no way to fetch a binary on other platforms without building from source. Co-Authored-By: JKRT Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01CRJK9NcghcYVowHN5tf4sj --- .github/workflows/test.yml | 69 +++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6c806b6..2e164a4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -83,9 +83,58 @@ jobs: name: server-release path: server-release/ + build-binaries: + if: startsWith(github.ref, 'refs/tags/') + strategy: + matrix: + include: + - os: macos-latest + arch: arm64 + artifact_name: modelica-language-server-macos-arm64 + - os: macos-13 + arch: x64 + artifact_name: modelica-language-server-macos-x64 + - os: windows-latest + arch: x64 + artifact_name: modelica-language-server-windows-x64.exe + runs-on: ${{ matrix.os }} + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: 24 + + - name: Install server dependencies + working-directory: server + run: npm ci + + - name: Build standalone binary + working-directory: server + run: npm run build:standalone + + - name: Stage binary + working-directory: server + shell: bash + run: | + mkdir -p ../server-release + if [ "${{ runner.os }}" = "Windows" ]; then + cp out/modelica-language-server.exe ../server-release/${{ matrix.artifact_name }} + else + cp out/modelica-language-server ../server-release/${{ matrix.artifact_name }} + fi + + - name: Archive binary + uses: actions/upload-artifact@v7 + with: + name: ${{ matrix.artifact_name }} + path: server-release/${{ matrix.artifact_name }} + release: if: startsWith(github.ref, 'refs/tags/') - needs: build + needs: [build, build-binaries] runs-on: ubuntu-latest permissions: contents: write @@ -106,6 +155,21 @@ jobs: name: server-release path: server-release/ + - uses: actions/download-artifact@v8 + with: + name: modelica-language-server-macos-arm64 + path: server-release/ + + - uses: actions/download-artifact@v8 + with: + name: modelica-language-server-macos-x64 + path: server-release/ + + - uses: actions/download-artifact@v8 + with: + name: modelica-language-server-windows-x64.exe + path: server-release/ + - name: Release uses: softprops/action-gh-release@v3 with: @@ -115,6 +179,9 @@ jobs: server-release/tree-sitter-modelica.wasm server-release/web-tree-sitter.wasm server-release/modelica-language-server-linux-x64 + server-release/modelica-language-server-macos-arm64 + server-release/modelica-language-server-macos-x64 + server-release/modelica-language-server-windows-x64.exe fail_on_unmatched_files: true generate_release_notes: true append_body: true From 9971c7746dedff47016c9e1c1a9a78c9b80df6b5 Mon Sep 17 00:00:00 2001 From: JKRT_CLAUDE <247156613+SVAGEN26@users.noreply.github.com> Date: Wed, 22 Jul 2026 11:42:27 +0200 Subject: [PATCH 2/5] ci: build standalone binaries on every push and PR, not only on tags Andreas asked that the mac/Windows binaries be built continuously to spot platform-specific breakage early, instead of first surfacing at release time. Drop the tag-only guard from build-binaries so it runs on push to main and on pull requests. The release job still gates on refs/tags/, so publishing behaviour is unchanged. Refs #61 Co-Authored-By: JKRT Co-Authored-By: JKRT_CLAUDE <247156613+SVAGEN26@users.noreply.github.com> Co-Authored-By: Claude --- .github/workflows/test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2e164a4..4bd34df 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -84,7 +84,6 @@ jobs: path: server-release/ build-binaries: - if: startsWith(github.ref, 'refs/tags/') strategy: matrix: include: From 746c224c6c70cd8a5ab392107d72116ae3c440c8 Mon Sep 17 00:00:00 2001 From: JKRT_CLAUDE <247156613+SVAGEN26@users.noreply.github.com> Date: Wed, 22 Jul 2026 14:41:22 +0200 Subject: [PATCH 3/5] build: fix Windows SEA build failing at postject step The Windows build-binaries matrix (now running on every push after 9971c77) fails at [3/4] with: Error: spawnSync ...\node_modules\.bin\postject ENOENT On Windows npm creates postject.cmd (and .ps1) in node_modules/.bin, not a bare "postject" file, so execFileSync of the bare name cannot find it. Resolve postject's JS entry via require.resolve and invoke node on it directly; this bypasses the .bin shim entirely and works uniformly on Linux, macOS, and Windows. Verified locally: the SEA build produces a 95 MB standalone binary on Linux with the new invocation and starts up (LSP refuses without a --stdio/--node-ipc mode, as expected). Refs #61 Co-Authored-By: JKRT Co-Authored-By: JKRT_CLAUDE <247156613+SVAGEN26@users.noreply.github.com> Co-Authored-By: Claude --- server/scripts/build-standalone.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/scripts/build-standalone.js b/server/scripts/build-standalone.js index 48478e6..261f7e8 100644 --- a/server/scripts/build-standalone.js +++ b/server/scripts/build-standalone.js @@ -20,7 +20,11 @@ const IS_WIN = process.platform === 'win32'; const IS_MAC = process.platform === 'darwin'; const BINARY_NAME = IS_WIN ? 'modelica-language-server.exe' : 'modelica-language-server'; const OUT_BINARY = path.join(OUT_DIR, BINARY_NAME); -const POSTJECT = path.join(__dirname, '..', 'node_modules', '.bin', 'postject'); +// Resolve postject's CLI script directly instead of the node_modules/.bin shim. +// On Windows npm creates postject.cmd there (not a bare "postject" file), so +// execFileSync of the bare name fails ENOENT. Invoking the JS entry under node +// works uniformly across platforms. +const POSTJECT_CLI = require.resolve('postject/dist/cli.js'); function run(cmd, args, opts) { console.log(` $ ${cmd} ${args.join(' ')}`); @@ -53,7 +57,7 @@ const postjectArgs = [ if (IS_MAC) { postjectArgs.push('--macho-segment-name', 'NODE_SEA'); } -run(POSTJECT, postjectArgs); +run(process.execPath, [POSTJECT_CLI, ...postjectArgs]); // 4. Re-sign on macOS (ad-hoc, sufficient for local use; CI can use a real identity). if (IS_MAC) { From bae61e26aa4973f1da268ba28f8432324271cfd3 Mon Sep 17 00:00:00 2001 From: JKRT Date: Wed, 2 Sep 2026 14:53:54 +0200 Subject: [PATCH 4/5] ci: replace the retired macos-13 runner with macos-15-intel The Intel macOS leg of build-binaries never ran. macos-13 has been retired from GitHub's hosted runner images, so the job found no runner, queued until the 24 hour limit and was cancelled: run 29920659897 reports a duration of 1d 0h 0m 3s for that leg while the arm64 and Windows legs finished in 27s and 56s. Re-running it only spends another day reaching the same state. macos-15-intel is the current Intel x64 image and is a standard runner, so it stays free on this public repository. The artifact keeps its name, since it is still an x64 macOS build. Co-Authored-By: JKRT Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01PDq3csHHprqNfAmwg5xURb --- .github/workflows/test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4bd34df..45ae993 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -90,7 +90,9 @@ jobs: - os: macos-latest arch: arm64 artifact_name: modelica-language-server-macos-arm64 - - os: macos-13 + # Intel macOS. macos-13 was retired, so a job asking for it never gets + # a runner: it queues until the 24 h limit and is cancelled. + - os: macos-15-intel arch: x64 artifact_name: modelica-language-server-macos-x64 - os: windows-latest From 2277d3f270dc030b992a5d0fa0a793d8f5eed2d6 Mon Sep 17 00:00:00 2001 From: JKRT Date: Wed, 2 Sep 2026 14:55:52 +0200 Subject: [PATCH 5/5] ci: build a standalone binary for arm64 Linux Only x64 Linux was covered, by the `build` job. arm64 Linux machines had no prebuilt server, so users there had to fall back to running server.js under Node.js. ubuntu-24.04-arm is a standard GitHub-hosted runner and free on public repositories, so the leg costs nothing to add. The staging step already handles non-Windows runners, and the release job now downloads and publishes the new artifact alongside the others. Co-Authored-By: JKRT Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01PDq3csHHprqNfAmwg5xURb --- .github/workflows/test.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 45ae993..bab7f96 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -98,6 +98,10 @@ jobs: - os: windows-latest arch: x64 artifact_name: modelica-language-server-windows-x64.exe + # arm64 Linux. The x64 Linux binary comes from the `build` job above. + - os: ubuntu-24.04-arm + arch: arm64 + artifact_name: modelica-language-server-linux-arm64 runs-on: ${{ matrix.os }} steps: - name: Checkout repository @@ -171,6 +175,11 @@ jobs: name: modelica-language-server-windows-x64.exe path: server-release/ + - uses: actions/download-artifact@v8 + with: + name: modelica-language-server-linux-arm64 + path: server-release/ + - name: Release uses: softprops/action-gh-release@v3 with: @@ -180,6 +189,7 @@ jobs: server-release/tree-sitter-modelica.wasm server-release/web-tree-sitter.wasm server-release/modelica-language-server-linux-x64 + server-release/modelica-language-server-linux-arm64 server-release/modelica-language-server-macos-arm64 server-release/modelica-language-server-macos-x64 server-release/modelica-language-server-windows-x64.exe