Integrate Sparkle auto-updates for macOS Developer ID builds

New Release-DeveloperID configuration gates Sparkle behind a SPARKLE
compile flag so the App Store Release build stays Sparkle-free. Adds
SPUStandardUpdaterController wrapper, Check for Updates menu command,
Advanced Settings section with beta channel toggle, and a Ruby script
plus GitHub Actions job that signs each release and publishes the
appcast to gh-pages for consumption by Sparkle and Homebrew cask.
This commit is contained in:
Arkadiusz Fal
2026-04-23 04:51:00 +02:00
parent 29c67d3276
commit a2a4691957
14 changed files with 630 additions and 13 deletions

View File

@@ -27,6 +27,9 @@ struct AdvancedSettingsView: View {
var body: some View {
SettingsFormContainer {
#if SPARKLE && os(macOS)
updatesSection
#endif
streamDetailsSection
mpvSection
settingsSection
@@ -350,6 +353,26 @@ struct AdvancedSettingsView: View {
#if SPARKLE && os(macOS)
@ViewBuilder
private var updatesSection: some View {
SettingsFormSection("settings.updates.title", footer: "settings.updates.footer") {
Toggle(isOn: Binding(
get: { AppUpdater.shared.wantsBetaChannel },
set: { AppUpdater.shared.wantsBetaChannel = $0 }
)) {
Label(String(localized: "settings.updates.receiveBeta"), systemImage: "testtube.2")
}
Button {
AppUpdater.shared.checkForUpdates()
} label: {
Label(String(localized: "menu.app.checkForUpdates"), systemImage: "arrow.triangle.2.circlepath")
}
.disabled(!AppUpdater.shared.canCheckForUpdates)
}
}
#endif
@ViewBuilder
private var developerSection: some View {
SettingsFormSection(footer: "settings.developer.footer") {

View File

@@ -0,0 +1,27 @@
//
// CheckForUpdatesMenuItem.swift
// Yattee
//
// "Check for Updates" menu item shown in the macOS app menu for
// Developer ID builds. Wired to the Sparkle-backed `AppUpdater`.
//
// Compiled in only when the `SPARKLE` Swift flag is set (i.e. the
// `Release-DeveloperID` configuration). See AGENTS.md.
//
#if SPARKLE && os(macOS)
import SwiftUI
struct CheckForUpdatesMenuItem: View {
@State private var updater = AppUpdater.shared
var body: some View {
Button(String(localized: "menu.app.checkForUpdates")) {
updater.checkForUpdates()
}
.disabled(!updater.canCheckForUpdates)
}
}
#endif