name: 📢 Release

on:
  workflow_run:
    workflows:
      - 🧪 Test
    types: [completed]
    branches:
      - master
      - release/**

concurrency:
  group: ${{ github.workflow }}-${{ github.ref_name }}
  cancel-in-progress: true

jobs:
  release-plan:
    name: 🤖 Plan release
    runs-on: ubuntu-latest
    if: github.event.workflow_run.conclusion == 'success'
    outputs:
      release: ${{ steps.plan_release.outputs.release }}
      version: ${{ steps.plan_release.outputs.version }}
      tag: ${{ steps.plan_release.outputs.tag }}
    steps:
      - uses: actions/checkout@v6
      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: latest
      - name: Install semantic-release
        run: |
          npm i semantic-release/changelog
      - name: Plan release
        id: plan_release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          npx semantic-release --dry-run | tee semantic-release.log
          version=$(awk '/The next release version is/ { print $NF }' semantic-release.log | tail -n1)
          if [[ -z "$version" ]]; then
            echo "release=False" >> "$GITHUB_OUTPUT"
          else
            echo "release=True" >> "$GITHUB_OUTPUT"
            printf 'version=%s\ntag=v%s\n' "$version" "$version" >> "$GITHUB_OUTPUT"
          fi

  linux-build:
    name: 🐧 linux build
    runs-on: ubuntu-latest
    needs: [release-plan]
    if: ${{ needs.release-plan.outputs.release == 'True' }}
    steps:
      - uses: actions/checkout@v6
      - name: apt install deps
        run: |
          sudo apt-get update -y -q
          sudo apt-get install -y -q --no-install-recommends cmake ninja-build libopencv-dev libgavl-dev libfreetype-dev libcairo2-dev
      - name: Build using cmake+ninja
        run: |
          mkdir build && cd build
          cmake -G "Ninja" -D FREI0R_VERSION=${{ needs.release-plan.outputs.version }} ../
          ninja
      - name: Upload linux filter
        uses: actions/upload-artifact@v6
        with:
          name: release-linux-filter
          path: build/src/filter/**/*.so
      - name: Upload linux mixer2
        uses: actions/upload-artifact@v6
        with:
          name: release-linux-mixer2
          path: build/src/mixer2/**/*.so
      - name: Upload linux mixer3
        uses: actions/upload-artifact@v6
        with:
          name: release-linux-mixer3
          path: build/src/mixer3/**/*.so
      - name: Upload linux generator
        uses: actions/upload-artifact@v6
        with:
          name: release-linux-generator
          path: build/src/generator/**/*.so
      - name: Upload linux pkg-config
        uses: actions/upload-artifact@v6
        with:
          name: release-linux-pkgconfig
          path: build/frei0r.pc

  win-build:
    name: 🪟 win64 build
    runs-on: windows-latest
    needs: [release-plan]
    if: ${{ needs.release-plan.outputs.release == 'True' }}
    steps:
      - uses: actions/checkout@v6
      - uses: ilammy/msvc-dev-cmd@v1
      - name: choco install deps
        uses: crazy-max/ghaction-chocolatey@v3
        with:
          args: install libopencv-dev
      - name: Build using nmake
        run: |
          mkdir build && cd build
          cmake -G "NMake Makefiles" -D WITHOUT_OPENCV=1 -D WITHOUT_CAIRO=1 -D WITHOUT_GAVL=1 -D FREI0R_VERSION=${{ needs.release-plan.outputs.version }} ../
          nmake
      - name: Upload win64 filter
        uses: actions/upload-artifact@v6
        with:
          name: release-win64-filter
          path: build/src/filter/**/*.dll
      - name: Upload win64 mixer2
        uses: actions/upload-artifact@v6
        with:
          name: release-win64-mixer2
          path: build/src/mixer2/**/*.dll
      - name: Upload win64 mixer3
        uses: actions/upload-artifact@v6
        with:
          name: release-win64-mixer3
          path: build/src/mixer3/**/*.dll
      - name: Upload win64 generator
        uses: actions/upload-artifact@v6
        with:
          name: release-win64-generator
          path: build/src/generator/**/*.dll
      - name: Upload win64 pkg-config
        uses: actions/upload-artifact@v6
        with:
          name: release-win64-pkgconfig
          path: build/frei0r.pc

  osx-build:
    name: 🍏 osx build
    runs-on: macos-latest
    needs: [release-plan]
    if: ${{ needs.release-plan.outputs.release == 'True' }}
    steps:
      - uses: actions/checkout@v6
      - name: Update Homebrew
        run: |
          brew update
      - name: Install Homebrew dependencies
        run: |
          env HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 \
          brew install ninja cairo
      - name: Build using ninja
        run: |
          mkdir build && cd build
          cmake -G "Ninja" -D WITHOUT_OPENCV=1 -D WITHOUT_GAVL=1 -D FREI0R_VERSION=${{ needs.release-plan.outputs.version }} ../
          ninja
      - name: Upload osx filter
        uses: actions/upload-artifact@v6
        with:
          name: release-osx-filter
          path: build/src/filter/**/*.so
      - name: Upload osx mixer2
        uses: actions/upload-artifact@v6
        with:
          name: release-osx-mixer2
          path: build/src/mixer2/**/*.so
      - name: Upload osx mixer3
        uses: actions/upload-artifact@v6
        with:
          name: release-osx-mixer3
          path: build/src/mixer3/**/*.so
      - name: Upload osx generator
        uses: actions/upload-artifact@v6
        with:
          name: release-osx-generator
          path: build/src/generator/**/*.so
      - name: Upload osx pkg-config
        uses: actions/upload-artifact@v6
        with:
          name: release-osx-pkgconfig
          path: build/frei0r.pc

  publish-release:
    name: 🚀 Publish release
    runs-on: ubuntu-latest
    needs: [release-plan, win-build, osx-build, linux-build]
    if: ${{ needs.release-plan.outputs.release == 'True' }}
    outputs:
      version: ${{ steps.publish_release.outputs.version }}
      tag: ${{ steps.publish_release.outputs.tag }}
    steps:
      - uses: actions/checkout@v6
      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: latest
      - name: Install semantic-release
        run: |
          npm i semantic-release/changelog
      - name: Publish release
        id: publish_release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          npx semantic-release
          printf 'version=%s\ntag=%s\n' \
            "${{ needs.release-plan.outputs.version }}" \
            "${{ needs.release-plan.outputs.tag }}" >> "$GITHUB_OUTPUT"

  draft-binary-release:
    name: 📦 Pack release
    needs: [release-plan, publish-release, win-build, osx-build, linux-build]
    if: ${{ needs.release-plan.outputs.release == 'True' }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: download binary artifacts
        uses: actions/download-artifact@v7
        with:
          path: |
            frei0r-bin
      - name: create compressed archives
        run: |
          dst=frei0r-${{ needs.publish-release.outputs.version }}_win64
          mkdir -p $dst/filter $dst/generator $dst/mixer2 $dst/mixer3
          find frei0r-bin/release-win64-filter    -type f -name '*.dll' -exec cp {} $dst/filter    \;
          find frei0r-bin/release-win64-generator -type f -name '*.dll' -exec cp {} $dst/generator \;
          find frei0r-bin/release-win64-mixer2    -type f -name '*.dll' -exec cp {} $dst/mixer2    \;
          find frei0r-bin/release-win64-mixer3    -type f -name '*.dll' -exec cp {} $dst/mixer3    \;
          cp README.md $dst/README.txt
          cp COPYING   $dst/LICENSE.txt
          cp ChangeLog $dst/ChangeLog.txt
          cp AUTHORS.md   $dst/AUTHORS.txt
          cp include/frei0r.h include/frei0r.hpp $dst/
          cp frei0r-bin/release-win64-pkgconfig/frei0r.pc $dst/
          echo "${{ needs.publish-release.outputs.version }}" > $dst/VERSION.txt
          zip -r -9 $dst.zip $dst

          dst=frei0r-${{ needs.publish-release.outputs.version }}_osx
          mkdir -p $dst/filter $dst/generator $dst/mixer2 $dst/mixer3
          find frei0r-bin/release-osx-filter    -type f -name '*.so' -exec cp {} $dst/filter    \;
          find frei0r-bin/release-osx-generator -type f -name '*.so' -exec cp {} $dst/generator \;
          find frei0r-bin/release-osx-mixer2    -type f -name '*.so' -exec cp {} $dst/mixer2    \;
          find frei0r-bin/release-osx-mixer3    -type f -name '*.so' -exec cp {} $dst/mixer3    \;
          cp README.md $dst/README.txt
          cp COPYING   $dst/LICENSE.txt
          cp ChangeLog $dst/ChangeLog.txt
          cp AUTHORS.md   $dst/AUTHORS.txt
          cp include/frei0r.h include/frei0r.hpp $dst/
          cp frei0r-bin/release-osx-pkgconfig/frei0r.pc $dst/
          echo "${{ needs.publish-release.outputs.version }}" > $dst/VERSION.txt
          zip -r -9 $dst.zip $dst

          dst=frei0r-${{ needs.publish-release.outputs.version }}_linux
          mkdir -p $dst/filter $dst/generator $dst/mixer2 $dst/mixer3
          find frei0r-bin/release-linux-filter    -type f -name '*.so' -exec cp {} $dst/filter    \;
          find frei0r-bin/release-linux-generator -type f -name '*.so' -exec cp {} $dst/generator \;
          find frei0r-bin/release-linux-mixer2    -type f -name '*.so' -exec cp {} $dst/mixer2    \;
          find frei0r-bin/release-linux-mixer3    -type f -name '*.so' -exec cp {} $dst/mixer3    \;
          cp README.md $dst/README.txt
          cp COPYING   $dst/LICENSE.txt
          cp ChangeLog $dst/ChangeLog.txt
          cp AUTHORS.md   $dst/AUTHORS.txt
          cp include/frei0r.h include/frei0r.hpp $dst/
          cp frei0r-bin/release-linux-pkgconfig/frei0r.pc $dst/
          echo "${{ needs.publish-release.outputs.version }}" > $dst/VERSION.txt
          tar cvfz $dst.tar.gz $dst

          sha256sum *.zip *.tar.gz > SHA256SUMS.txt

      - name: release all archives
        uses: softprops/action-gh-release@v2
        with:
          files: |
            *.zip
            *.tar.gz
            SHA256SUMS.txt
          tag_name: ${{ needs.publish-release.outputs.tag }}
          draft: true
          prerelease: false
          fail_on_unmatched_files: true
          generate_release_notes: true
