From 7d58997c42d84c116a4be56834ab23a743b2eab1 Mon Sep 17 00:00:00 2001 From: Gordon Beeming Date: Wed, 15 Jul 2026 22:33:54 +1000 Subject: [PATCH 1/3] Add Applications shortcut to update DMG --- .github/workflows/build.yml | 7 ++++++- Sources/Insomnia/Update/UpdateChecker.swift | 4 ++-- Sources/Insomnia/Views/MenuBarView.swift | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 24a2a4f..a973902 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -198,10 +198,15 @@ jobs: run: | VERSION="${GITHUB_REF_NAME#v}" DMG="Distribution/Insomnia-${VERSION}.dmg" + DMG_ROOT="${RUNNER_TEMP}/insomnia-dmg" + + mkdir -p "${DMG_ROOT}" + ditto Distribution/Insomnia.app "${DMG_ROOT}/Insomnia.app" + ln -s /Applications "${DMG_ROOT}/Applications" hdiutil create \ -volname "Insomnia" \ - -srcfolder Distribution/Insomnia.app \ + -srcfolder "${DMG_ROOT}" \ -ov \ -format UDZO \ "${DMG}" diff --git a/Sources/Insomnia/Update/UpdateChecker.swift b/Sources/Insomnia/Update/UpdateChecker.swift index 3e0574c..08c8efe 100644 --- a/Sources/Insomnia/Update/UpdateChecker.swift +++ b/Sources/Insomnia/Update/UpdateChecker.swift @@ -151,14 +151,14 @@ final class UpdateChecker { } } - // MARK: - Download and Install + // MARK: - Download Update /// Downloads the latest DMG and opens it for the user to install. /// /// The DMG is saved to `~/Downloads` and automatically mounted /// via `NSWorkspace` so the user can drag the app to Applications. /// File I/O is performed off the main thread to avoid UI jank. - func downloadAndInstall() async { + func downloadAndOpenInstaller() async { guard let url = downloadURL else { lastError = "No download URL available" return diff --git a/Sources/Insomnia/Views/MenuBarView.swift b/Sources/Insomnia/Views/MenuBarView.swift index de86103..4d292bb 100644 --- a/Sources/Insomnia/Views/MenuBarView.swift +++ b/Sources/Insomnia/Views/MenuBarView.swift @@ -177,7 +177,7 @@ struct MenuBarView: View { } else if updateChecker.downloadURL != nil { // DMG available — offer direct download Button("Download v\(version)") { - Task { await updateChecker.downloadAndInstall() } + Task { await updateChecker.downloadAndOpenInstaller() } } } else { // Update exists but no DMG asset — show version info only From 0c932cbebecd7a3a1405ea59fb1b7085c02fc7f9 Mon Sep 17 00:00:00 2001 From: Gordon Beeming Date: Wed, 15 Jul 2026 22:36:57 +1000 Subject: [PATCH 2/3] Isolate installer updates to the main actor --- Sources/Insomnia/Update/UpdateChecker.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/Insomnia/Update/UpdateChecker.swift b/Sources/Insomnia/Update/UpdateChecker.swift index 08c8efe..53bf643 100644 --- a/Sources/Insomnia/Update/UpdateChecker.swift +++ b/Sources/Insomnia/Update/UpdateChecker.swift @@ -158,6 +158,7 @@ final class UpdateChecker { /// The DMG is saved to `~/Downloads` and automatically mounted /// via `NSWorkspace` so the user can drag the app to Applications. /// File I/O is performed off the main thread to avoid UI jank. + @MainActor func downloadAndOpenInstaller() async { guard let url = downloadURL else { lastError = "No download URL available" From 28fa77c70845fa8985686d2eea5900526390dc74 Mon Sep 17 00:00:00 2001 From: Gordon Beeming Date: Wed, 15 Jul 2026 22:39:33 +1000 Subject: [PATCH 3/3] Reset DMG staging before packaging --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a973902..a2bd64a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -200,6 +200,7 @@ jobs: DMG="Distribution/Insomnia-${VERSION}.dmg" DMG_ROOT="${RUNNER_TEMP}/insomnia-dmg" + rm -rf "${DMG_ROOT}" mkdir -p "${DMG_ROOT}" ditto Distribution/Insomnia.app "${DMG_ROOT}/Insomnia.app" ln -s /Applications "${DMG_ROOT}/Applications"