#!/bin/bash set -e build_flag="--release" target_dir="release" open_result=false local_arch=false local_only=false overwrite_local_app=false bundle_name="" # Function for displaying help info help_info() { echo " Usage: ${0##*/} [options] [bundle_name] Build the application bundle. Options: -d Compile in debug mode -l Compile for local architecture and copy bundle to /Applications, implies -d. -o Open the resulting DMG or the app itself in local mode. -f Overwrite the local app bundle if it exists. -h Display this help and exit. " } # If -o option is specified, the folder of the resulting dmg will be opened in finder # If -d is specified, Zed will be compiled in debug mode and the application's path printed # If -od or -do is specified Zed will be bundled in debug and the application will be run. while getopts 'dlfoh' flag do case "${flag}" in o) open_result=true;; d) export CARGO_INCREMENTAL=true export CARGO_BUNDLE_SKIP_BUILD=true build_flag=""; local_arch=true target_dir="debug" ;; l) export CARGO_INCREMENTAL=true export CARGO_BUNDLE_SKIP_BUILD=true build_flag="" local_arch=true local_only=true target_dir="debug" ;; f) overwrite_local_app=true;; h) help_info exit 0 ;; esac done shift $((OPTIND-1)) if [ "$1" ]; then bundle_name=$1 fi export ZED_BUNDLE=true export MACOSX_DEPLOYMENT_TARGET=10.15.7 cargo_bundle_version=$(cargo -q bundle --help 2>&1 | head -n 1 || echo "") if [ "$cargo_bundle_version" != "cargo-bundle v0.6.0-zed" ]; then cargo install cargo-bundle --git https://github.com/zed-industries/cargo-bundle.git --branch zed-deploy fi rustup target add wasm32-wasi # Deal with versions of macOS that don't include libstdc++ headers export CXXFLAGS="-stdlib=libc++" version_info=$(rustc --version --verbose) host_line=$(echo "$version_info" | grep host) local_target_triple=${host_line#*: } if [ "$local_arch" = true ]; then echo "Building for local target only." cargo build ${build_flag} --package zed cargo build ${build_flag} --package cli else echo "Compiling zed binary for aarch64-apple-darwin" cargo build ${build_flag} --package zed --target aarch64-apple-darwin echo "Compiling zed binary for x86_64-apple-darwin" cargo build ${build_flag} --package zed --target x86_64-apple-darwin echo "Compiling cli binary for aarch64-apple-darwin" cargo build ${build_flag} --package cli --target aarch64-apple-darwin echo "Compiling cli binary for x86_64-apple-darwin" cargo build ${build_flag} --package cli --target x86_64-apple-darwin fi echo "Creating application bundle" pushd crates/zed channel=$( /tmp/zed-certificate.p12 security import /tmp/zed-certificate.p12 -k zed.keychain -P "$MACOS_CERTIFICATE_PASSWORD" -T /usr/bin/codesign rm /tmp/zed-certificate.p12 security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CERTIFICATE_PASSWORD" zed.keychain /usr/bin/codesign --force --deep --timestamp --options runtime --entitlements crates/zed/resources/zed.entitlements --sign "Zed Industries, Inc." "${app_path}" -v security default-keychain -s login.keychain else echo "One or more of the following variables are missing: MACOS_CERTIFICATE, MACOS_CERTIFICATE_PASSWORD, APPLE_NOTARIZATION_USERNAME, APPLE_NOTARIZATION_PASSWORD" echo "Performing an ad-hoc signature, but this bundle should not be distributed" echo "If you see 'The application cannot be opened for an unexpected reason,' you likely don't have the necessary entitlements to run the application in your signing keychain" echo "You will need to download a new signing key from developer.apple.com, add it to keychain, and export MACOS_SIGNING_KEY=" codesign --force --deep --entitlements crates/zed/resources/zed.entitlements --sign ${MACOS_SIGNING_KEY:- -} "${app_path}" -v fi if [[ "$target_dir" = "debug" && "$local_only" = false ]]; then if [ "$open_result" = true ]; then open "$app_path" else echo "Created application bundle:" echo "$app_path" fi exit 0 fi if [ "$local_only" = true ]; then # If bundle_name is not set or empty, use the basename of $app_path if [ -z "$bundle_name" ]; then bundle_name=$(basename "$app_path") else # If bundle_name doesn't end in .app, append it if [[ "$bundle_name" != *.app ]]; then bundle_name="$bundle_name.app" fi fi if [ "$overwrite_local_app" = true ]; then rm -rf "/Applications/$bundle_name" fi mv "$app_path" "/Applications/$bundle_name" if [ "$open_result" = true ]; then open "/Applications/$bundle_name" else echo "Installed application bundle:" echo "/Applications/$bundle_name" fi else echo "Creating DMG" dmg_target_directory="target/${target_dir}" dmg_source_directory="${dmg_target_directory}/dmg" dmg_file_path="${dmg_target_directory}/Zed.dmg" rm -rf ${dmg_source_directory} mkdir -p ${dmg_source_directory} mv "${app_path}" "${dmg_source_directory}" ln -s /Applications ${dmg_source_directory} hdiutil create -volname Zed -srcfolder "${dmg_source_directory}" -ov -format UDZO "${dmg_file_path}" # If someone runs this bundle script locally, a symlink will be placed in `dmg_source_directory`. # This symlink causes CPU issues with Zed if the Zed codebase is the project being worked on, so we simply remove it for now. rm ${dmg_source_directory}/Applications echo "Adding license agreement to DMG" npm install --global dmg-license minimist dmg-license script/eula/eula.json "${dmg_file_path}" if [[ -n $MACOS_CERTIFICATE && -n $MACOS_CERTIFICATE_PASSWORD && -n $APPLE_NOTARIZATION_USERNAME && -n $APPLE_NOTARIZATION_PASSWORD ]]; then echo "Notarizing DMG with Apple" npm install -g notarize-cli npx notarize-cli --file "${dmg_file_path}" --bundle-id dev.zed.Zed --username "$APPLE_NOTARIZATION_USERNAME" --password "$APPLE_NOTARIZATION_PASSWORD" fi if [ "$open_result" = true ]; then open $dmg_target_directory fi fi