feat(macos): сборка DMG, фикс keychain и opus-библиотек

- secure storage: usesDataProtectionKeychain=false — вход в аккаунт
  больше не падает с -34018 без аккаунта разработчика
- entitlements: убран app-sandbox/keychain-access-groups (adhoc без Team ID)
- иконка: squircle с прозрачными полями (нативный macOS-вид)
- opus/ogg: битые bitcode-библиотеки ogg_opus_player заменены на
  собранные из исходников universal (.a в macos/prebuilt/opus +
  scripts/fix_opus_macos.sh применяет их после pub get)
- scripts/build_dmg.sh: adhoc-сборка universal DMG с дизайном (create-dmg)
- CI: build-macos.yml собирает DMG-артефакт; flutter-main.yml чинит libs

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
klockky
2026-06-25 20:08:10 +03:00
co-authored by Claude Opus 4.8
parent c800cc0b32
commit 0f4844bf80
24 changed files with 445 additions and 22 deletions
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env bash
set -euo pipefail
APP_NAME="Komet"
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
APP_PATH="$PROJECT_ROOT/build/macos/Build/Products/Release/$APP_NAME.app"
VERSION="$(grep '^version:' "$PROJECT_ROOT/pubspec.yaml" | sed 's/version: *//' | cut -d'+' -f1)"
DIST_DIR="$PROJECT_ROOT/dist"
DMG_PATH="$DIST_DIR/$APP_NAME-$VERSION.dmg"
echo "==> Building release macOS app"
cd "$PROJECT_ROOT"
flutter pub get
"$PROJECT_ROOT/scripts/fix_opus_macos.sh"
flutter build macos --release
if [[ ! -d "$APP_PATH" ]]; then
echo "error: $APP_PATH not found after build" >&2
exit 1
fi
echo "==> Verifying ad-hoc signature (Xcode signs with CODE_SIGN_IDENTITY=- and Release.entitlements)"
codesign --verify --deep --strict "$APP_PATH"
if codesign -d --entitlements :- "$APP_PATH" 2>/dev/null | grep -q "com.apple.security.app-sandbox"; then
echo "error: app-sandbox is enabled; flutter_secure_storage keychain will fail (-34018) without a Developer Team" >&2
exit 1
fi
mkdir -p "$DIST_DIR"
rm -f "$DMG_PATH"
BACKGROUND="$PROJECT_ROOT/scripts/dmg/background.png"
if command -v create-dmg >/dev/null 2>&1; then
echo "==> Packaging with create-dmg"
create-dmg \
--volname "$APP_NAME $VERSION" \
--background "$BACKGROUND" \
--window-pos 200 120 \
--window-size 640 400 \
--icon-size 128 \
--text-size 13 \
--icon "$APP_NAME.app" 170 190 \
--app-drop-link 470 190 \
--hide-extension "$APP_NAME.app" \
--no-internet-enable \
"$DMG_PATH" \
"$APP_PATH"
else
echo "==> create-dmg not found, packaging with hdiutil"
STAGING="$(mktemp -d)"
cp -R "$APP_PATH" "$STAGING/"
ln -s /Applications "$STAGING/Applications"
hdiutil create \
-volname "$APP_NAME $VERSION" \
-srcfolder "$STAGING" \
-ov -format UDZO \
"$DMG_PATH"
rm -rf "$STAGING"
fi
echo "==> Done: $DMG_PATH"
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
set -euo pipefail
# Replaces the broken bitcode-only opus/ogg static libraries shipped by
# ogg_opus_player with real machine-code universal libraries vendored in
# macos/prebuilt/opus. Run after `flutter pub get`, before building macOS.
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SRC="$PROJECT_ROOT/macos/prebuilt/opus"
PKG_CFG="$PROJECT_ROOT/.dart_tool/package_config.json"
LIBS=""
if [ -f "$PKG_CFG" ] && command -v python3 >/dev/null 2>&1; then
ROOT="$(python3 - "$PKG_CFG" <<'PY'
import json, sys, urllib.parse
data = json.load(open(sys.argv[1]))
for pkg in data.get("packages", []):
if pkg["name"] == "ogg_opus_player":
print(urllib.parse.unquote(urllib.parse.urlparse(pkg["rootUri"]).path))
break
PY
)"
if [ -n "$ROOT" ]; then
case "$ROOT" in
/*) PKGDIR="$ROOT" ;;
*) PKGDIR="$(cd "$PROJECT_ROOT/.dart_tool/$ROOT" && pwd)" ;;
esac
LIBS="$PKGDIR/darwin/Libs"
fi
fi
if [ -z "$LIBS" ] || [ ! -d "$LIBS" ]; then
for cand in "${PUB_CACHE:-$HOME/.pub-cache}/hosted"/*/ogg_opus_player-*/darwin/Libs; do
[ -d "$cand" ] && LIBS="$cand" && break
done
fi
if [ -z "$LIBS" ] || [ ! -d "$LIBS" ]; then
echo "warning: ogg_opus_player macOS Libs dir not found; skipping opus fix" >&2
exit 0
fi
echo "==> Installing prebuilt opus libs into: $LIBS"
for f in libogg.a libopus.a libopusfile.a libopusenc.a; do
cp -f "$SRC/$f" "$LIBS/$f"
echo " installed $f ($(lipo -archs "$LIBS/$f" 2>/dev/null))"
done
echo "==> opus libs fixed"