name: build obs plugin

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

env:
  PLUGIN_NAME: gradient-source
  OBS_VERSION: 28.0.0-rc1
jobs:
  macos:
    name: macOS
    runs-on: macos-12
    strategy:
      fail-fast: false
      matrix:
        arch: [x86_64, arm64, universal]
    outputs:
      commitHash: ${{ steps.setup.outputs.commitHash }}
    env:
      CODESIGN_IDENT: '-'
      CODESIGN_IDENT_INSTALLER: ''
      MACOSX_DEPLOYMENT_TARGET: '10.15'  
    defaults:
      run:
        shell: zsh {0}
    steps:
      - name: Checkout
        uses: actions/checkout@v3.1.0
        with:
          path: plugin
          submodules: recursive

      - name: Checkout obs-studio
        uses: actions/checkout@v3
        with:
          repository: 'obsproject/obs-studio'
          path: obs-studio
          fetch-depth: 0
          submodules: recursive

      - name: Setup Environment
        id: setup
        working-directory: ${{ github.workspace }}/plugin
        run: |
          ## SETUP ENVIRONMENT SCRIPT
          print '::group::Clean Homebrew Environment'
          typeset -a to_remove=()

          for formula (speexdsp curl php) {
            if [[ -d ${HOMEBREW_PREFIX}/opt/${formula} ]] to_remove+=(${formula})
          }

          if (( #to_remove > 0 )) brew uninstall --ignore-dependencies ${to_remove}
          print '::endgroup::'

          print '::group::Set up code signing'
          if [[ '${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY }}' != '' && \
                '${{ secrets.MACOS_SIGNING_INSTALLER_IDENTITY }}' != '' && \
                '${{ secrets.MACOS_SIGNING_CERT }}' != '' ]] {
            print 'haveCodesignIdent=true' >> $GITHUB_OUTPUT
          } else {
            print 'haveCodesignIdent=false' >> $GITHUB_OUTPUT
          }

          if [[ '${{ secrets.MACOS_NOTARIZATION_USERNAME }}' != '' && \
                '${{ secrets.MACOS_NOTARIZATION_PASSWORD }}' != '' ]] {
            print 'haveNotarizationUser=true' >> $GITHUB_OUTPUT
          } else {
            print 'haveNotarizationUser=false' >> $GITHUB_OUTPUT
          }
          print '::endgroup::'

          print "ccacheDate=$(date +"%Y-%m-%d")" >> $GITHUB_OUTPUT
          print "commitHash=${"$(git rev-parse HEAD)"[0,9]}" >> $GITHUB_OUTPUT

      - name: Restore Compilation Cache
        id: ccache-cache
        uses: actions/cache@v3.0.11
        with:
          path: ${{ github.workspace }}/.ccache
          key: macos-${{ matrix.arch }}-ccache-plugin-${{ steps.setup.outputs.ccacheDate }}
          restore-keys: |
            macos-${{ matrix.arch }}-ccache-plugin-

      - name: Check for GitHub Labels
        id: seekingTesters
        if: ${{ github.event_name == 'pull_request' }}
        run: |
          if [[ -n "$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -s "${{ github.event.pull_request.url }}" | jq -e '.labels[] | select(.name == "Seeking Testers")')" ]] {
            print 'found=true' >> $GITHUB_OUTPUT
          } else {
            print 'found=false' >> $GITHUB_OUTPUT
          }

      - name: Install Apple Developer Certificate
        if: ${{ github.event_name != 'pull_request' && steps.setup.outputs.haveCodesignIdent == 'true' }}
        uses: apple-actions/import-codesign-certs@253ddeeac23f2bdad1646faac5c8c2832e800071
        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: ${{ github.event_name != 'pull_request' && steps.setup.outputs.haveCodesignIdent == 'true' }}
        run: |
          print "CODESIGN_IDENT=${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY }}" >> $GITHUB_ENV
          print "CODESIGN_IDENT_INSTALLER=${{ secrets.MACOS_SIGNING_INSTALLER_IDENTITY }}" >> $GITHUB_ENV

      - name: Build Plugin
        uses: ./plugin/.github/actions/build-plugin
        with:
          workingDirectory: ${{ github.workspace }}/plugin
          target: ${{ matrix.arch }}
          config: RelWithDebInfo
          codesign: 'true'
          codesignIdent: ${{ env.CODESIGN_IDENT }}

      - name: Package Plugin
        uses: ./plugin/.github/actions/package-plugin
        with:
          workingDirectory: ${{ github.workspace }}/plugin
          target: ${{ matrix.arch }}
          config: RelWithDebInfo
          codesign: ${{ github.event_name != 'pull_request' && steps.setup.outputs.haveCodesignIdent == 'true' }}
          notarize: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' && steps.setup.outputs.haveNotarizationUser == 'true' }}
          codesignIdent: ${{ env.CODESIGN_IDENT }}
          installerIdent: ${{ env.CODESIGN_IDENT_INSTALLER }}
          codesignUser: ${{ secrets.MACOS_NOTARIZATION_USERNAME }}
          codesignPass: ${{ secrets.MACOS_NOTARIZATION_PASSWORD }}

      - name: Upload Build Artifact
        uses: actions/upload-artifact@v3.1.1
        with:
          name: ${{ env.PLUGIN_NAME }}-macos-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}
          path: ${{ github.workspace }}/plugin/release/${{ env.PLUGIN_NAME }}-*-macos-${{ matrix.arch }}.pkg
  linux-in-tree:
    name: 'Linux'
    runs-on: ${{ matrix.ubuntu }}
    strategy:
      fail-fast: false
      matrix:
        ubuntu: ['ubuntu-20.04', 'ubuntu-22.04']
    steps:
      - name: Checkout
        uses: actions/checkout@v3.1.0
        with:
          repository: obsproject/obs-studio
          ref: ${{ env.OBS_VERSION }}
          submodules: 'recursive'
      - name: "Checkout plugin"
        uses: actions/checkout@v3.1.0
        with:
          path: plugins/${{ env.PLUGIN_NAME }}
      - name: Add plugin to obs cmake
        shell: bash
        run: echo "add_subdirectory(${{ env.PLUGIN_NAME }})" >> plugins/CMakeLists.txt
      - name: Fetch Git Tags
        run: git fetch --prune --tags --unshallow
      - name: 'Install dependencies'
        run: CI/linux/01_install_dependencies.sh --disable-pipewire
      - name: 'Configure'
        shell: bash
        run: |
          mkdir ./build
          cmake -S . -B "./build" -G Ninja -DCMAKE_BUILD_TYPE="RelWithDebInfo" -DLINUX_PORTABLE=OFF -DENABLE_AJA=OFF -DENABLE_NEW_MPEGTS_OUTPUT=OFF -DBUILD_CAPTIONS=OFF -DWITH_RTMPS=OFF -DBUILD_BROWSER=OFF -DBUILD_VIRTUALCAM=OFF -DBUILD_VST=OFF -DENABLE_PIPEWIRE=OFF -DENABLE_SCRIPTING=OFF
      - name: 'Build'
        shell: bash
        run: |
          cmake --build "./build"
      - name: 'Package'
        shell: bash
        run: |
          FILE_DATE=$(date +%Y-%m-%d)
          FILE_NAME=${{ env.PLUGIN_NAME }}-$FILE_DATE-${{ github.sha }}-${{ matrix.ubuntu }}.tar.gz
          echo "FILE_NAME=${FILE_NAME}" >> $GITHUB_ENV
          mkdir -p ./${{ env.PLUGIN_NAME }}/bin/64bit/
          mv ./build/plugins/${{ env.PLUGIN_NAME }}/${{ env.PLUGIN_NAME }}.so ./${{ env.PLUGIN_NAME }}/bin/64bit/${{ env.PLUGIN_NAME }}.so
          mv ./plugins/${{ env.PLUGIN_NAME }}/data ./${{ env.PLUGIN_NAME }}/data
          tar -cvzf "${FILE_NAME}" ${{ env.PLUGIN_NAME }}
      - name: 'Publish'
        uses: actions/upload-artifact@v3.1.1
        with:
          name: '${{ env.FILE_NAME }}'
          path: '*.tar.gz'
  windows-build:
    name: 'Windows Build'
    runs-on: [windows-latest]
    strategy:
      fail-fast: true
      matrix:
        target: [x64, x86]
        include:
          - target: x64
            cmake_build: 'x64'
            deps_ext: '64'
          - target: x86
            cmake_build: 'Win32'
            deps_ext: '32'
    env:
      QT_VERSION: '6.3.1'
      CMAKE_GENERATOR: "Visual Studio 17 2022"
      CMAKE_SYSTEM_VERSION: "10.0.18363.657"
      WINDOWS_DEPS_VERSION: '2022-08-02'
    steps:
      - name: Add msbuild to PATH
        uses: microsoft/setup-msbuild@v1.1.3
      - name: Checkout obs
        uses: actions/checkout@v3.1.0
        with:
          repository: obsproject/obs-studio
          ref: ${{ env.OBS_VERSION }}
          submodules: 'recursive'
      - name: Checkout plugin
        uses: actions/checkout@v3.1.0
        with:
          path: plugins/${{ env.PLUGIN_NAME}}
      - name: Add plugin to obs cmake
        shell: cmd
        run: echo add_subdirectory(${{ env.PLUGIN_NAME }}) >> plugins/CMakeLists.txt
      - name: Fetch Git Tags
        run: git fetch --prune --tags --unshallow
      - name: 'Install prerequisite: QT'
        run: |
          curl -kLO https://github.com/obsproject/obs-deps/releases/download/${{ env.WINDOWS_DEPS_VERSION }}/windows-deps-qt6-${{ env.WINDOWS_DEPS_VERSION }}-${{ matrix.target }}.zip -f --retry 5 -C -
          7z x windows-deps-qt6-${{ env.WINDOWS_DEPS_VERSION }}-${{ matrix.target }}.zip -o"${{ github.workspace }}/cmbuild/deps"
      - name: 'Install prerequisite: Pre-built dependencies'
        run: |
          curl -kLO https://github.com/obsproject/obs-deps/releases/download/${{ env.WINDOWS_DEPS_VERSION }}/windows-deps-${{ env.WINDOWS_DEPS_VERSION }}-${{ matrix.target }}.zip -f --retry 5 -C -
          7z x windows-deps-${{ env.WINDOWS_DEPS_VERSION }}-${{ matrix.target }}.zip -o"${{ github.workspace }}/cmbuild/deps"
      - name: Configure
        run: |
          mkdir ./package
          mkdir ./installer
          mkdir ./installer/media
          mkdir ./build
          cmake -S . -B "${{ github.workspace }}/build" -G"${{ env.CMAKE_GENERATOR }}" -DCMAKE_PREFIX_PATH:PATH="${{ github.workspace }}/cmbuild/deps" -A"${{ matrix.cmake_build }}" -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DBUILD_BROWSER=false -DBUILD_VST=false -DBUILD_VIRTUALCAM=false -DBUILD_CAPTIONS=false -DCOMPILE_D3D12_HOOK=false -DENABLE_SCRIPTING=false -DDepsPath="${{ github.workspace }}/cmbuild/deps" -DDepsPath${{ matrix.deps_ext }}="${{ github.workspace }}/cmbuild/deps" -DQTDIR="${{ github.workspace }}/cmbuild/deps/qt6" -DCOPIED_DEPENDENCIES=FALSE -DCOPY_DEPENDENCIES=TRUE -DENABLE_PLUGINS=TRUE -DDISABLE_PLUGINS=FALSE -DENABLE_BROWSER=FALSE -DENABLE_WEBSOCKET=FALSE
      - name: 'Build'
        run: msbuild /m /p:Configuration=RelWithDebInfo .\build\obs-studio.sln
      - name: Package
        if: success()
        run: |
          $env:FILE_NAME="${{ env.PLUGIN_NAME }}-${{ github.sha }}-windows-${{ matrix.target }}"
          echo "FILE_NAME=${env:FILE_NAME}" >> ${env:GITHUB_ENV}
          robocopy .\build\rundir\RelWithDebInfo\obs-plugins\${{ matrix.deps_ext }}bit\ .\package\obs-plugins\${{ matrix.deps_ext }}bit ${{ env.PLUGIN_NAME }}.* /E /XF .gitignore
          robocopy .\build\rundir\RelWithDebInfo\data\obs-plugins\${{ env.PLUGIN_NAME }}\ .\package\data\obs-plugins\${{ env.PLUGIN_NAME }}\ /E /XF .gitignore
          copy .\build\plugins\${{ env.PLUGIN_NAME }}\installer.iss .\installer\installer.iss
          robocopy .\plugins\${{ env.PLUGIN_NAME}}\media\ .\installer\media\ /E /XF .gitignore
          exit 0
      - name: Publish zip
        if: success()
        uses: actions/upload-artifact@v3.1.1
        with:
          name: '${{ env.FILE_NAME }}'
          path: package/*
      - name: Publish Installer Files
        if: success()
        uses: actions/upload-artifact@v3.1.1
        with:
          name: 'installer-files'
          path: installer/*
  windows-package:
    name: 'Windows Package'
    runs-on: [windows-latest]
    needs: [windows-build]
    steps:
      - name: Init
        if: success()
        run: |
          mkdir ./package
          $env:FILE_DATE=(Get-Date -UFormat "%F")
          $env:FILE_NAME="${{ env.PLUGIN_NAME }}-${env:FILE_DATE}-${{ github.sha }}-windows"
          echo "FILE_NAME=${env:FILE_NAME}" >> ${env:GITHUB_ENV}
          $env:FILE_NAME_X86="${{ env.PLUGIN_NAME }}-${{ github.sha }}-windows-x86"
          echo "FILE_NAME_X86=${env:FILE_NAME_X86}" >> ${env:GITHUB_ENV}
          $env:FILE_NAME_X64="${{ env.PLUGIN_NAME }}-${{ github.sha }}-windows-x64"
          echo "FILE_NAME_X64=${env:FILE_NAME_X64}" >> ${env:GITHUB_ENV}
      - name: Retrieve x86 build
        uses: actions/download-artifact@v3.0.1
        with:
          name: '${{ env.FILE_NAME_X86 }}'
          path: ./package
      - name: Retrieve x64 build
        uses: actions/download-artifact@v3.0.1
        with:
          name: '${{ env.FILE_NAME_X64 }}'
          path: ./package
      - name: Retrieve installer files
        uses: actions/download-artifact@v3.0.1
        with:
          name: 'installer-files'
          path: .
      - name: Create Code Signing Certificate
        if: success() && github.event_name != 'pull_request'
        run: |
          New-Item -ItemType directory -Path certificate
          Set-Content -Path certificate\certificate.txt -Value '${{ secrets.CERTIFICATE }}'
          certutil -decode certificate\certificate.txt certificate\certificate.pfx
      - name: Code Sign 32
        if: success() && github.event_name != 'pull_request'
        run: |
          & 'C:/Program Files (x86)/Windows Kits/10/bin/10.0.20348.0/x86/signtool.exe' sign /f certificate\certificate.pfx /p '${{ secrets.CERTIFICATE_PASS }}' /t http://timestamp.comodoca.com/authenticode .\package\obs-plugins\32bit\${{ env.PLUGIN_NAME }}.dll
      - name: Code Sign 64
        if: success() && github.event_name != 'pull_request'
        run: |
          & 'C:/Program Files (x86)/Windows Kits/10/bin/10.0.20348.0/x64/signtool.exe' sign /f certificate\certificate.pfx /p '${{ secrets.CERTIFICATE_PASS }}' /t http://timestamp.comodoca.com/authenticode .\package\obs-plugins\64bit\${{ env.PLUGIN_NAME }}.dll
      - name: Publish zip
        if: success()
        uses: actions/upload-artifact@v3.1.1
        with:
          name: '${{ env.FILE_NAME }}'
          path: package/*
      - name: "Package Installer (Prereqs)"
        run: |
          curl "-kL" "https://github.com/Xaymar/msvc-redist-helper/releases/download/0.1/msvc-redist-helper-64.exe" "-f" "--retry" "5" "-o" "msvc-redist-helper.exe"
          curl "-kL" "https://files.jrsoftware.org/is/6/innosetup-6.0.3.exe" "-f" "--retry" "5" "-o" "inno.exe"
          .\inno.exe /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART
      - name: "Package Installer (Compile)"
        run: |
          & 'C:\Program Files (x86)\Inno Setup 6\ISCC.exe' /Qp ".\installer.iss"
      - name: Code Sign Installer
        if: success() && github.event_name != 'pull_request'
        run: |
          & 'C:/Program Files (x86)/Windows Kits/10/bin/10.0.20348.0/x64/signtool.exe' sign /f certificate\certificate.pfx /p '${{ secrets.CERTIFICATE_PASS }}' /t http://timestamp.comodoca.com/authenticode .\package\${{ env.PLUGIN_NAME }}-installer.exe
      - name: Publish installer
        if: success()
        uses: actions/upload-artifact@v3.1.1
        with:
          name: '${{ env.FILE_NAME }}-installer'
          path: package/*.exe
      - name: Remove temp artifacts
        uses: geekyeggo/delete-artifact@v2.0.0
        with:
          name: "${{ env.FILE_NAME_X86 }}\n${{ env.FILE_NAME_X64 }}\ninstaller-files"
