name: Release

on:
  push:
    tags: [v\d+\.\d+\.\d+]

permissions:
  contents: write
  packages: write

env:
  CARGO_TERM_COLOR: always

jobs:
  create-release:
    permissions:
      contents: write
    runs-on: ubuntu-20.04
    outputs:
      release_id: ${{ steps.create-release.outputs.id }}
      release_upload_url: ${{ steps.create-release.outputs.upload_url }}
      release_body: "${{ steps.tag.outputs.message }}"

    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4

      - name: Get version
        id: get_version
        uses: battila7/get-version-action@d97fbc34ceb64d1f5d95f4dfd6dce33521ccccf5 # ratchet:battila7/get-version-action@v2

      - name: Get tag message
        id: tag
        run: |
          git fetch --depth=1 origin +refs/tags/*:refs/tags/*
          echo "message<<EOF" >> $GITHUB_OUTPUT
          echo "$(git tag -l --format='%(contents)' ${{ steps.get_version.outputs.version }})" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Create Release
        id: create-release
        uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # ratchet:ncipollo/release-action@v1
        with:
          draft: true
          name: ${{ steps.get_version.outputs.version }}
          tag: ${{ steps.get_version.outputs.version }}
          body: "${{ steps.tag.outputs.message }}"

  releases-matrix:
    needs: [create-release]
    strategy:
      fail-fast: false
      matrix:
        feature: [lua51, luajit]
        config:
          - os: ubuntu-latest
            os_name: linux
            arch: x86_64
            rust_target: x86_64-unknown-linux-gnu
            docker_platform: linux/amd64
            container: quay.io/pypa/manylinux2014_x86_64 # for glibc 2.17
          - os: ubuntu-latest
            os_name: linux
            arch: aarch64
            rust_target: aarch64-unknown-linux-gnu
          - os: macos-13
            os_name: darwin
            arch: x86_64
            rust_target: x86_64-apple-darwin
          - os: macos-latest
            os_name: darwin
            arch: aarch64
            rust_target: aarch64-apple-darwin
          - os: windows-latest
            os_name: windows
            arch: x86_64
            rust_target: x86_64-pc-windows-msvc
          - os: windows-latest
            os_name: windows
            arch: aarch64
            rust_target: aarch64-pc-windows-msvc

    runs-on: ${{ matrix.config.os }}

    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4

      - uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # ratchet:Swatinem/rust-cache@v2
        if: ${{ matrix.config.container == null }}
      - uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a # ratchet:dtolnay/rust-toolchain@master
        if: ${{ matrix.config.container == null }}
        with:
          targets: ${{ matrix.config.rust_target }}
          toolchain: 1.80.0
      - name: Build all crates
        if: ${{ matrix.config.container == null }}
        run: |
          cargo build --release --features ${{ matrix.feature }}

      - name: Build all crates with glibc 2.17 # for glibc 2.17
        if: ${{ matrix.config.container != null }}
        run: |
          # sudo apt-get install -y qemu qemu-user-static
          docker run \
            --rm \
            -v $(pwd):/workspace \
            -w /workspace \
            --platform ${{ matrix.config.docker_platform }} \
            ${{ matrix.config.container }} \
            bash -c "yum install -y openssl-devel && curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal && . /root/.cargo/env && cargo build --release --features ${{ matrix.feature }}"

      - name: Handle binaries
        if: ${{ matrix.config.os_name != 'windows' }}
        shell: bash
        run: |
          mkdir -p results
          if [ "${{ matrix.config.os_name }}" == "linux" ]; then
            EXT="so"
          else
            EXT="dylib"
          fi
          cp target/release/libavante_templates.$EXT results/avante_templates.$EXT
          cp target/release/libavante_tokenizers.$EXT results/avante_tokenizers.$EXT
          cp target/release/libavante_repo_map.$EXT results/avante_repo_map.$EXT

          cd results
          tar zcvf avante_lib-${{ matrix.config.os_name }}-${{ matrix.config.arch }}-${{ matrix.feature }}.tar.gz *.${EXT}

      - name: Handle binaries (Windows)
        if: ${{ matrix.config.os_name == 'windows' }}
        shell: pwsh
        run: |
          New-Item -ItemType Directory -Force -Path results

          Copy-Item -Path "target\release\avante_templates.dll" -Destination "results\avante_templates.dll"
          Copy-Item -Path "target\release\avante_tokenizers.dll" -Destination "results\avante_tokenizers.dll"
          Copy-Item -Path "target\release\avante_repo_map.dll" -Destination "results\avante_repo_map.dll"

          Set-Location -Path results

          $dllFiles = Get-ChildItem -Filter "*.dll" | Select-Object -ExpandProperty Name
          Compress-Archive -Path $dllFiles -DestinationPath "avante_lib-${{ matrix.config.os_name }}-${{ matrix.config.arch }}-${{ matrix.feature }}.zip"

      - name: Upload Release Asset
        uses: shogo82148/actions-upload-release-asset@8482bd769644976d847e96fb4b9354228885e7b4 # ratchet:shogo82148/actions-upload-release-asset@v1
        if: ${{ matrix.config.os_name != 'windows' }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          ASSET_NAME: avante_lib-${{ matrix.config.os_name }}-${{ matrix.config.arch }}-${{ matrix.feature }}.tar.gz
        with:
          upload_url: ${{ needs.create-release.outputs.release_upload_url }}
          asset_path: ./results/avante_lib-${{ matrix.config.os_name }}-${{ matrix.config.arch }}-${{ matrix.feature }}.tar.gz
      - name: Upload Release Asset (Windows)
        uses: shogo82148/actions-upload-release-asset@8482bd769644976d847e96fb4b9354228885e7b4 # ratchet:shogo82148/actions-upload-release-asset@v1
        if: ${{ matrix.config.os_name == 'windows' }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          ASSET_NAME: avante_lib-${{ matrix.config.os_name }}-${{ matrix.config.arch }}-${{ matrix.feature }}.zip
        with:
          upload_url: ${{ needs.create-release.outputs.release_upload_url }}
          asset_path: ./results/avante_lib-${{ matrix.config.os_name }}-${{ matrix.config.arch }}-${{ matrix.feature }}.zip

  publish-release:
    permissions:
      contents: write
    runs-on: ubuntu-20.04
    needs: [create-release, releases-matrix]

    steps:
      - name: publish release
        id: publish-release
        uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # ratchet:actions/github-script@v6
        env:
          release_id: ${{ needs.create-release.outputs.release_id }}
        with:
          script: |
            github.rest.repos.updateRelease({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: process.env.release_id,
              draft: false,
              prerelease: false
            })