From de4431b4e9a48fee18ed0cfe1abf080fb052314f Mon Sep 17 00:00:00 2001 From: Jatinjit Singh Date: Thu, 29 Oct 2026 16:27:12 +0900 Subject: [PATCH] Release Brandy 1.0.0 Set the version to 1.0.0 (44) and stop copying the WhiskyKit package folder, build products included, into the app's resources, which shrinks the app from 189 MB to 13 MB. Add scripts/package-brandy.sh to build an unsigned release disk image. It signs every nested binary ad-hoc without the hardened runtime, because library validation rejects an ad-hoc Sparkle.framework and the app would exit at launch. --- Whisky.xcodeproj/project.pbxproj | 18 ++++----- scripts/package-brandy.sh | 65 ++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 10 deletions(-) create mode 100755 scripts/package-brandy.sh diff --git a/Whisky.xcodeproj/project.pbxproj b/Whisky.xcodeproj/project.pbxproj index 37a67e0e3..d99bb7dce 100644 --- a/Whisky.xcodeproj/project.pbxproj +++ b/Whisky.xcodeproj/project.pbxproj @@ -50,7 +50,6 @@ 8C2AEFC82AED79B700CB568F /* WhiskyKit in Frameworks */ = {isa = PBXBuildFile; productRef = 8C2AEFC72AED79B700CB568F /* WhiskyKit */; }; 8C2AEFCA2AED79CD00CB568F /* WhiskyKit in Frameworks */ = {isa = PBXBuildFile; productRef = 8C2AEFC92AED79CD00CB568F /* WhiskyKit */; }; 8C73E1342AF472FC00B6FB45 /* ProgramMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C73E1332AF472FC00B6FB45 /* ProgramMenuView.swift */; }; - 8CB681E52AED7C6F0018D319 /* WhiskyKit in Resources */ = {isa = PBXBuildFile; fileRef = 8CB681E42AED7C6F0018D319 /* WhiskyKit */; }; 8CB681E72AED7CD00018D319 /* WhiskyKit in Frameworks */ = {isa = PBXBuildFile; productRef = 8CB681E62AED7CD00018D319 /* WhiskyKit */; }; DB696FC82AFAE5DA0037EB2F /* PinCreationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB696FC72AFAE5DA0037EB2F /* PinCreationView.swift */; }; EB58FB552A499896002DC184 /* SemanticVersion in Frameworks */ = {isa = PBXBuildFile; productRef = EB58FB542A499896002DC184 /* SemanticVersion */; }; @@ -556,7 +555,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8CB681E52AED7C6F0018D319 /* WhiskyKit in Resources */, 6E40495D29CCA19C006E3F1B /* Preview Assets.xcassets in Resources */, 6EB58AC92AEACE5E00B1ED3F /* Localizable.xcstrings in Resources */, 6E40495A29CCA19C006E3F1B /* Assets.xcassets in Resources */, @@ -801,7 +799,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 43; + CURRENT_PROJECT_VERSION = 44; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = "\"Whisky/Preview Content\""; DEVELOPMENT_TEAM = ""; @@ -820,7 +818,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 14.0; - MARKETING_VERSION = 2.3.5; + MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.istorry.Brandy; PRODUCT_MODULE_NAME = Whisky; PRODUCT_NAME = Brandy; @@ -841,7 +839,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 43; + CURRENT_PROJECT_VERSION = 44; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = "\"Whisky/Preview Content\""; DEVELOPMENT_TEAM = ""; @@ -860,7 +858,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 14.0; - MARKETING_VERSION = 2.3.5; + MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.istorry.Brandy; PRODUCT_MODULE_NAME = Whisky; PRODUCT_NAME = Brandy; @@ -930,7 +928,7 @@ CODE_SIGN_ENTITLEMENTS = WhiskyThumbnail/WhiskyThumbnail.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 43; + CURRENT_PROJECT_VERSION = 44; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = YES; @@ -946,7 +944,7 @@ "@executable_path/../../../../Frameworks", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 2.3.5; + MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.istorry.Brandy.Thumbnail; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -965,7 +963,7 @@ CODE_SIGN_ENTITLEMENTS = WhiskyThumbnail/WhiskyThumbnail.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 43; + CURRENT_PROJECT_VERSION = 44; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = YES; @@ -981,7 +979,7 @@ "@executable_path/../../../../Frameworks", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 2.3.5; + MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.istorry.Brandy.Thumbnail; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/scripts/package-brandy.sh b/scripts/package-brandy.sh new file mode 100755 index 000000000..4757e8f05 --- /dev/null +++ b/scripts/package-brandy.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# +# package-brandy.sh +# Brandy +# +# Builds Brandy for release without a Developer ID and packages it as a disk image. +# An ad-hoc signature has no Team ID, so the hardened runtime's library validation would refuse to +# load the embedded Sparkle.framework and the app would exit at launch. Every piece of code is +# therefore signed ad-hoc without the runtime, inside out, keeping each target's entitlements. +# +# Usage: scripts/package-brandy.sh [output folder] (run from the repository root; default build/release) +# + +set -euo pipefail + +readonly APP_NAME="Brandy" +readonly APP_ENTITLEMENTS="Whisky/Whisky.entitlements" +readonly THUMBNAIL_ENTITLEMENTS="WhiskyThumbnail/WhiskyThumbnail.entitlements" + +output="${1:-build/release}" +mkdir -p "$output" +output="$(cd "$output" && pwd)" +work="$(mktemp -d)" +trap 'rm -rf "$work"' EXIT + +echo "Building $APP_NAME" +xcodebuild build -quiet -project Whisky.xcodeproj -scheme Whisky -configuration Release \ + -destination "generic/platform=macOS" -derivedDataPath "$work/DerivedData" -onlyUsePackageVersionsFromResolvedFile \ + CODE_SIGNING_ALLOWED=NO CODE_SIGN_IDENTITY="" + +app="$work/$APP_NAME.app" +ditto "$work/DerivedData/Build/Products/Release/$APP_NAME.app" "$app" +contents="$app/Contents" +sparkle="$contents/Frameworks/Sparkle.framework" + +sign() { + codesign --force --sign - --timestamp=none "$@" +} + +echo "Signing" +sign --preserve-metadata=entitlements \ + "$sparkle/Versions/B/XPCServices/Installer.xpc" \ + "$sparkle/Versions/B/XPCServices/Downloader.xpc" \ + "$sparkle/Versions/B/Autoupdate" \ + "$sparkle/Versions/B/Updater.app" +sign "$sparkle" +sign "$contents/Resources/WhiskyCmd" "$contents/Resources/cabextract" +sign --entitlements "$THUMBNAIL_ENTITLEMENTS" "$contents/PlugIns/WhiskyThumbnail.appex" +sign --entitlements "$APP_ENTITLEMENTS" "$app" +codesign --verify --deep --strict "$app" + +version="$(plutil -extract CFBundleShortVersionString raw -o - "$contents/Info.plist")" +build="$(plutil -extract CFBundleVersion raw -o - "$contents/Info.plist")" +image="$output/$APP_NAME-$version.dmg" + +echo "Packaging $APP_NAME $version ($build)" +staging="$work/staging" +mkdir "$staging" +mv "$app" "$staging/" +ln -s /Applications "$staging/Applications" +hdiutil create -quiet -volname "$APP_NAME" -srcfolder "$staging" -fs HFS+ -format UDZO -ov "$image" +hdiutil verify -quiet "$image" + +echo "$image" +shasum -a 256 "$image"