name: Build Native Modules on: push: branches: [main] tags: - 'v*' pull_request: branches: [main] workflow_dispatch: inputs: skip_commit: description: 'Skip committing binaries' required: false type: boolean default: false workflow_call: inputs: skip_commit: description: 'Skip committing binaries' required: false type: boolean default: false env: CARGO_TERM_COLOR: always jobs: build: strategy: fail-fast: false matrix: settings: - host: ubuntu-22.04 target: x86_64-unknown-linux-gnu build: npm run build:napi -- --target x86_64-unknown-linux-gnu platform: linux-x64-gnu - host: ubuntu-22.04 target: aarch64-unknown-linux-gnu build: npm run build:napi -- --target aarch64-unknown-linux-gnu platform: linux-arm64-gnu - host: macos-14 target: x86_64-apple-darwin build: npm run build:napi -- --target x86_64-apple-darwin platform: darwin-x64 - host: macos-14 target: aarch64-apple-darwin build: npm run build:napi -- --target aarch64-apple-darwin platform: darwin-arm64 - host: windows-2022 target: x86_64-pc-windows-msvc build: npm run build:napi -- --target x86_64-pc-windows-msvc platform: win32-x64-msvc name: Build ${{ matrix.settings.platform }} runs-on: ${{ matrix.settings.host }} steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '18' - name: Setup Rust uses: dtolnay/rust-toolchain@stable with: toolchain: stable targets: ${{ matrix.settings.target }} - name: Cache Rust uses: Swatinem/rust-cache@v2 with: key: ${{ 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@^2.18.0 - name: Build native module working-directory: npm/packages/core run: ${{ matrix.settings.build }} env: CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc - name: Find built .node files (debug) shell: bash run: | echo "=== Searching entire workspace for .node files ===" find . -name "*.node" -type f 2>/dev/null || true echo "=== Checking npm/packages/core ===" ls -la npm/packages/core/*.node 2>/dev/null || echo "No .node in npm/packages/core/" ls -R npm/packages/core | grep "\.node" || echo "No .node files found" - name: Copy binary to platform package shell: bash run: | # NAPI-RS creates files as npm/packages/core/index.{platform}.node # We need to copy them to npm/core/platforms/{platform}/ruvector.node # Map platform names (NAPI-RS uses different naming for some platforms) case "${{ matrix.settings.platform }}" in linux-x64-gnu) NAPI_PLATFORM="linux-x64-gnu" ;; linux-arm64-gnu) NAPI_PLATFORM="linux-arm64-gnu" ;; darwin-x64) NAPI_PLATFORM="darwin-x64" ;; darwin-arm64) NAPI_PLATFORM="darwin-arm64" ;; win32-x64-msvc) NAPI_PLATFORM="win32-x64-msvc" ;; esac SRC_FILE="npm/packages/core/index.${NAPI_PLATFORM}.node" DEST_DIR="npm/core/platforms/${{ matrix.settings.platform }}" DEST_FILE="${DEST_DIR}/ruvector.node" echo "Looking for: $SRC_FILE" ls -lah "$SRC_FILE" || { echo "ERROR: Expected file not found: $SRC_FILE" echo "Searching for any .node files..." find npm/packages/core -name "*.node" -type f exit 1 } echo "Copying $SRC_FILE to $DEST_FILE" mkdir -p "$DEST_DIR" cp -v "$SRC_FILE" "$DEST_FILE" echo "Verifying copy:" ls -lah "$DEST_FILE" - name: Test native module (native platform only) if: | (matrix.settings.platform == 'linux-x64-gnu' && runner.os == 'Linux') || (matrix.settings.platform == 'darwin-x64' && runner.os == 'macOS' && runner.arch == 'X64') || (matrix.settings.platform == 'darwin-arm64' && runner.os == 'macOS' && runner.arch == 'ARM64') || (matrix.settings.platform == 'win32-x64-msvc' && runner.os == 'Windows') continue-on-error: true shell: bash run: | # Test the locally built .node file directly NODE_FILE="npm/packages/core/index.${{ matrix.settings.platform }}.node" if [ -f "$NODE_FILE" ]; then echo "Testing native module: $NODE_FILE" node -e " const native = require('./$NODE_FILE'); console.log('Native module exports:', Object.keys(native)); console.log('✅ Native module loaded successfully'); " else echo "⚠️ Native module not found at $NODE_FILE - skipping test" fi - name: Upload artifact uses: actions/upload-artifact@v4 with: name: bindings-${{ matrix.settings.platform }} path: npm/core/platforms/${{ matrix.settings.platform }}/*.node if-no-files-found: error # NOTE: build-graph job temporarily disabled until ruvector-graph-node compilation issues are fixed # See PR #15 for details commit-binaries: name: Commit Built Binaries runs-on: ubuntu-22.04 needs: build if: | !inputs.skip_commit && (github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/main')) permissions: contents: write steps: - uses: actions/checkout@v4 with: ref: ${{ github.head_ref || github.ref_name }} - name: Download all artifacts uses: actions/download-artifact@v4 with: path: artifacts - name: Copy binaries to platform packages run: | for dir in artifacts/bindings-*/; do platform=$(basename "$dir" | sed 's/bindings-//') mkdir -p "npm/core/platforms/${platform}" cp -v "$dir"/*.node "npm/core/platforms/${platform}/" done # Also copy linux-x64 to native directory if [ -f "npm/core/platforms/linux-x64-gnu/ruvector.node" ]; then mkdir -p npm/core/native/linux-x64 cp -v npm/core/platforms/linux-x64-gnu/ruvector.node npm/core/native/linux-x64/ fi - name: Show binary sizes run: | echo "=== Built Binaries ===" find npm/core/platforms -name "*.node" -exec ls -lh {} \; find npm/core/native -name "*.node" -exec ls -lh {} \; 2>/dev/null || true - name: Commit and push binaries run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add -f npm/core/platforms/ npm/core/native/ if git diff --staged --quiet; then echo "No changes to commit" else git commit -m "chore: Update NAPI-RS binaries for all platforms Built from commit ${{ github.sha }} Platforms updated: - linux-x64-gnu - linux-arm64-gnu - darwin-x64 - darwin-arm64 - win32-x64-msvc 🤖 Generated by GitHub Actions" git push fi # NOTE: Publish step removed - packages are published manually # Use `npm publish` in the respective package directories after downloading # artifacts from a successful build run