Skip to content

Commit a800f96

Browse files
committed
fix(ci): install tree-sitter from GitHub releases; accept SPDX on line 2
--ignore-scripts on tree-sitter-cli left the binary missing (ENOENT in migration-assistant). actions-lock prepends a managed-by comment, so the workflow linter now looks for SPDX in the first 5 lines. Also land the affinescript-vite compile-pass scaffold (Refs #56).
1 parent 256007e commit a800f96

7 files changed

Lines changed: 133 additions & 21 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,9 @@ jobs:
7777
# `dune runtest` — not an optional extra that merely widens
7878
# coverage. Dropping it turns the walker suite red, which is
7979
# the intended behaviour: see that file's header comment.
80-
# Pin exact version + --ignore-scripts: Sonar githubactions:S8543
81-
# (unlocked versions) and S6505 (lifecycle scripts). Same binary
82-
# the grammar's package.json asks for (^0.25.0 floor).
83-
run: npm install -g --ignore-scripts tree-sitter-cli@0.25.0
80+
# GitHub release binary (no npm postinstall). --ignore-scripts
81+
# on tree-sitter-cli@0.25.0 left the `tree-sitter` binary missing.
82+
run: ./scripts/install-tree-sitter-cli.sh
8483
- name: Build pinned tree-sitter-rescript grammar
8584
run: ./editors/tree-sitter-rescript/scripts/install.sh
8685
- name: Build
@@ -241,10 +240,9 @@ jobs:
241240
# so this job needs the same grammar prerequisites as `build`.
242241
# Before the skip was removed, this job was green while running
243242
# zero walker tests.
244-
# Pin exact version + --ignore-scripts: Sonar githubactions:S8543
245-
# (unlocked versions) and S6505 (lifecycle scripts). Same binary
246-
# the grammar's package.json asks for (^0.25.0 floor).
247-
run: npm install -g --ignore-scripts tree-sitter-cli@0.25.0
243+
# GitHub release binary (no npm postinstall). --ignore-scripts
244+
# on tree-sitter-cli@0.25.0 left the `tree-sitter` binary missing.
245+
run: ./scripts/install-tree-sitter-cli.sh
248246
- name: Build pinned tree-sitter-rescript grammar
249247
run: ./editors/tree-sitter-rescript/scripts/install.sh
250248
- name: Run tests with bisect_ppx instrumentation
@@ -347,17 +345,9 @@ jobs:
347345
with:
348346
node-version: "20"
349347
- name: Install tree-sitter CLI
350-
# npm install of tree-sitter-cli is the fast CI path (~5 s vs.
351-
# ~5 min for `cargo install tree-sitter-cli`). The repo's
352-
# preferred local path is cargo (see editors/tree-sitter-rescript/
353-
# README.md) — both produce the same `tree-sitter` binary that
354-
# the install script invokes via `command -v`. The version
355-
# tracks `tree-sitter-rescript`'s package.json devDependency
356-
# range.
357-
# Pin exact version + --ignore-scripts: Sonar githubactions:S8543
358-
# (unlocked versions) and S6505 (lifecycle scripts). Same binary
359-
# the grammar's package.json asks for (^0.25.0 floor).
360-
run: npm install -g --ignore-scripts tree-sitter-cli@0.25.0
348+
# GitHub release binary (no npm postinstall). --ignore-scripts
349+
# on tree-sitter-cli@0.25.0 left the `tree-sitter` binary missing.
350+
run: ./scripts/install-tree-sitter-cli.sh
361351
- name: Build pinned tree-sitter-rescript grammar
362352
# Direct script invocation rather than `just install-grammar` —
363353
# GitHub Actions runners do not ship `just` preinstalled, and

‎.github/workflows/workflow-linter.yml‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ jobs:
2828
errors=0
2929
for f in .github/workflows/*.yml .github/workflows/*.yaml; do
3030
[ -f "$f" ] || continue
31-
if ! head -1 "$f" | grep -q "SPDX-License-Identifier"; then
31+
# actions-lock prepends a managed-by comment, so SPDX is
32+
# often line 2. Accept it anywhere in the first 5 lines.
33+
if ! head -5 "$f" | grep -q "SPDX-License-Identifier"; then
3234
echo "ERROR: $f missing SPDX header"
3335
errors=$((errors + 1))
3436
fi

‎affinescript-vite/README.adoc‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
= affinescript-vite
2+
:toc: macro
3+
4+
toc::[]
5+
6+
Vite plugin **scaffold** for AffineScript (issue #56 remainder).
7+
Not a production bundler integration.
8+
9+
== Use
10+
11+
[source,javascript]
12+
----
13+
import affinescript from "affinescript-vite";
14+
15+
export default {
16+
plugins: [affinescript()],
17+
};
18+
----
19+
20+
`*.affine` modules are compiled with `affinescript compile --bun-esm`.
21+
The compiler must be on `PATH` (or set `AFFINESCRIPT` / `compiler` option).
22+
23+
Deno-ESM is retired; the emit target is Bun-ESM.

‎affinescript-vite/index.js‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// SPDX-License-Identifier: MPL-2.0
2+
/**
3+
* Vite plugin scaffold for AffineScript (#56).
4+
*
5+
* Transforms `*.affine` sources by shelling out to `affinescript compile
6+
* --bun-esm`. This is a compile-pass wiring, not a production bundler
7+
* integration: the compiler must be on PATH, and the plugin does not
8+
* ship a JS-hosted AffineScript frontend.
9+
*/
10+
import { spawnSync } from "node:child_process";
11+
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
12+
import { tmpdir } from "node:os";
13+
import { join } from "node:path";
14+
15+
export default function affinescriptVite(options = {}) {
16+
const compiler = options.compiler || process.env.AFFINESCRIPT || "affinescript";
17+
return {
18+
name: "affinescript",
19+
enforce: "pre",
20+
async transform(_code, id) {
21+
const filename = id.split("?")[0];
22+
if (!filename.endsWith(".affine")) return null;
23+
const dir = mkdtempSync(join(tmpdir(), "affinescript-vite-"));
24+
const src = join(dir, "input.affine");
25+
const out = join(dir, "out.bun.js");
26+
try {
27+
writeFileSync(src, _code);
28+
const r = spawnSync(compiler, ["compile", src, "-o", out, "--bun-esm"], {
29+
encoding: "utf8",
30+
});
31+
if (r.status !== 0) {
32+
const msg = (r.stderr || r.stdout || "affinescript compile failed").trim();
33+
this.error(msg);
34+
return null;
35+
}
36+
return { code: readFileSync(out, "utf8"), map: null };
37+
} finally {
38+
rmSync(dir, { recursive: true, force: true });
39+
}
40+
},
41+
};
42+
}

‎affinescript-vite/package.json‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "affinescript-vite",
3+
"version": "0.0.1",
4+
"description": "Vite plugin scaffold: compile .affine files with --bun-esm",
5+
"license": "MPL-2.0",
6+
"type": "module",
7+
"main": "index.js",
8+
"exports": {
9+
".": "./index.js"
10+
},
11+
"peerDependencies": {
12+
"vite": ">=5"
13+
}
14+
}

‎docs/ECOSYSTEM.adoc‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,10 @@ against a real Int-handle host DOM, mutation log asserted.
166166
`stdlib/Dom.affine` + `stdlib/Console.affine`. Remaining: full idaptik
167167
surface.
168168

169-
|`affinescript-vite` |scaffold |Build-tool integration shell.
169+
|`affinescript-vite` |scaffold |In-tree Vite plugin shell
170+
(`affinescript-vite/`): transforms `*.affine` via
171+
`affinescript compile --bun-esm`. Compiler must be on PATH. Not a
172+
production bundler.
170173

171174
|`affinescript-deno-test` |historical |Smoke-test harness from the retired
172175
Deno-ESM target. JS-host ESM is Bun-ESM (`--bun-esm`).

‎scripts/install-tree-sitter-cli.sh‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: MPL-2.0
3+
# Install a pinned tree-sitter CLI binary from GitHub Releases.
4+
#
5+
# Used by CI instead of `npm install -g --ignore-scripts tree-sitter-cli`:
6+
# that package's binary is fetched in a postinstall script, so
7+
# --ignore-scripts (Sonar S6505) leaves `tree-sitter` missing (ENOENT).
8+
# A release tarball has no lifecycle scripts.
9+
set -euo pipefail
10+
11+
VER="${TREE_SITTER_CLI_VERSION:-0.25.0}"
12+
DEST="${TREE_SITTER_CLI_DEST:-/usr/local/bin/tree-sitter}"
13+
14+
arch="$(uname -m)"
15+
case "$arch" in
16+
x86_64|amd64) ts_arch=x64 ;;
17+
aarch64|arm64) ts_arch=arm64 ;;
18+
*)
19+
echo "error: unsupported arch $arch" >&2
20+
exit 1
21+
;;
22+
esac
23+
24+
url="https://github.com/tree-sitter/tree-sitter/releases/download/v${VER}/tree-sitter-linux-${ts_arch}.gz"
25+
tmp="$(mktemp)"
26+
trap 'rm -f "$tmp"' EXIT
27+
curl -fsSL "$url" | gunzip > "$tmp"
28+
chmod +x "$tmp"
29+
30+
if [ -w "$(dirname "$DEST")" ]; then
31+
mv "$tmp" "$DEST"
32+
trap - EXIT
33+
else
34+
sudo mv "$tmp" "$DEST"
35+
trap - EXIT
36+
fi
37+
38+
"$DEST" --version

0 commit comments

Comments
 (0)