Update MacQetDeploy_arm64.sh

This commit is contained in:
Laurent Trinques
2026-05-14 12:44:45 +02:00
committed by GitHub
parent d6251c901e
commit 43fb34f852

View File

@@ -50,7 +50,7 @@ echo "\t - update the git depot"
echo "\t - build the application bundle," echo "\t - build the application bundle,"
echo "\t - copy over required Qt frameworks," echo "\t - copy over required Qt frameworks,"
echo "\t - copy additional files: translations, titleblocks and elements," echo "\t - copy additional files: translations, titleblocks and elements,"
echo "\t - create DMG disk image." echo "\t - notarize the .app, then create a signed DMG."
echo echo
echo "Enjoy ;-)" echo "Enjoy ;-)"
echo echo
@@ -224,18 +224,16 @@ if [ -d "${QET_LICENSES_DIR}" ]; then
fi fi
### Sign the bundle ################################################# ### Sign the bundle #################################################
# Sign in the correct order: deepest binaries first, bundle last. # Sign in correct order: all dylibs first (including flat libs copied
# We sign ALL .dylib files individually (including flat libs copied # by macdeployqt from Homebrew), then frameworks, plugins, bundle last.
# by macdeployqt into Contents/Frameworks/) before signing the bundle. # --deep is deprecated and misses flat dylibs in Frameworks/.
# Using --deep is deprecated and misses flat dylibs, causing notarization
# to fail with "not signed with a valid Developer ID certificate".
echo echo
echo "______________________________________________________________" echo "______________________________________________________________"
echo "Code signing (all dylibs, plugins, frameworks, then bundle):" echo "Code signing (dylibs frameworks → plugins → bundle):"
# 1. Sign all flat .dylib files in Frameworks (copied by macdeployqt from Homebrew) # 1. Sign all flat .dylib files in Frameworks/
echo "-- Signing dylibs in Frameworks..." echo "-- Signing dylibs in Frameworks/..."
find "$BUNDLE/Contents/Frameworks" -name "*.dylib" | while read lib; do find "$BUNDLE/Contents/Frameworks" -name "*.dylib" | while read lib; do
echo " $(basename $lib)" echo " $(basename $lib)"
codesign --force --sign "$IDENTITY" --timestamp --options=runtime "$lib" codesign --force --sign "$IDENTITY" --timestamp --options=runtime "$lib"
@@ -248,25 +246,30 @@ find "$BUNDLE/Contents/Frameworks" -maxdepth 1 -name "*.framework" | while read
codesign --force --sign "$IDENTITY" --timestamp --options=runtime "$fw" codesign --force --sign "$IDENTITY" --timestamp --options=runtime "$fw"
done done
# 3. Sign plugins (.dylib and .so in PlugIns/) # 3. Sign plugins
echo "-- Signing plugins..." echo "-- Signing plugins..."
find "$BUNDLE/Contents/PlugIns" \( -name "*.dylib" -o -name "*.so" \) | while read lib; do find "$BUNDLE/Contents/PlugIns" \( -name "*.dylib" -o -name "*.so" \) | while read lib; do
echo " $(basename $lib)" echo " $(basename $lib)"
codesign --force --sign "$IDENTITY" --timestamp --options=runtime "$lib" codesign --force --sign "$IDENTITY" --timestamp --options=runtime "$lib"
done done
# 4. Sign any remaining dylibs in MacOS/ # 4. Sign any dylibs in MacOS/
echo "-- Signing dylibs in MacOS/..." echo "-- Signing dylibs in MacOS/..."
find "$BUNDLE/Contents/MacOS" -name "*.dylib" | while read lib; do find "$BUNDLE/Contents/MacOS" -name "*.dylib" | while read lib; do
echo " $(basename $lib)" echo " $(basename $lib)"
codesign --force --sign "$IDENTITY" --timestamp --options=runtime "$lib" codesign --force --sign "$IDENTITY" --timestamp --options=runtime "$lib"
done done
# 5. Sign the bundle itself last # 5. Sign the main executable explicitly
echo "-- Signing main executable..."
codesign --force --sign "$IDENTITY" --timestamp --options=runtime \
"$BUNDLE/Contents/MacOS/$APPNAME"
# 6. Sign the bundle itself last
echo "-- Signing bundle..." echo "-- Signing bundle..."
codesign --force --sign "$IDENTITY" --timestamp --options=runtime "$BUNDLE" codesign --force --sign "$IDENTITY" --timestamp --options=runtime "$BUNDLE"
# 6. Verify the whole bundle signature before proceeding # 7. Verify
echo echo
echo "Verifying bundle signature..." echo "Verifying bundle signature..."
codesign --verify --deep --strict --verbose=2 "$BUNDLE" codesign --verify --deep --strict --verbose=2 "$BUNDLE"
@@ -274,27 +277,35 @@ if [ $? -ne 0 ]; then
echo "ERROR: bundle signature verification failed, aborting." echo "ERROR: bundle signature verification failed, aborting."
exit 1 exit 1
fi fi
spctl -a -vv "$BUNDLE"
echo "Bundle signature OK." echo "Bundle signature OK."
### Create zip for notarization only ################################ ### Notarize the .app (via temporary ZIP) ###########################
# Temporary ZIP used only for notarytool submission. # Strategy:
# The final deliverable is a DMG (see below). # 1. Submit the .app as a ZIP to Apple notarytool → get ticket
# 2. Staple the ticket onto the .app
# 3. Create the DMG from the stapled .app
# 4. Sign the DMG
# 5. Staple the DMG directly (no re-submission needed: Apple
# recognises the ticket already registered for the .app bundle)
#
# This avoids submitting the DMG to notarytool, which would fail
# because hdiutil copies the .app and can invalidate its Sealed
# Resources signature during DMG creation.
echo echo
echo "______________________________________________________________" echo "______________________________________________________________"
echo "Create temporary zip for notarization:" echo "Create temporary ZIP for notarization:"
NOTARIZE_ZIP="/tmp/${APPNAME}-$VERSION-r$HEAD-arm64-notarize.zip" NOTARIZE_ZIP="/tmp/${APPNAME}-$VERSION-r$HEAD-arm64-notarize.zip"
/usr/bin/ditto -c -k --keepParent "$BUNDLE" "$NOTARIZE_ZIP" /usr/bin/ditto -c -k --keepParent "$BUNDLE" "$NOTARIZE_ZIP"
### Notarize ######################################################## echo -e "\033[1;31mWould you like to notarize the .app \"${APPNAME}-${VERSION}-r${HEAD}\", n/Y?\033[m"
echo -e "\033[1;31mWould you like to upload for notarization \"${APPNAME}-${VERSION}-r${HEAD}-arm64\", n/Y?\033[m"
read a read a
if [[ $a == "Y" || $a == "y" ]]; then if [[ $a == "Y" || $a == "y" ]]; then
echo echo
echo "______________________________________________________________" echo "______________________________________________________________"
echo "Notarizing:" echo "Notarizing .app:"
xcrun notarytool submit "$NOTARIZE_ZIP" --keychain-profile "org.qelectrotech" --wait xcrun notarytool submit "$NOTARIZE_ZIP" --keychain-profile "org.qelectrotech" --wait
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "ERROR: notarization failed. Check the log with:" echo "ERROR: notarization failed. Check the log with:"
@@ -306,35 +317,36 @@ else
echo -e "\033[1;33mExit.\033[m" echo -e "\033[1;33mExit.\033[m"
fi fi
# Clean up temporary notarization zip echo "Cleaning up temporary notarization ZIP..."
echo "Cleaning up temporary notarization zip..."
rm -f "$NOTARIZE_ZIP" rm -f "$NOTARIZE_ZIP"
### Staple ########################################################## ### Staple the .app #################################################
echo -e "\033[1;31mWould you like to staple the app \"${APPNAME}-${VERSION}-r${HEAD}\", n/Y?\033[m" echo -e "\033[1;31mWould you like to staple the .app \"${APPNAME}-${VERSION}-r${HEAD}\", n/Y?\033[m"
read a read a
if [[ $a == "Y" || $a == "y" ]]; then if [[ $a == "Y" || $a == "y" ]]; then
xcrun stapler staple -v "$BUNDLE" xcrun stapler staple -v "$BUNDLE"
echo "Verifying staple..." if [ $? -ne 0 ]; then
echo "ERROR: stapling .app failed."
exit 1
fi
echo "Verifying staple on .app..."
xcrun stapler validate -v "$BUNDLE" xcrun stapler validate -v "$BUNDLE"
spctl -a -vv "$BUNDLE" spctl -a -vv "$BUNDLE"
echo ".app stapled OK."
else else
echo -e "\033[1;33mExit.\033[m" echo -e "\033[1;33mExit.\033[m"
fi fi
### Create final DMG ################################################ ### Create DMG from the stapled .app ################################
# A DMG is used instead of a ZIP because it correctly preserves the # The .app is already notarized and stapled at this point.
# Gatekeeper staple when downloaded via Chrome or any other browser. # We create the DMG directly from it — no need to re-submit to
# ZIP extraction via Archive Utility can strip extended attributes, # notarytool. Stapling the DMG directly retrieves the already-
# causing Gatekeeper to block the app. # registered ticket from Apple's CDN.
#
# The DMG is created directly in UDZO (compressed read-only) format
# to avoid a UDRW -> UDZO conversion step that can alter file signatures.
echo echo
echo "______________________________________________________________" echo "______________________________________________________________"
echo "Create final DMG (Gatekeeper-compatible with Chrome and Safari):" echo "Create DMG from stapled .app:"
mkdir -p "build-aux/mac-osx" mkdir -p "build-aux/mac-osx"
@@ -351,40 +363,24 @@ if [ $? -ne 0 ]; then
exit 1 exit 1
fi fi
# Sign the DMG itself # Sign the DMG
echo "Signing DMG..."
codesign \ codesign \
--sign "$IDENTITY" \ --sign "$IDENTITY" \
--timestamp \ --timestamp \
"$DMG_PATH" "$DMG_PATH"
echo "DMG created and signed: $DMG_PATH" # Staple the DMG — retrieves the ticket already registered for the
# .app bundle, no new notarytool submission required
### Notarize the DMG ################################################ echo "Stapling DMG..."
xcrun stapler staple "$DMG_PATH"
echo -e "\033[1;31mWould you like to notarize the DMG \"${DMG_NAME}\", n/Y?\033[m" if [ $? -ne 0 ]; then
read a echo "WARNING: stapling DMG failed. The DMG is still usable but"
if [[ $a == "Y" || $a == "y" ]]; then echo "will require an internet connection for Gatekeeper validation."
echo
echo "______________________________________________________________"
echo "Notarizing DMG:"
xcrun notarytool submit "$DMG_PATH" --keychain-profile "org.qelectrotech" --wait
if [ $? -ne 0 ]; then
echo "ERROR: DMG notarization failed. Check the log with:"
echo " xcrun notarytool log <submission-id> --keychain-profile org.qelectrotech"
exit 1
fi
echo "Stapling notarization ticket to DMG..."
xcrun stapler staple "$DMG_PATH"
if [ $? -ne 0 ]; then
echo "ERROR: stapling DMG failed."
exit 1
fi
echo "DMG notarized and stapled OK."
else
echo -e "\033[1;33mExit.\033[m"
fi fi
echo "DMG ready: $DMG_PATH"
### Clean up bundle ################################################# ### Clean up bundle #################################################
echo "Cleaning up bundle..." echo "Cleaning up bundle..."