A GitHub Action for installing tree-sitter and language grammars via tsdl.
This action wraps the official tree-sitter/setup-action and uses tsdl to build and install language-specific grammar shared libraries.
- π² Uses official
tree-sitter/setup-actionfor library and CLI installation - π¦ Builds grammar shared libraries (
.sofiles) via tsdl - π Pinned grammar versions by default (override with
grammar-*-refinputs) - β‘ Caching support via the official action
- π§ Configures environment variables (
TREE_SITTER_*_PATH) for each grammar - π§ Linux and macOS support
| Grammar | Input | Repository |
|---|---|---|
| Bash | grammar-bash |
tree-sitter/tree-sitter-bash |
| JSON | grammar-json |
tree-sitter/tree-sitter-json |
| TOML | grammar-toml |
tree-sitter-grammars/tree-sitter-toml |
| RBS | grammar-rbs |
joker1007/tree-sitter-rbs |
Note: JSONC (JSON with Comments) is supported by the main
tree-sitter-jsongrammar as of v0.24.0. A separate jsonc grammar is no longer needed.
Use one of the following version references:
@v2- Latest stable v2.x release (recommended for production)@v2.0.0- Specific version@main- Latest development version (may be unstable)
Install tree-sitter library and selected grammars:
steps:
- uses: actions/checkout@v4
- name: Install tree-sitter with grammars
uses: kettle-rb/ts-grammar-action@v2
with:
grammar-bash: true
grammar-toml: truesteps:
- uses: actions/checkout@v4
- name: Install tree-sitter with grammars
uses: kettle-rb/ts-grammar-action@v2
with:
# Tree-sitter library/CLI options
install-cli: false # Install tree-sitter CLI (default: false)
install-lib: true # Install libtree-sitter (default: true)
tree-sitter-ref: latest # tree-sitter version (default: latest)
# Rust toolchain (for tree_stump gem or CLI build)
setup-rust: false # Install Rust toolchain (default: false)
rust-toolchain: stable # Rust version (default: stable)
# Java/jtreesitter (for JRuby Java backend)
# Note: setup-jtreesitter: true automatically installs Java JDK
setup-java: false # Install Java JDK only (default: false)
java-version: "23" # Java version (default: 23)
java-distribution: temurin # Java distribution (default: temurin)
setup-jtreesitter: false # Download jtreesitter JAR + install Java (default: false)
jtreesitter-version: "0.24.0" # jtreesitter version (default: 0.24.0)
jtreesitter-install-dir: /usr/local/share/java # JAR install directory
# tsdl options
tsdl-version: v2.0.0 # tsdl version (default: v2.0.0)
# Grammar selections (all default to false)
grammar-bash: false
grammar-bash-ref: v0.25.1 # Pin grammar version
grammar-json: false
grammar-json-ref: v0.24.8
grammar-toml: false
grammar-toml-ref: v0.7.0
grammar-rbs: false
grammar-rbs-ref: v0.2.2
# Installation prefix (default: /usr/local)
grammar-install-prefix: /usr/localIf you're using the tree_stump gem for tree_haver's Rust backend on MRI Ruby, you need Rust installed to compile it:
steps:
- uses: actions/checkout@v4
- name: Install tree-sitter with Rust and grammars
uses: kettle-rb/ts-grammar-action@v2
with:
setup-rust: true # Install Rust toolchain
rust-toolchain: stable # Use stable Rust
grammar-toml: true
grammar-bash: true
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
bundler-cache: true
- name: Run tests
run: bundle exec rspecFor JRuby workflows using tree_haver's Java backend with jtreesitter:
Note: Setting
setup-jtreesitter: trueautomatically installs Java JDK - you don't need to also setsetup-java: true.
steps:
- uses: actions/checkout@v4
- name: Install tree-sitter with Java and grammars
uses: kettle-rb/ts-grammar-action@v2
with:
setup-jtreesitter: true # Automatically installs Java JDK + jtreesitter JAR
java-version: "23" # Java version to install
grammar-toml: true
grammar-bash: true
- name: Setup JRuby
uses: ruby/setup-ruby@v1
with:
ruby-version: jruby
bundler-cache: true
- name: Run tests
run: bundle exec rspec
env:
# These are automatically set by the action:
# TREE_SITTER_JAVA_JARS_DIR: /usr/local/share/java
# CLASSPATH: /usr/local/share/java/jtreesitter-0.24.0.jarThis action is designed to work with the tree_haver gem and the *-merge gem family for AST-based file merging:
steps:
- uses: actions/checkout@v4
- name: Install tree-sitter and grammars
uses: kettle-rb/ts-grammar-action@v2
with:
grammar-toml: true
grammar-bash: true
grammar-json: true
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
bundler-cache: true
- name: Run tests
run: bundle exec rspec
env:
# These are automatically set by the action:
# TREE_SITTER_TOML_PATH: /usr/local/lib/libtree-sitter-toml.so
# TREE_SITTER_BASH_PATH: /usr/local/lib/libtree-sitter-bash.so
# TREE_SITTER_JSON_PATH: /usr/local/lib/libtree-sitter-json.so| Output | Description |
|---|---|
grammars-installed |
Comma-separated list of installed grammar names |
lib-path |
Path to installed grammar libraries |
tsdl-version |
Installed tsdl version |
rust-installed |
Whether Rust toolchain was installed (true/false) |
java-installed |
Whether Java JDK was installed (true/false) |
jtreesitter-installed |
Whether jtreesitter JAR was installed (true/false) |
jtreesitter-jar-path |
Path to jtreesitter JAR file |
steps:
- uses: actions/checkout@v4
- name: Install grammars
id: grammars
uses: kettle-rb/ts-grammar-action@v2
with:
grammar-toml: true
grammar-json: true
- name: Show installed grammars
run: |
echo "Installed: ${{ steps.grammars.outputs.grammars-installed }}"
echo "Library path: ${{ steps.grammars.outputs.lib-path }}"
ls -la ${{ steps.grammars.outputs.lib-path }}/libtree-sitter-*.soThe action automatically sets environment variables for each installed component:
| Variable | Example Value |
|---|---|
TREE_SITTER_BASH_PATH |
/usr/local/lib/libtree-sitter-bash.so |
TREE_SITTER_JSON_PATH |
/usr/local/lib/libtree-sitter-json.so |
TREE_SITTER_TOML_PATH |
/usr/local/lib/libtree-sitter-toml.so |
TREE_SITTER_RBS_PATH |
/usr/local/lib/libtree-sitter-rbs.so |
LD_LIBRARY_PATH |
Updated to include grammar library directory |
| Variable | Example Value |
|---|---|
TREE_SITTER_JAVA_JARS_DIR |
/usr/local/share/java |
CLASSPATH |
/usr/local/share/java/jtreesitter-0.24.0.jar |
JAVA_HOME |
Set by actions/setup-java |
These environment variables are used by tree_haver to locate grammar libraries and Java JARs.
- Linux or macOS - Windows support may be added in the future
- sudo - For installing to system directories
- Java Setup (optional): Installs Java JDK via
actions/setup-javaifsetup-javaorsetup-jtreesitteris enabled - jtreesitter Setup (optional): Downloads jtreesitter JAR from Maven Central for JRuby's Java backend
- Rust Setup (optional): Installs Rust toolchain via
dtolnay/rust-toolchainifsetup-rustis enabled - Tree-sitter Setup: Uses the official
tree-sitter/setup-actionto install the tree-sitter library and optionally the CLI - tsdl Install: Downloads the tsdl binary from GitHub releases
- Grammar Build: Generates a
parsers.tomlconfig from inputs and runstsdl buildto compile grammars - Configuration: Sets up environment variables for grammar and JAR discovery
| Feature | tree-sitter/setup-action | ts-grammar-action |
|---|---|---|
| Library installation | β | β (via delegation) |
| CLI installation | β | β (via delegation) |
| Caching | β | β (via delegation) |
| Grammar installation | β | β (via tsdl) |
| Pinned grammar versions | β | β |
| Rust toolchain | β (for CLI only) | β (for tree_stump gem) |
| Java JDK | β | β |
| jtreesitter JAR | β | β |
| Environment variables | Library paths only | Library + grammar + Java |
This project is part of the kettle-rb family of tools. This action specifically facilitates testing many of the gems in the merge gem family in GitHub Actions.
The *-merge gem family provides intelligent, AST-based merging for various file formats. At the foundation is tree_haver, which provides a unified cross-Ruby parsing API that works seamlessly across MRI, JRuby, and TruffleRuby.
| Gem | Language / Format |
Parser Backend(s) | Description |
|---|---|---|---|
| tree_haver | Multi | MRI C, Rust, FFI, Java, Prism, Psych, Commonmarker, Markly, Citrus | Foundation: Cross-Ruby adapter for parsing libraries (like Faraday for HTTP) |
| ast-merge | Text | internal | Infrastructure: Shared base classes and merge logic for all *-merge gems |
| bash-merge | Bash | tree-sitter-bash (via tree_haver) | Smart merge for Bash scripts |
| commonmarker-merge | Markdown | Commonmarker (via tree_haver) | Smart merge for Markdown (CommonMark via comrak Rust) |
| dotenv-merge | Dotenv | internal | Smart merge for .env files |
| json-merge | JSON | tree-sitter-json (via tree_haver) | Smart merge for JSON files |
| jsonc-merge | JSONC | tree-sitter-json (via tree_haver) | Smart merge for JSON with Comments |
| markdown-merge | Markdown | Commonmarker / Markly (via tree_haver) | Foundation: Shared base for Markdown mergers with inner code block merging |
| markly-merge | Markdown | Markly (via tree_haver) | Smart merge for Markdown (CommonMark via cmark-gfm C) |
| prism-merge | Ruby | Prism (prism std lib gem) |
Smart merge for Ruby source files |
| psych-merge | YAML | Psych (psych std lib gem) |
Smart merge for YAML files |
| rbs-merge | RBS | tree-sitter-rbs (via tree_haver), RBS (rbs std lib gem) |
Smart merge for Ruby type signatures |
| toml-merge | TOML | Citrus + toml-rb (default, via tree_haver), tree-sitter-toml (via tree_haver) | Smart merge for TOML files |
tree_haver supports multiple parsing backends, but not all backends work on all Ruby platforms:
| Platform ποΈ TreeHaver Backend ποΈ |
MRI | JRuby | TruffleRuby | Notes |
|---|---|---|---|---|
| MRI (ruby_tree_sitter) | β | β | β | C extension, MRI only |
| Rust (tree_stump) | β | β | β | Rust extension via magnus/rb-sys, MRI only |
| FFI | β | β | β | TruffleRuby's FFI doesn't support STRUCT_BY_VALUE |
| Java (jtreesitter) | β | β | β | JRuby only, requires grammar JARs |
| Prism | β | β | β | Ruby parsing, stdlib in Ruby 3.4+ |
| Psych | β | β | β | YAML parsing, stdlib |
| Citrus | β | β | β | Pure Ruby, no native dependencies |
| Commonmarker | β | β | β | Rust extension for Markdown |
| Markly | β | β | β | C extension for Markdown |
Legend: β = Works, β = Does not work, β = Untested
Why some backends don't work on certain platforms:
- JRuby: Runs on the JVM; cannot load native C/Rust extensions (
.sofiles) - TruffleRuby: Has C API emulation via Sulong/LLVM, but it doesn't expose all MRI internals that native extensions require (e.g.,
RBasic.flags,rb_gc_writebarrier) - FFI on TruffleRuby: TruffleRuby's FFI implementation doesn't support returning structs by value, which tree-sitter's C API requires
Example implementations for the gem templating use case:
| Gem | Purpose | Description |
|---|---|---|
| kettle-dev | Gem Development | Gem templating tool using *-merge gems |
| kettle-jem | Gem Templating | Gem template library with smart merge support |
While kettle-rb tools are free software and will always be, the project would benefit immensely from some funding. Raising a monthly budget of... "dollars" would make the project more sustainable.
We welcome both individual and corporate sponsors! We also offer a wide array of funding channels to account for your preferences (although currently Open Collective is our preferred funding platform).
If you're working in a company that's making significant use of kettle-rb tools we'd appreciate it if you suggest to your company to become a kettle-rb sponsor.
You can support the development of kettle-rb tools via GitHub Sponsors, Liberapay, PayPal, Open Collective and Tidelift.
| π NOTE |
|---|
| If doing a sponsorship in the form of donation is problematic for your company from an accounting standpoint, we'd recommend the use of Tidelift, where you can get a support-like subscription instead. |
Support us with a monthly donation and help us continue our activities. [Become a backer]
NOTE: kettle-readme-backers updates this list every day, automatically.
No backers yet. Be the first!
Become a sponsor and get your logo on our README on GitHub with a link to your site. [Become a sponsor]
NOTE: kettle-readme-backers updates this list every day, automatically.
No sponsors yet. Be the first!
See SECURITY.md.
If you need some ideas of where to help, see issues, or PRs, or use the action and think about how it could be better.
See CONTRIBUTING.md for more detailed instructions.
We so if you make changes, remember to update it.
See CONTRIBUTING.md.
Everyone interacting with this project's codebases, issue trackers,
chat rooms and mailing lists agrees to follow the .
Made with contributors-img.
Also see GitLab Contributors: https://gitlab.com/kettle-rb/ts-grammar-action/-/graphs/main
The gem is available as open source under the terms of
the MIT License .
See LICENSE.txt for the official Copyright Notice.
-
Copyright (c) 2025 Peter H.Β Boling, of
Galtzo.com
, and ts-grammar-action contributors.
Maintainers have teeth and need to pay their dentists. After getting laid off in an RIF in March, and encountering difficulty finding a new one, I began spending most of my time building open source tools. I'm hoping to be able to pay for my kids' health insurance this month, so if you value the work I am doing, I need your support. Please consider sponsoring me or the project.
To join the community or get help ποΈ Join the Discord.
To say "thanks!" βοΈ Join the Discord or ποΈ send money.
Thanks for RTFM.