zed/script/bundle
Conrad Irwin 7c867b6e54 New entitlements:
* Universal links
* Shared keychain group (to make development easier)
2023-10-11 09:36:12 -06:00

220 lines
7.9 KiB
Bash
Executable File

#!/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=$(<RELEASE_CHANNEL)
cp Cargo.toml Cargo.toml.backup
sed \
-i .backup \
"s/package.metadata.bundle-${channel}/package.metadata.bundle/" \
Cargo.toml
if [ "$local_arch" = true ]; then
app_path=$(cargo bundle ${build_flag} --select-workspace-root | xargs)
else
app_path=$(cargo bundle ${build_flag} --target x86_64-apple-darwin --select-workspace-root | xargs)
fi
mv Cargo.toml.backup Cargo.toml
popd
echo "Bundled ${app_path}"
if [ "$local_arch" = false ]; then
echo "Creating fat binaries"
lipo \
-create \
target/{x86_64-apple-darwin,aarch64-apple-darwin}/${target_dir}/Zed \
-output \
"${app_path}/Contents/MacOS/zed"
lipo \
-create \
target/{x86_64-apple-darwin,aarch64-apple-darwin}/${target_dir}/cli \
-output \
"${app_path}/Contents/MacOS/cli"
fi
echo "Copying WebRTC.framework into the frameworks folder"
mkdir "${app_path}/Contents/Frameworks"
if [ "$local_arch" = false ]; then
cp -R target/${local_target_triple}/${target_dir}/WebRTC.framework "${app_path}/Contents/Frameworks/"
else
cp -R target/${target_dir}/WebRTC.framework "${app_path}/Contents/Frameworks/"
fi
cp crates/zed/contents/embedded.provisionprofile "${app_path}/Contents/"
if [[ -n $MACOS_CERTIFICATE && -n $MACOS_CERTIFICATE_PASSWORD && -n $APPLE_NOTARIZATION_USERNAME && -n $APPLE_NOTARIZATION_PASSWORD ]]; then
echo "Signing bundle with Apple-issued certificate"
security create-keychain -p "$MACOS_CERTIFICATE_PASSWORD" zed.keychain || echo ""
security default-keychain -s zed.keychain
security unlock-keychain -p "$MACOS_CERTIFICATE_PASSWORD" zed.keychain
echo "$MACOS_CERTIFICATE" | base64 --decode > /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=<email address of 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