From 3dfd97b8f2f8e57ef669f686d7825ea405dc1547 Mon Sep 17 00:00:00 2001 From: Bob Date: Wed, 8 Apr 2026 20:05:01 +0000 Subject: [PATCH 1/3] fix(build): skip framework main binaries in codesign Step 1 to avoid ambiguity error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The inside-out signing loop from #1246 signs ALL Mach-O files in Step 1, then .framework bundles in Step 2. But Python.framework/Python is both a Mach-O binary AND the main binary of a .framework bundle — codesign errors with "bundle format is ambiguous (could be app or framework)" when it's signed as a standalone file. Fix: Skip files whose parent directory is a .framework, .bundle, or .plugin in Step 1. These are correctly signed as part of their bundle in Step 2. Also extends Step 2 to cover .bundle and .plugin directories (not just .framework) for completeness. Fixes the Build Tauri master CI failure after #1246 merge. --- scripts/package/build_app_tauri.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/scripts/package/build_app_tauri.sh b/scripts/package/build_app_tauri.sh index f2ebb448a..5fee51199 100755 --- a/scripts/package/build_app_tauri.sh +++ b/scripts/package/build_app_tauri.sh @@ -116,8 +116,20 @@ if [ -n "$APPLE_PERSONALID" ]; then # Use `xargs file` to batch all type queries in O(1) subprocess calls instead of # one `file` invocation per binary (PyInstaller bundles can contain hundreds of files). # Sort by path length descending so deeper binaries are signed before shallower containers. + # IMPORTANT: Skip the main binary of .framework bundles (e.g. Python.framework/Python). + # codesign treats those as ambiguous ("could be app or framework") when signed as + # standalone files. They are correctly signed in Step 2 as part of the framework bundle. echo " Signing Mach-O binary files..." while IFS= read -r f; do + # Skip main binaries of bundle directories (.framework, .bundle, .plugin) — + # they'll be signed as part of the bundle in Step 2. Signing them standalone + # causes "bundle format is ambiguous" errors from codesign. + parent_dir="$(dirname "$f")" + if [[ "$parent_dir" == *.framework ]] || [[ "$parent_dir" == *.framework/Versions/* ]] \ + || [[ "$parent_dir" == *.bundle ]] || [[ "$parent_dir" == *.plugin ]]; then + echo " Skipping bundle binary (signed in Step 2): $f" + continue + fi sign_binary "$f" done < <(find "dist/${APP_NAME}.app" -type f \ | xargs file \ From 48aee92fd642d0a3bee617c190ed2eca1d4a4b37 Mon Sep 17 00:00:00 2001 From: Bob Date: Wed, 8 Apr 2026 20:53:10 +0000 Subject: [PATCH 2/3] fix(build): handle ambiguous bundle format in codesign Step 2 Python.framework (created by PyInstaller) has an ambiguous bundle structure that causes codesign to error with "bundle format is ambiguous (could be app or framework)" when signed as a bundle. The previous fix (#1247) only skipped the framework's main binary in Step 1 (per-binary signing). But Step 2 (bundle-level signing) also encounters this error when trying to sign the framework bundle itself. Fix: make bundle signing non-fatal in Step 2. Since all individual Mach-O files inside the framework are already signed in Step 1, and the top-level .app is signed in Step 3, the framework-level seal is not strictly required. --- scripts/package/build_app_tauri.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/package/build_app_tauri.sh b/scripts/package/build_app_tauri.sh index 5fee51199..c9ad1acc6 100755 --- a/scripts/package/build_app_tauri.sh +++ b/scripts/package/build_app_tauri.sh @@ -141,9 +141,15 @@ if [ -n "$APPLE_PERSONALID" ]; then # Deepest bundles first (sort by path length descending) to maintain inside-out order. # .bundle/.plugin coverage prevents missing CodeResources catalog seals that can # trigger notarytool bundle-integrity warnings. + # NOTE: Some frameworks (e.g. PyInstaller's Python.framework) have an ambiguous + # bundle structure that codesign rejects. Their individual binaries are already + # signed in Step 1, so skipping them here is safe — the .app-level signature + # in Step 3 will seal everything. echo " Signing bundle directories (.framework, .bundle, .plugin)..." while IFS= read -r fw; do - sign_binary "$fw" + if ! sign_binary "$fw"; then + echo " WARNING: Skipping $fw (bundle format may be ambiguous, contents already signed in Step 1)" + fi done < <(find "dist/${APP_NAME}.app" -type d \ \( -name "*.framework" -o -name "*.bundle" -o -name "*.plugin" \) \ | awk '{ print length, $0 }' | sort -rn | cut -d' ' -f2-) From 3111745e0d764badf48f3ab901f24c170be3039f Mon Sep 17 00:00:00 2001 From: Bob Date: Wed, 8 Apr 2026 21:02:30 +0000 Subject: [PATCH 3/3] fix(build): narrow Step 2 error catch to 'bundle format is ambiguous' only The previous fix suppressed all Step 2 codesign failures, which could silently produce an app with unsigned nested bundles (failing notarization without a clear error). Now only the known Python.framework ambiguity error is swallowed; any other signing failure aborts the build immediately with an error message. Addresses Greptile P1 review finding on PR #1248. --- scripts/package/build_app_tauri.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/scripts/package/build_app_tauri.sh b/scripts/package/build_app_tauri.sh index c9ad1acc6..eb7287787 100755 --- a/scripts/package/build_app_tauri.sh +++ b/scripts/package/build_app_tauri.sh @@ -147,8 +147,18 @@ if [ -n "$APPLE_PERSONALID" ]; then # in Step 3 will seal everything. echo " Signing bundle directories (.framework, .bundle, .plugin)..." while IFS= read -r fw; do - if ! sign_binary "$fw"; then - echo " WARNING: Skipping $fw (bundle format may be ambiguous, contents already signed in Step 1)" + echo " Signing: $fw" + if ! codesign_out=$(codesign --force --options runtime --timestamp \ + --entitlements "$ENTITLEMENTS" \ + --sign "$APPLE_PERSONALID" \ + "$fw" 2>&1); then + if echo "$codesign_out" | grep -q "bundle format is ambiguous"; then + echo " WARNING: $fw — bundle format is ambiguous; contents already signed in Step 1, skipping" + else + echo " ERROR: Failed to sign $fw:" >&2 + echo "$codesign_out" >&2 + exit 1 + fi fi done < <(find "dist/${APP_NAME}.app" -type d \ \( -name "*.framework" -o -name "*.bundle" -o -name "*.plugin" \) \