Skip to content

Commit

Permalink
Modernized build script
Browse files Browse the repository at this point in the history
  • Loading branch information
ygini committed Apr 12, 2023
1 parent 66815c6 commit 6644a80
Showing 1 changed file with 52 additions and 150 deletions.
202 changes: 52 additions & 150 deletions package/BuildAndPackage.command
Original file line number Diff line number Diff line change
@@ -1,135 +1,22 @@
#!/bin/bash

CONFIGURATION="Release"
# Use the CUSTOM_ prefixed values to overload the default value of this script.
# CUSTOM_DEVELOPER_ID_INSTALLER for the Installer certificate name used by codesign
# CUSTOM_DEVELOPER_ID_APP for the App certificate name used by codesign
# CUSTOM_NOTARIZATION_KEYCHAIN_PROFILE for the stored credential needed for notarytool
# Use xcrun notarytool store-credentials to store a credentials for notarization

DEFAULT_DEVELOPER_ID_INSTALLER="Developer ID Installer: Yoann GINI (CRXPBZF3N4)"
DEFAULT_DEVELOPER_ID_APP="Developer ID Application: Yoann GINI (CRXPBZF3N4)"
DEFAULT_NOTARIZATION_KEYCHAIN_PROFILE="[email protected]"

DEVELOPER_ID_INSTALLER=${CUSTOM_DEVELOPER_ID_INSTALLER:-${DEFAULT_DEVELOPER_ID_INSTALLER}}
DEVELOPER_ID_APP=${CUSTOM_DEVELOPER_ID_APP:-${DEFAULT_DEVELOPER_ID_APP}}

NOTARIZATION_DEFAULT_DEVELOPER_ID_LOGIN="[email protected]"
NOTARIZATION_DEVELOPER_ID_LOGIN=${NOTARIZATION_CUSTOM_DEVELOPER_ID_LOGIN:-${NOTARIZATION_DEFAULT_DEVELOPER_ID_LOGIN}}

# Use app-specific password, you can create one at appleid.apple.com
NOTARIZATION_DEFAULT_DEVELOPER_ID_PASSWORD="@keychain:altool-credentials"
NOTARIZATION_DEVELOPER_ID_PASSWORD=${NOTARIZATION_CUSTOM_DEVELOPER_ID_PASSWORD:-${NOTARIZATION_DEFAULT_DEVELOPER_ID_PASSWORD}}

function showNotarizationErrors {
NOTARIZATION_FILE="$1"
i=0
while true
do
NOTARIZATION_ERROR_MESSAGE=$(/usr/libexec/PlistBuddy -c "Print :product-errors:$i:message" "${NOTARIZATION_FILE}" 2>/dev/null)
if [ $? -ne 0 ]
then
break
fi

echo "#### NOTARIZATION ERROR ####"
echo "Last status: ${NOTARIZATION_STATUS}"
echo "${NOTARIZATION_ERROR_MESSAGE}"

i=$(($i + 1))
done
}

function notarizePayloadWithBundleID {
NOTARIZATION_PAYLOAD_PATH="$1"
NOTARIZATION_BUNDLE_ID="$2"
NOTARIZATION_TMP_DIR="$(mktemp -d)"

echo "####### Notarize distribution package"
echo "Working directory in ${NOTARIZATION_TMP_DIR}"
echo "### Requesting notarization"
xcrun altool --notarize-app --primary-bundle-id "${NOTARIZATION_BUNDLE_ID}" -u "${NOTARIZATION_DEVELOPER_ID_LOGIN}" -p "${NOTARIZATION_DEVELOPER_ID_PASSWORD}" -f "${NOTARIZATION_PAYLOAD_PATH}" --output-format xml > "${NOTARIZATION_TMP_DIR}/notarize-app.plist"

if [ $? -ne 0 ]
then
showNotarizationErrors "${NOTARIZATION_TMP_DIR}/notarize-app.plist"
exit $LINENO
fi

NOTARIZATION_UUID=$(/usr/libexec/PlistBuddy -c "Print :notarization-upload:RequestUUID" "${NOTARIZATION_TMP_DIR}/notarize-app.plist" 2>/dev/null)

echo "Notarization request UUID is ${NOTARIZATION_UUID}"

if [ -z "{NOTARIZATION_UUID}" ]
then
echo "#### NOTARIZATION ERROR ####"
echo "No UUID returned"
showNotarizationErrors "${NOTARIZATION_TMP_DIR}/notarize-app.plist"
exit $LINENO
fi

NOTARIZATION_STATUS="in progress"
echo "### Wait for notarization to complete"
sleep 10
while [ "${NOTARIZATION_STATUS}" != "success" ]
do
xcrun altool --notarization-info "${NOTARIZATION_UUID}" -u "${NOTARIZATION_DEVELOPER_ID_LOGIN}" -p "${NOTARIZATION_DEVELOPER_ID_PASSWORD}" --output-format xml > "${NOTARIZATION_TMP_DIR}/notarization-info.plist"
NOTARIZATION_STATUS=$(/usr/libexec/PlistBuddy -c "Print :notarization-info:Status" "${NOTARIZATION_TMP_DIR}/notarization-info.plist" 2>/dev/null)

echo "Current notarization status: '${NOTARIZATION_STATUS}'"

if [ "${NOTARIZATION_STATUS}" == "in progress" ]
then
sleep 10
elif [ "${NOTARIZATION_STATUS}" == "" ]
then
echo "No status found for request ${NOTARIZATION_UUID}"
$(/usr/libexec/PlistBuddy -c "Print :product-errors:$i:message" "${NOTARIZATION_TMP_DIR}/notarization-info.plist" 2>/dev/null)
echo "Some delay in the API processing may exist"
sleep 20
elif [ "${NOTARIZATION_STATUS}" != "success" ]
then
showNotarizationErrors "${NOTARIZATION_TMP_DIR}/notarization-info.plist"
exit $LINENO
fi
done

echo ""

NOTARIZATION_LOG_URL=$(/usr/libexec/PlistBuddy -c "Print :notarization-info:LogFileURL" "${NOTARIZATION_TMP_DIR}/notarization-info.plist" 2>/dev/null)

if [ -z "$(command -v jq)" ]
then
echo "Notarization logs available here: ${NOTARIZATION_LOG_URL}"
else
curl -s "${NOTARIZATION_LOG_URL}" > "${NOTARIZATION_TMP_DIR}/notarization-logs.json"

while read issue
do
NOTARIZATION_LOG_MESSAGE=$(echo "$issue" | jq ".message" )
NOTARIZATION_LOG_SEVERITY=$(echo "$issue" | jq ".severity" )
NOTARIZATION_LOG_PATH=$(echo "$issue" | jq ".path" )
NOTARIZATION_LOG_DOCURL=$(echo "$issue" | jq ".docUrl" )

echo "### Issue from notarization log:"
echo "Severity: ${NOTARIZATION_LOG_SEVERITY}"
echo "About: ${NOTARIZATION_LOG_PATH}"
echo ""
echo "${NOTARIZATION_LOG_MESSAGE}"
echo ""
if [ "${NOTARIZATION_LOG_DOCURL}" != "null" ]
then
echo "You should read ${NOTARIZATION_LOG_DOCURL}"
fi
done < <(cat "${NOTARIZATION_TMP_DIR}/notarization-logs.json" | jq -c ".issues[]")
fi

if [ "${NOTARIZATION_STATUS}" == "success" ]
then
echo "### Staple the distribution package"
xcrun stapler staple "${NOTARIZATION_PAYLOAD_PATH}"
else
showNotarizationErrors "${NOTARIZATION_TMP_DIR}/notarization-info.plist"
exit $LINENO
fi

rm -rf "${NOTARIZATION_TMP_DIR}"
}
NOTARIZATION_KEYCHAIN_PROFILE=${CUSTOM_NOTARIZATION_KEYCHAIN_PROFILE:-${DEFAULT_NOTARIZATION_KEYCHAIN_PROFILE}}

echo "Packaging will use ${DEVELOPER_ID_INSTALLER}"
echo "Apps will use ${DEFAULT_DEVELOPER_ID_APP}"
echo "Notarization will use ${NOTARIZATION_KEYCHAIN_PROFILE}"

cd "$(dirname "${BASH_SOURCE[0]}")"

Expand All @@ -141,16 +28,18 @@ cd "${GIT_ROOT_DIR}"

CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)

CONFIGURATION="Debug"

if [[ "$CURRENT_BRANCH" == "master" ]]
then
CONFIGURATION="Release"
elif [[ "$CURRENT_BRANCH" == release* ]]
then
CONFIGURATION="Release"
else
CONFIGURATION="Debug"
fi

MARKETING_VERSION=$(sed -n '/MARKETING_VERSION/{s/MARKETING_VERSION = //;s/;//;s/^[[:space:]]*//;p;q;}' "${PROJECT_DIR}/Hello-IT.xcconfig")

UNCOMMITED_CHANGE=$(git status -s | wc -l | bc)

if [ -z $FORCE_SKIP_REPO_STATE ]
Expand All @@ -163,23 +52,21 @@ then
echo "a development branch."
exit $LINENO
fi
fi

MARKETING_VERSION=$(sed -n '/MARKETING_VERSION/{s/MARKETING_VERSION = //;s/;//;s/^[[:space:]]*//;p;q;}' "${PROJECT_DIR}/Hello-IT.xcconfig")

if [[ "$CURRENT_BRANCH" == release* ]]
then
CONFIGURATION="Release"
VERSION_FROM_BRANCH=$(echo "${CURRENT_BRANCH}" | awk -F'/' '{print $2}')
if [[ "$VERSION_FROM_BRANCH" =~ ^[0-9]+\.[0-9]+ ]]
then
MARKETING_VERSION=$VERSION_FROM_BRANCH
sed -i '' "/MARKETING_VERSION/c\\
MARKETING_VERSION = ${MARKETING_VERSION}
" "${PROJECT_DIR}/Hello-IT.xcconfig"
git add "${PROJECT_DIR}/Hello-IT.xcconfig"
git commit -m "Update marketing version number according to release branch"
fi

if [[ "$CURRENT_BRANCH" == release* ]]
then
CONFIGURATION="Release"
VERSION_FROM_BRANCH=$(echo "${CURRENT_BRANCH}" | awk -F'/' '{print $2}')
if [[ "$VERSION_FROM_BRANCH" =~ ^[0-9]+\.[0-9]+ ]]
then
MARKETING_VERSION=$VERSION_FROM_BRANCH
sed -i '' "/MARKETING_VERSION/c\\
MARKETING_VERSION = ${MARKETING_VERSION}
" "${PROJECT_DIR}/Hello-IT.xcconfig"
git add "${PROJECT_DIR}/Hello-IT.xcconfig"
git commit -m "Update marketing version number according to release branch"
fi
fi
fi

"${PROJECT_DIR}/.BuildVersion.sh"
Expand Down Expand Up @@ -208,9 +95,14 @@ echo "Release location: ${RELEASE_LOCATION}"

echo "####### Build project"

echo "### Start building Hello IT"

echo "### Start building Hello IT SDK"
xcodebuild -UseModernBuildSystem=NO -arch x86_64 -arch arm64 ONLY_ACTIVE_ARCH=NO -quiet -project "${PROJECT_DIR}/HITDevKit/HITDevKit.xcodeproj" -configuration ${CONFIGURATION} -target "HITDevKit" CONFIGURATION_TEMP_DIR="${BUILT_PRODUCTS_DIR}/Intermediates" CONFIGURATION_BUILD_DIR="${BUILT_PRODUCTS_DIR}/Products" DWARF_DSYM_FOLDER_PATH="${BUILT_PRODUCTS_DIR}/dSYM" OTHER_CODE_SIGN_FLAGS="--timestamp"
if [[ $? != 0 ]]; then
echo "Building failed"
exit 1
fi

echo "### Start building Hello IT app and plugins"
xcodebuild -UseModernBuildSystem=NO -arch x86_64 -arch arm64 ONLY_ACTIVE_ARCH=NO -quiet -project "${PROJECT_DIR}/Hello IT.xcodeproj" -configuration ${CONFIGURATION} -target "Hello IT" CONFIGURATION_TEMP_DIR="${BUILT_PRODUCTS_DIR}/Intermediates" CONFIGURATION_BUILD_DIR="${BUILT_PRODUCTS_DIR}/Products" DWARF_DSYM_FOLDER_PATH="${BUILT_PRODUCTS_DIR}/dSYM" OTHER_CODE_SIGN_FLAGS="--timestamp"

if [[ $? != 0 ]]; then
Expand All @@ -222,6 +114,11 @@ cp -a "${BUILT_PRODUCTS_DIR}/Products/Hello IT.app" "${RELEASE_PRODUCT_LOCATION}

codesign --deep --force --verbose --timestamp --options runtime --sign "${DEVELOPER_ID_APP}" "${RELEASE_PRODUCT_LOCATION}/Hello IT.app"

if [[ $? != 0 ]]; then
echo "Code signature failed"
exit 1
fi

echo ""
echo ""

Expand All @@ -230,7 +127,7 @@ cp -a "${BUILT_PRODUCTS_DIR}/dSYM" "${RELEASE_DSYM_LOCATION}"

echo "####### Create package from build"

mkdir -p "${PKG_ROOT}//Applications/Utilities"
mkdir -p "${PKG_ROOT}/Applications/Utilities"
cp -a "${RELEASE_PRODUCT_LOCATION}/Hello IT.app" "${PKG_ROOT}/Applications/Utilities"

mkdir -p "${PKG_ROOT}/Library/Application Support/com.github.ygini.hello-it/CustomImageForItem"
Expand All @@ -240,13 +137,11 @@ cp -a "${PROJECT_DIR}/Plugins/ScriptedItem/CustomScripts" "${PKG_ROOT}/Library/A
mkdir -p "${PKG_ROOT}/Library/LaunchAgents"
cp -a "${GIT_ROOT_DIR}/package/LaunchAgents/com.github.ygini.hello-it.plist" "${PKG_ROOT}/Library/LaunchAgents"

#sudo chown -R root:wheel "${PKG_ROOT}"

PBK_BUILD_COMPONENT="${BUILT_PRODUCTS_DIR}/components.plist"
pkgbuild --analyze --root "${PKG_ROOT}" "${PBK_BUILD_COMPONENT}"

/usr/libexec/PlistBuddy -c "Set 0:BundleIsRelocatable bool false" "${PBK_BUILD_COMPONENT}"
#/usr/libexec/PlistBuddy -c "Print" "${PBK_BUILD_COMPONENT}"

pkgbuild --component-plist "${PBK_BUILD_COMPONENT}" --sign "${DEVELOPER_ID_INSTALLER}" --root "${PKG_ROOT}" --scripts "${GIT_ROOT_DIR}/package/pkg_scripts" --identifier "com.github.ygini.hello-it" --version "${MARKETING_VERSION}" "${RELEASE_LOCATION}/Hello-IT-${MARKETING_VERSION}-${CONFIGURATION}.pkg"

productbuild --product "${GIT_ROOT_DIR}/package/requirements.plist" --sign "${DEVELOPER_ID_INSTALLER}" --version "${MARKETING_VERSION}" --package "${RELEASE_LOCATION}/Hello-IT-${MARKETING_VERSION}-${CONFIGURATION}.pkg" "${RELEASE_LOCATION}/Hello-IT-${MARKETING_VERSION}-${CONFIGURATION}-Distribution.pkg"
Expand All @@ -258,12 +153,19 @@ fi

rm "${RELEASE_LOCATION}/Hello-IT-${MARKETING_VERSION}-${CONFIGURATION}.pkg"

notarizePayloadWithBundleID "${RELEASE_LOCATION}/Hello-IT-${MARKETING_VERSION}-${CONFIGURATION}-Distribution.pkg" "com.github.ygini.hello-it"
xcrun notarytool submit "${RELEASE_LOCATION}/Hello-IT-${MARKETING_VERSION}-${CONFIGURATION}-Distribution.pkg" --keychain-profile "${NOTARIZATION_KEYCHAIN_PROFILE}" --wait

rm -rf "${PKG_ROOT}"
if [[ $? != 0 ]]; then
echo "Notarization failed, run the following command with the appropriate UUID"
echo " xcrun notarytool log <UUID> --keychain-profile \"${NOTARIZATION_KEYCHAIN_PROFILE}\""
exit 1
fi

xcrun stapler staple "${RELEASE_LOCATION}/Hello-IT-${MARKETING_VERSION}-${CONFIGURATION}-Distribution.pkg"

echo "####### Cleaning temporary files"

rm -rf "${PKG_ROOT}"
rm -rf "${BUILT_PRODUCTS_DIR}"

exit 0

0 comments on commit 6644a80

Please sign in to comment.