infino 0.1.0

A fast retrieval engine that stores data on object storage and runs SQL, full-text search, and vector search over it from a single system — search-on-Parquet.
Documentation
name: Node publish

# Builds the prebuilt addon for every supported platform, then publishes the
# thin `infino` package plus its per-platform binary packages (`infino-<triple>`)
# to npm.
#
# Triggered manually. The default run is a dry run: it packs and validates the
# main package and every platform package without uploading anything. Re-run
# with dry_run unchecked to publish for real. A real run needs the NPM_TOKEN
# secret, with publish rights to the packages under the infino-ai org.

on:
  workflow_dispatch:
    inputs:
      dry_run:
        description: "Validate only — pack everything, publish nothing"
        type: boolean
        default: true

env:
  CARGO_TERM_COLOR: always
  # The binding builds infino as a normal dependency; don't fail on a
  # transitive-dependency deprecation warning (same as the CI node jobs).
  RUSTFLAGS: ""

jobs:
  build:
    name: Build addon (${{ matrix.target }})
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      # glibc + macOS build natively, one runner per target (`make node-build`
      # builds for the host). musl (Alpine) has no native GitHub runner, so it
      # builds inside the napi-rs Alpine image where the system `cc` is musl —
      # the crate has C-based deps (e.g. zstd), so a native musl toolchain is
      # simpler and more reliable than cross-compiling from glibc.
      matrix:
        include:
          - { os: ubuntu-latest, target: linux-x64-gnu }
          - { os: ubuntu-24.04-arm, target: linux-arm64-gnu }
          - { os: macos-15-intel, target: darwin-x64 }
          - { os: macos-14, target: darwin-arm64 }
          - { os: ubuntu-latest, target: linux-x64-musl, musl: x86_64-unknown-linux-musl }
          - { os: ubuntu-24.04-arm, target: linux-arm64-musl, musl: aarch64-unknown-linux-musl }
    steps:
      - uses: actions/checkout@v4
      - name: Free disk space
        if: runner.os == 'Linux'
        uses: jlumbroso/free-disk-space@main
        with:
          tool-cache: false
          android: true
          dotnet: true
          haskell: true
          large-packages: true
          docker-images: true
          swap-storage: true
      # --- native build (glibc / macOS) ---
      - uses: dtolnay/rust-toolchain@stable
        if: ${{ !matrix.musl }}
      - uses: actions/setup-node@v4
        if: ${{ !matrix.musl }}
        with:
          node-version: "20"
      - uses: Swatinem/rust-cache@v2
        if: ${{ !matrix.musl }}
        with:
          workspaces: infino-node
      - name: Build addon (native)
        if: ${{ !matrix.musl }}
        run: make node-build
      # Smoke-test the AS-SHIPPED package on this platform: pack the tarballs,
      # install them into a throwaway project, and run a real query — proving the
      # loader resolves the per-platform binary from a clean install (not the
      # sibling build `npm test` uses). Reuses the build above (no rebuild).
      - name: Verify packaged binary (native)
        if: ${{ !matrix.musl }}
        run: make node-verify
      # --- musl build (Alpine, via the napi-rs builder image; cc is musl) ---
      # Runs on the host runner (so the disk-free step above still applies) but
      # compiles inside Alpine, where the target arch matches the runner arch —
      # so this is a native musl build, not a cross-compile. Same install→load→
      # query smoke-test as the native legs, run inside the container (bash is
      # not in the base image, so add it for verify-pack.sh).
      - name: Build addon (musl, in Alpine) + verify packaged binary
        if: ${{ matrix.musl }}
        run: |
          docker run --rm -v "$PWD:/build" -w /build/infino-node \
            ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine \
            sh -c "apk add --no-cache bash >/dev/null && \
                   rustup target add ${{ matrix.musl }} && \
                   npm install --ignore-scripts && \
                   npx napi build --platform --release --strip --target ${{ matrix.musl }} --js native.js --dts native.d.ts infino && \
                   npx tsc && \
                   bash ./scripts/verify-pack.sh"
      - name: Upload addon
        uses: actions/upload-artifact@v4
        with:
          name: addon-${{ matrix.target }}
          path: infino-node/infino/*.node
          if-no-files-found: error
      # The JS loader and compiled wrapper are identical across platforms;
      # upload them once so the publish job needs no Rust build.
      - name: Upload JS bindings
        if: matrix.target == 'linux-x64-gnu'
        uses: actions/upload-artifact@v4
        with:
          name: js-bindings
          path: |
            infino-node/infino/native.js
            infino-node/infino/native.d.ts
            infino-node/infino/index.js
            infino-node/infino/index.d.ts
          if-no-files-found: error

  publish:
    name: Publish to npm
    needs: build
    runs-on: ubuntu-latest
    # OIDC token for npm provenance — the "built from this repo at this commit"
    # attestation shown on npmjs.org. A real supply-chain trust signal at launch.
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          registry-url: "https://registry.npmjs.org"
      # All platform binaries land flattened into infino-node/artifacts/;
      # `napi artifacts` matches each by the triple in its filename.
      - name: Download platform addons
        uses: actions/download-artifact@v4
        with:
          pattern: addon-*
          path: infino-node/artifacts
          merge-multiple: true
      - name: Download JS bindings
        uses: actions/download-artifact@v4
        with:
          name: js-bindings
          path: infino-node/infino
      - name: Install tooling
        run: cd infino-node && npm install --ignore-scripts
      # npm/ isn't committed — generate the per-platform package dirs from
      # package.json (triples, version, description) before staging binaries.
      - name: Generate platform package dirs
        run: cd infino-node && npx napi create-npm-dir -t .
      # Copy each binary into its per-platform package under npm/<triple>/.
      - name: Stage binaries into platform packages
        run: cd infino-node && npm run artifacts
      - name: Validate (dry run)
        if: ${{ inputs.dry_run }}
        run: |
          cd infino-node
          npx napi prepublish -t npm --skip-gh-release --dry-run
          npm publish --dry-run --tag latest --access public
      # Publishes the per-platform packages and pins them in the main
      # package's optionalDependencies, then publishes the main package.
      # `--tag latest` is required (not just default): the name's history
      # includes a higher version, so npm won't move the latest tag onto
      # 0.1.0 implicitly. Passing it explicitly sets latest to the engine.
      - name: Publish to npm
        if: ${{ !inputs.dry_run }}
        run: |
          cd infino-node
          npx napi prepublish -t npm --skip-gh-release
          npm publish --tag latest --access public
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
          # Emit provenance for the main package AND every per-platform package
          # (napi's prepublish shells out to `npm publish`, which honors this).
          NPM_CONFIG_PROVENANCE: "true"