name: CD

on:
  push:
    tags: ["v*"]

permissions:
  contents: write

jobs:
  build:
    name: auto - dist-${{ matrix.name }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include:
          - name: x86_64-linux
            target: x86_64-unknown-linux-musl
            os: ubuntu-latest
            npm_pkg: rsy-linux-x64
            bin: rsy
          - name: aarch64-linux
            target: aarch64-unknown-linux-musl
            os: ubuntu-latest
            npm_pkg: rsy-linux-arm64
            bin: rsy
          - name: x86_64-apple
            target: x86_64-apple-darwin
            os: ubuntu-latest
            npm_pkg: rsy-darwin-x64
            bin: rsy
            use_zigbuild: true
          - name: aarch64-apple
            target: aarch64-apple-darwin
            os: macos-latest
            npm_pkg: rsy-darwin-arm64
            bin: rsy
          - name: x86_64-msvc
            target: x86_64-pc-windows-msvc
            os: windows-latest
            npm_pkg: rsy-win32-x64
            bin: rsy.exe

    steps:
      - uses: actions/checkout@v4

      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - name: Install musl tools (Linux)
        if: contains(matrix.target, 'musl')
        run: |
          sudo apt-get update -q
          sudo apt-get install -y musl-tools
          cargo install cross --git https://github.com/cross-rs/cross

      - name: Install zigbuild (macOS cross-compile)
        if: matrix.use_zigbuild
        run: |
          sudo apt-get update -q
          sudo apt-get install -y python3 wget
          pip3 install ziglang
          cargo install cargo-zigbuild

      - name: Build (cross for Linux ARM64)
        if: matrix.target == 'aarch64-unknown-linux-musl'
        run: cross build --release --target ${{ matrix.target }}

      - name: Build (zigbuild for macOS cross-compile)
        if: matrix.use_zigbuild
        run: cargo zigbuild --release --target ${{ matrix.target }}

      - name: Build
        if: "!matrix.use_zigbuild && matrix.target != 'aarch64-unknown-linux-musl'"
        run: cargo build --release --target ${{ matrix.target }}

      - name: Stage binary
        shell: bash
        run: |
          mkdir -p npm/${{ matrix.npm_pkg }}/bin
          cp target/${{ matrix.target }}/release/${{ matrix.bin }} npm/${{ matrix.npm_pkg }}/bin/

      - uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.npm_pkg }}
          path: npm/${{ matrix.npm_pkg }}/bin/

  publish-npm:
    name: auto - publish-npm
    needs: build
    runs-on: ubuntu-latest
    environment: npm-publish
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          registry-url: "https://registry.npmjs.org"

      - uses: actions/download-artifact@v4
        with:
          path: artifacts/

      - name: Copy binaries into npm packages
        run: |
          for pkg in rsy-linux-x64 rsy-linux-arm64 rsy-darwin-x64 rsy-darwin-arm64 rsy-win32-x64; do
            mkdir -p npm/$pkg/bin
            cp -r artifacts/$pkg/. npm/$pkg/bin/
            chmod +x npm/$pkg/bin/* 2>/dev/null || true
          done

      - name: Publish platform packages
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: |
          for pkg in rsy-linux-x64 rsy-linux-arm64 rsy-darwin-x64 rsy-darwin-arm64 rsy-win32-x64; do
            (cd npm/$pkg && npm publish --access public) || true
          done

      - name: Publish main package
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: npm publish --access public || true

  publish-crate:
    name: auto - publish-crate
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - name: Publish
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: cargo publish --no-verify || true
