299 lines
11 KiB
YAML
299 lines
11 KiB
YAML
name: SONA NAPI Build & Publish
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'sona-v*'
|
|
paths:
|
|
- 'crates/sona/**'
|
|
- 'npm/packages/sona/**'
|
|
- '.github/workflows/sona-napi.yml'
|
|
pull_request:
|
|
paths:
|
|
- 'crates/sona/**'
|
|
- 'npm/packages/sona/**'
|
|
workflow_dispatch:
|
|
inputs:
|
|
publish:
|
|
description: 'Publish to npm'
|
|
type: boolean
|
|
default: false
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
|
|
jobs:
|
|
build:
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
# Linux x64 GNU
|
|
- os: ubuntu-latest
|
|
target: x86_64-unknown-linux-gnu
|
|
node-file: sona.linux-x64-gnu.node
|
|
# Linux x64 MUSL
|
|
- os: ubuntu-latest
|
|
target: x86_64-unknown-linux-musl
|
|
node-file: sona.linux-x64-musl.node
|
|
# Linux ARM64
|
|
- os: ubuntu-latest
|
|
target: aarch64-unknown-linux-gnu
|
|
node-file: sona.linux-arm64-gnu.node
|
|
# macOS x64
|
|
- os: macos-13
|
|
target: x86_64-apple-darwin
|
|
node-file: sona.darwin-x64.node
|
|
# macOS ARM64
|
|
- os: macos-14
|
|
target: aarch64-apple-darwin
|
|
node-file: sona.darwin-arm64.node
|
|
# Windows x64
|
|
- os: windows-latest
|
|
target: x86_64-pc-windows-msvc
|
|
node-file: sona.win32-x64-msvc.node
|
|
# Windows ARM64
|
|
- os: windows-latest
|
|
target: aarch64-pc-windows-msvc
|
|
node-file: sona.win32-arm64-msvc.node
|
|
|
|
runs-on: ${{ matrix.os }}
|
|
name: Build ${{ matrix.target }}
|
|
|
|
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: Setup Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
targets: ${{ matrix.target }}
|
|
|
|
- name: Install musl tools (Linux MUSL)
|
|
if: matrix.target == 'x86_64-unknown-linux-musl'
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y musl-tools
|
|
|
|
- name: Install napi-rs CLI
|
|
run: npm install -g @napi-rs/cli
|
|
|
|
- name: Build native module (cross-compile)
|
|
if: matrix.target == 'aarch64-unknown-linux-gnu'
|
|
working-directory: npm/packages/sona
|
|
run: |
|
|
npx napi build --platform --release -p ruvector-sona --manifest-path ../../../crates/sona/Cargo.toml --output-dir . -F napi --target ${{ matrix.target }} --use-napi-cross
|
|
|
|
- name: Build native module (macOS)
|
|
if: startsWith(matrix.target, 'x86_64-apple-darwin') || startsWith(matrix.target, 'aarch64-apple-darwin')
|
|
working-directory: npm/packages/sona
|
|
env:
|
|
CARGO_BUILD_TARGET: ${{ matrix.target }}
|
|
RUSTFLAGS: '-C link-arg=-undefined -C link-arg=dynamic_lookup'
|
|
run: |
|
|
npx napi build --platform --release -p ruvector-sona --manifest-path ../../../crates/sona/Cargo.toml --output-dir . -F napi --target ${{ matrix.target }}
|
|
|
|
- name: Build native module (other)
|
|
if: "!startsWith(matrix.target, 'x86_64-apple-darwin') && !startsWith(matrix.target, 'aarch64-apple-darwin') && matrix.target != 'aarch64-unknown-linux-gnu'"
|
|
working-directory: npm/packages/sona
|
|
env:
|
|
CARGO_BUILD_TARGET: ${{ matrix.target }}
|
|
run: |
|
|
npx napi build --platform --release -p ruvector-sona --manifest-path ../../../crates/sona/Cargo.toml --output-dir . -F napi --target ${{ matrix.target }}
|
|
|
|
- name: List built files
|
|
working-directory: npm/packages/sona
|
|
shell: bash
|
|
run: ls -la *.node || echo "No .node files"
|
|
|
|
- name: Upload artifact
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: bindings-${{ matrix.target }}
|
|
path: npm/packages/sona/${{ matrix.node-file }}
|
|
if-no-files-found: error
|
|
|
|
# Build universal macOS binary
|
|
universal-macos:
|
|
runs-on: macos-14
|
|
name: Universal macOS
|
|
needs: build
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Download x64 artifact
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: bindings-x86_64-apple-darwin
|
|
path: artifacts/x64
|
|
|
|
- name: Download ARM64 artifact
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: bindings-aarch64-apple-darwin
|
|
path: artifacts/arm64
|
|
|
|
- name: Create universal binary
|
|
run: |
|
|
mkdir -p artifacts/universal
|
|
lipo -create \
|
|
artifacts/x64/sona.darwin-x64.node \
|
|
artifacts/arm64/sona.darwin-arm64.node \
|
|
-output artifacts/universal/sona.darwin-universal.node
|
|
|
|
- name: Upload universal artifact
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: bindings-darwin-universal
|
|
path: artifacts/universal/sona.darwin-universal.node
|
|
|
|
# Publish to npm
|
|
publish:
|
|
runs-on: ubuntu-latest
|
|
name: Publish npm packages
|
|
needs: [build, universal-macos]
|
|
if: startsWith(github.ref, 'refs/tags/sona-v') || github.event.inputs.publish == 'true'
|
|
|
|
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: Install napi-rs CLI
|
|
run: npm install -g @napi-rs/cli
|
|
|
|
- name: Download all artifacts
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
path: artifacts
|
|
|
|
- name: List artifacts
|
|
run: |
|
|
echo "=== All downloaded artifacts ==="
|
|
find artifacts -name "*.node" -ls
|
|
|
|
- name: Copy .node files to npm package
|
|
working-directory: npm/packages/sona
|
|
run: |
|
|
# Copy all .node files from artifacts to the package directory
|
|
cp ../../../artifacts/bindings-x86_64-unknown-linux-gnu/*.node . 2>/dev/null || true
|
|
cp ../../../artifacts/bindings-x86_64-unknown-linux-musl/*.node . 2>/dev/null || true
|
|
cp ../../../artifacts/bindings-aarch64-unknown-linux-gnu/*.node . 2>/dev/null || true
|
|
cp ../../../artifacts/bindings-x86_64-apple-darwin/*.node . 2>/dev/null || true
|
|
cp ../../../artifacts/bindings-aarch64-apple-darwin/*.node . 2>/dev/null || true
|
|
cp ../../../artifacts/bindings-x86_64-pc-windows-msvc/*.node . 2>/dev/null || true
|
|
cp ../../../artifacts/bindings-aarch64-pc-windows-msvc/*.node . 2>/dev/null || true
|
|
cp ../../../artifacts/bindings-darwin-universal/*.node . 2>/dev/null || true
|
|
|
|
echo "=== .node files in package ==="
|
|
ls -la *.node
|
|
|
|
- name: Create and publish platform packages
|
|
working-directory: npm/packages/sona
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
run: |
|
|
VERSION=$(node -p "require('./package.json').version")
|
|
echo "Publishing version: $VERSION"
|
|
mkdir -p npm
|
|
|
|
publish_platform() {
|
|
local name=$1
|
|
local node_file=$2
|
|
local os_val=$3
|
|
local cpu_val=$4
|
|
local libc_val=$5
|
|
if [ -f "$node_file" ]; then
|
|
local dir_name=$(echo "$name" | sed 's/@ruvector\/sona-//')
|
|
mkdir -p "npm/$dir_name"
|
|
cp "$node_file" "npm/$dir_name/"
|
|
if [ -n "$libc_val" ]; then
|
|
node -e "require('fs').writeFileSync('npm/$dir_name/package.json', JSON.stringify({name:'$name',version:'$VERSION',os:['$os_val'],cpu:['$cpu_val'],libc:['$libc_val'],main:'$node_file',files:['$node_file'],license:'MIT OR Apache-2.0',repository:{type:'git',url:'https://github.com/ruvnet/ruvector.git'}},null,2))"
|
|
else
|
|
node -e "require('fs').writeFileSync('npm/$dir_name/package.json', JSON.stringify({name:'$name',version:'$VERSION',os:['$os_val'],cpu:['$cpu_val'],main:'$node_file',files:['$node_file'],license:'MIT OR Apache-2.0',repository:{type:'git',url:'https://github.com/ruvnet/ruvector.git'}},null,2))"
|
|
fi
|
|
echo "Publishing $name..."
|
|
cd "npm/$dir_name"
|
|
npm publish --access public || echo "Warning: $name may already exist"
|
|
cd ../..
|
|
fi
|
|
}
|
|
|
|
publish_platform "@ruvector/sona-linux-x64-gnu" "sona.linux-x64-gnu.node" "linux" "x64" ""
|
|
publish_platform "@ruvector/sona-linux-x64-musl" "sona.linux-x64-musl.node" "linux" "x64" "musl"
|
|
publish_platform "@ruvector/sona-linux-arm64-gnu" "sona.linux-arm64-gnu.node" "linux" "arm64" ""
|
|
publish_platform "@ruvector/sona-darwin-x64" "sona.darwin-x64.node" "darwin" "x64" ""
|
|
publish_platform "@ruvector/sona-darwin-arm64" "sona.darwin-arm64.node" "darwin" "arm64" ""
|
|
publish_platform "@ruvector/sona-win32-x64-msvc" "sona.win32-x64-msvc.node" "win32" "x64" ""
|
|
publish_platform "@ruvector/sona-win32-arm64-msvc" "sona.win32-arm64-msvc.node" "win32" "arm64" ""
|
|
echo "=== Platform packages published ==="
|
|
|
|
- name: Update main package with optionalDependencies
|
|
working-directory: npm/packages/sona
|
|
run: |
|
|
VERSION=$(node -p "require('./package.json').version")
|
|
|
|
# Add optionalDependencies to package.json
|
|
node -e "
|
|
const pkg = require('./package.json');
|
|
pkg.optionalDependencies = {
|
|
'@ruvector/sona-linux-x64-gnu': '$VERSION',
|
|
'@ruvector/sona-linux-x64-musl': '$VERSION',
|
|
'@ruvector/sona-linux-arm64-gnu': '$VERSION',
|
|
'@ruvector/sona-darwin-x64': '$VERSION',
|
|
'@ruvector/sona-darwin-arm64': '$VERSION',
|
|
'@ruvector/sona-win32-x64-msvc': '$VERSION',
|
|
'@ruvector/sona-win32-arm64-msvc': '$VERSION'
|
|
};
|
|
require('fs').writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\n');
|
|
"
|
|
|
|
echo "=== Updated package.json ==="
|
|
cat package.json
|
|
|
|
- name: Publish main package
|
|
working-directory: npm/packages/sona
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
run: |
|
|
echo "=== Main package contents ==="
|
|
ls -la
|
|
|
|
# Publish main package
|
|
npm publish --access public
|
|
|
|
# Test installation on all platforms
|
|
test-install:
|
|
runs-on: ${{ matrix.os }}
|
|
name: Test ${{ matrix.os }}
|
|
needs: publish
|
|
if: startsWith(github.ref, 'refs/tags/sona-v')
|
|
strategy:
|
|
matrix:
|
|
os: [ubuntu-latest, macos-14, windows-latest]
|
|
|
|
steps:
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
|
|
- name: Wait for npm propagation
|
|
run: sleep 30
|
|
|
|
- name: Test npm install
|
|
run: |
|
|
npm init -y
|
|
npm install @ruvector/sona@latest
|
|
node -e "const sona = require('@ruvector/sona'); console.log('SONA loaded successfully!'); console.log('SonaEngine:', typeof sona.SonaEngine);"
|