name: publish

permissions:
  contents: write

on:
  push:
    tags:
    - v[0-9]+.[0-9]+.[0-9]+

jobs:
  create-release:
    name: create-release
    runs-on: ubuntu-latest
    steps:
      - name: Create a GitHub release
        shell: bash
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh release create \
            ${{ github.ref_name }} \
            --repo ${{ github.event.repository.full_name }} \
            --verify-tag \
            --generate-notes

  publish-release:
    name: Publish (${{ matrix.build }})
    needs: ['create-release']
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        build:
        - Ubuntu
        - 'Ubuntu, aarch64'
        - Alpine
        - 'macOS, x86_64'
        - macOS
        - Windows
        include:
        - build: Ubuntu
          os: ubuntu-latest
          env: { RUSTFLAGS: "-C target-cpu=haswell" }
        - build: 'Ubuntu, aarch64'
          os: ubuntu-24.04-arm
          env: {}
        - build: Alpine
          os: ubuntu-latest
          env: { RUSTFLAGS: "-C target-cpu=haswell -C target-feature=-crt-static" }
        - build: 'macOS, x86_64'
          os: macos-15-intel
          env: { RUSTFLAGS: "-C target-cpu=haswell" }
        - build: macOS
          os: macos-latest
          env: {}
        - build: Windows
          os: windows-latest
          env: { RUSTFLAGS: "-C target-cpu=haswell" }
      fail-fast: false

    steps:
    - name: Checkout the repo
      uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
      with:
        persist-credentials: false

    - name: Install Node
      if: matrix.build != 'Alpine'
      uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
      with:
        node-version: 22

    - name: Install Rust
      if: matrix.build != 'Alpine'
      uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # v1
      with:
        toolchain: stable

    # Windows fails on `yarn exec` with "Couldn't find the binary", calling node directly
    - name: Build and package the binary
      if: matrix.build != 'Alpine'
      shell: bash
      env: ${{ matrix.env }}
      run: |
        export npm_package_name=node-weakauras-parser
        yarn install --production=false --ignore-scripts
        node node_modules/cargo-cp-artifact/bin/cargo-cp-artifact.js -nc native/index.node -- cargo build --release --manifest-path=native/Cargo.toml --message-format=json-render-diagnostics

        if command -v sha512sum; then
          SHA512="$(sha512sum native/index.node | awk '{ print $1 }')"
        elif command -v shasum; then
          SHA512="$(shasum -a 512 native/index.node | awk '{ print $1 }')"
        elif command -v openssl; then
          SHA512="$(openssl dgst -sha512 native/index.node | awk '{ print $2 }')"
        fi
        echo "SHA-512 of native/index.node: ${SHA512:-N/A}"

        rm -rf native/target/
        yarn package-binary

    - name: Build and package the binary (Docker)
      if: matrix.build == 'Alpine'
      shell: bash
      env: ${{ matrix.env }}
      run: |
        docker build -t alpine-builder -f .github/workflows/Dockerfile .

        CURRENT_USER=$(whoami)
        USER_ID=$(id -u $CURRENT_USER)
        GROUP_ID=$(id -g $CURRENT_USER)

        docker run --rm \
          -v "$PWD/native:/app:Z" \
          --workdir="/app" \
          --env="RUSTFLAGS=$RUSTFLAGS" \
          alpine-builder \
          cargo build --release

        docker run --rm \
          -v "$PWD/native:/app:Z" \
          --workdir="/app" \
          alpine-builder \
          chown -R $USER_ID:$GROUP_ID target/

        mv native/target/release/libnode_weakauras_parser.so native/index.node
        echo "SHA-512 of native/index.node: $(sha512sum native/index.node | awk '{ print $1 }')"

        rm -rf native/target/
        mkdir -p build/stage/${{ github.ref_name }}/
        tar -cvzf build/stage/${{ github.ref_name }}/linux-x64-musl.tar.gz native
        
    - name: Publish the binary
      shell: bash
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        FILENAME="$(find build/stage/${{ github.ref_name }}/ -name '*.tar.gz' -type f | head -n1)"
        gh release upload \
          ${{ github.ref_name }} \
          "$FILENAME" \
          --repo ${{ github.event.repository.full_name }}
