Repository navigation
feat(sona): metaharness-Darwin evolves EWC++ config beyond hand-tuned SOTA #99
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 — cross-compiled on Apple Silicon (macos-13 Intel runners are retired; | |
| # jobs requesting that label queue forever) | |
| - os: macos-14 | |
| 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 | |
| # index.js / index.d.ts are committed (CI napi CLI version drift | |
| # produced no loader at all — see #516). Hard-fail if absent: | |
| # npm publish silently skips missing `files` entries, which is | |
| # exactly how the broken 0.1.6 tarball shipped. | |
| test -f index.js -a -f index.d.ts || { echo "ERROR: index.js/index.d.ts missing"; exit 1; } | |
| 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 ../.. | |
| else | |
| echo "ERROR: expected platform binary $node_file is missing"; exit 1 | |
| 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: | | |
| # Rename bundled binaries to the index.<target>.node names the | |
| # committed loader (index.js) checks for. Must happen AFTER the | |
| # platform packages are created from the sona.<target>.node names. | |
| for f in sona.*.node; do | |
| if [ -e "$f" ]; then mv "$f" "index.${f#sona.}"; fi | |
| done | |
| 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);" |