2021-12-12 23:45:28 +00:00
#!/usr/bin/env zsh
function dxx_codesign {
2021-12-13 00:38:53 +00:00
# codesign parameters:
2021-12-18 03:22:51 +00:00
# --timestamp: Request a signing timestamp from Apple's servers (required for notarization).
2021-12-13 00:38:53 +00:00
# --options=runtime: Enable a hardened runtime (required for notarization).
# --verbose: More verbose output for tracking status.
# --force: Force overwriting existing ad hoc or identity-signed signatures. Existing resources are likely to have at least one signature (likely ad hoc) to replace.
2021-12-18 03:22:51 +00:00
# --sign: The signing identity to use to sign the resource.
2021-12-12 23:53:41 +00:00
codesign --timestamp --options= runtime --verbose --force --sign " ${ signing_identity [2] } " " $@ "
2021-12-12 23:45:28 +00:00
}
2021-12-18 03:23:37 +00:00
# Echo a message to stdout, and include the name of the script so that users
# can recognize the origin when this script is run as part of a larger build
# job.
function emsg {
echo " $0 : $@ "
}
# Echo a message to stderr, and include the string `error:` for users to easily
# find it via text search in a log.
function eerror {
echo " $0 : error: $@ " >& 2
}
2021-12-12 23:45:28 +00:00
zmodload zsh/zutil
autoload is-at-least
if ! is-at-least 5.8 ${ ZSH_VERSION } ; then
2021-12-18 03:24:43 +00:00
eerror " zsh 5.8 is required for the notarization script, but zsh version ${ ZSH_VERSION } was used. Please update to macOS 12 or higher, or install zsh 5.8 or higher and place it before the system zsh in your \$PATH. "
2021-12-12 23:45:28 +00:00
exit 1
fi
2021-12-15 05:01:28 +00:00
zparseopts -D -E -F - s:= signing_identity -signing-identity:= signing_identity a:= app_bundle_path -app-bundle-path:= app_bundle_path b:= binary_name -binary-name:= binary_name z:= zip_path -zip-path:= zip_path k:= notarization_keychain_profile -notarization-keychain-profile:= notarization_keychain_profile i:= apple_id -apple-id:= apple_id t:= team_id -team-id:= team_id || exit 1
2021-12-12 23:45:28 +00:00
end_opts = $@ [ ( i) ( --| -) ]
set -- " ${ @[0,end_opts-1] } " " ${ @[end_opts+1,-1] } "
DXX_SIGN_HAS_ERROR = 0
if [ [ -z " ${ signing_identity } " ] ] ; then
2021-12-18 03:23:37 +00:00
eerror "--signing-identity is required."
2021-12-12 23:45:28 +00:00
DXX_SIGN_HAS_ERROR = 1
fi
if [ [ -z " ${ app_bundle_path } " ] ] ; then
2021-12-18 03:23:37 +00:00
eerror "--app-bundle-path is required."
2021-12-12 23:45:28 +00:00
DXX_SIGN_HAS_ERROR = 1
elif [ [ ! -d " ${ app_bundle_path [2] } " ] ] ; then
2021-12-18 03:23:37 +00:00
eerror " App bundle specified in --app-bundle-path ( ${ app_bundle_path [2] } ) does not exist. "
2021-12-12 23:45:28 +00:00
DXX_SIGN_HAS_ERROR = 1
fi
2021-12-13 00:04:31 +00:00
if [ [ -z " ${ binary_name } " ] ] ; then
2021-12-18 03:23:37 +00:00
eerror "--binary-name is required."
2021-12-13 00:04:31 +00:00
DXX_SIGN_HAS_ERROR = 1
elif [ [ ! -f " ${ app_bundle_path [2] } /Contents/MacOS/ ${ binary_name [2] } " ] ] ; then
2021-12-18 03:23:37 +00:00
eerror " Binary specified in --binary-name ( ${ binary_name [2] } ) does not exist. "
2021-12-13 00:04:31 +00:00
DXX_SIGN_HAS_ERROR = 1
fi
2021-12-12 23:45:28 +00:00
if [ [ -z " ${ zip_path } " ] ] ; then
2021-12-18 03:23:37 +00:00
eerror "--zip-path is required."
2021-12-12 23:45:28 +00:00
DXX_SIGN_HAS_ERROR = 1
fi
if [ [ -z " ${ notarization_keychain_profile } " ] ] ; then
if [ [ -z " ${ apple_id } " || -z " ${ team_id } " ] ] ; then
2021-12-18 03:23:37 +00:00
eerror "If --notarization-keychain-profile is not provided, then both --apple-id and --team-id must be provided."
2021-12-12 23:45:28 +00:00
DXX_SIGN_HAS_ERROR = 1
fi
fi
if [ [ DXX_SIGN_HAS_ERROR -ne 0 ] ] ; then
2021-12-18 03:23:37 +00:00
# No message is needed here. A message was printed in the path(s) that set DXX_SIGN_HAS_ERROR.
2021-12-12 23:45:28 +00:00
exit 1
fi
if [ [ -d " ${ app_bundle_path [2] } /Contents/libs " ] ] ; then
DXX_DYLIB_PATH = " ${ app_bundle_path [2] } /Contents/libs "
else
2021-12-18 03:23:37 +00:00
# Unset this to prevent surprising results if the parent process set this in
# the environment.
2021-12-12 23:45:28 +00:00
unset DXX_DYLIB_PATH
fi
2021-12-13 00:04:31 +00:00
DXX_BINARY_PATH = " ${ app_bundle_path [2] } /Contents/MacOS/ ${ binary_name [2] } "
2021-12-12 23:45:28 +00:00
if [ [ ! -z " ${ DXX_DYLIB_PATH } " ] ] ; then
2021-12-18 03:23:37 +00:00
emsg " Signing dylibs at ${ DXX_DYLIB_PATH } with identity ${ signing_identity [2] } ... "
2021-12-12 23:45:28 +00:00
dxx_codesign " ${ DXX_DYLIB_PATH } " /*.dylib
if [ [ $? -ne 0 ] ] ; then
2021-12-18 03:23:37 +00:00
eerror " Failed to sign dylibs in ${ DXX_DYLIB_PATH } "
2021-12-12 23:45:28 +00:00
exit 1
fi
fi
2021-12-18 03:23:37 +00:00
emsg " Signing application binary at ${ DXX_BINARY_PATH } with identity ${ signing_identity [2] } ... "
2021-12-12 23:45:28 +00:00
2021-12-13 00:04:31 +00:00
dxx_codesign " ${ DXX_BINARY_PATH } "
2021-12-12 23:45:28 +00:00
if [ [ $? -ne 0 ] ] ; then
2021-12-18 03:23:37 +00:00
eerror " Failed to sign application binary ${ DXX_BINARY_PATH } "
2021-12-12 23:45:28 +00:00
exit 1
fi
2021-12-18 03:23:37 +00:00
emsg " Signing app bundle at ${ app_bundle_path [2] } with identity ${ signing_identity [2] } ... "
2021-12-12 23:45:28 +00:00
dxx_codesign " ${ app_bundle_path [2] } "
if [ [ $? -ne 0 ] ] ; then
2021-12-18 03:23:37 +00:00
eerror " Failed to sign app bundle ${ app_bundle_path [2] } "
2021-12-12 23:45:28 +00:00
exit 1
fi
DXX_ZIP_NAME = ${ zip_path [2]##*/ }
2021-12-13 00:49:27 +00:00
DXX_TMP_ZIP_PATH = " ${ TMPDIR } ${ DXX_ZIP_NAME } "
2021-12-12 23:45:28 +00:00
2021-12-18 03:23:37 +00:00
emsg " Compressing ${ app_bundle_path [2] } to temporary ZIP file at ${ DXX_TMP_ZIP_PATH } ... "
2021-12-12 23:45:28 +00:00
if [ [ -f " ${ DXX_TMP_ZIP_PATH } " ] ] ; then
rm -f " ${ DXX_TMP_ZIP_PATH } "
fi
if [ [ -f " ${ DXX_TMP_ZIP_PATH } " ] ] ; then
2021-12-18 03:23:37 +00:00
eerror " Unable to remove existing temporary ZIP file at ${ DXX_TMP_ZIP_PATH } "
2021-12-12 23:45:28 +00:00
exit 1
fi
/usr/bin/ditto -c -k --keepParent " ${ app_bundle_path [2] } " " ${ DXX_TMP_ZIP_PATH } "
if [ [ ! -f " ${ DXX_TMP_ZIP_PATH } " ] ] ; then
2021-12-18 03:23:37 +00:00
eerror "Error compressing app bundle to ZIP file."
2021-12-12 23:45:28 +00:00
exit 1
fi
2021-12-14 05:18:19 +00:00
# Note that the notarization process does NOT change the app bundle or the ZIP file.
# Instead, Apple reads the signature associated with the submitted resources and, if
# they don't detect any malicious code, create a ticket on their side that can be
# requested by a macOS client for the specific resource that was signed in order to
# validate that it went through the notarization process. This ticket can also be
# stapled to the app bundle for offline validation by macOS clients which are not
# connected to the Internet at the time. This stapling process happens further in
# the script.
2021-12-18 03:23:37 +00:00
emsg "Beginning notarization process. This may take a few minutes."
2021-12-12 23:45:28 +00:00
if [ [ -z " ${ notarization_keychain_profile } " ] ] ; then
2021-12-18 03:23:37 +00:00
emsg " Using Apple ID ' ${ apple_id [2] } ' and Apple team ID ' ${ team_id [2] } ' for notarization credentials. "
2021-12-15 05:01:28 +00:00
if [ [ ! -z " ${ DXX_NOTARIZATION_PASSWORD } " ] ] ; then
2021-12-18 03:23:37 +00:00
emsg "Using password passed in via DXX_NOTARIZATION_PASSWORD environment variable."
2021-12-15 05:01:28 +00:00
xcrun notarytool submit " ${ DXX_TMP_ZIP_PATH } " --apple-id " ${ apple_id [2] } " --team-id " ${ team_id [2] } " --password " ${ DXX_NOTARIZATION_PASSWORD } " --wait
2021-12-12 23:45:28 +00:00
if [ [ $? -ne 0 ] ] ; then
2021-12-18 03:23:37 +00:00
eerror "Error notarizing application. Check history for details."
2021-12-12 23:45:28 +00:00
exit 1
fi
else
2021-12-18 03:23:37 +00:00
emsg "Enter your application-specific password when prompted to submit for notarization."
2021-12-12 23:45:28 +00:00
xcrun notarytool submit " ${ DXX_TMP_ZIP_PATH } " --apple-id " ${ apple_id [2] } " --team-id " ${ team_id [2] } " --wait
if [ [ $? -ne 0 ] ] ; then
2021-12-18 03:23:37 +00:00
eerror "Error notarizing application. Check history for details."
2021-12-12 23:45:28 +00:00
exit 1
fi
fi
else
2021-12-18 03:23:37 +00:00
emsg " Using Keychain item specified in ' ${ notarization_keychain_profile [2] } ' for notarization credentials. "
2021-12-12 23:45:28 +00:00
xcrun notarytool submit " ${ DXX_TMP_ZIP_PATH } " --keychain-profile " ${ notarization_keychain_profile [2] } " --wait
if [ [ $? -ne 0 ] ] ; then
2021-12-18 03:23:37 +00:00
eerror "Error notarizing application. Check history for details."
2021-12-12 23:45:28 +00:00
exit 1
fi
fi
2021-12-18 03:23:37 +00:00
emsg " Stapling ticket to app bundle ${ app_bundle_path [2] } ... "
2021-12-12 23:45:28 +00:00
xcrun stapler staple " ${ app_bundle_path [2] } "
if [ [ $? -ne 0 ] ] ; then
2021-12-18 03:23:37 +00:00
eerror " Failed to staple ticket to app bundle ${ app_bundle_path [2] } "
2021-12-12 23:45:28 +00:00
exit 1
fi
rm -f " ${ DXX_TMP_ZIP_PATH } "
if [ [ -f " ${ zip_path [2] } " ] ] ; then
rm -f " ${ zip_path [2] } "
fi
if [ [ -f " ${ zip_path [2] } " ] ] ; then
2021-12-18 03:23:37 +00:00
eerror " Unable to remove existing target ZIP file at ${ zip_path [2] } "
2021-12-12 23:45:28 +00:00
exit 1
fi
2021-12-18 03:23:37 +00:00
emsg " Creating ${ zip_path [2] } ... "
2021-12-12 23:45:28 +00:00
/usr/bin/ditto -c -k --keepParent " ${ app_bundle_path [2] } " " ${ zip_path [2] } "