bundle

  1#!/bin/bash
  2
  3set -e
  4
  5build_flag="--release"
  6target_dir="release"
  7open_result=false
  8
  9# If -o option is specified, the folder of the resulting dmg will be opened in finder
 10# If -d is specified, Zed will be compiled in debug mode and the application's path printed
 11# If -od or -do is specified Zed will be bundled in debug and the application will be run.
 12while getopts 'od' flag
 13do
 14    case "${flag}" in
 15        o) open_result=true;;
 16        d)
 17            build_flag="";
 18            target_dir="debug"
 19            ;;
 20    esac
 21done
 22
 23export ZED_BUNDLE=true
 24export MACOSX_DEPLOYMENT_TARGET=10.15.7
 25
 26which cargo-bundle > /dev/null || cargo install cargo-bundle --version 0.5.0
 27rustup target add wasm32-wasi
 28
 29# Deal with versions of macOS that don't include libstdc++ headers
 30export CXXFLAGS="-stdlib=libc++"
 31
 32echo "Compiling zed binary for aarch64-apple-darwin"
 33cargo build ${build_flag} --package zed --target aarch64-apple-darwin
 34echo "Compiling zed binary for x86_64-apple-darwin"
 35cargo build ${build_flag} --package zed --target x86_64-apple-darwin
 36echo "Compiling cli binary for aarch64-apple-darwin"
 37cargo build ${build_flag} --package cli --target aarch64-apple-darwin
 38echo "Compiling cli binary for x86_64-apple-darwin"
 39cargo build ${build_flag} --package cli --target x86_64-apple-darwin
 40
 41echo "Creating application bundle"
 42pushd crates/zed
 43channel=$(<RELEASE_CHANNEL)
 44cp Cargo.toml Cargo.toml.backup
 45sed \
 46    -i .backup \
 47    "s/package.metadata.bundle-${channel}/package.metadata.bundle/" \
 48    Cargo.toml
 49app_path=$(cargo bundle ${build_flag} --target x86_64-apple-darwin | xargs)
 50
 51echo app_path
 52
 53mv Cargo.toml.backup Cargo.toml
 54popd
 55echo "Bundled ${app_path}"
 56
 57echo "Creating fat binaries"
 58lipo \
 59    -create \
 60    target/{x86_64-apple-darwin,aarch64-apple-darwin}/${target_dir}/Zed \
 61    -output \
 62    "${app_path}/Contents/MacOS/zed"
 63lipo \
 64    -create \
 65    target/{x86_64-apple-darwin,aarch64-apple-darwin}/${target_dir}/cli \
 66    -output \
 67    "${app_path}/Contents/MacOS/cli"
 68
 69echo "Copying WebRTC.framework into the frameworks folder"
 70mkdir "${app_path}/Contents/Frameworks"
 71cp -R target/x86_64-apple-darwin/${target_dir}/WebRTC.framework "${app_path}/Contents/Frameworks/"
 72
 73mv "${app_path}/Contents/Info.plist" "${app_path}/Contents/WithoutDocumentTypes.plist"
 74awk \
 75    "/<\/dict>/{while(getline line<\"./crates/zed/BundleDocumentTypes.plist\"){print line}}1" \
 76    "${app_path}/Contents/WithoutDocumentTypes.plist" \
 77    > "${app_path}/Contents/Info.plist"
 78rm "${app_path}/Contents/WithoutDocumentTypes.plist"
 79
 80if [[ -n $MACOS_CERTIFICATE && -n $MACOS_CERTIFICATE_PASSWORD && -n $APPLE_NOTARIZATION_USERNAME && -n $APPLE_NOTARIZATION_PASSWORD ]]; then
 81    echo "Signing bundle with Apple-issued certificate"
 82    security create-keychain -p "$MACOS_CERTIFICATE_PASSWORD" zed.keychain || echo ""
 83    security default-keychain -s zed.keychain
 84    security unlock-keychain -p "$MACOS_CERTIFICATE_PASSWORD" zed.keychain
 85    echo "$MACOS_CERTIFICATE" | base64 --decode > /tmp/zed-certificate.p12
 86    security import /tmp/zed-certificate.p12 -k zed.keychain -P "$MACOS_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
 87    rm /tmp/zed-certificate.p12
 88    security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CERTIFICATE_PASSWORD" zed.keychain
 89    /usr/bin/codesign --force --deep --timestamp --options runtime --sign "Zed Industries, Inc." "${app_path}" -v
 90    security default-keychain -s login.keychain
 91else
 92    echo "One or more of the following variables are missing: MACOS_CERTIFICATE, MACOS_CERTIFICATE_PASSWORD, APPLE_NOTARIZATION_USERNAME, APPLE_NOTARIZATION_PASSWORD"
 93    echo "Performing an ad-hoc signature, but this bundle should not be distributed"
 94    codesign --force --deep --sign - "${app_path}" -v
 95fi
 96
 97if [ "$target_dir" = "debug" ]; then
 98    if [ "$open_result" = true ]; then
 99        open "$app_path"
100    else
101        echo "Created application bundle:"
102        echo "$app_path"
103    fi
104    exit 0
105fi
106
107dmg_target_directory="target/${target_dir}"
108dmg_source_directory="${dmg_target_directory}/dmg"
109dmg_file_path="${dmg_target_directory}/Zed.dmg"
110
111echo "Creating DMG"
112rm -rf ${dmg_source_directory}
113mkdir -p ${dmg_source_directory}
114mv "${app_path}" "${dmg_source_directory}"
115
116ln -s /Applications ${dmg_source_directory}
117hdiutil create -volname Zed -srcfolder "${dmg_source_directory}" -ov -format UDZO "${dmg_file_path}"
118# If someone runs this bundle script locally, a symlink will be placed in `dmg_source_directory`.
119# This symlink causes CPU issues with Zed if the Zed codebase is the project being worked on, so we simply remove it for now.
120rm ${dmg_source_directory}/Applications
121
122echo "Adding license agreement to DMG"
123npm install --global dmg-license minimist
124dmg-license script/eula/eula.json "${dmg_file_path}"
125
126if [[ -n $MACOS_CERTIFICATE && -n $MACOS_CERTIFICATE_PASSWORD && -n $APPLE_NOTARIZATION_USERNAME && -n $APPLE_NOTARIZATION_PASSWORD ]]; then
127    echo "Notarizing DMG with Apple"
128    npm install -g notarize-cli
129    npx notarize-cli --file "${dmg_file_path}" --bundle-id dev.zed.Zed --username "$APPLE_NOTARIZATION_USERNAME" --password "$APPLE_NOTARIZATION_PASSWORD"
130fi
131
132if [ "$open_result" = true ]; then
133    open $dmg_target_directory
134fi