Last active
June 1, 2021 05:40
-
-
Save aparajita/3194e0ce1a01b6fe7d74c33c9578927e to your computer and use it in GitHub Desktop.
Script to notarize a 4D plugin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# | |
# $1 - Source plugin path, must be on a local filesystem | |
# | |
# DEPENDENCIES | |
# | |
# This script relies on jq, a JSON parser. You can download | |
# it at https://stedolan.github.io/jq, or install via package | |
# managers such as brew or apt. | |
# | |
# | |
# HOW TO USE | |
# | |
# To use this script, you need to set three environment variables. | |
# The easiest way to do this is to export them from .bashrc or .zshrc, | |
# depending on which shell you use. Add these three lines to your | |
# shell's rc file (without the leading #): | |
# | |
# export AC_USER= | |
# export AC_PASSWORD= | |
# export AC_PROVIDER= | |
# | |
# Now you will set the values after "=". | |
# | |
# AC_USER | |
# Your App Store Connect username, usually your Apple ID email address. | |
# | |
# AC_PASSWORD | |
# The password to your App Store Connect account. Note that you must create | |
# an app-specific password to use with this script: | |
# | |
# - Log in to appleid.apple.com | |
# - Click "Generate Password..." under "APP-SPECIFIC PASSWORDS" in the | |
# - Enter "codesign" | |
# - Copy the generated password | |
# - Open a terminal and execute this (<user> is the value you use | |
# for AC_USER, <password> is the copied password): | |
# | |
# xcrun altool --store-password-in-keychain-item codesign \ | |
# -u "<user>" -p "<password>" | |
# | |
# Once you have done all this, set the value of AC_PASSWORD to | |
# @keychain:codesign. Then reload your shell so AC_USER and AC_PASSWORD are | |
# available globally. | |
# | |
# AC_PROVIDER | |
# If you are not part of multiple teams in App Store Connect, ignore this. | |
# | |
# If you are part of multiple teams in App Store Connect, you must tell | |
# Apple under which team (provider) you are signing a plugin. To get the correct | |
# value to use, open a terminal and execute: | |
# | |
# xcrun altool --list-providers -u "$AC_USER" -p "$AC_PASSWORD" | |
# | |
# You will get a list of the teams (providers) you belong to. Copy the value | |
# in the ProviderShortName (NOT ProviderName) column for the team you want to | |
# sign your plugin under. Then set the value of AC_PROVIDER to the value you | |
# just copied and reload your shell. | |
# | |
# Setup | |
# | |
RED='\033[00;31m' | |
GREEN='\033[00;32m' | |
END='\033[0m' | |
notify() { | |
echo -e "${GREEN}${1}${END}" | |
} | |
fail() { | |
echo -e "${RED}${1}${END}" | |
exit 1 | |
} | |
pluginPath="$1" | |
# If pluginPath is a symbolic link, resolve it | |
if [ -L "$pluginPath" ]; then | |
pluginPath=$(readlink "$pluginPath") | |
notify "* Resolved path to:" | |
echo -e "$pluginPath\n" | |
fi | |
bundleName=$(basename "$pluginPath") | |
pluginName=${bundleName%.bundle} | |
# | |
# Sign the plugin bundle | |
# | |
identity=$(security find-identity -p codesigning -v | egrep 'Developer ID Application[^"]+' -o) | |
notify "* Signing $bundleName...\n" | |
xattr -cr "$pluginPath" | |
codesign --verbose --deep --timestamp --force --sign "$identity" "$pluginPath" | |
notify "\n* Checking signature...\n" | |
if ! codesign --verify --verbose=2 --deep --strict "$pluginPath"; then | |
exit $? | |
fi | |
if ! check-signature "$pluginPath"; then | |
exit $? | |
fi | |
# | |
# Make a zip for submission | |
# | |
tempDir=$(mktemp -d "/tmp/$pluginName.XXXX" || fail "Could not create temp dir for zip") | |
zipPath="$tempDir/$pluginName.zip" | |
notify "\n* Creating zip..." | |
ditto -c -k --keepParent "$pluginPath" "$zipPath" || rm -rf "$tempDir" | |
notify "* zip created at $zipPath" | |
# | |
# Submit the zip | |
# | |
notify "* Submitting zip...\n" | |
dateTime=$(date "+%Y%m%d%H%M%S") | |
bundleId=$(plutil -convert json -r -o - -- "$pluginPath"/Contents/Info.plist | grep CFBundleIdentifier | awk -F ' : ' '{ print $2 }' | tr -d '",') | |
if [[ -n "$AC_PROVIDER" ]]; then | |
provider="--asc-provider $AC_PROVIDER" | |
else | |
provider="" | |
fi | |
notarizeResponse=$(xcrun altool --notarize-app \ | |
--file "$zipPath" \ | |
--primary-bundle-id "$bundleId.$dateTime" \ | |
--username "$AC_USER" \ | |
--password "$AC_PASSWORD" \ | |
--output-format json \ | |
$provider) | |
uuid=$(echo "$notarizeResponse" | jq -M '."notarization-upload".RequestUUID' | tr -d '"') | |
echo "uuid = $uuid" | |
rm -rf "$tempDir" | |
notify "\n* Deleted zip" | |
notify "\n* Waiting for result of notarization..." | |
statusResponse="" | |
until [[ "$statusResponse" == "success" ]]; do | |
sleep 30 | |
statusResponse=$(xcrun altool --notarization-info "$uuid" \ | |
--username "$AC_USER" \ | |
--password "$AC_PASSWORD" \ | |
--asc-provider "$AC_PROVIDER" \ | |
--output-format json \ | |
| jq -M '."notarization-info".Status' \ | |
| tr -d '"') | |
echo "$(date "+%H:%M:%S") $statusResponse" | |
done | |
notify "\n* Plugin notarized, stapling...\n" | |
xcrun stapler staple "$pluginPath" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment