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
90 changes: 90 additions & 0 deletions .github/workflows/package-crates.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Vendored from tree-sitter/workflows/.github/workflows/package-crates.yml, with
# OIDC trusted publishing enabled (upstream PR #54, unmerged): CARGO_REGISTRY_TOKEN
# is optional and the publish job carries `id-token: write`. When no token is set,
# rust-lang/crates-io-auth-action mints a short-lived one via OIDC. `workflow_call`
# only, so it never runs on its own. Re-sync from upstream if the build drifts.
name: Publish package (crates.io)

on:
workflow_call:
inputs:
package-name:
description: The name of the package
default: ${{github.event.repository.name}}
type: string
environment-name:
description: The name of the environment
default: crates
type: string
rust-toolchain:
description: The Rust toolchain
default: ${{vars.RUST_TOOLCHAIN || 'stable'}}
type: string
generate:
description: Generate the parser artifacts
default: false
type: boolean
abi-version:
description: The tree-sitter ABI version
default: 15
type: number
secrets:
# Optional: unset -> OIDC trusted publishing; set -> classic token (rollback)
CARGO_REGISTRY_TOKEN:
description: An authentication token for crates.io
required: false

jobs:
package:
name: Publish Rust package
runs-on: ubuntu-latest
environment:
name: ${{inputs.environment-name}}
url: https://crates.io/crates/${{inputs.package-name}}
permissions:
contents: read
id-token: write
# Surface the token as env so the OIDC step can be skipped when a classic
# token is provided (secrets are not readable in a step `if`, env is).
env:
CARGO_REGISTRY_TOKEN: ${{secrets.CARGO_REGISTRY_TOKEN}}
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Set up Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: ${{inputs.rust-toolchain}}
- name: Set up tree-sitter CLI
if: ${{inputs.generate}}
uses: tree-sitter/setup-action/cli@v2
- name: Install dependencies
run: |-
if jq -e "$JQ_SCRIPT" package.json >/dev/null; then
npm i --ignore-scripts --omit peer --omit optional
fi
env:
JQ_SCRIPT: >-
.dependencies + .devDependencies |
with_entries(select(
(.key | startswith("tree-sitter-"))
and (.key != "tree-sitter-cli")
)) | length > 0
- name: Regenerate parser
if: ${{inputs.generate}}
run: |
while read -r grammar_dir; do
pushd "$grammar_dir"
tree-sitter generate
popd > /dev/null
done < <(jq -r '.grammars[].path // "."' tree-sitter.json)
env:
TREE_SITTER_ABI_VERSION: ${{inputs.abi-version}}
- name: Mint crates.io OIDC token
id: auth
if: env.CARGO_REGISTRY_TOKEN == ''
uses: rust-lang/crates-io-auth-action@v1
- name: Publish to crates.io
run: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{env.CARGO_REGISTRY_TOKEN || steps.auth.outputs.token}}
156 changes: 156 additions & 0 deletions .github/workflows/package-npm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Vendored from tree-sitter/workflows/.github/workflows/package-npm.yml, with
# OIDC trusted publishing enabled (upstream PR #54, unmerged): NODE_AUTH_TOKEN is
# optional and the publish job carries `id-token: write`. npm is upgraded to a
# release that supports trusted publishing (>= 11.5.1; the default Node ships an
# older npm). `workflow_call` only, so it never runs on its own. Re-sync from
# upstream if the build matrix drifts.
name: Publish package (npm)

on:
workflow_call:
inputs:
package-name:
description: The name of the package
default: ${{github.event.repository.name}}
type: string
environment-name:
description: The name of the environment
default: npm
type: string
node-version:
description: The NodeJS version
default: ${{vars.NODE_VERSION || '22'}}
type: string
generate:
description: Generate the parser artifacts
default: false
type: boolean
abi-version:
description: The tree-sitter ABI version
default: 15
type: number
secrets:
# Optional: unset -> OIDC trusted publishing; set -> classic token (rollback)
NODE_AUTH_TOKEN:
description: An authentication token for npm
required: false

defaults:
run:
shell: bash

jobs:
build_wasm:
name: Build Wasm binaries
runs-on: ubuntu-24.04
continue-on-error: true
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Set up NodeJS
uses: actions/setup-node@v6
with:
cache: npm
node-version: ${{inputs.node-version}}
- name: Install dependencies
run: npm i --omit peer --omit optional
- name: Regenerate parser
if: ${{inputs.generate}}
run: |
while read -r grammar_dir; do
pushd "$grammar_dir"
npm x -- tree-sitter generate
popd > /dev/null
done < <(jq -r '.grammars[].path // "."' tree-sitter.json)
env:
TREE_SITTER_ABI_VERSION: ${{inputs.abi-version}}
- name: Build Wasm binaries
run: |-
while read -r grammar_dir; do
npm x -- tree-sitter build --wasm "$grammar_dir"
done < <(jq -r '.grammars[].path // "."' tree-sitter.json)
- name: Upload binaries
uses: actions/upload-artifact@v7
with:
path: "*.wasm"
name: prebuilds-wasm
retention-days: 2

build_node:
name: Build NodeJS binaries on ${{matrix.os}}
runs-on: ${{matrix.os}}
strategy:
matrix:
os:
- windows-2022
- windows-11-arm
- ubuntu-24.04
- ubuntu-24.04-arm
- macos-15
- macos-15-intel
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Set up NodeJS
uses: actions/setup-node@v6
with:
cache: npm
node-version: ${{inputs.node-version}}
- name: Install dependencies
run: npm i --omit peer --omit optional
- name: Regenerate parser
if: ${{inputs.generate}}
shell: bash
run: |
while read -r grammar_dir; do
grammar_dir="${grammar_dir%$'\r'}"
pushd "$grammar_dir"
npm x -- tree-sitter generate
popd > /dev/null
done < <(jq -r '.grammars[].path // "."' tree-sitter.json)
- name: Build binary
run: npm x -- prebuildify -t 20.19.5
- name: Upload binaries
uses: actions/upload-artifact@v7
with:
path: prebuilds/**
name: prebuilds-${{matrix.os}}
retention-days: 2

package:
name: Publish NodeJS package
needs: [build_wasm, build_node]
runs-on: ubuntu-24.04
environment:
name: ${{inputs.environment-name}}
url: https://www.npmjs.com/package/${{inputs.package-name}}
permissions:
contents: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Set up NodeJS
uses: actions/setup-node@v6
with:
cache: npm
node-version: ${{inputs.node-version}}
registry-url: https://registry.npmjs.org/
- name: Download binaries
uses: actions/download-artifact@v8
with:
path: prebuilds
pattern: prebuilds-*
merge-multiple: true
- name: Check binaries
run: tree prebuilds
- name: Move Wasm binaries to root
continue-on-error: true
run: mv -v prebuilds/*.wasm .
# Trusted publishing requires npm >= 11.5.1; the bundled npm is older.
- name: Upgrade npm
run: npm install -g npm@latest
- name: Publish to npm
run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.NODE_AUTH_TOKEN}}
19 changes: 13 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,34 @@ jobs:

# Registry publish is gated in THIS run, not a separate tag-triggered workflow:
# a tag pushed by the default GITHUB_TOKEN cannot trigger another workflow.
# Local OIDC-enabled copy of package-npm.yml (see the pypi job below and
# tree-sitter/workflows#54). No NODE_AUTH_TOKEN passed -> npm publishes via
# the OIDC id-token.
npm:
needs: release-please
if: needs.release-please.outputs.release_created == 'true'
uses: tree-sitter/workflows/.github/workflows/package-npm.yml@main
permissions:
contents: read
id-token: write
uses: ./.github/workflows/package-npm.yml
with:
generate: true
secrets:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

# Local OIDC-enabled copy of package-crates.yml. No CARGO_REGISTRY_TOKEN
# passed -> crates-io-auth-action mints a short-lived token via OIDC.
crates:
needs: release-please
if: needs.release-please.outputs.release_created == 'true'
uses: tree-sitter/workflows/.github/workflows/package-crates.yml@main
permissions:
contents: read
id-token: write
uses: ./.github/workflows/package-crates.yml
# generate:false — the committed src/ is complete and tracked, so cargo
# publishes from it directly. generate:true made the job cargo-install the
# CLI into an in-workspace CARGO_HOME, whose .crates.toml/.crates2.json then
# tripped `cargo publish`'s uncommitted-changes check.
with:
generate: false
secrets:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

# Local copy of tree-sitter/workflows' package-pypi.yml, patched for OIDC
# trusted publishing (upstream PR tree-sitter/workflows#54, unmerged). No
Expand Down