Skip to content
#!/usr/bin/env bash
set -euo pipefail

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "${REPO_ROOT}"

DIST_DIR="${REPO_ROOT}/dist"
mkdir -p "${DIST_DIR}"

echo "==> Preparing Linux and macOS desktop builds..."
npm --prefix "${REPO_ROOT}/mac" install --no-package-lock --no-audit --no-fund
npm --prefix "${REPO_ROOT}/mac" run icons

# Build macOS universal binary from Linux using the macOS SDK and zig.
REQUIRED_TARGETS=(
    "aarch64-apple-darwin"
    "x86_64-apple-darwin"
)
for target in "${REQUIRED_TARGETS[@]}"; do
    if ! rustup target list | grep -q "${target} (installed)"; then
        echo "  -> Adding Rust target ${target}..."
        rustup target add "${target}"
    fi
done

SDKROOT="${MACOSX_SDK_DIR:-"${HOME}/.cache/macosx-sdk"}"
if [ ! -d "${SDKROOT}" ] || [ ! -d "${SDKROOT}/usr/lib" ]; then
    echo "  -> Downloading macOS SDK into ${SDKROOT}..."
    mkdir -p "${SDKROOT}"
    curl -sSL "https://github.com/joseluisq/macosx-sdks/releases/download/14.5/MacOSX14.5.sdk.tar.xz" \
        | tar -xJ -C "${SDKROOT}" --strip-components=1
fi

echo "==> Building Notify for macOS..."
DARWIN_LINK_FLAGS="-C link-arg=-isysroot -C link-arg=${SDKROOT} -C link-arg=-L${SDKROOT}/usr/lib -C link-arg=-F${SDKROOT}/System/Library/Frameworks"
for target in "${REQUIRED_TARGETS[@]}"; do
    echo "  -> Building ${target}..."
    RUSTFLAGS="${DARWIN_LINK_FLAGS}" cargo zigbuild -p notify-desktop --release --target "${target}"
done

if command -v llvm-lipo >/dev/null 2>&1; then
    LIPO_CMD="llvm-lipo"
elif command -v lipo >/dev/null 2>&1; then
    LIPO_CMD="lipo"
else
    LIPO_CMD=""
fi

MAC_APP_DIR="${DIST_DIR}/Notify.app"
rm -rf "${MAC_APP_DIR}"
mkdir -p "${MAC_APP_DIR}/Contents/MacOS" "${MAC_APP_DIR}/Contents/Resources"

if [ -n "${LIPO_CMD}" ]; then
    echo "  -> Creating universal macOS binary..."
    "${LIPO_CMD}" -create -output "${MAC_APP_DIR}/Contents/MacOS/Notify" \
        "${REPO_ROOT}/target/aarch64-apple-darwin/release/notify-desktop" \
        "${REPO_ROOT}/target/x86_64-apple-darwin/release/notify-desktop"
else
    cp "${REPO_ROOT}/target/aarch64-apple-darwin/release/notify-desktop" "${MAC_APP_DIR}/Contents/MacOS/Notify"
fi
chmod +x "${MAC_APP_DIR}/Contents/MacOS/Notify"

if [ -f "${REPO_ROOT}/mac/src-tauri/icons/icon.icns" ]; then
    cp "${REPO_ROOT}/mac/src-tauri/icons/icon.icns" "${MAC_APP_DIR}/Contents/Resources/icon.icns"
fi

cat << 'EOF' > "${MAC_APP_DIR}/Contents/Info.plist"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleExecutable</key>
    <string>Notify</string>
    <key>CFBundleIdentifier</key>
    <string>com.silen.notify</string>
    <key>CFBundleName</key>
    <string>Notify</string>
    <key>CFBundleDisplayName</key>
    <string>Notify</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>0.1.0</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>CFBundleIconFile</key>
    <string>icon.icns</string>
    <key>LSMinimumSystemVersion</key>
    <string>10.15</string>
    <key>NSHighResolutionCapable</key>
    <true/>
</dict>
</plist>
EOF

(
    cd "${DIST_DIR}"
    rm -f Notify-mac.zip Notify-mac.tar.gz
    zip -r -q -y Notify-mac.zip Notify.app
    tar -czf Notify-mac.tar.gz Notify.app
)

# Linux bundles are built natively so Tauri can produce an AppImage and DEB.
if [ "$(uname -s)" != "Linux" ]; then
    echo "Error: Linux desktop bundles must be built on Linux." >&2
    exit 1
fi
if [ "$(uname -m)" != "x86_64" ]; then
    echo "Error: Linux desktop bundles currently target x86_64; found $(uname -m)." >&2
    exit 1
fi
if ! command -v npm >/dev/null 2>&1; then
    echo "Error: npm is required to build the Linux Tauri bundles." >&2
    exit 1
fi

echo "==> Building Notify for Linux (AppImage and DEB)..."
npm --prefix "${REPO_ROOT}/mac" run build -- --bundles appimage,deb

shopt -s nullglob
APPIMAGES=("${REPO_ROOT}"/target/release/bundle/appimage/*.AppImage)
DEBS=("${REPO_ROOT}"/target/release/bundle/deb/*.deb)
shopt -u nullglob
if [ "${#APPIMAGES[@]}" -eq 0 ] || [ "${#DEBS[@]}" -eq 0 ]; then
    echo "Error: Tauri did not produce both Linux AppImage and DEB bundles." >&2
    exit 1
fi
cp "${APPIMAGES[0]}" "${DIST_DIR}/Notify-linux-x86_64.AppImage"
cp "${DEBS[0]}" "${DIST_DIR}/Notify-linux-x86_64.deb"

(
    cd "${DIST_DIR}"
    sha256sum Notify-mac.* Notify-linux-* > SHA256SUMS
)

echo "๐ŸŽ‰ Linux and macOS installers successfully built in ${DIST_DIR}:"
ls -lh "${DIST_DIR}"