Compare commits
58 Commits
v26.0.31
...
62d4a9ac96
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62d4a9ac96 | ||
|
|
75fe670779 | ||
|
|
a961baab28 | ||
|
|
7246b132f6 | ||
|
|
1afce31641 | ||
|
|
281016bfc9 | ||
|
|
144ad27aa6 | ||
|
|
aa655bb7d6 | ||
|
|
1ac34e1f04 | ||
|
|
5f045c113a | ||
|
|
2dbe739c97 | ||
|
|
da9dd2f7ed | ||
|
|
2ae67b6675 | ||
|
|
989717539c | ||
|
|
6d05419abb | ||
|
|
be37bf526a | ||
|
|
6c1f5c6d25 | ||
|
|
32f97ff7d4 | ||
|
|
dbbe1752d1 | ||
|
|
2fe9821ac1 | ||
|
|
87d4bffb99 | ||
|
|
92782716fc | ||
|
|
002c9e8cf2 | ||
|
|
8820244589 | ||
|
|
48d2f0ea42 | ||
|
|
1947d05d78 | ||
|
|
86039cd5a9 | ||
|
|
4f9c008498 | ||
|
|
76818578b9 | ||
|
|
9070882f38 | ||
|
|
541927c30a | ||
|
|
ab3a7ca469 | ||
|
|
ee27efc0d4 | ||
|
|
c3f445e3c3 | ||
|
|
215c24d5a2 | ||
|
|
b96b018f70 | ||
|
|
65a65939a7 | ||
|
|
25723b7f07 | ||
|
|
10683ebc73 | ||
|
|
393bcf27e1 | ||
|
|
839a513fde | ||
|
|
77e82753ba | ||
|
|
bbb0b580b0 | ||
|
|
dd225b2b8e | ||
|
|
76b01352ac | ||
|
|
fcca8cee38 | ||
|
|
94d1b3fec4 | ||
|
|
4352ae1476 | ||
|
|
846e0b149b | ||
|
|
11ca4dbede | ||
|
|
1d8bdfe491 | ||
|
|
4f5a07822f | ||
|
|
67709dfda6 | ||
|
|
6753226087 | ||
|
|
a3671acf38 | ||
|
|
0aa773a0b3 | ||
|
|
adbc061d0b | ||
|
|
4deae63d43 |
3
NOTES.md
3
NOTES.md
@@ -5,5 +5,6 @@
|
|||||||
|
|
||||||
add a marker for "reboot required"
|
add a marker for "reboot required"
|
||||||
|
|
||||||
dummy22
|
dummy2
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ GITEA_REPO="iKeyMon"
|
|||||||
# optional Sparkle feed helpers:
|
# optional Sparkle feed helpers:
|
||||||
# SPARKLE_EDDSA_KEY_FILE="$HOME/.config/Sparkle/iKeyMon.key"
|
# SPARKLE_EDDSA_KEY_FILE="$HOME/.config/Sparkle/iKeyMon.key"
|
||||||
# SPARKLE_DOWNLOAD_BASE_TEMPLATE="https://git.24unix.net/tracer/iKeyMon/releases/download/v{{VERSION}}"
|
# SPARKLE_DOWNLOAD_BASE_TEMPLATE="https://git.24unix.net/tracer/iKeyMon/releases/download/v{{VERSION}}"
|
||||||
|
# If you prefer SPARKLE_DOWNLOAD_BASE_URL, it will automatically append `/v<version>` for you.
|
||||||
# SPARKLE_APPCAST_OUTPUT="$ROOT_DIR/Sparkle/appcast.xml" # default
|
# SPARKLE_APPCAST_OUTPUT="$ROOT_DIR/Sparkle/appcast.xml" # default
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ final class SparkleUpdater: NSObject, ObservableObject {
|
|||||||
}()
|
}()
|
||||||
private let logger = Logger(subsystem: "net.24unix.iKeyMon", category: "Sparkle")
|
private let logger = Logger(subsystem: "net.24unix.iKeyMon", category: "Sparkle")
|
||||||
private let verboseLogging: Bool
|
private let verboseLogging: Bool
|
||||||
|
@Published var logMessages: [String] = []
|
||||||
|
@Published var showLogs: Bool = false
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
self.verboseLogging = ProcessInfo.processInfo.environment["SPARKLE_VERBOSE_LOGGING"] == "1"
|
self.verboseLogging = ProcessInfo.processInfo.environment["SPARKLE_VERBOSE_LOGGING"] == "1"
|
||||||
@@ -34,6 +36,7 @@ final class SparkleUpdater: NSObject, ObservableObject {
|
|||||||
|
|
||||||
private func log(_ message: String) {
|
private func log(_ message: String) {
|
||||||
logger.log("\(message, privacy: .public)")
|
logger.log("\(message, privacy: .public)")
|
||||||
|
addLogMessage("[INFO] \(message)")
|
||||||
if verboseLogging {
|
if verboseLogging {
|
||||||
print("[Sparkle] \(message)")
|
print("[Sparkle] \(message)")
|
||||||
}
|
}
|
||||||
@@ -41,11 +44,21 @@ final class SparkleUpdater: NSObject, ObservableObject {
|
|||||||
|
|
||||||
private func logError(_ message: String) {
|
private func logError(_ message: String) {
|
||||||
logger.error("\(message, privacy: .public)")
|
logger.error("\(message, privacy: .public)")
|
||||||
|
addLogMessage("[ERROR] \(message)")
|
||||||
if verboseLogging {
|
if verboseLogging {
|
||||||
fputs("[Sparkle][error] \(message)\n", stderr)
|
fputs("[Sparkle][error] \(message)\n", stderr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func addLogMessage(_ message: String) {
|
||||||
|
let timestamp = DateFormatter.localizedString(from: Date(), dateStyle: .none, timeStyle: .medium)
|
||||||
|
let timestampedMessage = "[\(timestamp)] \(message)"
|
||||||
|
logMessages.append(timestampedMessage)
|
||||||
|
if logMessages.count > 100 {
|
||||||
|
logMessages.removeFirst()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func describe(update item: SUAppcastItem) -> String {
|
private func describe(update item: SUAppcastItem) -> String {
|
||||||
let short = item.displayVersionString
|
let short = item.displayVersionString
|
||||||
let build = item.versionString
|
let build = item.versionString
|
||||||
@@ -53,41 +66,63 @@ final class SparkleUpdater: NSObject, ObservableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor
|
|
||||||
extension SparkleUpdater: SPUUpdaterDelegate {
|
extension SparkleUpdater: SPUUpdaterDelegate {
|
||||||
func updater(_ updater: SPUUpdater, didFinishLoading appcast: SUAppcast) {
|
nonisolated func updater(_ updater: SPUUpdater, didFinishLoading appcast: SUAppcast) {
|
||||||
|
Task { @MainActor in
|
||||||
log("Loaded Sparkle appcast containing \(appcast.items.count) item(s).")
|
log("Loaded Sparkle appcast containing \(appcast.items.count) item(s).")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func updater(_ updater: SPUUpdater, didFindValidUpdate item: SUAppcastItem) {
|
nonisolated func updater(_ updater: SPUUpdater, didFindValidUpdate item: SUAppcastItem) {
|
||||||
|
Task { @MainActor in
|
||||||
log("Found valid update \(describe(update: item))")
|
log("Found valid update \(describe(update: item))")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func updaterDidNotFindUpdate(_ updater: SPUUpdater) {
|
nonisolated func updaterDidNotFindUpdate(_ updater: SPUUpdater) {
|
||||||
|
Task { @MainActor in
|
||||||
log("No updates available.")
|
log("No updates available.")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func updater(_ updater: SPUUpdater, willDownloadUpdate item: SUAppcastItem, with request: NSMutableURLRequest) {
|
nonisolated func updater(_ updater: SPUUpdater, willDownloadUpdate item: SUAppcastItem, with request: NSMutableURLRequest) {
|
||||||
|
Task { @MainActor in
|
||||||
log("Downloading \(describe(update: item)) from \(request.url?.absoluteString ?? "unknown URL")")
|
log("Downloading \(describe(update: item)) from \(request.url?.absoluteString ?? "unknown URL")")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func updater(_ updater: SPUUpdater, didDownloadUpdate item: SUAppcastItem) {
|
nonisolated func updater(_ updater: SPUUpdater, didDownloadUpdate item: SUAppcastItem) {
|
||||||
|
Task { @MainActor in
|
||||||
log("Finished downloading \(describe(update: item))")
|
log("Finished downloading \(describe(update: item))")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func updater(_ updater: SPUUpdater, failedToDownloadUpdate item: SUAppcastItem, error: Error) {
|
nonisolated func updater(_ updater: SPUUpdater, failedToDownloadUpdate item: SUAppcastItem, error: Error) {
|
||||||
|
Task { @MainActor in
|
||||||
logError("Failed to download \(describe(update: item)): \(error.localizedDescription)")
|
logError("Failed to download \(describe(update: item)): \(error.localizedDescription)")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func userDidCancelDownload(_ updater: SPUUpdater) {
|
nonisolated func userDidCancelDownload(_ updater: SPUUpdater) {
|
||||||
|
Task { @MainActor in
|
||||||
log("User cancelled Sparkle download.")
|
log("User cancelled Sparkle download.")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func updater(_ updater: SPUUpdater, willInstallUpdate item: SUAppcastItem) {
|
nonisolated func updater(_ updater: SPUUpdater, willInstallUpdate item: SUAppcastItem) {
|
||||||
|
Task { @MainActor in
|
||||||
log("Will install update \(describe(update: item))")
|
log("Will install update \(describe(update: item))")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func updater(_ updater: SPUUpdater, didAbortWithError error: Error) {
|
nonisolated func updater(_ updater: SPUUpdater, didAbortWithError error: Error) {
|
||||||
logError("Sparkle aborted: \(error.localizedDescription)")
|
Task { @MainActor in
|
||||||
|
let errorDescription = error as NSError
|
||||||
|
let details = "Domain: \(errorDescription.domain), Code: \(errorDescription.code), Description: \(error.localizedDescription)"
|
||||||
|
logError("Sparkle aborted: \(details)")
|
||||||
|
if let underlying = errorDescription.userInfo[NSUnderlyingErrorKey] as? NSError {
|
||||||
|
logError("Underlying error: Domain: \(underlying.domain), Code: \(underlying.code), Description: \(underlying.localizedDescription)")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -257,11 +257,64 @@ private struct UpdatesPreferencesView: View {
|
|||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
.padding(.top, 4)
|
.padding(.top, 4)
|
||||||
|
|
||||||
|
Divider()
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
|
||||||
|
Button(action: { sparkleUpdater.showLogs.toggle() }) {
|
||||||
|
Label(sparkleUpdater.showLogs ? "Hide Logs" : "Show Logs", systemImage: "terminal.fill")
|
||||||
|
}
|
||||||
|
|
||||||
|
if sparkleUpdater.showLogs {
|
||||||
|
logsView
|
||||||
|
}
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
.toggleStyle(.switch)
|
.toggleStyle(.switch)
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var logsView: some View {
|
||||||
|
VStack(alignment: .leading, spacing: 8) {
|
||||||
|
Text("Update Logs")
|
||||||
|
.font(.caption)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
|
if sparkleUpdater.logMessages.isEmpty {
|
||||||
|
Text("No logs yet. Check for updates to see activity.")
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.italic()
|
||||||
|
} else {
|
||||||
|
ForEach(sparkleUpdater.logMessages, id: \.self) { message in
|
||||||
|
Text(message)
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.lineLimit(3)
|
||||||
|
.textSelection(.enabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
.padding(8)
|
||||||
|
}
|
||||||
|
.frame(height: 200)
|
||||||
|
.background(Color(nsColor: .controlBackgroundColor))
|
||||||
|
.cornerRadius(6)
|
||||||
|
.border(.separator, width: 1)
|
||||||
|
|
||||||
|
Button(action: {
|
||||||
|
sparkleUpdater.logMessages.removeAll()
|
||||||
|
}) {
|
||||||
|
Label("Clear Logs", systemImage: "trash")
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
|
.disabled(sparkleUpdater.logMessages.isEmpty)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct NotificationsPreferencesView: View {
|
private struct NotificationsPreferencesView: View {
|
||||||
|
|||||||
30
Sparkle/appcast.xml
vendored
30
Sparkle/appcast.xml
vendored
@@ -3,28 +3,28 @@
|
|||||||
<channel>
|
<channel>
|
||||||
<title>iKeyMon</title>
|
<title>iKeyMon</title>
|
||||||
<item>
|
<item>
|
||||||
<title>26.0.30</title>
|
<title>26.0.56</title>
|
||||||
<pubDate>Sun, 07 Dec 2025 17:48:37 +0100</pubDate>
|
<pubDate>Tue, 30 Dec 2025 19:09:34 +0100</pubDate>
|
||||||
<sparkle:version>63</sparkle:version>
|
<sparkle:version>121</sparkle:version>
|
||||||
<sparkle:shortVersionString>26.0.30</sparkle:shortVersionString>
|
<sparkle:shortVersionString>26.0.56</sparkle:shortVersionString>
|
||||||
<sparkle:minimumSystemVersion>15.2</sparkle:minimumSystemVersion>
|
<sparkle:minimumSystemVersion>15.2</sparkle:minimumSystemVersion>
|
||||||
<enclosure url="https://git.24unix.net/tracer/iKeyMon/releases/download/iKeyMon-26.0.30.zip" length="4811494" type="application/octet-stream" sparkle:edSignature="x+Ot/ksA2mzYThyC0dRpYJEy2bmfYBTiSO0FCtwvyqQ+HibLonO0v6HxZH0bUsStWQkNnbURR6tHYWGkOzO3Bw=="/>
|
<enclosure url="https://git.24unix.net/tracer/iKeyMon/releases/download/v26.0.56/iKeyMon-26.0.56.zip" length="3007443" type="application/octet-stream" sparkle:edSignature="m6cENPrqaTn3Y2pP+9UTkKFgNuJy7Rbs0pMxKSpNhBPEK2jwUm0cNNdIbpXWgD0kw6U2pTBLzYoWg7FFJQnqDA=="/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<title>26.0.29</title>
|
<title>26.0.55</title>
|
||||||
<pubDate>Sun, 07 Dec 2025 17:07:32 +0100</pubDate>
|
<pubDate>Tue, 30 Dec 2025 18:59:41 +0100</pubDate>
|
||||||
<sparkle:version>61</sparkle:version>
|
<sparkle:version>119</sparkle:version>
|
||||||
<sparkle:shortVersionString>26.0.29</sparkle:shortVersionString>
|
<sparkle:shortVersionString>26.0.55</sparkle:shortVersionString>
|
||||||
<sparkle:minimumSystemVersion>15.2</sparkle:minimumSystemVersion>
|
<sparkle:minimumSystemVersion>15.2</sparkle:minimumSystemVersion>
|
||||||
<enclosure url="https://git.24unix.net/tracer/iKeyMon/releases/download/v26.0.29/iKeyMon-26.0.29.zip" length="4811507" type="application/octet-stream" sparkle:edSignature="eRH4M8hEYa9gYiyjAVtTpXN3T1o+OGadDRMQu4kHL/dbJ2vj/5pY1+am9/9qG33Qairt3Od/6/WKLyxxs4mWCw=="/>
|
<enclosure url="https://git.24unix.net/tracer/iKeyMon/releases/download/v26.0.55/iKeyMon-26.0.55.zip" length="4842575" type="application/octet-stream" sparkle:edSignature="3xK6KKwXxArmlpuqIgWAQVhAKmv29PB1id/jAMIcwipeGZYcqW9oXvB48tUN6Wu5jyn2QSUjdNmduhfjdWh9CA=="/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<title>26.0.28</title>
|
<title>26.0.54</title>
|
||||||
<pubDate>Sun, 07 Dec 2025 17:02:18 +0100</pubDate>
|
<pubDate>Tue, 30 Dec 2025 18:52:38 +0100</pubDate>
|
||||||
<sparkle:version>59</sparkle:version>
|
<sparkle:version>117</sparkle:version>
|
||||||
<sparkle:shortVersionString>26.0.28</sparkle:shortVersionString>
|
<sparkle:shortVersionString>26.0.54</sparkle:shortVersionString>
|
||||||
<sparkle:minimumSystemVersion>15.2</sparkle:minimumSystemVersion>
|
<sparkle:minimumSystemVersion>15.2</sparkle:minimumSystemVersion>
|
||||||
<enclosure url="https://git.24unix.net/tracer/iKeyMon/releases/download/v26.0.28/iKeyMon-26.0.28.zip" length="4811473" type="application/octet-stream" sparkle:edSignature="tF188T0m/j22MStCVbVkrf2JllyZ9wiEmc++kgF4GTKhoAuHURYvT/Euy+ivEodmQ/LzeFolN4lViqaVa3y+DQ=="/>
|
<enclosure url="https://git.24unix.net/tracer/iKeyMon/releases/download/v26.0.54/iKeyMon-26.0.54.zip" length="4842612" type="application/octet-stream" sparkle:edSignature="cGicDuk+QGTh91UFjBUuDyRx3Qgehuaef2G1KF4KA29kT3qev7zBUAokuZB0TODmBAd6LSw4FQnpEbhvgEF8Dw=="/>
|
||||||
</item>
|
</item>
|
||||||
</channel>
|
</channel>
|
||||||
</rss>
|
</rss>
|
||||||
@@ -6,5 +6,7 @@
|
|||||||
<string>https://git.24unix.net/tracer/iKeyMon/raw/branch/master/Sparkle/appcast.xml</string>
|
<string>https://git.24unix.net/tracer/iKeyMon/raw/branch/master/Sparkle/appcast.xml</string>
|
||||||
<key>SUPublicEDKey</key>
|
<key>SUPublicEDKey</key>
|
||||||
<string>EgJgrOGQ79L5me616jA7kDCEOgx+Rg11uYLYLLIyzTI=</string>
|
<string>EgJgrOGQ79L5me616jA7kDCEOgx+Rg11uYLYLLIyzTI=</string>
|
||||||
|
<key>SUEnableInstallerLauncherService</key>
|
||||||
|
<false/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -2,11 +2,5 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>com.apple.security.app-sandbox</key>
|
|
||||||
<true/>
|
|
||||||
<key>com.apple.security.files.user-selected.read-only</key>
|
|
||||||
<true/>
|
|
||||||
<key>com.apple.security.network.client</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
5221016D2EE5E82700D04952 /* appcast.xml in Resources */ = {isa = PBXBuildFile; fileRef = 5221016B2EE5E82700D04952 /* appcast.xml */; };
|
||||||
52A9B79F2EC8E7EE004DD4A2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 52A9B7872EC8E7EE004DD4A2 /* Assets.xcassets */; };
|
52A9B79F2EC8E7EE004DD4A2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 52A9B7872EC8E7EE004DD4A2 /* Assets.xcassets */; };
|
||||||
52A9B8222EC8FA8A004DD4A2 /* CHANGELOG.md in Resources */ = {isa = PBXBuildFile; fileRef = 52A9B8212EC8FA8A004DD4A2 /* CHANGELOG.md */; };
|
52A9B8222EC8FA8A004DD4A2 /* CHANGELOG.md in Resources */ = {isa = PBXBuildFile; fileRef = 52A9B8212EC8FA8A004DD4A2 /* CHANGELOG.md */; };
|
||||||
52A9B9722ECF751C004DD4A2 /* signing.env.example in Resources */ = {isa = PBXBuildFile; fileRef = 52A9B9712ECF751C004DD4A2 /* signing.env.example */; };
|
52A9B9722ECF751C004DD4A2 /* signing.env.example in Resources */ = {isa = PBXBuildFile; fileRef = 52A9B9712ECF751C004DD4A2 /* signing.env.example */; };
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
5203C24D2D997D2800576D4A /* iKeyMon.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iKeyMon.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
5203C24D2D997D2800576D4A /* iKeyMon.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iKeyMon.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
5221016B2EE5E82700D04952 /* appcast.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = appcast.xml; sourceTree = "<group>"; };
|
||||||
52A9B7872EC8E7EE004DD4A2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
52A9B7872EC8E7EE004DD4A2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
52A9B7882EC8E7EE004DD4A2 /* iKeyMon.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = iKeyMon.entitlements; sourceTree = "<group>"; };
|
52A9B7882EC8E7EE004DD4A2 /* iKeyMon.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = iKeyMon.entitlements; sourceTree = "<group>"; };
|
||||||
52A9B8212EC8FA8A004DD4A2 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = "<group>"; };
|
52A9B8212EC8FA8A004DD4A2 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = "<group>"; };
|
||||||
@@ -76,6 +78,7 @@
|
|||||||
52A9B9712ECF751C004DD4A2 /* signing.env.example */,
|
52A9B9712ECF751C004DD4A2 /* signing.env.example */,
|
||||||
52A9BEC92ED3874F004DD4A2 /* README.md */,
|
52A9BEC92ED3874F004DD4A2 /* README.md */,
|
||||||
52A9BD122ED37E08004DD4A2 /* Frameworks */,
|
52A9BD122ED37E08004DD4A2 /* Frameworks */,
|
||||||
|
5221016C2EE5E82700D04952 /* Sparkle */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
@@ -87,6 +90,14 @@
|
|||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
5221016C2EE5E82700D04952 /* Sparkle */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
5221016B2EE5E82700D04952 /* appcast.xml */,
|
||||||
|
);
|
||||||
|
path = Sparkle;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
52A9BD122ED37E08004DD4A2 /* Frameworks */ = {
|
52A9BD122ED37E08004DD4A2 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -166,6 +177,7 @@
|
|||||||
files = (
|
files = (
|
||||||
52A9B8222EC8FA8A004DD4A2 /* CHANGELOG.md in Resources */,
|
52A9B8222EC8FA8A004DD4A2 /* CHANGELOG.md in Resources */,
|
||||||
52A9BECA2ED3874F004DD4A2 /* README.md in Resources */,
|
52A9BECA2ED3874F004DD4A2 /* README.md in Resources */,
|
||||||
|
5221016D2EE5E82700D04952 /* appcast.xml in Resources */,
|
||||||
52A9B79F2EC8E7EE004DD4A2 /* Assets.xcassets in Resources */,
|
52A9B79F2EC8E7EE004DD4A2 /* Assets.xcassets in Resources */,
|
||||||
52A9B9722ECF751C004DD4A2 /* signing.env.example in Resources */,
|
52A9B9722ECF751C004DD4A2 /* signing.env.example in Resources */,
|
||||||
);
|
);
|
||||||
@@ -310,7 +322,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = iKeyMon.entitlements;
|
CODE_SIGN_ENTITLEMENTS = iKeyMon.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 63;
|
CURRENT_PROJECT_VERSION = 121;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = Q5486ZVAFT;
|
DEVELOPMENT_TEAM = Q5486ZVAFT;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
@@ -325,7 +337,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 26.0.30;
|
MARKETING_VERSION = 26.0.56;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.24unix.iKeyMon;
|
PRODUCT_BUNDLE_IDENTIFIER = net.24unix.iKeyMon;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
@@ -341,7 +353,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = iKeyMon.entitlements;
|
CODE_SIGN_ENTITLEMENTS = iKeyMon.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 63;
|
CURRENT_PROJECT_VERSION = 121;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = Q5486ZVAFT;
|
DEVELOPMENT_TEAM = Q5486ZVAFT;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
@@ -356,7 +368,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 26.0.30;
|
MARKETING_VERSION = 26.0.56;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.24unix.iKeyMon;
|
PRODUCT_BUNDLE_IDENTIFIER = net.24unix.iKeyMon;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ generate_appcast() {
|
|||||||
download_prefix="${SPARKLE_DOWNLOAD_BASE_URL%/}/v${VERSION}"
|
download_prefix="${SPARKLE_DOWNLOAD_BASE_URL%/}/v${VERSION}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Ensure the version segment is present to match Gitea's /download/vX.Y.Z/ layout.
|
||||||
|
if [[ -n "$download_prefix" ]] && [[ "$download_prefix" != *"/$VERSION"* ]]; then
|
||||||
|
download_prefix="${download_prefix%/}/v${VERSION}"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -z "$generator" || -z "${SPARKLE_EDDSA_KEY_FILE:-}" || -z "$download_prefix" ]]; then
|
if [[ -z "$generator" || -z "${SPARKLE_EDDSA_KEY_FILE:-}" || -z "$download_prefix" ]]; then
|
||||||
echo "ℹ️ Skipping Sparkle appcast generation (generator/key/download prefix not configured)."
|
echo "ℹ️ Skipping Sparkle appcast generation (generator/key/download prefix not configured)."
|
||||||
return
|
return
|
||||||
@@ -160,7 +165,6 @@ if [[ -n "${CODESIGN_IDENTITY:-}" ]]; then
|
|||||||
--force \
|
--force \
|
||||||
--options runtime \
|
--options runtime \
|
||||||
--timestamp \
|
--timestamp \
|
||||||
--entitlements "$ROOT_DIR/iKeyMon.entitlements" \
|
|
||||||
--sign "$CODESIGN_IDENTITY" \
|
--sign "$CODESIGN_IDENTITY" \
|
||||||
"$APP_PATH"
|
"$APP_PATH"
|
||||||
else
|
else
|
||||||
@@ -184,9 +188,7 @@ print(data.get("marketing_version", "dev"))
|
|||||||
PY
|
PY
|
||||||
)"
|
)"
|
||||||
ZIP_NAME="iKeyMon-${VERSION}.zip"
|
ZIP_NAME="iKeyMon-${VERSION}.zip"
|
||||||
pushd "$(dirname "$APP_PATH")" >/dev/null
|
ditto -c -k --keepParent "$APP_PATH" "$ARTIFACTS_DIR/$ZIP_NAME"
|
||||||
zip -r "$ARTIFACTS_DIR/$ZIP_NAME" "$(basename "$APP_PATH")"
|
|
||||||
popd >/dev/null
|
|
||||||
|
|
||||||
DMG_NAME="iKeyMon-${VERSION}.dmg"
|
DMG_NAME="iKeyMon-${VERSION}.dmg"
|
||||||
hdiutil create -volname "iKeyMon" -srcfolder "$STAGING_DIR" -ov -format UDZO "$ARTIFACTS_DIR/$DMG_NAME"
|
hdiutil create -volname "iKeyMon" -srcfolder "$STAGING_DIR" -ov -format UDZO "$ARTIFACTS_DIR/$DMG_NAME"
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"marketing_version": "26.0.30"
|
"marketing_version": "26.0.56"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user