Skip to content

fix: regenerate with alef codegen fixes (clippy allows, noqa) #252

fix: regenerate with alef codegen fixes (clippy allows, noqa)

fix: regenerate with alef codegen fixes (clippy allows, noqa) #252

Workflow file for this run

name: CI
on:
push:
branches: [main]
paths:
- "crates/**"
- "packages/**"
- "e2e/**"
- "fixtures/**"
- "sources/**"
- "scripts/**"
- "docs/snippets/**"
- ".github/workflows/ci.yaml"
- ".github/actions/**"
- ".pre-commit-config.yaml"
- ".golangci.yml"
- ".cargo/config.toml"
- "rust-toolchain.toml"
- "Cargo.toml"
- "Cargo.lock"
- "Taskfile.yml"
- ".task/**"
- "pyproject.toml"
- ".clang-format"
- "alef.toml"
pull_request:
branches: [main]
paths:
- "crates/**"
- "packages/**"
- "e2e/**"
- "fixtures/**"
- "sources/**"
- "scripts/**"
- "docs/snippets/**"
- ".github/workflows/ci.yaml"
- ".github/actions/**"
- ".pre-commit-config.yaml"
- ".golangci.yml"
- ".cargo/config.toml"
- "rust-toolchain.toml"
- "Cargo.toml"
- "Cargo.lock"
- "Taskfile.yml"
- ".task/**"
- "pyproject.toml"
- ".clang-format"
- "alef.toml"
workflow_run:
workflows: ["Publish Release"]
types: [completed]
workflow_dispatch:
concurrency:
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: 0
CARGO_PROFILE_DEV_DEBUG: 0
RUST_BACKTRACE: short
BUILD_PROFILE: ci
jobs:
# ---------------------------------------------------------------------------
# 0. Clone vendors (shared prerequisite for most jobs)
# ---------------------------------------------------------------------------
clone-vendors:
name: Clone vendors
if: github.repository == 'kreuzberg-dev/tree-sitter-language-pack' && github.actor != 'dependabot[bot]'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
- name: Install tree-sitter CLI
run: npm install -g tree-sitter-cli
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: "3.14"
- name: Install Python dependencies
run: uv sync --no-install-project
- name: Cache parsers
uses: actions/cache@v5
with:
path: parsers
key: parsers-${{ hashFiles('sources/language_definitions.json') }}
restore-keys: |
parsers-
- name: Clone vendors
run: |
mkdir -p parsers
uv run --script scripts/clone_vendors.py
- name: Upload parsers
uses: actions/upload-artifact@v7
with:
name: language-parsers
path: parsers
retention-days: 1
# ---------------------------------------------------------------------------
# 1. validate — Lint & Format (prek hooks)
# ---------------------------------------------------------------------------
validate:
name: Validate (Lint & Format)
if: github.repository == 'kreuzberg-dev/tree-sitter-language-pack' && github.actor != 'dependabot[bot]'
runs-on: ubuntu-24.04-arm
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
# --- Task runner ---
- name: Install Task
uses: kreuzberg-dev/actions/install-task@v1
# --- Rust ---
- name: Setup Rust
uses: kreuzberg-dev/actions/setup-rust@v1
with:
use-sccache: "false"
install-llvm-cov: "false"
# --- Python ---
- name: Setup Python
uses: kreuzberg-dev/actions/setup-python-env@v1
with:
python-version: "3.13"
# --- Node.js / pnpm ---
- name: Setup Node Workspace
uses: kreuzberg-dev/actions/setup-node-workspace@v1
# --- Go ---
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: "1.26"
cache-dependency-path: packages/go/go.sum
- name: Install golangci-lint
uses: golangci/golangci-lint-action@v9
with:
install-only: true
# --- Java ---
- name: Setup Java
uses: actions/setup-java@v5
with:
distribution: "temurin"
java-version: "25"
# --- Elixir ---
- name: Setup Elixir
uses: kreuzberg-dev/actions/setup-elixir@v1
# --- Ruby ---
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.4"
bundler-cache: true
working-directory: packages/ruby
# --- PHP ---
- name: Setup PHP
uses: kreuzberg-dev/actions/setup-php@v1
# --- C/C++ ---
- name: Install C/C++ tools
run: |
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends cppcheck clang-format
# --- Alef ---
- name: Install alef
uses: kreuzberg-dev/actions/install-alef@v1
# --- Alef binding deps ---
- name: Install binding dependencies
run: alef setup
# --- Prek ---
- name: Run prek hooks
uses: j178/prek-action@v2
with:
extra-args: --all-files
env:
SKIP: alef-verify
# ---------------------------------------------------------------------------
# 2. validate-rust — Rust lint + alef checks
# ---------------------------------------------------------------------------
validate-rust:
name: Validate Rust & Alef
if: github.repository == 'kreuzberg-dev/tree-sitter-language-pack' && github.actor != 'dependabot[bot]'
needs: [clone-vendors]
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download parsers
uses: actions/download-artifact@v8
with:
name: language-parsers
path: parsers
- name: Setup Rust
uses: kreuzberg-dev/actions/setup-rust@v1
with:
use-sccache: "false"
install-llvm-cov: "false"
- name: Check Rust formatting
run: cargo fmt --check
- name: Run clippy
run: cargo clippy --workspace --exclude ts-pack-core-wasm -- -D warnings
env:
PROJECT_ROOT: ${{ github.workspace }}
TSLP_LANGUAGES: "python,rust,javascript,typescript,go,html,css,json"
TSLP_LINK_MODE: static
- name: Install alef
uses: kreuzberg-dev/actions/install-alef@v1
- name: Verify binding API parity
run: alef verify
- name: Check README freshness
run: |
alef readme
git diff --exit-code -- packages/*/README.md crates/*/README.md || {
echo "::error::READMEs are out of date. Run 'alef readme' and commit."
exit 1
}
- name: Check API docs freshness
run: |
alef docs
# Ignore whitespace-only diffs (markdown formatter may add/remove blank lines)
git diff --ignore-blank-lines --exit-code -- docs/reference/ || {
echo "::error::API docs are out of date. Run 'alef docs' and commit."
exit 1
}
- name: Check version sync
run: |
alef sync-versions
git diff --exit-code -- packages/ crates/ || {
echo "::error::Versions are out of sync. Run 'alef sync-versions' and commit."
exit 1
}
# ---------------------------------------------------------------------------
# 3. changes — Detect which parts of the repo changed
# ---------------------------------------------------------------------------
changes:
name: Detect Changes
if: github.repository == 'kreuzberg-dev/tree-sitter-language-pack' && github.actor != 'dependabot[bot]'
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
core: ${{ steps.filter.outputs.core }}
rust: ${{ steps.filter.outputs.rust }}
ffi: ${{ steps.filter.outputs.ffi }}
python: ${{ steps.filter.outputs.python }}
node: ${{ steps.filter.outputs.node }}
wasm: ${{ steps.filter.outputs.wasm }}
go: ${{ steps.filter.outputs.go }}
java: ${{ steps.filter.outputs.java }}
csharp: ${{ steps.filter.outputs.csharp }}
ruby: ${{ steps.filter.outputs.ruby }}
php: ${{ steps.filter.outputs.php }}
elixir: ${{ steps.filter.outputs.elixir }}
docker: ${{ steps.filter.outputs.docker }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Detect changes
uses: dorny/paths-filter@v3
id: filter
with:
filters: |
core:
- 'crates/ts-pack-core/**'
- 'Cargo.toml'
- 'Cargo.lock'
- 'sources/**'
rust:
- 'crates/ts-pack-core/**'
- 'crates/ts-pack-cli/**'
- 'e2e/rust/**'
ffi:
- 'crates/ts-pack-core-ffi/**'
- 'crates/ts-pack-core/**'
python:
- 'crates/ts-pack-core-py/**'
- 'packages/python/**'
- 'e2e/python/**'
- 'fixtures/**'
node:
- 'crates/ts-pack-core-node/**'
- 'packages/typescript/**'
- 'e2e/node/**'
- 'fixtures/**'
wasm:
- 'crates/ts-pack-core-wasm/**'
- 'packages/wasm/**'
- 'e2e/wasm/**'
- 'fixtures/**'
go:
- 'packages/go/**'
- 'e2e/go/**'
- 'crates/ts-pack-core-ffi/**'
- 'fixtures/**'
java:
- 'packages/java/**'
- 'e2e/java/**'
- 'crates/ts-pack-core-ffi/**'
- 'fixtures/**'
csharp:
- 'packages/csharp/**'
- 'e2e/csharp/**'
- 'crates/ts-pack-core-ffi/**'
- 'fixtures/**'
ruby:
- 'packages/ruby/**'
- 'e2e/ruby/**'
- 'fixtures/**'
php:
- 'crates/ts-pack-core-php/**'
- 'packages/php/**'
- 'e2e/php/**'
- 'fixtures/**'
elixir:
- 'packages/elixir/**'
- 'e2e/elixir/**'
- 'fixtures/**'
docker:
- 'Dockerfile*'
- 'docker/**'
# ---------------------------------------------------------------------------
# 4. rust-tests — Core Rust unit + e2e tests
# ---------------------------------------------------------------------------
rust-tests:
name: Rust Tests
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.core == 'true' ||
needs.changes.outputs.rust == 'true')
needs: [validate, validate-rust, changes, clone-vendors]
runs-on: ubuntu-latest
timeout-minutes: 60
env:
PROJECT_ROOT: ${{ github.workspace }}
TSLP_LANGUAGES: "python,rust,javascript,typescript,go,html,css,json"
TSLP_LINK_MODE: static
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download parsers
uses: actions/download-artifact@v8
with:
name: language-parsers
path: parsers
- name: Setup Rust
uses: kreuzberg-dev/actions/setup-rust@v1
with:
components: "rustfmt"
use-sccache: "false"
install-llvm-cov: "false"
- name: Install Task
uses: kreuzberg-dev/actions/install-task@v1
- name: Run workspace tests
run: cargo test --workspace --exclude ts-pack-core-wasm
- name: Run Rust E2E tests
run: task rust:e2e:test
# ---------------------------------------------------------------------------
# 5. build-ffi — Build FFI shared/static library
# ---------------------------------------------------------------------------
build-ffi:
name: Build FFI (${{ matrix.os }})
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.core == 'true' ||
needs.changes.outputs.ffi == 'true')
needs: [validate, validate-rust, changes, clone-vendors]
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
env:
PROJECT_ROOT: ${{ github.workspace }}
TSLP_LANGUAGES: "python,rust,javascript,typescript,go,html,css,json"
TSLP_LINK_MODE: static
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download parsers
uses: actions/download-artifact@v8
with:
name: language-parsers
path: parsers
- name: Setup Rust
uses: kreuzberg-dev/actions/setup-rust@v1
with:
components: ""
use-sccache: "false"
install-llvm-cov: "false"
- name: Build FFI library
run: cargo build --release -p ts-pack-core-ffi
- name: Upload FFI artifacts
uses: actions/upload-artifact@v7
with:
name: ffi-${{ matrix.os }}
path: |
target/release/libts_pack_core_ffi.a
target/release/libts_pack_core_ffi.so
target/release/libts_pack_core_ffi.dylib
crates/ts-pack-core-ffi/include/
retention-days: 7
# ---------------------------------------------------------------------------
# 6. build-python — Python wheels (maturin)
# ---------------------------------------------------------------------------
build-python:
name: Build Python (${{ matrix.platform }})
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.core == 'true' ||
needs.changes.outputs.python == 'true')
needs: [rust-tests, changes, clone-vendors]
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
platform: linux-x86_64
- os: macos-latest
platform: macos-arm64
env:
PROJECT_ROOT: ${{ github.workspace }}
TSLP_LANGUAGES: "python,rust,javascript,typescript,go,html,css,json"
TSLP_LINK_MODE: static
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download parsers
uses: actions/download-artifact@v8
with:
name: language-parsers
path: parsers
- name: Setup Rust
uses: kreuzberg-dev/actions/setup-rust@v1
with:
components: ""
use-sccache: "false"
install-llvm-cov: "false"
- name: Install maturin
run: pip install maturin
- name: Build wheel
run: maturin build --release --manifest-path crates/ts-pack-core-py/Cargo.toml --out dist
- name: Upload wheel
uses: actions/upload-artifact@v7
with:
name: wheel-${{ matrix.platform }}
path: dist/*.whl
if-no-files-found: error
retention-days: 7
# ---------------------------------------------------------------------------
# 6b. test-python — Run Python E2E tests against built wheels
# ---------------------------------------------------------------------------
test-python:
name: Test Python (${{ matrix.python-version }}, ${{ matrix.platform }})
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.core == 'true' ||
needs.changes.outputs.python == 'true')
needs: [build-python, changes]
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
platform: linux-x86_64
python-version: "3.10"
- os: ubuntu-latest
platform: linux-x86_64
python-version: "3.14"
- os: macos-latest
platform: macos-arm64
python-version: "3.14"
env:
PROJECT_ROOT: ${{ github.workspace }}
TSLP_LANGUAGES: "python,rust,javascript,typescript,go,html,css,json"
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Download wheel
uses: actions/download-artifact@v8
with:
name: wheel-${{ matrix.platform }}
path: dist
- name: Install wheel
shell: bash
run: |
wheel_file=$(find dist -name '*.whl' -print -quit)
pip install "$wheel_file" tree-sitter pytest
- name: Run E2E tests
run: cd e2e/python && pip install -e . && pytest tests/ -v
# ---------------------------------------------------------------------------
# 7. build-node — Node.js NAPI native module
# ---------------------------------------------------------------------------
build-node:
name: Build Node.js (${{ matrix.platform }})
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.core == 'true' ||
needs.changes.outputs.node == 'true')
needs: [rust-tests, changes, clone-vendors]
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
platform: linux-x64
- os: macos-latest
target: aarch64-apple-darwin
platform: macos-arm64
env:
PROJECT_ROOT: ${{ github.workspace }}
TSLP_LANGUAGES: "python,rust,javascript,typescript,go,html,css,json"
TSLP_LINK_MODE: static
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download parsers
uses: actions/download-artifact@v8
with:
name: language-parsers
path: parsers
- name: Setup Rust
uses: kreuzberg-dev/actions/setup-rust@v1
with:
components: ""
use-sccache: "false"
install-llvm-cov: "false"
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
- name: Install NAPI-RS CLI
run: npm install -g @napi-rs/cli
- name: Build native module
working-directory: crates/ts-pack-core-node
run: napi build --release --platform --target ${{ matrix.target }}
- name: Upload native module
uses: actions/upload-artifact@v7
with:
name: node-${{ matrix.platform }}
path: crates/ts-pack-core-node/*.node
if-no-files-found: error
retention-days: 7
# ---------------------------------------------------------------------------
# 7b. test-node — Node.js E2E tests
# ---------------------------------------------------------------------------
test-node:
name: Test Node.js (${{ matrix.platform }})
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.core == 'true' ||
needs.changes.outputs.node == 'true')
needs: [build-node, changes]
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
platform: linux-x64
- os: macos-latest
platform: macos-arm64
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Node.js workspace
uses: kreuzberg-dev/actions/setup-node-workspace@v1
- name: Download native module
uses: actions/download-artifact@v8
with:
name: node-${{ matrix.platform }}
path: crates/ts-pack-core-node/
- name: Smoke test native module
shell: bash
working-directory: crates/ts-pack-core-node
run: node -e "const m = require('./'); console.log('Languages:', m.availableLanguages().length)"
- name: Run E2E tests
shell: bash
working-directory: e2e/typescript
run: npx vitest run
# ---------------------------------------------------------------------------
# 8. build-wasm — WebAssembly (web + node targets)
# ---------------------------------------------------------------------------
build-wasm:
name: Build WASM
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.core == 'true' ||
needs.changes.outputs.wasm == 'true')
needs: [rust-tests, changes, clone-vendors]
runs-on: ubuntu-latest
timeout-minutes: 120
env:
TSLP_LANGUAGES: "python,rust,javascript,typescript,go,html,css,json"
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download parsers
uses: actions/download-artifact@v8
with:
name: language-parsers
path: parsers
- name: Setup Rust
uses: kreuzberg-dev/actions/setup-rust@v1
with:
target: wasm32-unknown-unknown
components: ""
use-sccache: "true"
install-llvm-cov: "false"
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Install wasi-sdk
uses: kreuzberg-dev/actions/install-wasi-sdk@v1
- name: Build WASM (web target)
working-directory: crates/ts-pack-core-wasm
run: wasm-pack build --target web --release
env:
PROJECT_ROOT: ${{ github.workspace }}
- name: Verify WASM artifacts
shell: bash
run: |
for FILE in \
crates/ts-pack-core-wasm/pkg/ts_pack_wasm.js \
crates/ts-pack-core-wasm/pkg/ts_pack_wasm.d.ts \
crates/ts-pack-core-wasm/pkg/ts_pack_wasm_bg.wasm; do
if [ ! -f "$FILE" ]; then
echo "ERROR: Expected file missing: $FILE"
exit 1
fi
echo "OK: $FILE"
done
- name: Upload WASM artifacts
uses: actions/upload-artifact@v7
with:
name: wasm-pkg
path: |
crates/ts-pack-core-wasm/pkg/*.wasm
crates/ts-pack-core-wasm/pkg/*.js
crates/ts-pack-core-wasm/pkg/*.ts
crates/ts-pack-core-wasm/pkg/package.json
retention-days: 7
- name: Build WASM (Node.js target)
working-directory: crates/ts-pack-core-wasm
run: wasm-pack build --target nodejs --release
env:
PROJECT_ROOT: ${{ github.workspace }}
- name: Upload WASM Node.js artifacts
uses: actions/upload-artifact@v7
with:
name: wasm-node-pkg
path: |
crates/ts-pack-core-wasm/pkg/*.wasm
crates/ts-pack-core-wasm/pkg/*.js
crates/ts-pack-core-wasm/pkg/*.ts
crates/ts-pack-core-wasm/pkg/package.json
retention-days: 7
# ---------------------------------------------------------------------------
# 8b. test-wasm — WASM E2E tests
# ---------------------------------------------------------------------------
test-wasm:
name: Test WASM
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.core == 'true' ||
needs.changes.outputs.wasm == 'true')
needs: [build-wasm, changes]
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download WASM Node.js artifacts
uses: actions/download-artifact@v8
with:
name: wasm-node-pkg
path: crates/ts-pack-core-wasm/pkg/
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
- name: Install E2E dependencies
working-directory: e2e/wasm
run: npm install
- name: Run E2E tests
working-directory: e2e/wasm
run: npx vitest run
# ---------------------------------------------------------------------------
# 9. test-go — Go tests (needs FFI)
# ---------------------------------------------------------------------------
test-go:
name: Test Go
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.go == 'true' ||
needs.changes.outputs.core == 'true' ||
needs.changes.outputs.ffi == 'true')
needs: [build-ffi, changes, clone-vendors]
runs-on: ubuntu-latest
timeout-minutes: 30
env:
PROJECT_ROOT: ${{ github.workspace }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download parsers
uses: actions/download-artifact@v8
with:
name: language-parsers
path: parsers
- name: Download FFI artifacts
uses: actions/download-artifact@v8
with:
name: ffi-ubuntu-latest
path: ffi-artifacts
- name: Restore FFI to expected paths
run: |
mkdir -p target/release
cp ffi-artifacts/target/release/libts_pack_core_ffi.* target/release/ 2>/dev/null || true
mkdir -p crates/ts-pack-core-ffi/include
cp -r ffi-artifacts/crates/ts-pack-core-ffi/include/* crates/ts-pack-core-ffi/include/ 2>/dev/null || true
mkdir -p crates/ts-pack-core-ffi/target/release
cp target/release/libts_pack_core_ffi.* crates/ts-pack-core-ffi/target/release/ 2>/dev/null || true
- name: Verify go.mod placement
run: |
test -f packages/go/go.mod || (echo "ERROR: go.mod missing at packages/go/go.mod" && exit 1)
grep -q 'module github.com/kreuzberg-dev/tree-sitter-language-pack/packages/go$' packages/go/go.mod \
|| (echo "ERROR: module path in go.mod is wrong" && exit 1)
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: "1.26"
cache-dependency-path: packages/go/go.sum
- name: Install Task
uses: kreuzberg-dev/actions/install-task@v1
- name: Run Go tests
run: task go:test
- name: Run Go lint
run: task go:lint
- name: Check Go formatting
run: task go:format:check
- name: Setup Rust (for e2e generate)
uses: kreuzberg-dev/actions/setup-rust@v1
with:
components: ""
use-sccache: "false"
install-llvm-cov: "false"
- name: Generate Go E2E tests
run: task go:e2e:generate
- name: Run Go E2E tests
run: task go:e2e:test
# ---------------------------------------------------------------------------
# 10. test-java — Java tests (needs FFI)
# ---------------------------------------------------------------------------
test-java:
name: Test Java
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.java == 'true' ||
needs.changes.outputs.core == 'true' ||
needs.changes.outputs.ffi == 'true')
needs: [build-ffi, changes, clone-vendors]
runs-on: ubuntu-latest
timeout-minutes: 30
env:
PROJECT_ROOT: ${{ github.workspace }}
TSLP_LANGUAGES: "python,rust,javascript,typescript,go,html,css,json"
TSLP_LINK_MODE: static
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download parsers
uses: actions/download-artifact@v8
with:
name: language-parsers
path: parsers
- name: Download FFI artifacts
uses: actions/download-artifact@v8
with:
name: ffi-ubuntu-latest
path: ffi-artifacts
- name: Restore FFI to expected paths
run: |
mkdir -p target/release
cp ffi-artifacts/target/release/libts_pack_core_ffi.* target/release/ 2>/dev/null || true
mkdir -p crates/ts-pack-core-ffi/include
cp -r ffi-artifacts/crates/ts-pack-core-ffi/include/* crates/ts-pack-core-ffi/include/ 2>/dev/null || true
- name: Setup Java
uses: actions/setup-java@v5
with:
distribution: "temurin"
java-version: "25"
cache: "maven"
- name: Set library paths for JNI
shell: bash
run: echo "LD_LIBRARY_PATH=${{ github.workspace }}/target/release:${LD_LIBRARY_PATH:-}" >> "$GITHUB_ENV"
- name: Run Java unit tests
working-directory: packages/java
run: mvn test
env:
TSPACK_LIB_PATH: ${{ github.workspace }}/target/release/libts_pack_core_ffi.so
- name: Upload test reports
if: always()
uses: actions/upload-artifact@v7
with:
name: java-unit-reports
path: packages/java/target/surefire-reports
if-no-files-found: ignore
retention-days: 7
- name: Setup Rust (for alef e2e generate)
uses: kreuzberg-dev/actions/setup-rust@v1
with:
components: ""
use-sccache: "false"
install-llvm-cov: "false"
- name: Build Java jar
working-directory: packages/java
run: mvn package -DskipTests
- name: Run Java E2E tests
working-directory: e2e/java
run: mvn test
env:
TSPACK_LIB_PATH: ${{ github.workspace }}/target/release/libts_pack_core_ffi.so
MAVEN_OPTS: "--enable-native-access=ALL-UNNAMED -Dsun.misc.unsafe.memory.access=allow"
- name: Upload E2E test reports
if: always()
uses: actions/upload-artifact@v7
with:
name: java-e2e-reports
path: e2e/java/target/surefire-reports
if-no-files-found: ignore
retention-days: 7
# ---------------------------------------------------------------------------
# 11. test-csharp — C# tests (builds FFI locally per platform)
# ---------------------------------------------------------------------------
test-csharp:
name: Test C# (${{ matrix.os }})
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.csharp == 'true' ||
needs.changes.outputs.core == 'true' ||
needs.changes.outputs.ffi == 'true')
needs: [build-ffi, changes, clone-vendors]
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
env:
DOTNET_VERSION: "10.0.x"
PROJECT_ROOT: ${{ github.workspace }}
TSLP_LANGUAGES: "python,rust,javascript,typescript,go,html,css,json"
TSLP_LINK_MODE: static
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download parsers
uses: actions/download-artifact@v8
with:
name: language-parsers
path: parsers
- name: Setup Rust
uses: kreuzberg-dev/actions/setup-rust@v1
with:
components: ""
use-sccache: "true"
cache-key-prefix: csharp-${{ matrix.os }}
install-llvm-cov: "false"
- name: Install Task
uses: kreuzberg-dev/actions/install-task@v1
- name: Build FFI library
run: cargo build -p ts-pack-core-ffi --release
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Set library paths for .NET
shell: bash
run: |
echo "LD_LIBRARY_PATH=${{ github.workspace }}/target/release:${LD_LIBRARY_PATH:-}" >> "$GITHUB_ENV"
echo "TSPACK_FFI_DIR=${{ github.workspace }}/target/release" >> "$GITHUB_ENV"
- name: Build C# bindings
working-directory: packages/csharp
run: dotnet build TreeSitterLanguagePack.csproj -c Release
- name: Run C# unit tests
working-directory: packages/csharp
run: dotnet test TreeSitterLanguagePack.csproj -c Release --no-build
- name: Run C# E2E tests
working-directory: e2e/csharp
run: dotnet test -c Release
- name: Cleanup Rust cache
if: always()
uses: kreuzberg-dev/actions/cleanup-rust-cache@v1
# ---------------------------------------------------------------------------
# 12. test-ruby — Ruby tests (Magnus/rake compile)
# ---------------------------------------------------------------------------
test-ruby:
name: Test Ruby
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.ruby == 'true' ||
needs.changes.outputs.core == 'true')
needs: [rust-tests, changes, clone-vendors]
runs-on: ubuntu-latest
timeout-minutes: 30
env:
PROJECT_ROOT: ${{ github.workspace }}
TSLP_LANGUAGES: "python,rust,javascript,typescript,go,html,css,json"
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download parsers
uses: actions/download-artifact@v8
with:
name: language-parsers
path: parsers
- name: Setup Rust
uses: kreuzberg-dev/actions/setup-rust@v1
with:
components: ""
use-sccache: "false"
install-llvm-cov: "false"
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.4"
- name: Install Ruby dependencies
working-directory: packages/ruby
run: bundle install
- name: Build native extension
working-directory: packages/ruby
run: bundle exec rake compile
env:
CARGO_TARGET_DIR: ${{ github.workspace }}/packages/ruby/target
- name: Run RSpec tests
working-directory: packages/ruby
run: bundle exec rspec
- name: Run Ruby E2E tests
working-directory: e2e/ruby
run: |
bundle install
bundle exec rspec
# ---------------------------------------------------------------------------
# 13. test-php — PHP extension tests
# ---------------------------------------------------------------------------
test-php:
name: Test PHP (${{ matrix.os }})
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.php == 'true' ||
needs.changes.outputs.core == 'true')
needs: [rust-tests, changes, clone-vendors]
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
env:
PROJECT_ROOT: ${{ github.workspace }}
TSLP_LANGUAGES: "python,rust,javascript,typescript,go,html,css,json"
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download parsers
uses: actions/download-artifact@v8
with:
name: language-parsers
path: parsers
- name: Setup Rust
uses: kreuzberg-dev/actions/setup-rust@v1
with:
components: ""
use-sccache: "true"
cache-key-prefix: php-${{ matrix.os }}
install-llvm-cov: "false"
- name: Install Task
uses: kreuzberg-dev/actions/install-task@v1
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.4"
extensions: ffi
tools: composer
- name: Export PHP build config
shell: bash
run: |
PHP_CONFIG_BIN="$(command -v php-config || true)"
if [ -z "$PHP_CONFIG_BIN" ]; then
echo "php-config not found in PATH" >&2
exit 1
fi
echo "PHP_CONFIG=$PHP_CONFIG_BIN" >> "$GITHUB_ENV"
- name: Export macOS PHP linker flags
if: matrix.os == 'macos-latest'
shell: bash
run: |
EXTRA_FLAGS="-C link-arg=-Wl,-undefined,dynamic_lookup"
if [ -n "${RUSTFLAGS:-}" ]; then
echo "RUSTFLAGS=${RUSTFLAGS} ${EXTRA_FLAGS}" >> "$GITHUB_ENV"
else
echo "RUSTFLAGS=${EXTRA_FLAGS}" >> "$GITHUB_ENV"
fi
- name: Build PHP extension
run: cargo build --release --manifest-path crates/ts-pack-core-php/Cargo.toml
- name: Create PHP extension ini
if: matrix.os == 'ubuntu-latest'
run: |
EXT_FILE="${{ github.workspace }}/target/release/libts_pack_php.so"
if [ ! -f "$EXT_FILE" ]; then
EXT_FILE=$(find ${{ github.workspace }}/target/release -name "*ts_pack_php*" | head -1)
fi
if [ -z "$EXT_FILE" ]; then
echo "ERROR: PHP extension not found"
find ${{ github.workspace }}/target/release -name "*.so" | head -10
exit 1
fi
echo "extension=$EXT_FILE" > /tmp/ts-pack-php.ini
echo "Extension: $EXT_FILE"
- name: Run PHP E2E tests
if: matrix.os == 'ubuntu-latest'
working-directory: e2e/php
run: |
composer install --no-progress --prefer-dist
php -c /tmp/ts-pack-php.ini vendor/bin/phpunit
- name: Cleanup Rust cache
if: always()
uses: kreuzberg-dev/actions/cleanup-rust-cache@v1
# ---------------------------------------------------------------------------
# 14. test-elixir — Elixir NIF tests
# ---------------------------------------------------------------------------
test-elixir:
name: Test Elixir
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.elixir == 'true' ||
needs.changes.outputs.core == 'true')
needs: [rust-tests, changes, clone-vendors]
runs-on: ubuntu-latest
timeout-minutes: 30
env:
PROJECT_ROOT: ${{ github.workspace }}
TSLP_LANGUAGES: "python,rust,javascript,typescript,go,html,css,json"
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download parsers
uses: actions/download-artifact@v8
with:
name: language-parsers
path: parsers
- name: Setup Rust
uses: kreuzberg-dev/actions/setup-rust@v1
with:
components: ""
use-sccache: "false"
install-llvm-cov: "false"
- name: Setup Elixir
uses: erlef/setup-elixir@v1
with:
elixir-version: "1.17"
otp-version: "27.2"
version-type: strict
- name: Install Task
uses: kreuzberg-dev/actions/install-task@v1
- name: Cache Elixir dependencies
uses: actions/cache@v5
with:
path: |
packages/elixir/deps
packages/elixir/_build
key: elixir-deps-${{ runner.os }}-${{ hashFiles('packages/elixir/mix.lock') }}
restore-keys: |
elixir-deps-${{ runner.os }}-
- name: Install Elixir dependencies
run: task elixir:deps
- name: Patch Rustler --cfg flag placement
working-directory: packages/elixir
run: |
sed -i 's/args ++ \["--cfg", "build_#{System.system_time(:millisecond)}"\]/args ++ ["--", "--cfg", "build_#{System.system_time(:millisecond)}"]/' deps/rustler/lib/rustler/compiler.ex
mix deps.compile rustler --force
- name: Build NIF library
working-directory: packages/elixir
run: cargo build --release
- name: Stage NIF for Elixir
run: |
mkdir -p packages/elixir/priv/native
cp packages/elixir/target/release/libts_pack_elixir.so packages/elixir/priv/native/ts_pack_elixir.so
cp packages/elixir/target/release/libts_pack_elixir.so packages/elixir/priv/native/ts-pack-elixir.so
- name: Compile Elixir (warnings as errors)
working-directory: packages/elixir
env:
MIX_ENV: test
TSLP_BUILD: "1"
run: mix compile --warnings-as-errors
- name: Run Elixir tests
run: task elixir:test
env:
TSLP_BUILD: "1"
- name: Generate Elixir E2E tests
run: task elixir:e2e:generate
- name: Run Elixir E2E tests
run: task elixir:e2e:test
env:
TSLP_BUILD: "1"
MIX_ENV: test
# ---------------------------------------------------------------------------
# 15. test-c-ffi — C FFI E2E tests
# ---------------------------------------------------------------------------
test-c-ffi:
name: Test C FFI
if: |
github.repository == 'kreuzberg-dev/tree-sitter-language-pack' &&
github.actor != 'dependabot[bot]' &&
(github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.ffi == 'true' ||
needs.changes.outputs.core == 'true')
needs: [rust-tests, changes, clone-vendors]
runs-on: ubuntu-latest
timeout-minutes: 30
env:
PROJECT_ROOT: ${{ github.workspace }}
TSLP_LANGUAGES: "python,rust,javascript,typescript,go,html,css,json"
TSLP_LINK_MODE: static
LD_LIBRARY_PATH: ${{ github.workspace }}/target/release
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download parsers
uses: actions/download-artifact@v8
with:
name: language-parsers
path: parsers
- name: Setup Rust
uses: kreuzberg-dev/actions/setup-rust@v1
with:
components: ""
use-sccache: "false"
install-llvm-cov: "false"
- name: Install Task
uses: kreuzberg-dev/actions/install-task@v1
- name: Generate C E2E tests
run: task c:e2e:generate
- name: Build and run C E2E tests
run: task c:e2e:test