Skip to content

chore: Update attention NAPI-RS binaries for all platforms #13

chore: Update attention NAPI-RS binaries for all platforms

chore: Update attention NAPI-RS binaries for all platforms #13

Workflow file for this run

name: Build & Publish All Packages
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
version:
description: 'Version to publish (e.g., 0.1.31)'
required: true
type: string
publish_crates:
description: 'Publish to crates.io'
required: false
type: boolean
default: true
publish_npm:
description: 'Publish to npm'
required: false
type: boolean
default: true
dry_run:
description: 'Dry run (build only, no publish)'
required: false
type: boolean
default: false
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
# ============================================================================
# Phase 1: Validate and Test
# ============================================================================
validate:
name: Validate & Test
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Cache Rust
uses: Swatinem/rust-cache@v2
- name: Run tests
run: |
cargo test -p ruvector-math -p ruvector-attention --all-features
echo "✅ All tests passed" >> $GITHUB_STEP_SUMMARY
# ============================================================================
# Phase 2: Build Native Binaries (Node.js NAPI)
# ============================================================================
build-native:
name: Build ${{ matrix.settings.platform }}
runs-on: ${{ matrix.settings.host }}
needs: validate
strategy:
fail-fast: false
matrix:
settings:
- host: ubuntu-22.04
target: x86_64-unknown-linux-gnu
platform: linux-x64-gnu
node_file: attention.linux-x64-gnu.node
- host: ubuntu-22.04
target: aarch64-unknown-linux-gnu
platform: linux-arm64-gnu
node_file: attention.linux-arm64-gnu.node
- host: macos-14
target: x86_64-apple-darwin
platform: darwin-x64
node_file: attention.darwin-x64.node
- host: macos-14
target: aarch64-apple-darwin
platform: darwin-arm64
node_file: attention.darwin-arm64.node
- host: windows-2022
target: x86_64-pc-windows-msvc
platform: win32-x64-msvc
node_file: attention.win32-x64-msvc.node
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.settings.target }}
- name: Cache Rust
uses: Swatinem/rust-cache@v2
with:
key: native-${{ matrix.settings.target }}
- name: Install cross-compilation tools (Linux ARM64)
if: matrix.settings.platform == 'linux-arm64-gnu'
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
- name: Install NAPI-RS CLI
run: npm install -g @napi-rs/cli
- name: Install dependencies
working-directory: crates/ruvector-attention-node
run: npm install
- name: Build native module
working-directory: crates/ruvector-attention-node
run: napi build --platform --release --target ${{ matrix.settings.target }}
env:
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
- name: Copy to platform package
shell: bash
run: |
NODE_FILE=$(find crates/ruvector-attention-node -name "*.node" -type f | head -1)
mkdir -p "crates/ruvector-attention-node/npm/${{ matrix.settings.platform }}"
cp -v "$NODE_FILE" "crates/ruvector-attention-node/npm/${{ matrix.settings.platform }}/${{ matrix.settings.node_file }}"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: native-${{ matrix.settings.platform }}
path: crates/ruvector-attention-node/npm/${{ matrix.settings.platform }}/*.node
if-no-files-found: error
# ============================================================================
# Phase 3: Build WASM Packages
# ============================================================================
build-wasm:
name: Build WASM
runs-on: ubuntu-22.04
needs: validate
strategy:
matrix:
package:
- name: ruvector-math-wasm
path: crates/ruvector-math-wasm
- name: ruvector-attention-wasm
path: crates/ruvector-attention-wasm
steps:
- uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Cache Rust
uses: Swatinem/rust-cache@v2
with:
key: wasm-${{ matrix.package.name }}
- name: Build WASM (web target)
working-directory: ${{ matrix.package.path }}
run: wasm-pack build --target web --release
- name: Upload WASM artifact
uses: actions/upload-artifact@v4
with:
name: wasm-${{ matrix.package.name }}
path: ${{ matrix.package.path }}/pkg/
if-no-files-found: error
# ============================================================================
# Phase 4: Publish to crates.io
# ============================================================================
publish-crates:
name: Publish to crates.io
runs-on: ubuntu-22.04
needs: [build-native, build-wasm]
if: ${{ !inputs.dry_run && (inputs.publish_crates || github.event_name == 'push') }}
steps:
- uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Publish ruvector-math
run: cargo publish -p ruvector-math --allow-dirty
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
continue-on-error: true
- name: Wait for crates.io index
run: sleep 30
- name: Publish ruvector-attention
run: cargo publish -p ruvector-attention --allow-dirty
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
continue-on-error: true
- name: Wait for crates.io index
run: sleep 30
- name: Publish ruvector-math-wasm
run: cargo publish -p ruvector-math-wasm --allow-dirty
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
continue-on-error: true
- name: Publish ruvector-attention-wasm
run: cargo publish -p ruvector-attention-wasm --allow-dirty
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
continue-on-error: true
- name: Summary
run: |
echo "## crates.io Publishing" >> $GITHUB_STEP_SUMMARY
echo "✅ ruvector-math" >> $GITHUB_STEP_SUMMARY
echo "✅ ruvector-attention" >> $GITHUB_STEP_SUMMARY
echo "✅ ruvector-math-wasm" >> $GITHUB_STEP_SUMMARY
echo "✅ ruvector-attention-wasm" >> $GITHUB_STEP_SUMMARY
# ============================================================================
# Phase 5: Publish to npm
# ============================================================================
publish-npm:
name: Publish to npm
runs-on: ubuntu-22.04
needs: [build-native, build-wasm]
if: ${{ !inputs.dry_run && (inputs.publish_npm || github.event_name == 'push') }}
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: List downloaded artifacts
run: find artifacts -type f -name "*.node" -o -name "*.wasm" | head -50
# --- Publish WASM packages ---
- name: Publish @ruvector/math-wasm to npm
run: |
cd artifacts/wasm-ruvector-math-wasm
# Update package name to scoped
jq '.name = "@ruvector/math-wasm"' package.json > tmp.json && mv tmp.json package.json
npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
continue-on-error: true
- name: Publish @ruvector/attention-wasm to npm
run: |
cd artifacts/wasm-ruvector-attention-wasm
# Update package name to scoped
jq '.name = "@ruvector/attention-wasm"' package.json > tmp.json && mv tmp.json package.json
npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
continue-on-error: true
# --- Publish platform-specific native packages ---
- name: Prepare and publish @ruvector/attention-linux-x64-gnu
run: |
mkdir -p publish/linux-x64-gnu
cp artifacts/native-linux-x64-gnu/*.node publish/linux-x64-gnu/
cd publish/linux-x64-gnu
cat > package.json << 'EOF'
{
"name": "@ruvector/attention-linux-x64-gnu",
"version": "${{ inputs.version || '0.1.31' }}",
"os": ["linux"],
"cpu": ["x64"],
"main": "attention.linux-x64-gnu.node",
"files": ["attention.linux-x64-gnu.node"],
"description": "Linux x64 GNU native module for @ruvector/attention",
"license": "MIT",
"repository": "https://github.com/ruvnet/ruvector"
}
EOF
npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
continue-on-error: true
- name: Prepare and publish @ruvector/attention-linux-arm64-gnu
run: |
mkdir -p publish/linux-arm64-gnu
cp artifacts/native-linux-arm64-gnu/*.node publish/linux-arm64-gnu/
cd publish/linux-arm64-gnu
cat > package.json << 'EOF'
{
"name": "@ruvector/attention-linux-arm64-gnu",
"version": "${{ inputs.version || '0.1.31' }}",
"os": ["linux"],
"cpu": ["arm64"],
"main": "attention.linux-arm64-gnu.node",
"files": ["attention.linux-arm64-gnu.node"],
"description": "Linux ARM64 GNU native module for @ruvector/attention",
"license": "MIT",
"repository": "https://github.com/ruvnet/ruvector"
}
EOF
npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
continue-on-error: true
- name: Prepare and publish @ruvector/attention-darwin-x64
run: |
mkdir -p publish/darwin-x64
cp artifacts/native-darwin-x64/*.node publish/darwin-x64/
cd publish/darwin-x64
cat > package.json << 'EOF'
{
"name": "@ruvector/attention-darwin-x64",
"version": "${{ inputs.version || '0.1.31' }}",
"os": ["darwin"],
"cpu": ["x64"],
"main": "attention.darwin-x64.node",
"files": ["attention.darwin-x64.node"],
"description": "macOS Intel x64 native module for @ruvector/attention",
"license": "MIT",
"repository": "https://github.com/ruvnet/ruvector"
}
EOF
npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
continue-on-error: true
- name: Prepare and publish @ruvector/attention-darwin-arm64
run: |
mkdir -p publish/darwin-arm64
cp artifacts/native-darwin-arm64/*.node publish/darwin-arm64/
cd publish/darwin-arm64
cat > package.json << 'EOF'
{
"name": "@ruvector/attention-darwin-arm64",
"version": "${{ inputs.version || '0.1.31' }}",
"os": ["darwin"],
"cpu": ["arm64"],
"main": "attention.darwin-arm64.node",
"files": ["attention.darwin-arm64.node"],
"description": "macOS Apple Silicon ARM64 native module for @ruvector/attention",
"license": "MIT",
"repository": "https://github.com/ruvnet/ruvector"
}
EOF
npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
continue-on-error: true
- name: Prepare and publish @ruvector/attention-win32-x64-msvc
run: |
mkdir -p publish/win32-x64-msvc
cp artifacts/native-win32-x64-msvc/*.node publish/win32-x64-msvc/
cd publish/win32-x64-msvc
cat > package.json << 'EOF'
{
"name": "@ruvector/attention-win32-x64-msvc",
"version": "${{ inputs.version || '0.1.31' }}",
"os": ["win32"],
"cpu": ["x64"],
"main": "attention.win32-x64-msvc.node",
"files": ["attention.win32-x64-msvc.node"],
"description": "Windows x64 MSVC native module for @ruvector/attention",
"license": "MIT",
"repository": "https://github.com/ruvnet/ruvector"
}
EOF
npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
continue-on-error: true
# --- Publish main @ruvector/attention package ---
- name: Publish @ruvector/attention (main package)
run: |
mkdir -p publish/attention-main
cd publish/attention-main
cat > package.json << 'EOF'
{
"name": "@ruvector/attention",
"version": "${{ inputs.version || '0.1.31' }}",
"description": "High-performance attention mechanisms with 7 mathematical theories: Optimal Transport, Mixed Curvature, Topology, Information Geometry, Information Bottleneck, PDE/Diffusion, Unified Diagnostics",
"main": "index.js",
"types": "index.d.ts",
"license": "MIT",
"repository": "https://github.com/ruvnet/ruvector",
"keywords": ["attention", "transformer", "machine-learning", "optimal-transport", "hyperbolic", "topology"],
"optionalDependencies": {
"@ruvector/attention-linux-x64-gnu": "${{ inputs.version || '0.1.31' }}",
"@ruvector/attention-linux-arm64-gnu": "${{ inputs.version || '0.1.31' }}",
"@ruvector/attention-darwin-x64": "${{ inputs.version || '0.1.31' }}",
"@ruvector/attention-darwin-arm64": "${{ inputs.version || '0.1.31' }}",
"@ruvector/attention-win32-x64-msvc": "${{ inputs.version || '0.1.31' }}"
}
}
EOF
# Create index.js that loads the correct platform binary
cat > index.js << 'INDEXJS'
const { platform, arch } = process;
const platformPackages = {
'linux-x64': '@ruvector/attention-linux-x64-gnu',
'linux-arm64': '@ruvector/attention-linux-arm64-gnu',
'darwin-x64': '@ruvector/attention-darwin-x64',
'darwin-arm64': '@ruvector/attention-darwin-arm64',
'win32-x64': '@ruvector/attention-win32-x64-msvc',
};
const key = `${platform}-${arch}`;
const pkg = platformPackages[key];
if (!pkg) {
throw new Error(`Unsupported platform: ${key}. Supported: ${Object.keys(platformPackages).join(', ')}`);
}
module.exports = require(pkg);
INDEXJS
# Create TypeScript definitions
cat > index.d.ts << 'INDEXDTS'
export interface AttentionConfig {
dim: number;
numHeads?: number;
dropout?: number;
}
export function scaledDotProductAttention(query: Float32Array, keys: Float32Array[], values: Float32Array[]): Float32Array;
export function multiHeadAttention(query: Float32Array, keys: Float32Array[], values: Float32Array[], config: AttentionConfig): Float32Array;
export function flashAttention(query: Float32Array, keys: Float32Array[], values: Float32Array[], blockSize?: number): Float32Array;
export function hyperbolicAttention(query: Float32Array, keys: Float32Array[], values: Float32Array[], curvature?: number): Float32Array;
INDEXDTS
npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
continue-on-error: true
- name: Summary
run: |
echo "## npm Publishing" >> $GITHUB_STEP_SUMMARY
echo "### WASM Packages" >> $GITHUB_STEP_SUMMARY
echo "✅ @ruvector/math-wasm" >> $GITHUB_STEP_SUMMARY
echo "✅ @ruvector/attention-wasm" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Native Packages" >> $GITHUB_STEP_SUMMARY
echo "✅ @ruvector/attention-linux-x64-gnu" >> $GITHUB_STEP_SUMMARY
echo "✅ @ruvector/attention-linux-arm64-gnu" >> $GITHUB_STEP_SUMMARY
echo "✅ @ruvector/attention-darwin-x64" >> $GITHUB_STEP_SUMMARY
echo "✅ @ruvector/attention-darwin-arm64" >> $GITHUB_STEP_SUMMARY
echo "✅ @ruvector/attention-win32-x64-msvc" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Main Package" >> $GITHUB_STEP_SUMMARY
echo "✅ @ruvector/attention" >> $GITHUB_STEP_SUMMARY
# ============================================================================
# Phase 6: Create GitHub Release
# ============================================================================
create-release:
name: Create GitHub Release
runs-on: ubuntu-22.04
needs: [publish-crates, publish-npm]
if: ${{ !inputs.dry_run && github.event_name == 'push' }}
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Create release archives
run: |
mkdir -p release-assets
# Create platform archives
for platform in linux-x64-gnu linux-arm64-gnu darwin-x64 darwin-arm64 win32-x64-msvc; do
if [ -d "artifacts/native-${platform}" ]; then
tar -czvf "release-assets/ruvector-attention-${platform}.tar.gz" -C "artifacts/native-${platform}" .
fi
done
# Create WASM archives
for pkg in ruvector-math-wasm ruvector-attention-wasm; do
if [ -d "artifacts/wasm-${pkg}" ]; then
tar -czvf "release-assets/${pkg}.tar.gz" -C "artifacts/wasm-${pkg}" .
fi
done
- name: Create Release
uses: softprops/action-gh-release@v1
with:
name: Release ${{ github.ref_name }}
body: |
## RuVector Release ${{ github.ref_name }}
### Published Packages
#### crates.io
- `ruvector-math` - Advanced math primitives
- `ruvector-attention` - 7-theory attention mechanisms
- `ruvector-math-wasm` - WASM bindings for math
- `ruvector-attention-wasm` - WASM bindings for attention
#### npm
- `@ruvector/math-wasm` - Browser WASM package
- `@ruvector/attention` - Main Node.js package (auto-selects platform)
- `@ruvector/attention-wasm` - Browser WASM package
- Platform-specific: linux-x64, linux-arm64, darwin-x64, darwin-arm64, win32-x64
### Installation
```bash
# Rust
cargo add ruvector-math ruvector-attention
# Node.js (auto-selects correct binary)
npm install @ruvector/attention
# Browser (WASM)
npm install @ruvector/math-wasm @ruvector/attention-wasm
```
files: release-assets/*
draft: false
prerelease: false