mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 10:29:58 +02:00
Add a second macOS shipping channel alongside the App Store build: - New VniDropDirect target (Release-Direct config) sharing VniDrop's sources via an AppBase target template; links Sparkle behind the DIRECT_DISTRIBUTION flag so the App Store binary never bundles a self-updater. arm64-only (core is arm64). - Sparkle updater (SparkleUpdater.swift) + "Check for Updates" menu, compiled only under DIRECT_DISTRIBUTION; Info.plist SUFeedURL points at the GitHub Release /latest/download/appcast.xml, non-sandboxed entitlements for Developer ID. - build-dmg.sh (archive → Developer ID export → DMG → sign → notarize → staple), generate-appcast.sh, and ExportOptions-DeveloperID.plist. - apple-release.yml: on tag v*.*.*, build/notarize the DMG, publish the GitHub Release with appcast, and push the Homebrew cask to sudosylabs/homebrew-vnidrop. apple.yml gains a PR compile-check of the direct target. - CFBundleVersion is stamped at build time as a UTC YYMMDD.HHMM timestamp for both channels, replacing the hand-maintained build number. - Docs (RELEASE-MACOS.md, README), cask template + tap README, localized updates_check string, Makefile targets, gitignore for dist/ artifacts.
50 lines
1.5 KiB
Swift
50 lines
1.5 KiB
Swift
#if DIRECT_DISTRIBUTION && os(macOS)
|
|
import Combine
|
|
import Sparkle
|
|
import SwiftUI
|
|
|
|
/// Owns the Sparkle updater for the direct-download (.dmg) build.
|
|
///
|
|
/// Compiled only under `DIRECT_DISTRIBUTION`, so the App Store / TestFlight target
|
|
/// (which must not ship a self-updater) never compiles or links Sparkle. The feed
|
|
/// URL and public EdDSA key are read from Info.plist (`SUFeedURL`, `SUPublicEDKey`).
|
|
@MainActor
|
|
final class SparkleUpdaterController: ObservableObject {
|
|
private let updaterController: SPUStandardUpdaterController
|
|
/// Mirrors `SPUUpdater.canCheckForUpdates` so the menu item can disable itself
|
|
/// while a check is already in flight.
|
|
@Published private(set) var canCheckForUpdates = false
|
|
|
|
init() {
|
|
// `startingUpdater: true` begins the automatic background check schedule.
|
|
updaterController = SPUStandardUpdaterController(
|
|
startingUpdater: true,
|
|
updaterDelegate: nil,
|
|
userDriverDelegate: nil
|
|
)
|
|
updaterController.updater
|
|
.publisher(for: \.canCheckForUpdates)
|
|
.assign(to: &$canCheckForUpdates)
|
|
}
|
|
|
|
func checkForUpdates() {
|
|
updaterController.checkForUpdates(nil)
|
|
}
|
|
}
|
|
|
|
/// Adds a "Check for Updates…" item to the application menu (right after the
|
|
/// standard "About VniDrop" item), matching the macOS convention.
|
|
struct UpdatesCommands: Commands {
|
|
@ObservedObject var controller: SparkleUpdaterController
|
|
|
|
var body: some Commands {
|
|
CommandGroup(after: .appInfo) {
|
|
Button(String(localized: L10n.Updates.check)) {
|
|
controller.checkForUpdates()
|
|
}
|
|
.disabled(!controller.canCheckForUpdates)
|
|
}
|
|
}
|
|
}
|
|
#endif
|