From 5ce0124aaf51e089f0f5da3249c3287cebdc8f2f Mon Sep 17 00:00:00 2001
From: falkTX <falktx@falktx.com>
Date: Mon, 11 Mar 2024 09:03:31 +0100
Subject: [PATCH] Add codesign step

Signed-off-by: falkTX <falktx@falktx.com>
---
 .github/workflows/build.yml    |  24 +++++---
 Makefile                       |   6 +-
 src/mod-ui                     |   2 +-
 src/systray/utils.cpp          |   2 +-
 utils/debug/jackd              |   2 +-
 utils/debug/mod-ui             |   2 +-
 utils/macos/entitlements.plist |   8 +++
 utils/macos/macos-dmg.sh       | 103 +++++++++++++++++++++++++++++++++
 utils/macos/macos-pkg.sh       |  48 +++++++++++++++
 9 files changed, 183 insertions(+), 14 deletions(-)
 create mode 100644 utils/macos/entitlements.plist
 create mode 100755 utils/macos/macos-dmg.sh

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 402db29..d1dc708 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -7,11 +7,12 @@ env:
   CACHE_VERSION_MACOS: 20
   CACHE_VERSION_WIN64: 19
   DEBIAN_FRONTEND: noninteractive
+  HOMEBREW_NO_AUTO_UPDATE: 1
   PAWPAW_FAST_MATH: 1
   PAWPAW_SKIP_LTO: 1
   PAWPAW_SKIP_TESTS: 1
   RELEASE_OS_LINUX: ubuntu:18.04
-  RELEASE_OS_MAC: macos-11
+  RELEASE_OS_MAC: macos-12
   RELEASE_OS_WIN64: ubuntu:22.04
 
 jobs:
@@ -211,10 +212,10 @@ jobs:
             target: macos-10.15
           - os: macos-12
             target: macos-universal-10.15
-          - os: macos-13
-            target: macos-10.15
-          - os: macos-13
-            target: macos-universal-10.15
+          # - os: macos-13
+          #   target: macos-10.15
+          # - os: macos-13
+          #   target: macos-universal-10.15
     runs-on: ${{ matrix.os }}
     steps:
       - uses: actions/checkout@v4
@@ -222,6 +223,7 @@ jobs:
           submodules: recursive
       - name: Set up dependencies
         run: |
+          brew uninstall --ignore-dependencies --force azure-cli aws-sam-cli php
           ./src/PawPaw/.github/workflows/bootstrap-deps.sh ${{ matrix.target }}
           brew install p7zip wget
       - name: Set up cache
@@ -239,9 +241,10 @@ jobs:
         run: |
           make PAWPAW_TARGET=${{ matrix.target }}
       - name: Validate plugins
-        if: steps.cache.outputs.cache-hit == 'true'
+        if: false
+        #if: steps.cache.outputs.cache-hit == 'true'
         run: |
-          ./utils/plugin-builder/validate-plugins.sh ${{ matrix.target }}
+          # ./utils/plugin-builder/validate-plugins.sh ${{ matrix.target }}
           # FIXME dirty carla leaves temp folders around
           rm -rf *.tmp
       - name: Set version tag for release
@@ -254,6 +257,13 @@ jobs:
           echo "VERSION_TAG=$(echo ${{ github.event.pull_request.number || github.sha }} | cut -c1-8)" >> $GITHUB_ENV
       - name: Pack
         if: steps.cache.outputs.cache-hit == 'true'
+        env:
+          CODESIGN_APP_IDENTITY: ${{ secrets.CODESIGN_APP_IDENTITY }}
+          CODESIGN_PKG_IDENTITY: ${{ secrets.CODESIGN_PKG_IDENTITY }}
+          CODESIGN_APP_P12_CONTENTS: ${{ secrets.CODESIGN_APP_P12_CONTENTS }}
+          CODESIGN_PKG_P12_CONTENTS: ${{ secrets.CODESIGN_PKG_P12_CONTENTS }}
+          CODESIGN_APP_P12_PASSWORD: ${{ secrets.CODESIGN_APP_P12_PASSWORD }}
+          CODESIGN_PKG_P12_PASSWORD: ${{ secrets.CODESIGN_PKG_P12_PASSWORD }}
         run: |
           ./utils/macos/macos-pkg.sh ${{ matrix.target }}
           if [ "${{ env.VERSION_TAG }}" != "$(cat VERSION)" ]; then
diff --git a/Makefile b/Makefile
index 296932e..932f3f0 100644
--- a/Makefile
+++ b/Makefile
@@ -96,6 +96,7 @@ TARGETS += build/mod-desktop.app/Contents/Frameworks/QtOpenGL.framework
 TARGETS += build/mod-desktop.app/Contents/Frameworks/QtPrintSupport.framework
 TARGETS += build/mod-desktop.app/Contents/Frameworks/QtSvg.framework
 TARGETS += build/mod-desktop.app/Contents/Frameworks/QtWidgets.framework
+TARGETS += build/mod-desktop.app/Contents/LV2
 TARGETS += build/mod-desktop.app/Contents/MacOS/jackd
 TARGETS += build/mod-desktop.app/Contents/MacOS/jack/jack-session.conf
 TARGETS += build/mod-desktop.app/Contents/MacOS/jack/jack_coreaudio.so
@@ -115,7 +116,6 @@ TARGETS += build/mod-desktop.app/Contents/MacOS/modtools
 TARGETS += build/mod-desktop.app/Contents/PlugIns/generic/libqtuiotouchplugin.dylib
 TARGETS += build/mod-desktop.app/Contents/PlugIns/iconengines/libqsvgicon.dylib
 TARGETS += build/mod-desktop.app/Contents/PlugIns/imageformats/libqsvg.dylib
-TARGETS += build/mod-desktop.app/Contents/PlugIns/LV2
 TARGETS += build/mod-desktop.app/Contents/PlugIns/platforms/libqcocoa.dylib
 TARGETS += build/mod-desktop.app/Contents/PlugIns/styles/libqmacstyle.dylib
 TARGETS += build/mod-desktop.app/Contents/Resources/default.pedalboard
@@ -408,8 +408,8 @@ build/mod-desktop.app/Contents/PlugIns/imageformats/libq%.dylib: $(PAWPAW_PREFIX
 	@mkdir -p build/mod-desktop.app/Contents/PlugIns/imageformats
 	ln -sf $(abspath $<) $@
 
-build/mod-desktop.app/Contents/PlugIns/LV2:
-	@mkdir -p build/mod-desktop.app/Contents/PlugIns
+build/mod-desktop.app/Contents/LV2:
+	@mkdir -p build/mod-desktop.app/Contents
 	@mkdir -p build/plugins
 	ln -sf $(abspath build/plugins) $@
 
diff --git a/src/mod-ui b/src/mod-ui
index 6615183..0595788 160000
--- a/src/mod-ui
+++ b/src/mod-ui
@@ -1 +1 @@
-Subproject commit 661518336c1222638d5ca4dbc79fb02dd40d1eef
+Subproject commit 0595788f54ade32e58b897d4292d865fd805b972
diff --git a/src/systray/utils.cpp b/src/systray/utils.cpp
index 33ab0b0..9aa0957 100644
--- a/src/systray/utils.cpp
+++ b/src/systray/utils.cpp
@@ -254,7 +254,7 @@ void initEvironment()
     std::strncat(path, appDir, PATH_MAX - 1);
    #ifdef __APPLE__
     path[dataDirLen + 5 + appDirLen - 5] = '\0'; // remove "MacOS"
-    std::strncat(path, "PlugIns/LV2", PATH_MAX - 1);
+    std::strncat(path, "LV2", PATH_MAX - 1);
    #else
     std::strncat(path, "/plugins", PATH_MAX - 1);
    #endif
diff --git a/utils/debug/jackd b/utils/debug/jackd
index c655525..555e80a 100755
--- a/utils/debug/jackd
+++ b/utils/debug/jackd
@@ -64,7 +64,7 @@ fi
 
 LV2_PATH="$(convert_path "${DOCS_DIR}/MOD Desktop/lv2")"
 if [ -e mod-desktop.app ]; then
-    LV2_PATH+=":$(convert_path $(pwd)/mod-desktop.app/Contents/PlugIns/LV2)"
+    LV2_PATH+=":$(convert_path $(pwd)/mod-desktop.app/Contents/LV2)"
 else
     LV2_PATH="${PATH_SEP}$(convert_path $(pwd)/plugins)"
 fi
diff --git a/utils/debug/mod-ui b/utils/debug/mod-ui
index e7682f5..1786eea 100755
--- a/utils/debug/mod-ui
+++ b/utils/debug/mod-ui
@@ -41,7 +41,7 @@ PYTHON="${EXE_WRAPPER} ${PAWPAW_PREFIX}/bin/python3${APP_EXT}"
 
 LV2_PATH="$(convert_path "${DOCS_DIR}/MOD Desktop/lv2")"
 if [ -e mod-desktop.app ]; then
-    LV2_PATH+=":$(convert_path $(pwd)/mod-desktop.app/Contents/PlugIns/LV2)"
+    LV2_PATH+=":$(convert_path $(pwd)/mod-desktop.app/Contents/LV2)"
 else
     LV2_PATH="${PATH_SEP}$(convert_path $(pwd)/plugins)"
 fi
diff --git a/utils/macos/entitlements.plist b/utils/macos/entitlements.plist
new file mode 100644
index 0000000..4efe1ce
--- /dev/null
+++ b/utils/macos/entitlements.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+    <key>com.apple.security.cs.allow-jit</key>
+    <true/>
+</dict>
+</plist>
diff --git a/utils/macos/macos-dmg.sh b/utils/macos/macos-dmg.sh
new file mode 100755
index 0000000..9c7633e
--- /dev/null
+++ b/utils/macos/macos-dmg.sh
@@ -0,0 +1,103 @@
+#!/bin/bash
+
+set -e
+
+if [ ! -d build ]; then
+  echo "Please run this script from the root folder"
+  exit
+fi
+
+if [ "$(uname -m)" = "x86_64" ] && [ x"${1}" != x"macos-universal-10.15" ]; then
+    PAWPAW_PREFIX="${HOME}/PawPawBuilds/targets/macos-10.15"
+else
+    PAWPAW_PREFIX="${HOME}/PawPawBuilds/targets/macos-universal-10.15"
+fi
+
+rm -rf build/dmg build/*.dmg
+rm -rf mod-ui/mod/__pycache__
+rm -rf mod-ui/mod/communication/__pycache__
+rm -rf mod-ui/modtools/__pycache__
+./utils/pack-html.sh
+
+# create dmg dir for placing patched app bundle inside
+mkdir build/dmg
+gcp -rL "build/mod-desktop.app" "build/dmg/MOD Desktop.app"
+
+# patch rpath for Qt libs and jack tools
+pushd "build/dmg/MOD Desktop.app/Contents"
+
+rm -rf Frameworks/*/*.prl
+rm -rf Frameworks/*/Headers
+rm -rf Frameworks/*/Versions
+rm -rf MacOS/data
+
+QTLIBS=("Core" "Gui" "OpenGL" "PrintSupport" "Svg" "Widgets")
+
+for f in $(ls Frameworks/*/Qt* PlugIns/*/libq*.dylib); do
+    for q in "${QTLIBS[@]}"; do
+        install_name_tool -change "@rpath/Qt${q}.framework/Versions/5/Qt${q}" "@executable_path/../Frameworks/Qt${q}.framework/Qt${q}" "${f}"
+    done
+done
+
+for f in $(ls MacOS/lib/libmod_utils.so MacOS/libjack*.dylib); do
+    install_name_tool -change "${PAWPAW_PREFIX}/lib/libjack.0.1.0.dylib" "@executable_path/libjack.0.dylib" "${f}"
+    install_name_tool -change "${PAWPAW_PREFIX}/lib/libjackserver.0.1.0.dylib" "@executable_path/libjackserver.0.dylib" "${f}"
+done
+
+for f in $(ls MacOS/jackd MacOS/jack/*.so); do
+    install_name_tool -change "${PAWPAW_PREFIX}/lib/libjack.0.1.0.dylib" "@executable_path/libjackserver.0.dylib" "${f}"
+    install_name_tool -change "${PAWPAW_PREFIX}/lib/libjackserver.0.1.0.dylib" "@executable_path/libjackserver.0.dylib" "${f}"
+done
+
+popd
+
+# sign app bundle
+if [ -n "${CODESIGN_APP_IDENTITY}" ]; then
+    security create-keychain -p dummypassword build.keychain
+    security unlock-keychain -p dummypassword build.keychain
+    security set-keychain-settings -lut 21600 build.keychain
+
+    echo "${CODESIGN_APP_P12_CONTENTS}" | base64 -d -o codesign.p12
+    security import codesign.p12 -f pkcs12 -P "${CODESIGN_APP_P12_PASSWORD}" -k build.keychain -T /usr/bin/codesign -T /usr/bin/security
+    rm codesign.p12
+
+    security set-key-partition-list -S apple-tool:,apple: -k dummypassword build.keychain
+    security list-keychains -d user -s build.keychain login.keychain
+
+    mv "build/dmg/MOD Desktop.app/Contents/PlugIns/LV2" "build/dmg/LV2"
+
+    codesign -s "${CODESIGN_APP_IDENTITY}" \
+        --deep \
+        --force \
+        --verbose \
+        --timestamp \
+        --option runtime \
+        --entitlements "utils/macos/entitlements.plist" \
+        "build/dmg/MOD Desktop.app"
+
+    for f in $(find build/dmg/LV2 -name "*.dylib"); do
+        codesign -s "${CODESIGN_APP_IDENTITY}" \
+            --force \
+            --verbose \
+            --timestamp \
+            --option runtime \
+            --entitlements "utils/macos/entitlements.plist" \
+            "${f}"
+    done
+
+    mv "build/dmg/LV2" "build/dmg/MOD Desktop.app/Contents/PlugIns/LV2"
+fi
+
+# create dmg
+hdiutil create "mod-desktop-$(cat VERSION)-macOS.dmg" -srcfolder build/dmg -volname "MOD Desktop" -fs HFS+ -ov
+
+if [ -n "${CODESIGN_IDENTITY}" ]; then
+    codesign -s "${MACOS_APP_DEV_ID}" --force --verbose --option runtime "mod-desktop-$(cat VERSION)-macOS.dmg"
+    security delete-keychain build.keychain
+fi
+
+# cleanup
+rm -rf build/dmg
+
+# xcrun notarytool store-credentials build-notary --apple-id xyz --team-id xyz --password xyz
+# xcrun notarytool submit choptones-amps-macOS.pkg --keychain-profile "build-notary" --wait
diff --git a/utils/macos/macos-pkg.sh b/utils/macos/macos-pkg.sh
index a7fb3f8..a587783 100755
--- a/utils/macos/macos-pkg.sh
+++ b/utils/macos/macos-pkg.sh
@@ -51,12 +51,56 @@ done
 
 popd
 
+# sign app bundle
+if [ -n "${CODESIGN_APP_IDENTITY}" ]; then
+    security create-keychain -p dummypassword build.keychain
+    security unlock-keychain -p dummypassword build.keychain
+    security set-keychain-settings -lut 21600 build.keychain
+
+    echo "${CODESIGN_APP_P12_CONTENTS}" | base64 -d -o codesign.p12
+    security import codesign.p12 -f pkcs12 -P "${CODESIGN_APP_P12_PASSWORD}" -k build.keychain -T /usr/bin/codesign -T /usr/bin/security
+    rm codesign.p12
+
+    echo "${CODESIGN_PKG_P12_CONTENTS}" | base64 -d -o codesign.p12
+    security import codesign.p12 -f pkcs12 -P "${CODESIGN_PKG_P12_PASSWORD}" -k build.keychain -T /usr/bin/pkgbuild -T /usr/bin/productbuild -T /usr/bin/security
+    rm codesign.p12
+
+    security set-key-partition-list -S apple-tool:,apple: -k dummypassword build.keychain
+    security list-keychains -d user -s build.keychain login.keychain
+
+    pushd "build/pkg/MOD Desktop.app/Contents/LV2"
+
+    for f in $(find . -name "*.dylib"); do
+        codesign -s "${CODESIGN_APP_IDENTITY}" \
+            --force \
+            --verbose \
+            --timestamp \
+            --option runtime \
+            --entitlements "../../../../../utils/macos/entitlements.plist" \
+            "${f}"
+    done
+
+    popd
+
+    codesign -s "${CODESIGN_APP_IDENTITY}" \
+        --deep \
+        --force \
+        --verbose \
+        --timestamp \
+        --option runtime \
+        --entitlements "utils/macos/entitlements.plist" \
+        "build/pkg/MOD Desktop.app"
+
+    PKG_SIGN_ARGS=(--sign "${CODESIGN_PKG_IDENTITY}")
+fi
+
 # create base app pkg
 pkgbuild \
   --identifier "audio.mod.desktop-app" \
   --component-plist "utils/macos/build.plist" \
   --install-location "/Applications/" \
   --root "${PWD}/build/pkg/" \
+  "${PKG_SIGN_ARGS[@]}" \
   build/mod-desktop.pkg
 
 # create final pkg
@@ -68,7 +112,11 @@ productbuild \
   --identifier "audio.mod.desktop-app" \
   --package-path "${PWD}/build" \
   --version 0 \
+  "${PKG_SIGN_ARGS[@]}" \
   mod-desktop-$(cat VERSION)-macOS.pkg
 
 # cleanup
 rm -rf build/pkg
+[ -n "${CODESIGN_APP_IDENTITY}" ] && security delete-keychain build.keychain
+
+exit 0