diff --git a/.github/workflows/release-apps.yml b/.github/workflows/release-apps.yml index 2d44b2830..a4acee284 100644 --- a/.github/workflows/release-apps.yml +++ b/.github/workflows/release-apps.yml @@ -217,7 +217,7 @@ jobs: cp "$RUNNER_TEMP/maccatalyst.provisionprofile" "$PP_PATH/$PROFILE_UUID.provisionprofile" echo "Installed Mac Catalyst profile with UUID: $PROFILE_UUID" - - name: Publish Mac Catalyst PKG + - name: Publish Mac Catalyst App run: | dotnet publish ${{ env.MAUI_PROJECT_PATH }} \ -f net10.0-maccatalyst \ @@ -226,13 +226,97 @@ jobs: -p:CodesignKey="${{ secrets.IOS_CODESIGN_KEY }}" \ -p:CodesignProvision="${{ secrets.MACCATALYST_PROVISIONING_PROFILE_NAME }}" \ -p:CodesignEntitlements=Platforms/MacCatalyst/Entitlements.AppStore.plist \ - -p:CreatePackage=true \ + -p:CreatePackage=false \ -p:EnableCodeSigning=true \ - -p:EnablePackageSigning=true \ - -p:PackageSigningKey="${{ secrets.MACCATALYST_INSTALLER_SIGNING_KEY }}" \ -p:ApplicationDisplayVersion='${{ env.APP_VERSION }}' \ -p:ApplicationVersion='${{ steps.build.outputs.number }}' + - name: Patch bundle identifier for App Store + run: | + APP_PATH=$(find PolyPilot/bin/Release/net10.0-maccatalyst -name "PolyPilot.app" -type d | head -1) + echo "App path: $APP_PATH" + + # MAUI builds with maccatalyst.nl.versluis.polypilot to match the provisioning + # profile, but App Store Connect expects the base bundle ID without the prefix. + # Apple's tooling understands the maccatalyst. prefix convention in profiles, + # but the binary's CFBundleIdentifier must be the base ID. + PLIST="$APP_PATH/Contents/Info.plist" + CURRENT_ID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$PLIST") + echo "Current CFBundleIdentifier: $CURRENT_ID" + + if [[ "$CURRENT_ID" == maccatalyst.* ]]; then + BASE_ID="${CURRENT_ID#maccatalyst.}" + /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BASE_ID" "$PLIST" + echo "Patched CFBundleIdentifier to: $BASE_ID" + else + echo "CFBundleIdentifier already uses base ID: $CURRENT_ID" + fi + + - name: Re-sign app bundle (inside-out) + env: + CODESIGN_KEY: ${{ secrets.IOS_CODESIGN_KEY }} + run: | + APP_PATH=$(find PolyPilot/bin/Release/net10.0-maccatalyst -name "PolyPilot.app" -type d | head -1) + echo "App path: $APP_PATH" + + # Sign the copilot CLI binary with minimal helper entitlements (sandbox + inherit) + COPILOT_BIN="$APP_PATH/Contents/MonoBundle/copilot" + if [ -f "$COPILOT_BIN" ]; then + echo "Signing bundled copilot binary..." + codesign --force --sign "$CODESIGN_KEY" \ + --entitlements PolyPilot/Platforms/MacCatalyst/Entitlements.Helper.plist \ + --options runtime --timestamp \ + "$COPILOT_BIN" + else + echo "Warning: copilot binary not found at $COPILOT_BIN" + fi + + # Re-sign all dylibs (inside-out) + find "$APP_PATH" -type f \( -name "*.dylib" -o -name "*.so" \) | while read f; do + echo " Signing: $f" + codesign --force --options runtime --timestamp \ + --sign "$CODESIGN_KEY" "$f" + done + + # Re-sign frameworks + find "$APP_PATH" -type d -name "*.framework" | while read f; do + echo " Signing: $f" + codesign --force --options runtime --timestamp \ + --sign "$CODESIGN_KEY" "$f" + done + + # Re-sign the top-level app bundle with full app entitlements + codesign --force --sign "$CODESIGN_KEY" \ + --entitlements PolyPilot/Platforms/MacCatalyst/Entitlements.AppStore.plist \ + --options runtime --timestamp \ + "$APP_PATH" + + echo "=== Verify signature ===" + codesign --verify --deep --strict "$APP_PATH" 2>&1 + echo "=== Signature details ===" + codesign -dvv "$APP_PATH" 2>&1 | head -20 + echo "=== Verify copilot binary ===" + codesign -dvv "$COPILOT_BIN" 2>&1 | head -10 + + - name: Create and sign PKG + env: + PKG_SIGN_KEY: ${{ secrets.MACCATALYST_INSTALLER_SIGNING_KEY }} + run: | + APP_PATH=$(find PolyPilot/bin/Release/net10.0-maccatalyst -name "PolyPilot.app" -type d | head -1) + PKG_DIR="PolyPilot/bin/Release/net10.0-maccatalyst" + + # Create component package + productbuild --component "$APP_PATH" /Applications \ + "$PKG_DIR/PolyPilot-unsigned.pkg" + + # Sign the package with Mac Installer certificate + productsign --sign "$PKG_SIGN_KEY" \ + "$PKG_DIR/PolyPilot-unsigned.pkg" \ + "$PKG_DIR/PolyPilot-${{ env.APP_VERSION }}.pkg" + + rm "$PKG_DIR/PolyPilot-unsigned.pkg" + echo "Created signed PKG" + - name: Find PKG file id: find_pkg run: | @@ -288,7 +372,7 @@ jobs: xcrun altool --upload-package "$PKG_PATH" \ -t macos \ --apple-id "6759370598" \ - --bundle-id "maccatalyst.nl.versluis.polypilot" \ + --bundle-id "nl.versluis.polypilot" \ --bundle-version "$BUILD_NUMBER" \ --bundle-short-version-string "$APP_VERSION" \ --apiKey "$APPSTORE_KEY_ID" \ diff --git a/PolyPilot/Platforms/MacCatalyst/Entitlements.Helper.plist b/PolyPilot/Platforms/MacCatalyst/Entitlements.Helper.plist new file mode 100644 index 000000000..0bbc9f170 --- /dev/null +++ b/PolyPilot/Platforms/MacCatalyst/Entitlements.Helper.plist @@ -0,0 +1,13 @@ + + + + + + com.apple.security.app-sandbox + + com.apple.security.inherit + + + diff --git a/PolyPilot/Platforms/MacCatalyst/Info.plist b/PolyPilot/Platforms/MacCatalyst/Info.plist index ecac4e986..325cf53eb 100644 --- a/PolyPilot/Platforms/MacCatalyst/Info.plist +++ b/PolyPilot/Platforms/MacCatalyst/Info.plist @@ -9,8 +9,8 @@ - - + LSApplicationCategoryType + public.app-category.developer-tools UIDeviceFamily 2