373 lines
9.6 KiB
Bash
Executable File
373 lines
9.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
export PATH=~/Library/Python/2.7/bin:$PATH
|
|
|
|
source $(dirname "$0")/notarization.sh
|
|
source $(dirname "$0")/packageDMG.sh
|
|
|
|
BOLD=$(tput bold)
|
|
NORMAL=$(tput sgr0)
|
|
|
|
#Unlock keychain
|
|
# $1 - Password
|
|
# $2 - Timeout
|
|
unlock_login_keychain() {
|
|
if [ -z "$1" ]; then
|
|
echo "Password parameter must be exists"
|
|
return 1
|
|
fi
|
|
local timeout=3600
|
|
if [ -n "$2" ]; then
|
|
timeout=$2
|
|
fi
|
|
|
|
security list-keychains -s ~/Library/Keychains/login.keychain-db
|
|
security unlock-keychain -p $1 ~/Library/Keychains/login.keychain-db
|
|
security set-keychain-settings -t $timeout -l ~/Library/Keychains/login.keychain-db
|
|
}
|
|
|
|
#Passed external variables
|
|
ARTIFACT_TYPE=$1
|
|
BUILD_CONDITIONS=$2
|
|
BUILD_TIMESTAMP=$3
|
|
|
|
#Cases for local and remote building
|
|
if [ -z "$BUILD_TIMESTAMP" ] && [ -n "${CI_JOB_ID}" ]; then
|
|
BUILD_TIMESTAMP="$BUILD_CONDITIONS"
|
|
BUILD_CONDITIONS=""
|
|
fi
|
|
|
|
# Detect configuration for building. By default - Release.
|
|
CONFIG="Release"
|
|
|
|
ROOT=$(pwd)
|
|
DEVELOPER_SIGNATURE="Developer ID Application: PRIVADO NETWORKS LLC (4D7YV49724)"
|
|
|
|
# Remove +x from Info.plist
|
|
#chmod a-x $ROOT/Vendors/openssl/openssl.framework/Versions/A/Resources/Info.plist
|
|
|
|
#Remove Delivered data
|
|
rm -rf ~/Library/Developer/Xcode/DerivedData
|
|
|
|
#------- Settings -------
|
|
|
|
cd $ROOT
|
|
|
|
RESULT_PATH=$ROOT/Result
|
|
APPLICATION_NAME=PrivadoVPN
|
|
DMG_PATH=$RESULT_PATH/$APPLICATION_NAME
|
|
DMG_FULL_PATH=$DMG_PATH.dmg
|
|
|
|
JOB_ID=$CI_JOB_ID
|
|
if [ -z "$JOB_ID" ]; then
|
|
JOB_ID=42
|
|
fi
|
|
DERIVED_PATH=$ROOT/Derived-$JOB_ID
|
|
|
|
BUILD_NUMBER=""
|
|
if [ -n "$CI_PIPELINE_ID" ]; then
|
|
BUILD_NUMBER="$CI_PIPELINE_ID"
|
|
else
|
|
BUILD_NUMBER=$(cat "./build")
|
|
fi
|
|
|
|
#Remove old results
|
|
rm -rf $RESULT_PATH
|
|
rm -rf $RESULT_PATH
|
|
mkdir -p $RESULT_PATH
|
|
|
|
#------- Build Launcher helper -------
|
|
|
|
echo "🕐 🛠 Build ${BOLD}Launcher${NORMAL} helper"
|
|
|
|
unlock_login_keychain "$K8S_SECRET_JARVIS"
|
|
|
|
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BUILD_NUMBER" ./macOS/Launcher/Info.plist
|
|
|
|
mkdir -p $DERIVED_PATH
|
|
|
|
#Build Launcher
|
|
xcodebuild \
|
|
-sdk macosx \
|
|
-project ./macOS/Launcher/Launcher.xcodeproj \
|
|
-scheme Launcher \
|
|
-configuration "$CONFIG" \
|
|
-derivedDataPath $DERIVED_PATH \
|
|
build | xcpretty
|
|
|
|
if [ "${PIPESTATUS[0]}" != "0" ]; then
|
|
echo >&2 "⛔️ 🛠 Error: xcodebuild Launcher failed";
|
|
exit 1
|
|
fi
|
|
|
|
rm -rf $DERIVED_PATH
|
|
|
|
echo "✅ 🛠 Build Launcher successed"
|
|
|
|
#------- Build Hive helper -------
|
|
|
|
echo "🕑 🛠 Build ${BOLD}Hive${NORMAL} helper"
|
|
|
|
unlock_login_keychain "$K8S_SECRET_JARVIS"
|
|
|
|
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BUILD_NUMBER" ./macOS/Hive/Info.plist
|
|
|
|
mkdir -p $DERIVED_PATH
|
|
|
|
#Build Hive
|
|
xcodebuild \
|
|
-sdk macosx \
|
|
-project ./macOS/Hive/Hive.xcodeproj \
|
|
-scheme io.privado.main.hive \
|
|
-configuration "$CONFIG" \
|
|
-derivedDataPath $DERIVED_PATH \
|
|
build | xcpretty
|
|
|
|
if [ "${PIPESTATUS[0]}" != "0" ]; then
|
|
echo >&2 "⛔️ 🛠 Error: xcodebuild Hive failed";
|
|
exit 1
|
|
fi
|
|
|
|
rm -rf $DERIVED_PATH
|
|
|
|
echo "✅ 🛠 Build Hive successed"
|
|
|
|
#------- Build Uninstaller helper -------
|
|
|
|
echo "🕒 🛠 Build ${BOLD}Uninstaller${NORMAL} helper"
|
|
|
|
unlock_login_keychain "$K8S_SECRET_JARVIS"
|
|
|
|
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BUILD_NUMBER" ./macOS/Uninstaller/Info.plist
|
|
|
|
mkdir -p $DERIVED_PATH
|
|
|
|
#Build Uninstaller
|
|
xcodebuild \
|
|
-sdk macosx \
|
|
-project ./macOS/Uninstaller/Uninstaller.xcodeproj \
|
|
-scheme io.privado.main.uninstaller \
|
|
-configuration "$CONFIG" \
|
|
-derivedDataPath $DERIVED_PATH \
|
|
build | xcpretty
|
|
|
|
if [ "${PIPESTATUS[0]}" != "0" ]; then
|
|
echo >&2 "⛔️ 🛠 Error: xcodebuild Uninstaller failed";
|
|
exit 1
|
|
fi
|
|
|
|
rm -rf $DERIVED_PATH
|
|
|
|
echo "✅ 🛠 Build Uninstaller successed"
|
|
|
|
#------- Build Privado Application -------
|
|
|
|
echo "🕓 🛠 Build ${BOLD}Privado${NORMAL} Application"
|
|
|
|
echo "Current directory is: $(pwd)"
|
|
|
|
unlock_login_keychain "$K8S_SECRET_JARVIS"
|
|
|
|
#Change build date
|
|
/usr/libexec/PlistBuddy -c "Set :PRIVADO_BUILD_TIMESTAMP $(date +%F)" ./macOS/Privado/Info.plist
|
|
|
|
#Build Application
|
|
|
|
gcc_preprocessor='${inherited}'
|
|
swift_compilation='${inherited}'
|
|
if [ -n "$BUILD_CONDITIONS" ]; then
|
|
gcc_preprocessor="$gcc_preprocessor $BUILD_CONDITIONS"
|
|
swift_compilation="$swift_compilation $BUILD_CONDITIONS"
|
|
fi
|
|
|
|
if [ "$ARTIFACT_TYPE" != "Production" ]; then
|
|
gcc_preprocessor="$gcc_preprocessor INTERNAL $ARTIFACT_TYPE"
|
|
swift_compilation="$swift_compilation INTERNAL $ARTIFACT_TYPE"
|
|
fi
|
|
|
|
mkdir -p $DERIVED_PATH
|
|
|
|
xcodebuild \
|
|
-sdk macosx \
|
|
-project ./macOS/Privado/Privado.xcodeproj \
|
|
-scheme PrivadoVPN \
|
|
-configuration "$CONFIG" \
|
|
-archivePath $RESULT_PATH/$APPLICATION_NAME \
|
|
-derivedDataPath $DERIVED_PATH \
|
|
archive \
|
|
GCC_PREPROCESSOR_DEFINITIONS="$gcc_preprocessor" \
|
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS="$swift_compilation" | xcpretty
|
|
|
|
if [ "${PIPESTATUS[0]}" != "0" ]; then
|
|
echo >&2 "⛔️ 🛠 Error: xcodebuild Privado failed";
|
|
exit 1
|
|
fi
|
|
|
|
rm -rf $DERIVED_PATH
|
|
|
|
echo "✅ 🛠 Build Privado successed"
|
|
|
|
unlock_login_keychain "$K8S_SECRET_JARVIS"
|
|
|
|
#Archieve app with signing
|
|
echo "🕔 🗜 Archive Privado application"
|
|
|
|
xcodebuild \
|
|
-exportArchive \
|
|
-archivePath $RESULT_PATH/$APPLICATION_NAME.xcarchive \
|
|
-exportPath $RESULT_PATH/Result \
|
|
-exportOptionsPlist ./BuildTools/Privado-macOS-ExportOptions.plist | xcpretty
|
|
|
|
if [ "${PIPESTATUS[0]}" != "0" ]; then
|
|
echo >&2 "⛔️ 🗜 Error: archieve failed";
|
|
exit 1
|
|
fi
|
|
|
|
echo "✅ 🗜 Archieve application successed"
|
|
|
|
#------- Prepare dSYMs -------
|
|
|
|
echo "🕕 🔎 Prepare dSYMs for debug"
|
|
|
|
#Create folder with dSYMs and copy there all required dsyms. In next step we upload it to Sentry
|
|
DSYMS_PATH=$RESULT_PATH/${APPLICATION_NAME}_dSYM
|
|
mkdir -p $DSYMS_PATH
|
|
|
|
#zip -vr $DSYMS_PATH/Launcher.app.dSYM.zip $RESULT_PATH/$APPLICATION_NAME.xcarchive/dSYMs/Launcher.app.dSYM
|
|
#zip -vr $DSYMS_PATH/openvpn.appex.dSYM.zip $RESULT_PATH/Privado.xcarchive/dSYMs/openvpn.appex.dSYM
|
|
zip -vr $DSYMS_PATH/$APPLICATION_NAME.app.dSYM.zip $RESULT_PATH/$APPLICATION_NAME.xcarchive/dSYMs/PrivadoVPN.app.dSYM
|
|
#zip -vr $DSYMS_PATH/TunnelKit.framework.dSYM.zip $RESULT_PATH/Privado.xcarchive/dSYMs/TunnelKit.framework.dSYM
|
|
#zip -vr $DSYMS_PATH/Sentry.framework.dSYM.zip ./Vendors/Sentry/Sentry.framework.dSYM
|
|
zip -vr $DSYMS_PATH/Sparkle.framework.dSYM.zip $RESULT_PATH/$APPLICATION_NAME.xcarchive/dSYMs/Sparkle.framework.dSYM
|
|
|
|
#------- Create DMG and sign it -------
|
|
|
|
echo "🕖 🍎 ${BOLD}Create DMG${NORMAL}"
|
|
|
|
#Prepare for creating DMG
|
|
packageDMG \
|
|
$DMG_PATH \
|
|
$DMG_FULL_PATH \
|
|
$RESULT_PATH/Result/$APPLICATION_NAME.app \
|
|
"$APPLICATION_NAME" \
|
|
"PrivadoVPN" \
|
|
$(dirname "$0")/installer/background.png \
|
|
$(dirname "$0")/installer/1024x1024.png
|
|
|
|
if [ "$?" != "0" ]; then
|
|
echo >&2 "⛔️ 🍎 Error: create DMG failed";
|
|
exit 1
|
|
fi
|
|
|
|
echo "✅ 🍎 Create DMG successed"
|
|
|
|
#Sign
|
|
|
|
echo "🕗 🍎 ${BOLD}Sign DMG${NORMAL}"
|
|
|
|
codesign -s "${DEVELOPER_SIGNATURE}" $DMG_FULL_PATH
|
|
|
|
if [ "$?" != "0" ]; then
|
|
echo >&2 "⛔️ 🍎 Error: codesign failed";
|
|
exit 1
|
|
fi
|
|
|
|
echo "✅ 🍎 Sign DMG successed"
|
|
|
|
#-------Notarisation-------
|
|
|
|
echo "🕘 🍏 ${BOLD}Notarisation${NORMAL}"
|
|
|
|
appleNotarization $DMG_FULL_PATH $K8S_SECRET_NOTARIZATION
|
|
|
|
if [ "$?" != "0" ]; then
|
|
echo >&2 "⛔️ 🍏 Error: Notarisation failed";
|
|
exit 1
|
|
fi
|
|
|
|
#Check signing!
|
|
spctl -a -t open --context context:primary-signature -v $DMG_FULL_PATH
|
|
|
|
echo "🕙 ♻️ Upload to Sentry"
|
|
|
|
#upload to Sentry --log-level debug \
|
|
TOKEN=ecd2667998c54ea9b8dd1fc640b54549aa09c161b53d4e6f96de4761682f366e
|
|
|
|
sentry-cli --url https://sentry.privado.io/ --auth-token $TOKEN upload-dsym $DSYMS_PATH --org sentry --project macos
|
|
|
|
echo "✅ ♻️ Upload to Sentry successed"
|
|
|
|
# Prevent create Update pachage for local building
|
|
if [ "${CI_JOB_ID}" == "" ]; then
|
|
echo "❌ Do nothing on local build"
|
|
exit 1
|
|
fi
|
|
|
|
#-------Update Bundle creation-------
|
|
|
|
echo "🕚 🔝 Generate files for ${BOLD}updater${NORMAL}"
|
|
|
|
# Generate and upload update
|
|
if [ "$ARTIFACT_TYPE" == "Production" ]; then
|
|
UPDATE_PATH=$ROOT/Update
|
|
UPDATE_HTML=$UPDATE_PATH/$APPLICATION_NAME.html
|
|
else
|
|
UPDATE_PATH=$ROOT/$ARTIFACT_TYPE/Update
|
|
UPDATE_HTML=$UPDATE_PATH/$ARTIFACT_TYPE.html
|
|
fi
|
|
|
|
APPCAST=$UPDATE_PATH/appcast.xml
|
|
|
|
rm -rf $UPDATE_PATH
|
|
rm -rf $UPDATE_PATH
|
|
|
|
mkdir -p $UPDATE_PATH
|
|
#
|
|
KEY_PATH=""
|
|
if [ -n "$BUILD_CONDITIONS" ] && [ -n "$CI_COMMIT_TAG" ]; then
|
|
KEY_PATH="Production"
|
|
else
|
|
KEY_PATH="Release"
|
|
fi
|
|
|
|
cp $ROOT/ReleaseNotes/$KEY_PATH.html $UPDATE_HTML
|
|
cp $DMG_FULL_PATH $UPDATE_PATH
|
|
|
|
#if not production, then rename dmg filename
|
|
if [ "$ARTIFACT_TYPE" != "Production" ]; then
|
|
|
|
# Add extended log to updater's html
|
|
$(dirname "$0")/notes.swift path=$UPDATE_HTML
|
|
|
|
mv $UPDATE_PATH/$APPLICATION_NAME.dmg $UPDATE_PATH/$ARTIFACT_TYPE$BUILD_TIMESTAMP.dmg
|
|
mv $UPDATE_PATH/$ARTIFACT_TYPE.html $UPDATE_PATH/$ARTIFACT_TYPE$BUILD_TIMESTAMP.html
|
|
fi
|
|
|
|
#echo "✅ Build completed"
|
|
#exit 0
|
|
|
|
# Generate Sparkle appcast for updater
|
|
|
|
#$ROOT/Vendors/Sparkle/bin/generate_appcast $UPDATE_PATH -f $ROOT/BuildTools/$KEY_PATH/dsa_priv.pem
|
|
$ROOT/Vendors/Sparkle/bin/generate_appcast $UPDATE_PATH
|
|
|
|
if [ "$?" != "0" ]; then
|
|
echo >&2 "⛔️ 🔝 Error: generate_appcast";
|
|
exit 1
|
|
fi
|
|
|
|
rm -rf $UPDATE_PATH/.tmp
|
|
|
|
#Upload to production ONLY when build from master and production build
|
|
if [ -n "$CI_COMMIT_TAG" ] && [ "$KEY_PATH" == "Production" ] && [ "$ARTIFACT_TYPE" == "Production" ]; then
|
|
sed -i ".bak" 's#PrivadoVPN.html#https://privadovpn.com/apps/osx/PrivadoVPN.html#g' $APPCAST
|
|
sed -i ".bak" 's#PrivadoVPN.dmg#https://privadovpn.com/apps/osx/PrivadoVPN.dmg#g' $APPCAST
|
|
else
|
|
sed -i ".bak" "s#$ARTIFACT_TYPE$BUILD_TIMESTAM.html#https://privado.dev/apps/osx/$ARTIFACT_TYPE/$ARTIFACT_TYPE$BUILD_TIMESTAM.html#g" $APPCAST
|
|
sed -i ".bak" "s#$ARTIFACT_TYPE$BUILD_TIMESTAMP.dmg#https://privado.dev/apps/osx/$ARTIFACT_TYPE/$ARTIFACT_TYPE$BUILD_TIMESTAMP.dmg#g" $APPCAST
|
|
fi
|
|
|
|
rm -rf $APPCAST.bak
|
|
|
|
echo "✅ Build completed"
|