name: Build Packages

on:
  push:
    branches: [ master ]
    tags: ['*']
    paths-ignore: ['**.md']
  pull_request:
    branches: [ master ]
    paths-ignore: ['**.md']
  workflow_dispatch:

env:
  VCPKG_BINARY_SOURCES: "clear;files,${{ github.workspace }}/vcpkg_cache,readwrite"

jobs:
  build:
    name: ${{ matrix.config.name }}
    runs-on: ${{ matrix.config.os }}

    strategy:
      fail-fast: false
      matrix:
        config:
          - name: Linux GCC
            os: ubuntu-22.04
            toolchain: $VCPKG_INSTALLATION_ROOT
            triplet: x64-linux-dynamic-release
            artifact-name: AppImage
            artifact-path: build/*.AppImage
            extra-options: -DCMAKE_INSTALL_PREFIX=/usr

          - name: MSVC x64
            os: windows-latest
            arch: x64
            toolchain: ${env:VCPKG_INSTALLATION_ROOT}
            triplet: x64-windows-static-release
            artifact-name: Win-64
            artifact-path: build/*.zip
            extra-options: >-
              -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded
              -DCMAKE_IGNORE_PATH="C:/Strawberry/perl/bin;C:/Strawberry/c/lib"

          - name: MSVC x86
            os: windows-latest
            arch: x86
            toolchain: ${env:VCPKG_INSTALLATION_ROOT}
            triplet: x86-windows-static-release
            artifact-name: Win-32
            artifact-path: build/*.zip
            extra-options: >-
              -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded
              -DCMAKE_IGNORE_PATH="C:/Strawberry/perl/bin;C:/Strawberry/c/lib"

          - name: macOS uni
            os: macos-latest
            toolchain: $VCPKG_INSTALLATION_ROOT
            triplet: arm64-osx
            triplet-x64: x64-osx
            artifact-name: Mac-uni
            artifact-path: build/*.zip
            extra-options: -DCMAKE_INSTALL_PREFIX=/usr

    steps:
      - uses: actions/checkout@v4

      - name: Install dependencies (Linux)
        if: runner.os == 'Linux'
        run: |
          sudo sed -i 's/# deb-src/deb-src/' /etc/apt/sources.list
          sudo apt-get update
          sudo apt-get install ninja-build
          sudo apt-get build-dep libsdl2-dev
          
      - name: Developer Command Prompt
        if: runner.os == 'Windows'
        uses: ilammy/msvc-dev-cmd@v1
        with:
          arch: ${{ matrix.config.arch }}

      - name: Restore vcpkg cache
        id: cache
        uses: actions/cache/restore@v4
        with:
          path: ${{ github.workspace }}/vcpkg_cache
          key: vcpkg-${{ matrix.config.triplet }}

      - name: Configure
        run: >-
          cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
          -DENABLE_WERROR=ON -DENABLE_HARDENING=ON -DENABLE_LTO=ON
          -DWITH_FLUIDSYNTH=ON
          -DCMAKE_TOOLCHAIN_FILE="${{ matrix.config.toolchain }}/scripts/buildsystems/vcpkg.cmake"
          -DVCPKG_TARGET_TRIPLET=${{ matrix.config.triplet }}
          ${{ matrix.config.extra-options }}

      - name: Configure macOS x64
        if: ${{ matrix.config.name == 'macOS uni' }}
        run: >-
          cmake -B build-x64 -G Ninja -DCMAKE_BUILD_TYPE=Release
          -DENABLE_WERROR=ON -DENABLE_HARDENING=ON -DENABLE_LTO=ON
          -DWITH_FLUIDSYNTH=ON
          -DCMAKE_OSX_ARCHITECTURES=x86_64
          -DCMAKE_TOOLCHAIN_FILE="${{ matrix.config.toolchain }}/scripts/buildsystems/vcpkg.cmake"
          -DVCPKG_TARGET_TRIPLET=${{ matrix.config.triplet-x64 }}
          ${{ matrix.config.extra-options }}

      # Delete the old cache on hit to emulate a cache update.
      - name: Delete old cache
        continue-on-error: true
        if: steps.cache.outputs.cache-hit
        env:
          GH_TOKEN: ${{ github.token }}
        run: gh cache delete --repo ${{ github.repository }} ${{ steps.cache.outputs.cache-primary-key }}

      - name: Save cache
        uses: actions/cache/save@v4
        with:
          path: ${{ github.workspace }}/vcpkg_cache
          key: ${{ steps.cache.outputs.cache-primary-key }}

      - name: Build
        run: cmake --build build --config "Release"

      - name: Build macOS x64
        if: ${{ matrix.config.name == 'macOS uni' }}
        run: cmake --build build-x64 --config "Release"

      - name: Test
        if: github.event_name == 'workflow_dispatch'
        run: |
          cd demotest
          pip install pyyaml joblib
          python demotest --jobs 4 --port ../build/src/woof

      - name: Package (Linux)
        if: runner.os == 'Linux'
        run: |
          export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ github.workspace }}/build/vcpkg_installed/${{ matrix.config.triplet }}/lib"
          cd build
          cpack

      - name: Package (Windows)
        if: runner.os == 'Windows'
        run: |
          cd build
          cpack

      - name: Package (macOS)
        if: ${{ matrix.config.name == 'macOS uni' }}
        run: |
          lipo build/src/woof build-x64/src/woof -create -output woof
          lipo build/src/woof-setup build-x64/src/woof-setup -create -output woof-setup
          rm build/src/woof
          rm build/src/woof-setup
          mv woof build/src
          mv woof-setup build/src
          cd build
          cpack

      - name: Upload Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.config.artifact-name }}
          path: ${{ matrix.config.artifact-path }}

      - name: Extract Version Number
        if: ${{ contains(github.ref, 'tags') }}
        shell: bash
        run: echo "VERSION=${GITHUB_REF##*_}" >> $GITHUB_ENV

      - name: Release
        if: ${{ contains(github.ref, 'tags') }}
        uses: ncipollo/release-action@v1
        with:
          name: Woof! ${{ env.VERSION }}
          bodyFile: CHANGELOG.md
          allowUpdates: true
          artifacts: ${{ matrix.config.artifact-path }}
