fix(build): sign non-standard framework binary via temp copy to avoid ambiguity#1250
Conversation
… ambiguity codesign refuses to sign Python.framework/Python in-place when the binary is inside a .framework directory — it sees the directory context and reports 'bundle format is ambiguous (could be app or framework)'. The ActivityWatch#1249 fallback correctly detected this case but then called sign_binary on the same path, which hits the same codesign check. Fix: copy the binary to a temp path outside any .framework dir, sign it there, then copy the signed binary back. Code signatures are embedded in the Mach-O binary (not path-dependent), so the result is identical. This should be the final fix needed to unblock the Build Tauri master CI and allow the Thursday 2026-04-09 12:00 UTC scheduled dev release to run.
Greptile SummaryThis PR fixes the lingering "bundle format is ambiguous" codesign failure introduced after #1249 by copying the non-standard PyInstaller-embedded Confidence Score: 5/5Safe to merge — fix is targeted, logic is correct, and the only finding is a minor temp-file cleanup suggestion. The core approach (temp-copy → sign → copy-back) is well-reasoned and correctly addresses the root cause. No files require special attention.
|
| Filename | Overview |
|---|---|
| scripts/package/build_app_tauri.sh | Adds temp-copy workaround for signing a non-standard PyInstaller-embedded Python.framework binary; logic is sound and permissions are preserved correctly on copy-back. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Step 2: iterate .framework / .bundle / .plugin dirs] --> B["codesign bundle in-place"]
B --> C{Success?}
C -- Yes --> D[Log 'Signed bundle']
C -- No --> E{Error: 'bundle format is ambiguous'?}
E -- No --> F[Exit with error]
E -- Yes --> G["Derive main binary path\n(e.g. Python.framework/Python)"]
G --> H{Binary exists?}
H -- No --> I[Exit with error]
H -- Yes --> J["mktemp → tmp_binary"]
J --> K["cp fw_binary → tmp_binary"]
K --> L["codesign tmp_binary\n(no .framework context)"]
L --> M["cp tmp_binary → fw_binary\n(signed, permissions preserved)"]
M --> N["rm tmp_binary"]
N --> O[Continue to next bundle]
D --> O
Reviews (1): Last reviewed commit: "fix(build): sign non-standard framework ..." | Re-trigger Greptile
| tmp_binary=$(mktemp) | ||
| cp "$fw_binary" "$tmp_binary" | ||
| sign_binary "$tmp_binary" | ||
| cp "$tmp_binary" "$fw_binary" | ||
| rm -f "$tmp_binary" |
There was a problem hiding this comment.
Temp file not cleaned up on signing failure
If sign_binary "$tmp_binary" fails (non-zero exit), set -e aborts the script before rm -f "$tmp_binary" runs, leaving the temp file in /tmp. In CI this is harmless since the machine isn't reused, but a trap guard would make this leak-proof in any environment.
| tmp_binary=$(mktemp) | |
| cp "$fw_binary" "$tmp_binary" | |
| sign_binary "$tmp_binary" | |
| cp "$tmp_binary" "$fw_binary" | |
| rm -f "$tmp_binary" | |
| tmp_binary=$(mktemp) | |
| trap 'rm -f "$tmp_binary"' EXIT | |
| cp "$fw_binary" "$tmp_binary" | |
| sign_binary "$tmp_binary" | |
| cp "$tmp_binary" "$fw_binary" | |
| rm -f "$tmp_binary" | |
| trap - EXIT |
… ambiguity (ActivityWatch#1250) codesign refuses to sign Python.framework/Python in-place when the binary is inside a .framework directory — it sees the directory context and reports 'bundle format is ambiguous (could be app or framework)'. The ActivityWatch#1249 fallback correctly detected this case but then called sign_binary on the same path, which hits the same codesign check. Fix: copy the binary to a temp path outside any .framework dir, sign it there, then copy the signed binary back. Code signatures are embedded in the Mach-O binary (not path-dependent), so the result is identical. This should be the final fix needed to unblock the Build Tauri master CI and allow the Thursday 2026-04-09 12:00 UTC scheduled dev release to run.
Problem
After #1249 merged, master Build Tauri still fails with:
#1249 added a fallback for the "bundle format is ambiguous" error in Step 2: when signing
Python.frameworkas a bundle fails, it tries to sign the main binary (Python.framework/Python) directly viasign_binary.But
sign_binarycallscodesignon the same path (Python.framework/Python), which still sees the.frameworkparent directory and reports the same "bundle format is ambiguous" error — same failure, one level deeper.Fix
Instead of signing
Python.framework/Pythonin-place, copy it to a temp path outside any.frameworkdirectory, sign it there, then copy the signed binary back.Code signatures are embedded in the Mach-O binary (not path-dependent), so the result is identical. When the binary is at a temp path,
codesignsees no.frameworkcontext and signs it successfully as a standalone executable.Test plan
Package dmgstep completes without "bundle format is ambiguous" errorsThis should be the final fix needed to unblock the Thursday 2026-04-09 12:00 UTC scheduled
Create dev releaserun.