From db86f4006efe0c0feb16b6701176dc139f96b462 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 15 Feb 2024 06:47:12 +0100 Subject: [PATCH] Staple notarization ticket to .dmg and .app bundle (#7775) This should eliminate a pretty significant (multiple seconds) slowdown that new users (or users after restarting their OS) have been experiencing. Previously, we would just notarize the application, which meant that every user of the application had to perform an integrity check against Apple's servers to ensure the app wasn't malicious. With this commit, we are now using `xcrun stapler staple`, which attaches the notarization ticket to both the app bundle as well as the DMG. This should prevent users from needing to reach out to Apple's notarization service in order to verify the app's integrity. You can confirm the quarantine status of the application by running `ls -l@` in `Terminal.app`: ls -l@ /Applications/Zed.app/Contents/MacOS/zed Release Notes: - Improved startup time when opening Zed for the first time or after restarting the operating system. Co-authored-by: Thorsten Co-authored-by: bennetbo Co-authored-by: Martin Palma Co-authored-by: evrsen <146845123+evrsen@users.noreply.github.com> --- script/bundle | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/script/bundle b/script/bundle index 7eced084c29e21b19ee180d5d03b0d8d71f8014f..6b8d429e22ab995fdf3e0970109545fceacc52c3 100755 --- a/script/bundle +++ b/script/bundle @@ -218,17 +218,17 @@ if [[ "$target_dir" = "debug" && "$local_only" = false ]]; then exit 0 fi -if [ "$local_only" = true ]; then - # If bundle_name is not set or empty, use the basename of $app_path - if [ -z "$bundle_name" ]; then - bundle_name=$(basename "$app_path") - else - # If bundle_name doesn't end in .app, append it - if [[ "$bundle_name" != *.app ]]; then - bundle_name="$bundle_name.app" - fi +# If bundle_name is not set or empty, use the basename of $app_path +if [ -z "$bundle_name" ]; then + bundle_name=$(basename "$app_path") +else + # If bundle_name doesn't end in .app, append it + if [[ "$bundle_name" != *.app ]]; then + bundle_name="$bundle_name.app" fi +fi +if [ "$local_only" = true ]; then if [ "$overwrite_local_app" = true ]; then rm -rf "/Applications/$bundle_name" fi @@ -241,19 +241,38 @@ if [ "$local_only" = true ]; then echo "/Applications/$bundle_name" fi else - echo "Creating DMG" dmg_target_directory="target/${target_dir}" dmg_source_directory="${dmg_target_directory}/dmg" dmg_file_path="${dmg_target_directory}/Zed.dmg" + xcode_bin_dir_path="$(xcode-select -p)/usr/bin" rm -rf ${dmg_source_directory} mkdir -p ${dmg_source_directory} mv "${app_path}" "${dmg_source_directory}" + if [[ -n $MACOS_CERTIFICATE && -n $MACOS_CERTIFICATE_PASSWORD && -n $APPLE_NOTARIZATION_USERNAME && -n $APPLE_NOTARIZATION_PASSWORD ]]; then + echo "Creating temporary DMG at ${dmg_file_path} using ${dmg_source_directory} to notarize app bundle" + hdiutil create -volname Zed -srcfolder "${dmg_source_directory}" -ov -format UDZO "${dmg_file_path}" + + echo "Notarizing DMG with Apple" + "${xcode_bin_dir_path}/notarytool" submit --wait --apple-id "$APPLE_NOTARIZATION_USERNAME" --password "$APPLE_NOTARIZATION_PASSWORD" --team-id "$APPLE_NOTORIZATION_TEAM" "${dmg_file_path}" + + echo "Removing temporary DMG (used only for notarization)" + rm "${dmg_file_path}" + + echo "Stapling notarization ticket to ${dmg_source_directory}/${bundle_name}" + "${xcode_bin_dir_path}/stapler" staple "${dmg_source_directory}/${bundle_name}" + fi + + echo "Adding symlink to /Applications to ${dmg_source_directory}" ln -s /Applications ${dmg_source_directory} + + echo "Creating final DMG at ${dmg_file_path} using ${dmg_source_directory}" hdiutil create -volname Zed -srcfolder "${dmg_source_directory}" -ov -format UDZO "${dmg_file_path}" + # If someone runs this bundle script locally, a symlink will be placed in `dmg_source_directory`. # This symlink causes CPU issues with Zed if the Zed codebase is the project being worked on, so we simply remove it for now. + echo "Removing symlink to /Applications from ${dmg_source_directory}" rm ${dmg_source_directory}/Applications echo "Adding license agreement to DMG" @@ -262,7 +281,8 @@ else if [[ -n $MACOS_CERTIFICATE && -n $MACOS_CERTIFICATE_PASSWORD && -n $APPLE_NOTARIZATION_USERNAME && -n $APPLE_NOTARIZATION_PASSWORD ]]; then echo "Notarizing DMG with Apple" - "$(xcode-select -p)/usr/bin/notarytool" submit --wait --apple-id "$APPLE_NOTARIZATION_USERNAME" --password "$APPLE_NOTARIZATION_PASSWORD" --team-id "$APPLE_NOTORIZATION_TEAM" "${dmg_file_path}" + "${xcode_bin_dir_path}/notarytool" submit --wait --apple-id "$APPLE_NOTARIZATION_USERNAME" --password "$APPLE_NOTARIZATION_PASSWORD" --team-id "$APPLE_NOTORIZATION_TEAM" "${dmg_file_path}" + "${xcode_bin_dir_path}/stapler" staple "${dmg_file_path}" fi if [ "$open_result" = true ]; then