name: Plugin Build

on:
  push:
    paths-ignore:
      - '**.md'
    branches:
      - main
    tags:
      - '*'
  pull_request:
    paths-ignore:
      - '**.md'
    branches:
      - main

env:
  artifactName: ${{ contains(github.ref_name, '/') && 'artifact' || github.ref_name }}
  qt: false

jobs:
  linux_build:
    runs-on: ${{ matrix.ubuntu }}
    strategy:
      fail-fast: false
      matrix:
        obs: [27, 28]
        ubuntu: ['ubuntu-20.04']
    defaults:
      run:
        shell: bash
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive

      - name: Download obs-studio development environment
        id: obsdeps
        uses: norihiro/obs-studio-devel-action@v1-beta
        with:
          obs: ${{ matrix.obs }}
          verbose: true
          qt: ${{ env.qt }}

      - name: Build plugin
        run: |
          OBS_QT_VERSION_MAJOR=${{ steps.obsdeps.outputs.OBS_QT_VERSION_MAJOR }}
          mkdir build
          cd build
          case ${{ matrix.obs }} in
            27)
              cmake_opt=(
                -D CMAKE_INSTALL_LIBDIR=/usr/lib/
                -D CPACK_DEBIAN_PACKAGE_DEPENDS='obs-studio (>= 27), obs-studio (<< 28)'
              )
              ;;
            28)
              cmake_opt=(
                -D CPACK_DEBIAN_PACKAGE_DEPENDS='obs-studio (>= 28)'
              )
              ;;
          esac
          cmake .. \
            -D QT_VERSION=$OBS_QT_VERSION_MAJOR \
            -D CMAKE_INSTALL_PREFIX=/usr \
            -D CMAKE_BUILD_TYPE=RelWithDebInfo \
            -D LINUX_PORTABLE=OFF \
            -D CPACK_DEBIAN_PACKAGE_SHLIBDEPS=ON \
            -D PKG_SUFFIX=-obs${{ matrix.obs }}-${{ matrix.ubuntu }}-x86_64 \
            "${cmake_opt[@]}"
          make -j4
          make package
          echo "FILE_NAME=$(find $PWD -name '*.deb' | head -n 1)" >> $GITHUB_ENV
      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ env.artifactName }}-linux-obs${{ matrix.obs }}-${{ matrix.ubuntu }}
          path: '${{ env.FILE_NAME }}'
      - name: Check package
        run: |
          . build/ci/ci_includes.generated.sh
          set -ex
          sudo apt install '${{ env.FILE_NAME }}'
          case ${{ matrix.obs }} in
            27) plugins_dir=/usr/lib/obs-plugins ;;
            28) plugins_dir=/usr/lib/x86_64-linux-gnu/obs-plugins ;;
          esac
          ldd $plugins_dir/${PLUGIN_NAME}.so > ldd.out
          if grep not.found ldd.out ; then
            echo "Error: unresolved shared object." >&2
            exit 1
          fi
          ls /usr/share/obs/obs-plugins/${PLUGIN_NAME}/

  macos_build:
    runs-on: macos-12
    strategy:
      fail-fast: false
      matrix:
        include:
          - obs: 27
            arch: x86_64
          - obs: 28
            arch: universal
    defaults:
      run:
        shell: bash
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive

      - name: Setup Environment
        id: setup
        run: |
          set -e
          echo '::group::Set up code signing'
          if [[ '${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY }}' != '' && \
                '${{ secrets.MACOS_SIGNING_INSTALLER_IDENTITY }}' != '' && \
                '${{ secrets.MACOS_SIGNING_CERT }}' != '' ]]; then
            echo "haveCodesignIdent=true" >> $GITHUB_OUTPUT
          else
            echo "haveCodesignIdent=false" >> $GITHUB_OUTPUT
          fi
          if [[ '${{ secrets.MACOS_NOTARIZATION_USERNAME }}' != '' && \
                '${{ secrets.MACOS_NOTARIZATION_PASSWORD }}' != '' ]]; then
            echo "haveNotarizationUser=true" >> $GITHUB_OUTPUT
          else
            echo "haveNotarizationUser=false" >> $GITHUB_OUTPUT
          fi
          echo '::endgroup::'

      - name: Install Apple Developer Certificate
        if: ${{ github.event_name != 'pull_request' && steps.setup.outputs.haveCodesignIdent == 'true' }}
        uses: apple-actions/import-codesign-certs@v2
        with:
          keychain-password: ${{ github.run_id }}
          p12-file-base64: ${{ secrets.MACOS_SIGNING_CERT }}
          p12-password: ${{ secrets.MACOS_SIGNING_CERT_PASSWORD }}

      - name: Set Signing Identity
        if: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' && steps.setup.outputs.haveCodesignIdent == 'true' && steps.setup.outputs.haveNotarizationUser == 'true' }}
        run: |
          set -e
          TEAM_ID=$(echo "${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY }}" | sed 's/.*(\([A-Za-z0-9]*\))$/\1/')
          xcrun notarytool store-credentials AC_PASSWORD \
            --apple-id "${{ secrets.MACOS_NOTARIZATION_USERNAME }}" \
            --team-id "$TEAM_ID" \
            --password "${{ secrets.MACOS_NOTARIZATION_PASSWORD }}"

      - name: Download obs-studio development environment
        id: obsdeps
        uses: norihiro/obs-studio-devel-action@v1-beta
        with:
          path: /tmp/deps-${{ matrix.obs }}-${{ matrix.arch }}
          arch: ${{ matrix.arch }}
          obs: ${{ matrix.obs }}
          verbose: true
          qt: ${{ env.qt }}

      - name: Build plugin
        run: |
          arch=${{ matrix.arch }}
          deps=/tmp/deps-${{ matrix.obs }}-${{ matrix.arch }}
          MACOSX_DEPLOYMENT_TARGET=${{ steps.obsdeps.outputs.MACOSX_DEPLOYMENT_TARGET }}
          OBS_QT_VERSION_MAJOR=${{ steps.obsdeps.outputs.OBS_QT_VERSION_MAJOR }}
          GIT_TAG=$(git describe --tags --always)
          PKG_SUFFIX=-${GIT_TAG}-obs${{ matrix.obs }}-macos-${{ matrix.arch }}
          set -e
          case "${{ matrix.obs }}" in
            27)
              cmake_opt=()
              ;;
            28)
              cmake_opt=(
                -D MACOSX_PLUGIN_BUNDLE_TYPE=BNDL
                -D OBS_BUNDLE_CODESIGN_IDENTITY='${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY }}'
              )
              ;;
          esac
          cmake -S . -B build -G Ninja \
            -D QT_VERSION=$OBS_QT_VERSION_MAJOR \
            -DCMAKE_BUILD_TYPE=RelWithDebInfo \
            -DCMAKE_PREFIX_PATH="$PWD/release/" \
            -DCMAKE_OSX_ARCHITECTURES=${arch/#universal/x86_64;arm64} \
            -DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} \
            -DCMAKE_FRAMEWORK_PATH="$deps/Frameworks;$deps/lib/cmake;$deps" \
            -D PKG_SUFFIX=$PKG_SUFFIX \
            "${cmake_opt[@]}"
          cmake --build build --config RelWithDebInfo

      - name: Prepare package
        run: |
          set -ex
          . build/ci/ci_includes.generated.sh
          cmake --install build --config RelWithDebInfo --prefix=release
          case ${{ matrix.obs }} in
            27)
              (cd release/${PLUGIN_NAME} && ../../ci/macos/change-rpath.sh -obs ${{ matrix.obs }} -lib lib/ bin/${PLUGIN_NAME}.so)
              cp LICENSE release/${PLUGIN_NAME}/data/LICENSE-$PLUGIN_NAME
              ;;
            28)
              (cd release/${PLUGIN_NAME}.plugin/Contents && ../../../ci/macos/change-rpath.sh -obs 28 -lib lib/ MacOS/${PLUGIN_NAME})
              cp LICENSE release/${PLUGIN_NAME}.plugin/Contents/Resources/LICENSE-$PLUGIN_NAME
              ;;
          esac

      - name: Codesign
        if: ${{ github.event_name != 'pull_request' && steps.setup.outputs.haveCodesignIdent == 'true' }}
        run: |
          . build/ci/ci_includes.generated.sh
          set -ex
          case ${{ matrix.obs }} in
            27)
              files=(
                $(find release/${PLUGIN_NAME}/ -name '*.dylib')
                release/${PLUGIN_NAME}/bin/${PLUGIN_NAME}.so
              )
              ;;
            28)
              files=(
                $(find release/${PLUGIN_NAME}.plugin/ -name '*.dylib')
                release/${PLUGIN_NAME}.plugin/Contents/MacOS/${PLUGIN_NAME}
              )
              ;;
          esac
          for dylib in "${files[@]}"; do
            codesign --force --sign "${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY }}" "$dylib"
          done
          for dylib in "${files[@]}"; do
            codesign -vvv --deep --strict "$dylib"
          done

      - name: Package
        run: |
          . build/ci/ci_includes.generated.sh
          set -ex
          zipfile=$PWD/package/${PLUGIN_NAME}${PKG_SUFFIX}.zip
          mkdir package
          case ${{ matrix.obs }} in
            27) (cd release/ && zip -r $zipfile ${PLUGIN_NAME}) ;;
            28) (cd release/ && zip -r $zipfile ${PLUGIN_NAME}.plugin) ;;
          esac
          ci/macos/install-packagesbuild.sh
          packagesbuild \
            --build-folder $PWD/package/ \
            build/installer-macOS.generated.pkgproj

      - name: Productsign
        if: ${{ github.event_name != 'pull_request' && steps.setup.outputs.haveCodesignIdent == 'true' }}
        run: |
          . build/ci/ci_includes.generated.sh
          pkgfile=package/${PLUGIN_NAME}${PKG_SUFFIX}.pkg
          set -e
          . build/ci/ci_includes.generated.sh
          productsign --sign "${{ secrets.MACOS_SIGNING_INSTALLER_IDENTITY }}" $pkgfile package/${PLUGIN_NAME}-signed.pkg
          mv package/${PLUGIN_NAME}-signed.pkg $pkgfile

      - name: Notarize
        if: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' && steps.setup.outputs.haveCodesignIdent == 'true' }}
        uses: norihiro/macos-notarize-action@v1
        with:
          path: package/*
          keychainProfile: AC_PASSWORD
          verbose: true

      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ env.artifactName }}-macos-obs${{ matrix.obs }}-${{ matrix.arch }}
          path: package/*

  windows_build:
    runs-on: windows-2022
    strategy:
      fail-fast: false
      matrix:
        obs: [27]
        arch: [x64]
    env:
      visualStudio: 'Visual Studio 17 2022'
      Configuration: 'RelWithDebInfo'
    defaults:
      run:
        shell: pwsh
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive
      - name: Download obs-studio
        id: obsdeps
        uses: norihiro/obs-studio-devel-action@v1-beta
        with:
          obs: ${{ matrix.obs }}
          qt: ${{ env.qt }}

      - name: Build plugin
        run: |
          $CmakeArgs = @(
            '-G', "${{ env.visualStudio }}"
            '-DQT_VERSION=${{ steps.obsdeps.outputs.OBS_QT_VERSION_MAJOR }}'
            '-DCMAKE_SYSTEM_VERSION=10.0.18363.657'
            "-DCMAKE_INSTALL_PREFIX=$(Resolve-Path -Path "./obs-build-dependencies/plugin-deps-${{ matrix.arch }}")"
            "-DCMAKE_PREFIX_PATH=$(Resolve-Path -Path "./obs-build-dependencies/plugin-deps-${{ matrix.arch }}")"
          )
          cmake -S . -B build @CmakeArgs
          cmake --build build --config RelWithDebInfo -j 4
          cmake --install build --config RelWithDebInfo --prefix "$(Resolve-Path -Path .)/release"
      - name: Package plugin
        run: ci/windows/package-windows.cmd ${{ matrix.obs }}
      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ env.artifactName }}-windows-obs${{ matrix.obs }}-${{ matrix.arch }}
          path: package/*
