Skip to content

Commit 68a5678

Browse files
revmischaclaude
andcommitted
Add code signing and notarization for macOS releases
Signs the app bundle and .pkg installer with Developer ID certificates, then notarizes both with Apple's notary service for Gatekeeper approval. Uses App Store Connect API key for notarization credentials. Replaces CPack with direct pkgbuild/productbuild for better signing control. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 0231108 commit 68a5678

File tree

5 files changed

+118
-7
lines changed

5 files changed

+118
-7
lines changed

.github/workflows/release-macos.yaml

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,108 @@ jobs:
117117
'-DDEFAULT_TEXTURES_PATH=${application.dir}/../share/projectMSDL/textures/' \
118118
-DENABLE_INSTALL_BDEPS=ON
119119
cmake --build cmake-build-frontend-sdl2 --parallel
120+
cmake --install cmake-build-frontend-sdl2 --prefix "${{ github.workspace }}/install"
121+
122+
- name: Import Code Signing Certificates
123+
env:
124+
MACOS_CERTIFICATE_APPLICATION: ${{ secrets.MACOS_CERTIFICATE_APPLICATION }}
125+
MACOS_CERTIFICATE_INSTALLER: ${{ secrets.MACOS_CERTIFICATE_INSTALLER }}
126+
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
127+
run: |
128+
echo "$MACOS_CERTIFICATE_APPLICATION" | base64 --decode > app_cert.p12
129+
echo "$MACOS_CERTIFICATE_INSTALLER" | base64 --decode > installer_cert.p12
130+
131+
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
132+
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
133+
security default-keychain -s build.keychain
134+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
135+
136+
security import app_cert.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
137+
security import installer_cert.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PASSWORD" -T /usr/bin/productsign
138+
139+
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
140+
141+
rm app_cert.p12 installer_cert.p12
142+
143+
- name: Sign Application Bundle
144+
run: |
145+
APP_PATH="${{ github.workspace }}/install/projectM.app"
146+
IDENTITY="Developer ID Application: Mischa Spiegelmock (5926VBQM6Y)"
147+
148+
# Sign all dylibs first
149+
find "$APP_PATH/Contents/PlugIns" -name "*.dylib" -exec \
150+
codesign --force --options runtime --sign "$IDENTITY" {} \;
151+
152+
# Sign the main executable
153+
codesign --force --options runtime --sign "$IDENTITY" \
154+
"$APP_PATH/Contents/MacOS/projectMSDL"
155+
156+
# Sign the entire bundle
157+
codesign --force --options runtime --sign "$IDENTITY" "$APP_PATH"
158+
159+
# Verify
160+
codesign --verify --deep --strict "$APP_PATH"
161+
162+
- name: Notarize Application
163+
env:
164+
API_KEY: ${{ secrets.MACOS_NOTARY_API_KEY }}
165+
API_KEY_ID: ${{ secrets.MACOS_NOTARY_KEY_ID }}
166+
API_ISSUER_ID: ${{ secrets.MACOS_NOTARY_ISSUER_ID }}
167+
run: |
168+
mkdir -p ~/.private_keys
169+
echo "$API_KEY" > ~/.private_keys/AuthKey_${API_KEY_ID}.p8
170+
171+
ditto -c -k --keepParent \
172+
"${{ github.workspace }}/install/projectM.app" \
173+
"projectM-notarize.zip"
174+
175+
xcrun notarytool submit "projectM-notarize.zip" \
176+
--key ~/.private_keys/AuthKey_${API_KEY_ID}.p8 \
177+
--key-id "$API_KEY_ID" \
178+
--issuer "$API_ISSUER_ID" \
179+
--wait
180+
181+
xcrun stapler staple "${{ github.workspace }}/install/projectM.app"
120182
121183
- name: Package projectMSDL
122184
run: |
123-
cd cmake-build-frontend-sdl2
124-
cpack -G productbuild
185+
# Get version from CMake
186+
VERSION=$(grep "project(projectMSDL" frontend-sdl2/CMakeLists.txt | sed -E 's/.*VERSION ([0-9.]+).*/\1/')
187+
188+
# Build component package from signed app
189+
pkgbuild \
190+
--root "${{ github.workspace }}/install" \
191+
--identifier "org.projectm-visualizer.projectmsdl" \
192+
--version "$VERSION" \
193+
--install-location "/Applications" \
194+
--component-plist "frontend-sdl2/src/resources/projectMSDL-component.plist" \
195+
"projectMSDL-component.pkg"
196+
197+
# Build product archive with installer UI
198+
productbuild \
199+
--distribution "frontend-sdl2/src/resources/distribution.xml" \
200+
--package-path "." \
201+
--resources "frontend-sdl2/src/resources" \
202+
--sign "Developer ID Installer: Mischa Spiegelmock (5926VBQM6Y)" \
203+
"projectM-${VERSION}-macOS-universal.pkg"
204+
205+
- name: Notarize Package
206+
env:
207+
API_KEY_ID: ${{ secrets.MACOS_NOTARY_KEY_ID }}
208+
API_ISSUER_ID: ${{ secrets.MACOS_NOTARY_ISSUER_ID }}
209+
run: |
210+
PKG_FILE=$(ls projectM-*.pkg | head -1)
211+
212+
xcrun notarytool submit "$PKG_FILE" \
213+
--key ~/.private_keys/AuthKey_${API_KEY_ID}.p8 \
214+
--key-id "$API_KEY_ID" \
215+
--issuer "$API_ISSUER_ID" \
216+
--wait
217+
218+
xcrun stapler staple "$PKG_FILE"
125219
126220
- name: Upload Artifact
127221
uses: actions/upload-artifact@v4
128222
with:
129223
name: projectMSDL-macOS-Universal
130-
path: cmake-build-frontend-sdl2/*.pkg
224+
path: projectM-*.pkg

packaging-macos.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/src/resources/gpl-3
1010
set(CPACK_STRIP_FILES TRUE)
1111

1212
### Productbuild configuration
13-
set(CPACK_PKGBUILD_IDENTITY_NAME "${CODESIGN_IDENTITY_INSTALLER}")
14-
set(CPACK_PRODUCTBUILD_IDENTITY_NAME "${CODESIGN_IDENTITY_INSTALLER}")
13+
set(CPACK_PKGBUILD_IDENTITY_NAME "$ENV{CODESIGN_IDENTITY_INSTALLER}")
14+
set(CPACK_PRODUCTBUILD_IDENTITY_NAME "$ENV{CODESIGN_IDENTITY_INSTALLER}")
1515
set(CPACK_PRODUCTBUILD_IDENTIFIER "org.projectm-visualizer.projectmsdl")
1616

1717
string(REPLACE ";" "," INSTALL_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}")

src/resources/distribution.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<installer-gui-script minSpecVersion="2">
3+
<title>projectM</title>
4+
<organization>org.projectm-visualizer</organization>
5+
<welcome file="macos-welcome.txt"/>
6+
<readme file="macos-readme.txt"/>
7+
<license file="gpl-3.0.rtf"/>
8+
<options customize="never" require-scripts="false" hostArchitectures="x86_64,arm64"/>
9+
<domains enable_anywhere="false" enable_currentUserHome="false" enable_localSystem="true"/>
10+
<choices-outline>
11+
<line choice="default"/>
12+
</choices-outline>
13+
<choice id="default" title="projectM">
14+
<pkg-ref id="org.projectm-visualizer.projectmsdl"/>
15+
</choice>
16+
<pkg-ref id="org.projectm-visualizer.projectmsdl" version="0" onConclusion="none">projectMSDL-component.pkg</pkg-ref>
17+
</installer-gui-script>

src/resources/projectMSDL-component.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<key>BundleOverwriteAction</key>
1313
<string>upgrade</string>
1414
<key>RootRelativeBundlePath</key>
15-
<string>Applications/projectM.app</string>
15+
<string>projectM.app</string>
1616
</dict>
1717
</array>
1818
</plist>

vendor/imgui

Submodule imgui updated 157 files

0 commit comments

Comments
 (0)