Skip to content

Commit 1ea981c

Browse files
funsaizedclaude
andcommitted
fix(release): sign app and framework inside-out
codesign on the Xcode 26 toolchain refuses to re-sign a bundle whose Mach-O still carries the linker's ad-hoc signature (errors 'code object is not signed at all'), so each inner binary must be signed before its bundle. Replaced the single bundle codesign with an inside-out sequence (framework binary -> framework -> app binary -> app bundle). Also swapped the find|while pipeline for a glob loop so a signing failure aborts loudly under set -e instead of being swallowed in a subshell (which is what masked this on CI). Verified locally: codesign --verify --deep --strict passes; spctl reports a correctly-signed Unnotarized Developer ID app. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent eef5c46 commit 1ea981c

1 file changed

Lines changed: 21 additions & 8 deletions

File tree

scripts/release/build-and-sign.sh

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,30 @@ APP="$DIST/PowerSnek.app"
2828

2929
if [[ -n "${APPLE_DEVELOPER_IDENTITY:-}" ]]; then
3030
echo "==> Signing with: $APPLE_DEVELOPER_IDENTITY"
31-
# Sign embedded frameworks first (inside-out), then the app bundle.
32-
if [[ -d "$APP/Contents/Frameworks" ]]; then
33-
find "$APP/Contents/Frameworks" -maxdepth 1 -name "*.framework" -print0 \
34-
| while IFS= read -r -d '' fw; do
35-
codesign --force --options runtime --timestamp \
36-
--sign "$APPLE_DEVELOPER_IDENTITY" "$fw"
37-
done
38-
fi
31+
sign() { codesign --force --options runtime --timestamp --sign "$APPLE_DEVELOPER_IDENTITY" "$@"; }
32+
33+
# Sign INSIDE-OUT. On the Xcode 26 toolchain the linker leaves an ad-hoc
34+
# signature on every Mach-O; `codesign` on a bundle will NOT re-sign through
35+
# that (it errors "code object is not signed at all"), so each inner binary
36+
# must be signed before its bundle. A glob loop — not `find | while` — keeps
37+
# any failure visible under `set -e` instead of swallowing it in a subshell.
38+
shopt -s nullglob
39+
for fw in "$APP/Contents/Frameworks"/*.framework; do
40+
name="$(basename "$fw" .framework)"
41+
echo " - signing framework: $name"
42+
sign "$fw/Versions/A/$name" # inner binary first
43+
sign "$fw/Versions/A" # then the version bundle
44+
done
45+
shopt -u nullglob
46+
47+
app_bin="$APP/Contents/MacOS/$(/usr/libexec/PlistBuddy -c 'Print CFBundleExecutable' "$APP/Contents/Info.plist")"
48+
echo " - signing app binary: $(basename "$app_bin")"
49+
sign "$app_bin"
50+
echo " - signing app bundle"
3951
codesign --force --options runtime --timestamp \
4052
--entitlements "$ENTITLEMENTS" \
4153
--sign "$APPLE_DEVELOPER_IDENTITY" "$APP"
54+
4255
echo "==> Verifying signature"
4356
codesign --verify --deep --strict --verbose=2 "$APP"
4457
else

0 commit comments

Comments
 (0)