Improvements and fixes on macos sing and notarize script
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
files = [f"{containing_folder}/FreeCAD.app"]
|
||||
# Ensure default values are set in defines if they are not already provided
|
||||
defines.setdefault("containing_folder", "./APP")
|
||||
defines.setdefault("app_name", "FreeCAD.app")
|
||||
defines.setdefault("icon_path", "Contents/Resources/freecad.icns")
|
||||
|
||||
|
||||
files = [f"{defines['containing_folder']}/{defines['app_name']}"]
|
||||
symlinks = {"Applications": "/Applications"}
|
||||
badge_icon = f"{containing_folder}/FreeCAD.app/Contents/Resources/freecad.icns"
|
||||
badge_icon = f"{defines['containing_folder']}/{defines['app_name']}/{defines['icon_path']}"
|
||||
window_rect = ((200, 200), (600, 400))
|
||||
icon_locations = {"FreeCAD.app": (180, 150), "Applications": (420, 150)}
|
||||
icon_locations = {f"{defines['app_name']}": (180, 150), "Applications": (420, 150)}
|
||||
size = "3g"
|
||||
|
||||
@@ -16,23 +16,105 @@
|
||||
# for instructions on how to configure the credentials for the tool for use before running this
|
||||
# script.
|
||||
|
||||
# CONFIGURATION OPTIONS
|
||||
CONTAINING_FOLDER="FreeCAD_0.21.1_arm64" # Must contain FreeCAD.app and nothing else
|
||||
ARCH="arm64" # intel_x86 or arm64
|
||||
VERSION_MAJOR="0"
|
||||
VERSION_MINOR="21"
|
||||
VERSION_PATCH="1"
|
||||
VERSION_SUFFIX="" # e.g. alpha, beta, RC1, RC2, release
|
||||
# Default values
|
||||
SIGNING_KEY_ID="${FREECAD_SIGNING_KEY_ID}"
|
||||
KEYCHAIN_PROFILE="FreeCAD"
|
||||
CONTAINING_FOLDER="APP"
|
||||
APP_NAME="FreeCAD.app"
|
||||
VOLUME_NAME="FreeCAD"
|
||||
DMG_NAME="FreeCAD-macOS-$(uname -m).dmg"
|
||||
DMG_SETTINGS="dmg_settings.py"
|
||||
|
||||
|
||||
# Function to display usage information
|
||||
function usage {
|
||||
echo "Usage: $0 [-k|--key-id <signing_key_id>] [-p|--keychain-profile <keychain_profile>]"
|
||||
echo " [-d|--dir <containing_folder>] [-n|--app-name <app_name.app>]"
|
||||
echo " [-v|--volume-name <volume_name>] [-o|--output <image_name.dmg>]"
|
||||
echo " [-s|--dmg-settings <dmg_settings.py>]"
|
||||
echo
|
||||
echo "This script signs and notarizes a FreeCAD.app bundle. It expects that the bundle is in a folder"
|
||||
echo "by itself (that folder will be used as the basis for the created disk image file, so anything"
|
||||
echo "else in it will become part of the image). That folder should be located in the same folder as"
|
||||
echo "this script."
|
||||
echo
|
||||
echo "If <signing_key_id> is not passed it defaults to env variable FREECAD_SIGNING_KEY_ID, it should"
|
||||
echo "be a Developer ID Application certificate that has been installed into the login keychain."
|
||||
echo "For a list of available keys see the output of"
|
||||
echo " security find-identity -p basic -v"
|
||||
echo "For instructions on how to configure the credentials for the tool for use before running this"
|
||||
echo "script see the documentation for"
|
||||
echo " xcrun notarytool store-credentials"
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case $1 in
|
||||
-k|--key-id)
|
||||
SIGNING_KEY_ID="$2"
|
||||
shift 2
|
||||
;;
|
||||
-p|--keychain-profile)
|
||||
KEYCHAIN_PROFILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-d|--dir)
|
||||
CONTAINING_FOLDER="$2"
|
||||
shift 2
|
||||
;;
|
||||
-n|--app-name)
|
||||
APP_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
-v|--volume-name)
|
||||
VOLUME_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
-o|--output)
|
||||
DMG_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
-s|--dmg-settings)
|
||||
DMG_SETTINGS="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
echo "Unknown parameter passed: $1"
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check if SIGNING_KEY_ID is set
|
||||
if [ -z "$SIGNING_KEY_ID" ]; then
|
||||
echo "Error: Signing key ID is required."
|
||||
usage
|
||||
fi
|
||||
|
||||
# Check for dmgbuild executable
|
||||
if ! command -v dmgbuild &> /dev/null; then
|
||||
echo 'Error: dmgbuild not installed. Please install it'
|
||||
echo '- using pixi:'
|
||||
echo 'pixi g install dmgbuild --with pyobjc-framework-Quartz'
|
||||
echo '- using pip:'
|
||||
echo 'pip3 install dmgbuild pyobjc-framework-Quartz'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function run_codesign {
|
||||
echo "Signing $1"
|
||||
codesign --options runtime -f -s ${FREECAD_SIGNING_KEY_ID} --timestamp --entitlements entitlements.plist $1
|
||||
codesign --options runtime -f -s ${SIGNING_KEY_ID} --timestamp --entitlements entitlements.plist $1
|
||||
}
|
||||
|
||||
IFS=$'\n'
|
||||
dylibs=($(find ${CONTAINING_FOLDER}/FreeCAD.app -name "*.dylib"))
|
||||
shared_objects=($(find ${CONTAINING_FOLDER}/FreeCAD.app -name "*.so"))
|
||||
executables=($(file `find . -type f -perm +111 -print` | grep "Mach-O 64-bit executable" | sed 's/:.*//g'))
|
||||
dylibs=($(find "${CONTAINING_FOLDER}/${APP_NAME}" -name "*.dylib"))
|
||||
shared_objects=($(find "${CONTAINING_FOLDER}/${APP_NAME}" -name "*.so"))
|
||||
executables=($(find "${CONTAINING_FOLDER}/${APP_NAME}" -type f -perm +111 -exec file {} + | grep "Mach-O 64-bit executable" | sed 's/:.*//g'))
|
||||
IFS=$' \t\n' # The default
|
||||
|
||||
signed_files=("${dylibs[@]}" "${shared_objects[@]}" "${executables[@]}")
|
||||
@@ -44,20 +126,18 @@ for exe in ${signed_files}; do
|
||||
done
|
||||
|
||||
# Two additional files that must be signed that aren't caught by the above searches:
|
||||
run_codesign "${CONTAINING_FOLDER}/FreeCAD.app/Contents/packages.txt"
|
||||
run_codesign "${CONTAINING_FOLDER}/FreeCAD.app/Contents/Library/QuickLook/QuicklookFCStd.qlgenerator/Contents/MacOS/QuicklookFCStd"
|
||||
run_codesign "${CONTAINING_FOLDER}/${APP_NAME}/Contents/packages.txt"
|
||||
run_codesign "${CONTAINING_FOLDER}/${APP_NAME}/Contents/Library/QuickLook/QuicklookFCStd.qlgenerator/Contents/MacOS/QuicklookFCStd"
|
||||
|
||||
# Finally, sign the app itself (must be done last)
|
||||
run_codesign "${CONTAINING_FOLDER}/FreeCAD.app"
|
||||
run_codesign "${CONTAINING_FOLDER}/${APP_NAME}"
|
||||
|
||||
# Create a disk image from the folder
|
||||
DMG_NAME="FreeCAD-${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-mac-${ARCH}.dmg"
|
||||
echo "Creating disk image ${DMG_NAME}"
|
||||
pip3 install "dmgbuild[badge_icons]>=1.6.0,<1.7.0"
|
||||
dmgbuild -s dmg_settings.py -Dcontaining_folder="${CONTAINING_FOLDER}" "FreeCAD" "${DMG_NAME}.dmg"
|
||||
dmgbuild -s ${DMG_SETTINGS} -Dcontaining_folder="${CONTAINING_FOLDER}" -Dapp_name="${APP_NAME}" "${VOLUME_NAME}" "${DMG_NAME}"
|
||||
|
||||
# Submit it for notarization (requires that an App Store API Key has been set up in the notarytool)
|
||||
xcrun notarytool submit --wait --keychain-profile "FreeCAD" ${DMG_NAME}
|
||||
xcrun notarytool submit --wait --keychain-profile "${KEYCHAIN_PROFILE}" "${DMG_NAME}"
|
||||
|
||||
# Assuming that notarization succeeded, it's a good practice to staple that notarization to the DMG
|
||||
xcrun stapler staple ${DMG_NAME}
|
||||
xcrun stapler staple "${DMG_NAME}"
|
||||
|
||||
Reference in New Issue
Block a user