Skip to content

Build Release Package for macOS #4

Build Release Package for macOS

Build Release Package for macOS #4

Workflow file for this run

# Release workflow for macOS
# Builds a universal binary on macOS.
name: Build Release Package for macOS
on: workflow_dispatch
jobs:
build-deb:
name: ProductBuild Installer, macOS x86_64+arm64
runs-on: macos-latest
steps:
# We need to build third-party libraries (POCO, SDL2 and projectM) ourselves, as neither Homebrew
# nor vcpkg support building universal binaries.
- name: Checkout libSDL2 Sources
uses: actions/checkout@v4
with:
repository: libsdl-org/SDL
path: libsdl2
ref: 'release-2.32.10'
submodules: recursive
- name: Build libSDL2
run: |
mkdir cmake-build-libsdl2
cmake -G Ninja -S libsdl2 -B cmake-build-libsdl2 \
'-DCMAKE_OSX_ARCHITECTURES=x86_64;arm64' \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install-libsdl2
cmake --build cmake-build-libsdl2 --parallel
cmake --install "${{ github.workspace }}/cmake-build-libsdl2"
- name: Checkout Poco Sources
uses: actions/checkout@v4
with:
repository: pocoproject/poco
path: poco
ref: 'poco-1.14.1'
submodules: recursive
- name: Build Poco
run: |
mkdir cmake-build-poco
cmake -G Ninja -S poco -B cmake-build-poco \
'-DCMAKE_OSX_ARCHITECTURES=x86_64;arm64' \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install-poco \
-DENABLE_CRYPTO=OFF \
-DENABLE_NET=OFF \
-DENABLE_NETSSL=OFF \
-DENABLE_ZIP=OFF \
-DENABLE_MONGODB=OFF \
-DENABLE_REDIS=OFF \
-DENABLE_PAGECOMPILER=OFF \
-DENABLE_PAGECOMPILER_FILE2PAGE=OFF \
-DENABLE_ACTIVERECORD=OFF \
-DENABLE_ACTIVERECORD_COMPILER=OFF \
-DENABLE_DATA_ODBC=OFF \
-DENABLE_DATA_POSTGRESQL=OFF \
-DENABLE_DATA_MYSQL=OFF \
-DENABLE_JWT=OFF \
-DENABLE_PROMETHEUS=OFF
cmake --build cmake-build-poco --parallel
cmake --install "${{ github.workspace }}/cmake-build-poco"
- name: Checkout libprojectM Sources
uses: actions/checkout@v4
with:
repository: projectM-visualizer/projectm
path: projectm
submodules: recursive
- name: Build/Install libprojectM
run: |
mkdir cmake-build-libprojectm
cmake -G Ninja -S projectm -B cmake-build-libprojectm \
'-DCMAKE_OSX_ARCHITECTURES=x86_64;arm64' \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install-libprojectm
cmake --build cmake-build-libprojectm --parallel
cmake --install "${{ github.workspace }}/cmake-build-libprojectm"
- name: Checkout projectMSDL Sources
uses: actions/checkout@v4
with:
path: frontend-sdl2
submodules: recursive
- name: Checkout Cream of the Crop preset pack
uses: actions/checkout@v4
with:
repository: projectM-visualizer/presets-cream-of-the-crop
path: presets-cream-of-the-crop
- name: Checkout Milkdrop Texture Pack
uses: actions/checkout@v4
with:
repository: projectM-visualizer/presets-milkdrop-texture-pack
path: presets-milkdrop-texture-pack
- name: Build projectMSDL
run: |
mkdir cmake-build-frontend-sdl2
cmake -G Ninja -S frontend-sdl2 -B cmake-build-frontend-sdl2 \
'-DCMAKE_OSX_ARCHITECTURES=x86_64;arm64' \
-DCMAKE_BUILD_TYPE=Release \
-DENABLE_FREETYPE=OFF \
"-DCMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/install-libprojectm;${GITHUB_WORKSPACE}/install-poco;${GITHUB_WORKSPACE}/install-libsdl2" \
"-DPRESET_DIRS=${{ github.workspace }}/presets-cream-of-the-crop" \
"-DTEXTURE_DIRS=${{ github.workspace }}/presets-milkdrop-texture-pack/textures" \
'-DDEFAULT_CONFIG_PATH=${application.dir}/../share/projectMSDL/' \
'-DDEFAULT_PRESETS_PATH=${application.dir}/../share/projectMSDL/presets/' \
'-DDEFAULT_TEXTURES_PATH=${application.dir}/../share/projectMSDL/textures/' \
-DENABLE_INSTALL_BDEPS=ON
cmake --build cmake-build-frontend-sdl2 --parallel
cmake --install cmake-build-frontend-sdl2 --prefix "${{ github.workspace }}/install"
- name: Import Code Signing Certificates
env:
MACOS_CERTIFICATE_APPLICATION: ${{ secrets.MACOS_CERTIFICATE_APPLICATION }}
MACOS_CERTIFICATE_INSTALLER: ${{ secrets.MACOS_CERTIFICATE_INSTALLER }}
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
run: |
echo "$MACOS_CERTIFICATE_APPLICATION" | base64 --decode > app_cert.p12 && chmod 600 app_cert.p12
echo "$MACOS_CERTIFICATE_INSTALLER" | base64 --decode > installer_cert.p12 && chmod 600 installer_cert.p12
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security import app_cert.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
security import installer_cert.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PASSWORD" -T /usr/bin/productsign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
rm app_cert.p12 installer_cert.p12
- name: Sign Application Bundle
run: |
APP_PATH="${{ github.workspace }}/install/projectM.app"
IDENTITY="Developer ID Application: Mischa Spiegelmock (5926VBQM6Y)"
# Sign all dylibs first (if PlugIns directory exists)
if [ -d "$APP_PATH/Contents/PlugIns" ]; then
find "$APP_PATH/Contents/PlugIns" -name "*.dylib" -exec \
codesign --force --options runtime --sign "$IDENTITY" {} \;
fi
# Sign the main executable
codesign --force --options runtime --sign "$IDENTITY" \
"$APP_PATH/Contents/MacOS/projectM"
# Sign the entire bundle
codesign --force --options runtime --sign "$IDENTITY" "$APP_PATH"
# Verify
codesign --verify --deep --strict "$APP_PATH"
- name: Notarize Application
env:
API_KEY: ${{ secrets.MACOS_NOTARY_API_KEY }}
API_KEY_ID: ${{ secrets.MACOS_NOTARY_KEY_ID }}
API_ISSUER_ID: ${{ secrets.MACOS_NOTARY_ISSUER_ID }}
run: |
mkdir -p ~/.private_keys
echo "$API_KEY" > ~/.private_keys/AuthKey_${API_KEY_ID}.p8
chmod 600 ~/.private_keys/AuthKey_${API_KEY_ID}.p8
ditto -c -k --keepParent \
"${{ github.workspace }}/install/projectM.app" \
"projectM-notarize.zip"
xcrun notarytool submit "projectM-notarize.zip" \
--key ~/.private_keys/AuthKey_${API_KEY_ID}.p8 \
--key-id "$API_KEY_ID" \
--issuer "$API_ISSUER_ID" \
--wait
xcrun stapler staple "${{ github.workspace }}/install/projectM.app"
- name: Package projectMSDL
run: |
# Get version from CMake
VERSION=$(grep "project(projectMSDL" frontend-sdl2/CMakeLists.txt | sed -E 's/.*VERSION ([0-9.]+).*/\1/')
# Build component package from signed app
pkgbuild \
--root "${{ github.workspace }}/install" \
--identifier "org.projectm-visualizer.projectmsdl" \
--version "$VERSION" \
--install-location "/Applications" \
--component-plist "frontend-sdl2/src/resources/projectMSDL-component.plist" \
"projectMSDL-component.pkg"
# Build product archive with installer UI
productbuild \
--distribution "frontend-sdl2/src/resources/distribution.xml" \
--package-path "." \
--resources "frontend-sdl2/src/resources" \
--sign "Developer ID Installer: Mischa Spiegelmock (5926VBQM6Y)" \
"projectM-${VERSION}-macOS-universal.pkg"
- name: Notarize Package
env:
API_KEY_ID: ${{ secrets.MACOS_NOTARY_KEY_ID }}
API_ISSUER_ID: ${{ secrets.MACOS_NOTARY_ISSUER_ID }}
run: |
PKG_FILE=$(ls projectM-*.pkg | head -1)
xcrun notarytool submit "$PKG_FILE" \
--key ~/.private_keys/AuthKey_${API_KEY_ID}.p8 \
--key-id "$API_KEY_ID" \
--issuer "$API_ISSUER_ID" \
--wait
xcrun stapler staple "$PKG_FILE"
# Clean up API key
rm -f ~/.private_keys/AuthKey_${API_KEY_ID}.p8
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: projectMSDL-macOS-Universal
path: projectM-*.pkg