datalayer-driver 6.0.0

Native Chia DataLayer Driver for storing and retrieving data in Chia blockchain
Documentation
name: CI
env:
  DEBUG: napi:*
  APP_NAME: datalayer-driver
  MACOSX_DEPLOYMENT_TARGET: '10.13'
permissions:
  contents: write
  id-token: write
on:
  push:
    branches:
      - main
    tags-ignore:
      - '**'
    paths-ignore:
      - '**/*.md'
      - LICENSE
      - '**/*.gitignore'
      - .editorconfig
      - docs/**
  pull_request:
    branches:
      - '**'

jobs:
  rust-checks:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: stable

      - name: Clippy
        run: rustup component add clippy && cargo clippy --all-targets --all-features -- -D warnings

      - name: Unused dependencies
        run: |
          cargo install cargo-machete --locked
          cargo machete

      - name: Fmt
        run: rustup component add rustfmt && cargo fmt --all -- --check

  build:
    needs: rust-checks
    strategy:
      fail-fast: false
      matrix:
        settings:
          - host: macos-latest
            target: x86_64-apple-darwin
            build: cd napi && npm run build -- --target x86_64-apple-darwin
          - host: windows-latest
            build: cd napi && npm run build -- --target x86_64-pc-windows-msvc
            target: x86_64-pc-windows-msvc
          - host: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian
            build: |
              set -e &&
              rustup update stable && rustup default stable &&
              cd /build/napi && npm install && npm run build -- --target x86_64-unknown-linux-gnu &&
              strip /build/napi/*.node
          - host: macos-latest
            target: aarch64-apple-darwin
            build: cd napi && npm run build -- --target aarch64-apple-darwin
          - host: ubuntu-latest
            target: aarch64-unknown-linux-gnu
            docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64
            build: |
              set -e &&
              rustup update stable && rustup default stable &&
              cd /build/napi && npm install && npm run build -- --target aarch64-unknown-linux-gnu
    name: stable - ${{ matrix.settings.target }} - node@20
    runs-on: ${{ matrix.settings.host }}
    steps:
      - uses: actions/checkout@v4
      - name: Setup node
        uses: actions/setup-node@v4
        if: ${{ !matrix.settings.docker }}
        with:
          node-version: 20
          cache: npm
          cache-dependency-path: napi/package-lock.json
      - name: Install
        uses: dtolnay/rust-toolchain@stable
        if: ${{ !matrix.settings.docker }}
        with:
          toolchain: stable
          targets: ${{ matrix.settings.target }}
      - name: Cache cargo
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            .cargo-cache
            target/
          key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.host }}
      - uses: goto-bus-stop/setup-zig@v2
        if: ${{ matrix.settings.target == 'armv7-unknown-linux-gnueabihf' || matrix.settings.target == 'armv7-unknown-linux-musleabihf' }}
        with:
          version: 0.13.0
      - name: Setup toolchain
        run: ${{ matrix.settings.setup }}
        if: ${{ matrix.settings.setup }}
        shell: bash
      - name: Setup node x86
        if: matrix.settings.target == 'i686-pc-windows-msvc'
        run: echo "Setting up for i686 build"
        shell: bash
      - name: Install dependencies
        run: cd napi && npm install
      - name: Setup node x86
        uses: actions/setup-node@v4
        if: matrix.settings.target == 'i686-pc-windows-msvc'
        with:
          node-version: 20
          cache: npm
          cache-dependency-path: napi/package-lock.json
          architecture: x86
      - name: Build in docker
        uses: addnab/docker-run-action@v3
        if: ${{ matrix.settings.docker }}
        with:
          image: ${{ matrix.settings.docker }}
          options: '--user 0:0 -v ${{ github.workspace }}/.cargo-cache/git/db:/usr/local/cargo/git/db -v ${{ github.workspace }}/.cargo/registry/cache:/usr/local/cargo/registry/cache -v ${{ github.workspace }}/.cargo/registry/index:/usr/local/cargo/registry/index -v ${{ github.workspace }}:/build -w /build'
          run: ${{ matrix.settings.build }}
      - name: Pin base64ct for stable toolchain
        if: ${{ !matrix.settings.docker }}
        run: cargo update -p base64ct --precise 1.6.0 || true
        shell: bash
      - name: Build
        run: ${{ matrix.settings.build }}
        if: ${{ !matrix.settings.docker }}
        shell: bash
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: bindings-${{ matrix.settings.target }}
          path: napi/${{ env.APP_NAME }}.*.node
          if-no-files-found: error

  test-macOS-windows-binding:
    name: Test bindings on ${{ matrix.settings.target }} - node@${{ matrix.node }}
    needs:
      - build
    strategy:
      fail-fast: false
      matrix:
        settings:
          - host: macos-latest
            target: x86_64-apple-darwin
          - host: windows-latest
            target: x86_64-pc-windows-msvc
        node:
          - '18'
          - '20'
    runs-on: ${{ matrix.settings.host }}
    steps:
      - uses: actions/checkout@v4
      - name: Setup node
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
          cache: npm
          cache-dependency-path: napi/package-lock.json
          architecture: x64
      - name: Install dependencies
        run: cd napi && npm install
      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          name: bindings-${{ matrix.settings.target }}
          path: napi
      - name: List packages
        run: |
          echo "Root directory:"
          ls -la
          echo "NAPI directory:"
          ls -la napi/
        shell: bash
      - name: Test bindings
        run: cd napi && npm test

  test-linux-x64-gnu-binding:
    name: Test bindings on Linux-x64-gnu - node@${{ matrix.node }}
    needs:
      - build
    strategy:
      fail-fast: false
      matrix:
        node:
          - '18'
          - '20'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup node
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
          cache: npm
          cache-dependency-path: napi/package-lock.json
      - name: Install dependencies
        run: cd napi && npm install
      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          name: bindings-x86_64-unknown-linux-gnu
          path: napi
      - name: List packages
        run: |
          echo "Root directory:"
          ls -la
          echo "NAPI directory:"
          ls -la napi/
        shell: bash
      - name: Test bindings
        run: docker run --rm -v $(pwd):/build -w /build/napi node:${{ matrix.node }}-slim sh -c "npm install && npm test"

  test-linux-aarch64-gnu-binding:
    name: Test bindings on aarch64-unknown-linux-gnu - node@${{ matrix.node }}
    needs:
      - build
    strategy:
      fail-fast: false
      matrix:
        node:
          - '18'
          - '20'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          name: bindings-aarch64-unknown-linux-gnu
          path: napi
      - name: List packages
        run: |
          echo "Root directory:"
          ls -la
          echo "NAPI directory:"
          ls -la napi/
        shell: bash
      - name: Install dependencies
        run: |
          cd napi && npm install
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
        with:
          platforms: arm64
      - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
      - name: Setup and run tests
        uses: addnab/docker-run-action@v3
        with:
          image: node:${{ matrix.node }}-slim
          options: '--platform linux/arm64 -v ${{ github.workspace }}:/build -w /build'
          run: |
            set -e
            cd napi && npm install && npm test

  publish-npm:
    name: Publish to NPM
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    needs:
      - test-macOS-windows-binding
      - test-linux-x64-gnu-binding
      - test-linux-aarch64-gnu-binding
    steps:
      - uses: actions/checkout@v4
      - name: Setup node
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
          cache-dependency-path: napi/package-lock.json
      - name: Install dependencies
        run: |
          cd napi
          npm install
      - name: Download all artifacts
        uses: actions/download-artifact@v4
        with:
          path: napi/artifacts
      - name: Move artifacts
        run: |
          cd napi
          npm run artifacts
      - name: List packages
        run: ls -R ./napi/npm
        shell: bash
      # PINNED to the 11.x line, NOT @latest. Trusted publishing needs npm >= 11.5.1, but npm 12
      # requires Node ^22.22.2 while this job sets up Node 20 — so `@latest` started failing the
      # moment npm 12 shipped, with EBADENGINE, and took the 5.0.0 npm publish down with it while
      # the crates.io half succeeded. npm 11.6.2 declares `^20.17.0 || >=22.9.0`, so it satisfies
      # both this runner and trusted publishing. Raise this pin only together with the Node version
      # in the `Setup node` step above.
      - name: Upgrade npm for trusted publishing
        run: npm install -g npm@11
      - name: Publish to NPM
        run: |
          cd napi
          npm --version
          if git log -1 --pretty=%B | grep "^[0-9]\+\.[0-9]\+\.[0-9]\+$";
          then
            npm publish --access public
          elif git log -1 --pretty=%B | grep "^[0-9]\+\.[0-9]\+\.[0-9]\+";
          then
            npm publish --tag next --access public
          else
            echo "Not a release, skipping npm publish"
          fi
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

  publish-crates:
    name: Publish to Crates.io
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    needs:
      - test-macOS-windows-binding
      - test-linux-x64-gnu-binding
      - test-linux-aarch64-gnu-binding
    steps:
      - uses: actions/checkout@v4
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
      - name: Prepare for crates.io publish
        run: |
          if git log -1 --pretty=%B | grep "^[0-9]\+\.[0-9]\+\.[0-9]\+$";
          then
            echo "Release detected, preparing for crates.io publish"
            # Ensure Cargo.lock is up to date
            cargo update --dry-run || true
            # Check if there are any changes and commit them
            if ! git diff --quiet Cargo.lock; then
              echo "Cargo.lock has changes, committing them"
              git config --local user.email "action@github.com"
              git config --local user.name "GitHub Action"
              git add Cargo.lock
              git commit -m "Update Cargo.lock for release" || true
            fi
          else
            echo "Not a release, skipping crates.io preparation"
          fi
      - name: Publish to crates.io
        run: |
          if git log -1 --pretty=%B | grep "^[0-9]\+\.[0-9]\+\.[0-9]\+$";
          then
            # Skip a version already on the index, so RE-triggering a release is not red.
            # This matters because the two registries can diverge: on 5.0.0 the crates.io half
            # succeeded and the npm half failed on an unrelated engine error, and the only way to
            # retry npm is another release commit — which would otherwise fail here on
            # "crate version is already uploaded" and hide the npm result behind a red crates job.
            # The User-Agent header is REQUIRED; without it crates.io answers in a way that reads
            # exactly like "not published", which would turn this guard into a silent skip.
            VERSION=$(git log -1 --pretty=%B | grep -m1 "^[0-9]\+\.[0-9]\+\.[0-9]\+$")
            if curl -sH 'User-Agent: dig-datalayer-driver-ci' \
                 https://index.crates.io/da/ta/datalayer-driver \
                 | grep -q "\"vers\":\"${VERSION}\""; then
              echo "datalayer-driver ${VERSION} is already on crates.io — skipping publish"
            else
              cargo login $CARGO_REGISTRY_TOKEN
              cargo publish --no-verify --allow-dirty
            fi
          else
            echo "Not a release, skipping crates.io publish"
          fi
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}