Add Sparkle updates to Oficina Meet on macOS
6 files changed,
+62
−16
native/apple/Package.resolved+25 −8native/apple/Package.swift+7 −1native/apple/Sources/MeetMac/MeetMac.swift+10 −1native/mac-updates.json+6 −0native/scripts/build-mac.sh+6 −5native/scripts/bundle-mac.py+8 −1
diff --git a/native/apple/Package.resolved b/native/apple/Package.resolved| index c68b7f5..dfd04e9 100644 |
| --- a/native/apple/Package.resolved |
| +++ b/native/apple/Package.resolved |
| @@ -1,14 +1,31 @@ |
| { |
| - "pins" : [ |
| + "pins": [ |
| { |
| - "identity" : "webrtc", |
| - "kind" : "remoteSourceControl", |
| - "location" : "https://github.com/stasel/WebRTC.git", |
| - "state" : { |
| - "revision" : "1d04692697cb642bfebf6ad2dd99fe52649c3d6d", |
| - "version" : "152.0.0" |
| + "identity": "native", |
| + "kind": "remoteSourceControl", |
| + "location": "https://amadan.net/rastrillo/native", |
| + "state": { |
| + "revision": "4c61d6283a188c95647e1d0e609e69d29c2e7fa1" |
| + } |
| + }, |
| + { |
| + "identity": "sparkle", |
| + "kind": "remoteSourceControl", |
| + "location": "https://github.com/sparkle-project/Sparkle", |
| + "state": { |
| + "revision": "ac2def288cbff5cfc7df3ffef6abdf45b72bcb0a", |
| + "version": "2.9.6" |
| + } |
| + }, |
| + { |
| + "identity": "webrtc", |
| + "kind": "remoteSourceControl", |
| + "location": "https://github.com/stasel/WebRTC.git", |
| + "state": { |
| + "revision": "1d04692697cb642bfebf6ad2dd99fe52649c3d6d", |
| + "version": "152.0.0" |
| } |
| } |
| ], |
| - "version" : 2 |
| + "version": 2 |
| } |
diff --git a/native/apple/Package.swift b/native/apple/Package.swift| index 546f1d8..9328049 100644 |
| --- a/native/apple/Package.swift |
| +++ b/native/apple/Package.swift |
| @@ -1,5 +1,10 @@ |
| // swift-tools-version: 5.9 |
| import PackageDescription |
| +import Foundation |
| + |
| +let sharedNative: Package.Dependency = ProcessInfo.processInfo.environment["OFICINA_NATIVE_PACKAGE_PATH"].map { .package(path: $0) } |
| + ?? .package(url: "https://amadan.net/rastrillo/native", revision: "4c61d6283a188c95647e1d0e609e69d29c2e7fa1") |
| + |
| let package = Package( |
| name: "MeetNative", |
| @@ -10,13 +15,14 @@ let package = Package( |
| .executable(name: "MeetInterop", targets: ["MeetInterop"]), |
| ], |
| dependencies: [ |
| + sharedNative, |
| .package(url: "https://github.com/stasel/WebRTC.git", exact: "152.0.0") |
| ], |
| targets: [ |
| .binaryTarget(name: "MeetBridge", path: "../build/MeetBridge.xcframework"), |
| .target( |
| name: "MeetKit", dependencies: ["MeetBridge", .product(name: "WebRTC", package: "WebRTC")]), |
| - .executableTarget(name: "MeetMac", dependencies: ["MeetKit"], resources: [.copy("Resources/AppIcon.png"), .copy("Resources/MacIcon.png")]), |
| + .executableTarget(name: "MeetMac", dependencies: [.product(name: "RastrilloMacUpdates", package: "native", condition: .when(platforms: [.macOS])), "MeetKit"], resources: [.copy("Resources/AppIcon.png"), .copy("Resources/MacIcon.png")]), |
| .executableTarget(name: "MeetInterop", dependencies: ["MeetKit"]), |
| .testTarget(name: "MeetKitTests", dependencies: ["MeetKit"]), |
| ] |
diff --git a/native/apple/Sources/MeetMac/MeetMac.swift b/native/apple/Sources/MeetMac/MeetMac.swift| index 54d21c1..b81bd11 100644 |
| --- a/native/apple/Sources/MeetMac/MeetMac.swift |
| +++ b/native/apple/Sources/MeetMac/MeetMac.swift |
| @@ -1,3 +1,6 @@ |
| +#if os(macOS) |
| +import RastrilloMacUpdates |
| +#endif |
| import AppKit |
| @preconcurrency import MeetBridge |
| import MeetKit |
| @@ -5,6 +8,9 @@ import SwiftUI |
| import WebRTC |
| @main struct MeetMacApp: App { |
| + #if os(macOS) |
| + @State private var updater = NativeUpdater() |
| + #endif |
| @NSApplicationDelegateAdaptor(MeetAppDelegate.self) private var appDelegate |
| @StateObject private var model = MeetModel() |
| var body: some Scene { |
| @@ -12,7 +18,10 @@ import WebRTC |
| ContentView(model: model).frame(minWidth: 760, minHeight: 540).onDisappear { model.leave() } |
| } |
| .defaultSize(width: 1000, height: 760) |
| - .commands { CommandGroup(replacing: .newItem) {} } |
| + .commands { |
| + CommandGroup(replacing: .newItem) {} |
| + NativeUpdateCommands(updater: updater) |
| + } |
| } |
| } |
diff --git a/native/mac-updates.json b/native/mac-updates.json| new file mode 100644 |
| index 0000000..7e35b42 |
| --- /dev/null |
| +++ b/native/mac-updates.json |
| @@ -0,0 +1,6 @@ |
| +{ |
| + "bundle_id": "net.amadan.oficina.meet", |
| + "feed_url": "https://raw.amadan.net/oficina/native-releases/main/meet/appcast.xml", |
| + "public_ed_key": "/FxO7cZnM7P5c9ZrUPUJvpCnR65sNmrzte+I5vHarE8=", |
| + "keychain_account": "oficina" |
| +} |
diff --git a/native/scripts/build-mac.sh b/native/scripts/build-mac.sh| index 841baed..05d6cc9 100755 |
| --- a/native/scripts/build-mac.sh |
| +++ b/native/scripts/build-mac.sh |
| @@ -1,9 +1,10 @@ |
| #!/bin/sh |
| set -eu |
| cd "$(dirname "$0")/.." |
| -./scripts/build-bridge.sh |
| -swift scripts/generate-mac-icon.swift |
| -swift build --package-path apple |
| -python3 scripts/bundle-mac.py |
| -codesign --force --deep --sign - build/Meet.app |
| +if [ "${OFICINA_SKIP_PREPARE:-0}" != 1 ]; then ./scripts/build-bridge.sh; fi |
| +configuration="${OFICINA_BUILD_CONFIGURATION:-debug}" |
| +swift build --package-path apple --configuration "$configuration" --product MeetMac |
| +python3 scripts/bundle-mac.py "$configuration" |
| +shared_native="${OFICINA_NATIVE_PACKAGE_PATH:-apple/.build/checkouts/native}" |
| +python3 "$shared_native/tools/mac_updates.py" build/Meet.app --package apple "$@" |
| printf 'Built %s/build/Meet.app\n' "$PWD" |
diff --git a/native/scripts/bundle-mac.py b/native/scripts/bundle-mac.py| index 52d2e6f..d13a7e5 100644 |
| --- a/native/scripts/bundle-mac.py |
| +++ b/native/scripts/bundle-mac.py |
| @@ -3,17 +3,24 @@ from pathlib import Path |
| import plistlib |
| import shutil |
| import subprocess |
| +import sys |
| root = Path(__file__).resolve().parent.parent |
| +configuration = sys.argv[1] if len(sys.argv) > 1 else 'debug' |
| +if configuration not in ('debug', 'release'): raise ValueError('invalid build configuration') |
| +products = Path(subprocess.check_output(['swift', 'build', '--package-path', str(root / 'apple'), '--configuration', configuration, '--show-bin-path'], text=True).strip()) |
| bundle = root / 'build/Meet.app/Contents' |
| +if bundle.parent.exists(): shutil.rmtree(bundle.parent) |
| (bundle / 'MacOS').mkdir(parents=True, exist_ok=True) |
| (bundle / 'Frameworks').mkdir(parents=True, exist_ok=True) |
| (bundle / 'Resources').mkdir(parents=True, exist_ok=True) |
| -shutil.copy2(root / 'apple/.build/debug/MeetMac', bundle / 'MacOS/MeetMac') |
| +shutil.copy2(products / 'MeetMac', bundle / 'MacOS/MeetMac') |
| subprocess.run(['swift', str(root / 'scripts/generate-mac-icon.swift')], check=True) |
| icon = root / 'apple/Sources/MeetMac/Resources/MacIcon.png' |
| shutil.copy2(icon, bundle / 'Resources/MacIcon.png') |
| shutil.copy2(root / 'LICENSE.lucide', bundle / 'Resources/LICENSE.lucide') |
| +for resource in products.glob('*.bundle'): |
| + shutil.copytree(resource, bundle / 'Resources' / resource.name, symlinks=True) |
| # Finder reads the ICNS before the app launches; the PNG also supplies the |
| # runtime Dock icon. Generate each required representation from the master. |
| iconset = root / 'build/AppIcon.iconset' |