Skip auto-update for dev builds
`make install` now stamps "dev" as the local SHA256, which tells the auto-updater to skip update checks entirely. DMG-based installs continue to work normally with real SHA256 comparison. Clicking "Check for Updates" on a dev build shows a clear "Dev Build" message instead of prompting to downgrade. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
c14ab51724
commit
9746499231
4
Makefile
4
Makefile
|
|
@ -53,7 +53,9 @@ install: bundle
|
|||
@rm -rf /Applications/$(APP_NAME).app
|
||||
@cp -R $(APP_BUNDLE) /Applications/$(APP_NAME).app
|
||||
@xattr -cr /Applications/$(APP_NAME).app
|
||||
@echo "Installed /Applications/$(APP_NAME).app"
|
||||
@mkdir -p "$(HOME)/Library/Application Support/Pommedoro"
|
||||
@echo "dev" > "$(HOME)/Library/Application Support/Pommedoro/current.sha256"
|
||||
@echo "Installed /Applications/$(APP_NAME).app (dev build – auto-update disabled)"
|
||||
|
||||
run: bundle
|
||||
@open $(APP_BUNDLE)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ enum AutoUpdater {
|
|||
|
||||
// MARK: - Configuration
|
||||
|
||||
/// Sentinel value written by `make install` to indicate a dev build.
|
||||
/// The updater skips automatic updates when this is the local stamp.
|
||||
private static let devSentinel = "dev"
|
||||
|
||||
/// Raw URL for the SHA256 file in the repo (Gitea raw endpoint)
|
||||
private static let remoteSHA256URL = URL(
|
||||
string: "https://git.nixc.us/colin/pommedoro/raw/branch/main/releases/Pommedoro.dmg.sha256"
|
||||
|
|
@ -49,48 +53,56 @@ enum AutoUpdater {
|
|||
// MARK: - Core Logic
|
||||
|
||||
private static func performCheck(silent: Bool) {
|
||||
// 1. Fetch remote SHA256
|
||||
// 1. Read local SHA256 (written at last install/build)
|
||||
let localSHA = readLocalSHA()
|
||||
|
||||
// 2. Dev builds are stamped "dev" – skip silent checks entirely
|
||||
if localSHA == devSentinel {
|
||||
if !silent {
|
||||
showAlert(title: "Dev Build", message: "Auto-update is disabled for local dev builds.")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 3. Fetch remote SHA256
|
||||
guard let remoteSHA = fetchRemoteSHA() else {
|
||||
if !silent { showAlert(title: "Update Check Failed", message: "Could not reach the update server.") }
|
||||
return
|
||||
}
|
||||
|
||||
// 2. Read local SHA256 (written at last install/build)
|
||||
let localSHA = readLocalSHA()
|
||||
|
||||
// 3. Compare
|
||||
// 4. Compare
|
||||
if remoteSHA == localSHA {
|
||||
if !silent { showAlert(title: "Up to Date", message: "You are running the latest version.") }
|
||||
return
|
||||
}
|
||||
|
||||
// 4. There's an update – prompt user
|
||||
// 5. There's an update – prompt user
|
||||
let shouldUpdate = promptForUpdate()
|
||||
guard shouldUpdate else { return }
|
||||
|
||||
// 5. Download new DMG
|
||||
// 6. Download new DMG
|
||||
guard downloadDMG() else {
|
||||
showAlert(title: "Update Failed", message: "Could not download the update.")
|
||||
return
|
||||
}
|
||||
|
||||
// 6. Verify downloaded DMG matches remote SHA
|
||||
// 7. Verify downloaded DMG matches remote SHA
|
||||
guard let downloadedSHA = sha256(of: downloadedDMGPath), downloadedSHA == remoteSHA else {
|
||||
showAlert(title: "Update Failed", message: "Downloaded file integrity check failed.")
|
||||
try? FileManager.default.removeItem(at: downloadedDMGPath)
|
||||
return
|
||||
}
|
||||
|
||||
// 7. Extract new app from DMG to staging area
|
||||
// 8. Extract new app from DMG to staging area
|
||||
guard stageFromDMG() else {
|
||||
showAlert(title: "Update Failed", message: "Could not extract the update.")
|
||||
return
|
||||
}
|
||||
|
||||
// 8. Save new SHA so we don't re-update next launch
|
||||
// 9. Save new SHA so we don't re-update next launch
|
||||
try? remoteSHA.write(to: localSHAPath, atomically: true, encoding: .utf8)
|
||||
|
||||
// 9. Spawn swap script, then terminate so applicationWillTerminate saves state
|
||||
// 10. Spawn swap script, then terminate so applicationWillTerminate saves state
|
||||
spawnSwapAndRelaunch()
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
|
@ -142,7 +154,7 @@ enum AutoUpdater {
|
|||
|
||||
// MARK: - SHA256 Computation
|
||||
|
||||
private static func sha256(of fileURL: URL) -> String? {
|
||||
static func sha256(of fileURL: URL) -> String? {
|
||||
guard let handle = try? FileHandle(forReadingFrom: fileURL) else { return nil }
|
||||
defer { handle.closeFile() }
|
||||
|
||||
|
|
@ -242,7 +254,6 @@ enum AutoUpdater {
|
|||
proc.arguments = [scriptPath]
|
||||
proc.standardOutput = FileHandle.nullDevice
|
||||
proc.standardError = FileHandle.nullDevice
|
||||
// Detach from our process group so it survives our exit
|
||||
proc.qualityOfService = .utility
|
||||
try? proc.run()
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
7e15ab9b42481c28c9566c7d71bad03558bb2cdec7dcceb956443caf5cb1724a
|
||||
98fa348545458a05d36e15656fdd788564e309784c4536a060499f0827141260
|
||||
|
|
|
|||
Loading…
Reference in New Issue