name: Node

on:
  push:
    tags: ["v*"]
  pull_request:
    paths:
      - "node/**"
      - ".github/workflows/node.yaml"

permissions: read-all

env:
  CARGO_TERM_COLOR: always

jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
        with:
          node-version: "22"
      - name: Lint
        working-directory: node
        run: |
          npm ci
          npx biome check

  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
      - uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
      - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2
      - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
        with:
          node-version: "22"

      - name: Build release binary (for test fixture)
        run: cargo build --release

      - name: Install and test
        working-directory: node
        run: |
          npm ci
          npx napi build --platform --release
          node __test__/index.test.mjs

  build:
    name: Build (${{ matrix.settings.target }})
    needs: [lint, test]
    runs-on: ${{ matrix.settings.host }}
    strategy:
      fail-fast: false
      matrix:
        settings:
          - host: macos-latest
            target: aarch64-apple-darwin
          - host: macos-14
            target: x86_64-apple-darwin
          - host: ubuntu-latest
            target: x86_64-unknown-linux-gnu
          - host: ubuntu-latest
            target: aarch64-unknown-linux-gnu
            docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64
          - host: ubuntu-latest
            target: x86_64-unknown-linux-musl
            docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
          - host: windows-latest
            target: x86_64-pc-windows-msvc
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
        if: ${{ !matrix.settings.docker }}
        with:
          node-version: "22"

      - uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
        if: ${{ !matrix.settings.docker }}
        with:
          targets: ${{ matrix.settings.target }}

      - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2
        if: ${{ !matrix.settings.docker }}

      - name: Install dependencies
        working-directory: node
        run: npm ci

      - name: Build (native)
        if: ${{ !matrix.settings.docker }}
        working-directory: node
        run: npx napi build --platform --release --target ${{ matrix.settings.target }}

      - name: Build (docker)
        if: ${{ matrix.settings.docker }}
        uses: addnab/docker-run-action@4f65fabd2431ebc8d299f8e5a018d79a769ae185 # v3
        with:
          image: ${{ matrix.settings.docker }}
          options: --user 0:0 -v ${{ github.workspace }}:/build -w /build/node
          run: |
            apk add --no-cache curl libstdc++ xz
            curl -fsSL https://unofficial-builds.nodejs.org/download/release/v22.14.0/node-v22.14.0-linux-x64-musl.tar.xz \
              | tar -xJ --strip-components=1 -C /usr/local
            curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
            export PATH="$HOME/.cargo/bin:$PATH"
            rustc --version
            node --version
            npm ci
            npx napi build --platform --release --target ${{ matrix.settings.target }}

      - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
        with:
          name: bindings-${{ matrix.settings.target }}
          path: node/*.node
          if-no-files-found: error

  publish:
    name: Publish to npm
    if: startsWith(github.ref, 'refs/tags/v')
    needs: build
    runs-on: ubuntu-latest
    permissions:
      id-token: write
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

      - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
        with:
          node-version: "22"
          registry-url: "https://registry.npmjs.org"

      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          pattern: bindings-*
          merge-multiple: true
          path: node/

      - name: List artifacts
        run: ls -la node/*.node

      - name: Publish
        working-directory: node
        run: |
          npm ci --ignore-scripts
          npx napi pre-publish -t npm
          npm publish --access public --provenance
