|
2 | 2 | # Builds a universal binary on macOS. |
3 | 3 | name: Build Release Package for macOS |
4 | 4 |
|
5 | | -on: workflow_dispatch |
| 5 | +on: |
| 6 | + workflow_dispatch: |
| 7 | + workflow_call: |
| 8 | + secrets: |
| 9 | + MACOS_CERTIFICATE_APPLICATION: |
| 10 | + required: true |
| 11 | + MACOS_CERTIFICATE_INSTALLER: |
| 12 | + required: true |
| 13 | + MACOS_CERTIFICATE_PASSWORD: |
| 14 | + required: true |
| 15 | + MACOS_NOTARY_API_KEY: |
| 16 | + required: true |
| 17 | + MACOS_NOTARY_KEY_ID: |
| 18 | + required: true |
| 19 | + MACOS_NOTARY_ISSUER_ID: |
| 20 | + required: true |
6 | 21 |
|
7 | 22 | jobs: |
8 | 23 | build-deb: |
@@ -112,19 +127,123 @@ jobs: |
112 | 127 | "-DCMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/install-libprojectm;${GITHUB_WORKSPACE}/install-poco;${GITHUB_WORKSPACE}/install-libsdl2" \ |
113 | 128 | "-DPRESET_DIRS=${{ github.workspace }}/presets-cream-of-the-crop" \ |
114 | 129 | "-DTEXTURE_DIRS=${{ github.workspace }}/presets-milkdrop-texture-pack/textures" \ |
115 | | - '-DDEFAULT_CONFIG_PATH=${application.dir}/../share/projectMSDL/' \ |
116 | | - '-DDEFAULT_PRESETS_PATH=${application.dir}/../share/projectMSDL/presets/' \ |
117 | | - '-DDEFAULT_TEXTURES_PATH=${application.dir}/../share/projectMSDL/textures/' \ |
118 | 130 | -DENABLE_INSTALL_BDEPS=ON |
119 | 131 | cmake --build cmake-build-frontend-sdl2 --parallel |
| 132 | + cmake --install cmake-build-frontend-sdl2 --prefix "${{ github.workspace }}/install" |
| 133 | +
|
| 134 | + - name: Import Code Signing Certificates |
| 135 | + env: |
| 136 | + MACOS_CERTIFICATE_APPLICATION: ${{ secrets.MACOS_CERTIFICATE_APPLICATION }} |
| 137 | + MACOS_CERTIFICATE_INSTALLER: ${{ secrets.MACOS_CERTIFICATE_INSTALLER }} |
| 138 | + MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} |
| 139 | + run: | |
| 140 | + echo "$MACOS_CERTIFICATE_APPLICATION" | base64 --decode > app_cert.p12 && chmod 600 app_cert.p12 |
| 141 | + echo "$MACOS_CERTIFICATE_INSTALLER" | base64 --decode > installer_cert.p12 && chmod 600 installer_cert.p12 |
| 142 | +
|
| 143 | + KEYCHAIN_PASSWORD=$(openssl rand -base64 32) |
| 144 | + security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain |
| 145 | + security default-keychain -s build.keychain |
| 146 | + security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain |
| 147 | +
|
| 148 | + security import app_cert.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PASSWORD" -T /usr/bin/codesign |
| 149 | + security import installer_cert.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PASSWORD" -T /usr/bin/productsign |
| 150 | +
|
| 151 | + security set-key-partition-list -S apple-tool:,apple:,codesign:,productbuild: -s -k "$KEYCHAIN_PASSWORD" build.keychain |
| 152 | +
|
| 153 | + rm app_cert.p12 installer_cert.p12 |
| 154 | +
|
| 155 | + - name: Sign Application Bundle |
| 156 | + run: | |
| 157 | + APP_PATH="${{ github.workspace }}/install/projectM.app" |
| 158 | + IDENTITY="Developer ID Application: Mischa Spiegelmock (5926VBQM6Y)" |
| 159 | +
|
| 160 | + # Sign all dylibs first (if PlugIns directory exists) |
| 161 | + if [ -d "$APP_PATH/Contents/PlugIns" ]; then |
| 162 | + find "$APP_PATH/Contents/PlugIns" -name "*.dylib" -exec \ |
| 163 | + codesign --force --options runtime --sign "$IDENTITY" {} \; |
| 164 | + fi |
| 165 | +
|
| 166 | + # Sign the main executable |
| 167 | + codesign --force --options runtime --sign "$IDENTITY" \ |
| 168 | + "$APP_PATH/Contents/MacOS/projectM" |
| 169 | +
|
| 170 | + # Sign the entire bundle |
| 171 | + codesign --force --options runtime --sign "$IDENTITY" "$APP_PATH" |
| 172 | +
|
| 173 | + # Verify |
| 174 | + codesign --verify --deep --strict "$APP_PATH" |
| 175 | +
|
| 176 | + - name: Notarize Application |
| 177 | + env: |
| 178 | + API_KEY_BASE64: ${{ secrets.MACOS_NOTARY_API_KEY }} |
| 179 | + API_KEY_ID: ${{ secrets.MACOS_NOTARY_KEY_ID }} |
| 180 | + API_ISSUER_ID: ${{ secrets.MACOS_NOTARY_ISSUER_ID }} |
| 181 | + run: | |
| 182 | + mkdir -p ~/.private_keys |
| 183 | + echo "$API_KEY_BASE64" | base64 --decode > ~/.private_keys/AuthKey_${API_KEY_ID}.p8 |
| 184 | + chmod 600 ~/.private_keys/AuthKey_${API_KEY_ID}.p8 |
| 185 | +
|
| 186 | + ditto -c -k --keepParent \ |
| 187 | + "${{ github.workspace }}/install/projectM.app" \ |
| 188 | + "projectM-notarize.zip" |
| 189 | +
|
| 190 | + xcrun notarytool submit "projectM-notarize.zip" \ |
| 191 | + --key ~/.private_keys/AuthKey_${API_KEY_ID}.p8 \ |
| 192 | + --key-id "$API_KEY_ID" \ |
| 193 | + --issuer "$API_ISSUER_ID" \ |
| 194 | + --wait |
| 195 | +
|
| 196 | + xcrun stapler staple "${{ github.workspace }}/install/projectM.app" |
120 | 197 |
|
121 | 198 | - name: Package projectMSDL |
122 | 199 | run: | |
123 | | - cd cmake-build-frontend-sdl2 |
124 | | - cpack -G productbuild |
| 200 | + # Get version from CMake |
| 201 | + VERSION=$(grep "project(projectMSDL" frontend-sdl2/CMakeLists.txt | sed -E 's/.*VERSION ([0-9.]+).*/\1/') |
| 202 | +
|
| 203 | + # Build component package from signed app |
| 204 | + pkgbuild \ |
| 205 | + --root "${{ github.workspace }}/install" \ |
| 206 | + --identifier "org.projectm-visualizer.projectmsdl" \ |
| 207 | + --version "$VERSION" \ |
| 208 | + --install-location "/Applications" \ |
| 209 | + --component-plist "frontend-sdl2/src/resources/projectMSDL-component.plist" \ |
| 210 | + "projectMSDL-component.pkg" |
| 211 | +
|
| 212 | + # Build unsigned product archive |
| 213 | + productbuild \ |
| 214 | + --distribution "frontend-sdl2/src/resources/distribution.xml" \ |
| 215 | + --package-path "." \ |
| 216 | + --resources "frontend-sdl2/src/resources" \ |
| 217 | + "projectM-${VERSION}-macOS-universal-unsigned.pkg" |
| 218 | +
|
| 219 | + # Sign the package with productsign |
| 220 | + productsign \ |
| 221 | + --sign "Developer ID Installer: Mischa Spiegelmock (5926VBQM6Y)" \ |
| 222 | + "projectM-${VERSION}-macOS-universal-unsigned.pkg" \ |
| 223 | + "projectM-${VERSION}-macOS-universal.pkg" |
| 224 | +
|
| 225 | + rm "projectM-${VERSION}-macOS-universal-unsigned.pkg" |
| 226 | +
|
| 227 | + - name: Notarize Package |
| 228 | + env: |
| 229 | + API_KEY_ID: ${{ secrets.MACOS_NOTARY_KEY_ID }} |
| 230 | + API_ISSUER_ID: ${{ secrets.MACOS_NOTARY_ISSUER_ID }} |
| 231 | + run: | |
| 232 | + PKG_FILE=$(ls projectM-*.pkg | head -1) |
| 233 | +
|
| 234 | + xcrun notarytool submit "$PKG_FILE" \ |
| 235 | + --key ~/.private_keys/AuthKey_${API_KEY_ID}.p8 \ |
| 236 | + --key-id "$API_KEY_ID" \ |
| 237 | + --issuer "$API_ISSUER_ID" \ |
| 238 | + --wait |
| 239 | +
|
| 240 | + xcrun stapler staple "$PKG_FILE" |
| 241 | +
|
| 242 | + # Clean up API key |
| 243 | + rm -f ~/.private_keys/AuthKey_${API_KEY_ID}.p8 |
125 | 244 |
|
126 | 245 | - name: Upload Artifact |
127 | 246 | uses: actions/upload-artifact@v4 |
128 | 247 | with: |
129 | 248 | name: projectMSDL-macOS-Universal |
130 | | - path: cmake-build-frontend-sdl2/*.pkg |
| 249 | + path: projectM-*.pkg |
0 commit comments