Skip to content

Commit dd846c7

Browse files
committed
Enhance update management
1 parent 7130066 commit dd846c7

14 files changed

Lines changed: 585 additions & 86 deletions

File tree

docs/contributing.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ GitHub Actions packages macOS (universal DMG) and Windows (NSIS) when you add a
5151

5252
If you already published a GitHub Release for that tag, CI deletes that release (the tag stays) and creates a draft so the files can be uploaded.
5353

54-
The download site lists the newest published release that has installers, including prereleases. The in-app update checker follows the Stable or Pre-release choice in App settings. Drafts are ignored. `/releases/latest` is not used, because that endpoint skips prereleases.
54+
The download site lists the newest published release that has installers, including prereleases. The packaged app uses electron-updater to download and install that release. Keep these files on the published GitHub release: `latest-mac.yml`, `latest.yml`, `Dagr_<version>.zip`, `Dagr_<version>.exe`, and the matching `.blockmap` files. The in-app update checker follows the Stable or Pre-release choice in App settings. Drafts are ignored. Stable uses published full releases. Pre-release sets `allowPrerelease`.
5555

5656
The GitHub repository must be public for those checks to work in the packaged app. A private repo makes the unauthenticated GitHub API return 404. The website can set `GITHUB_TOKEN` if you still need to read a private repo. The desktop app can use `DAGR_GITHUB_TOKEN` or `GITHUB_TOKEN` for local checks only. Do not ship a token in the app.
5757

58-
Builds are unsigned in this pass.
58+
Builds are unsigned in this pass. Unsigned macOS builds often cannot replace the running app, so the UI falls back to opening the GitHub DMG. Signing and notarization come later.
5959

6060
## Download website
6161

docs/desktop/preferences.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ The gear on the left rail opens settings for this device.
2727

2828
**Appearance:** Light, Dark, or System.
2929

30-
**Updates:** choose **Stable** or **Pre-release**, then **Check for updates**. A download link appears when a newer GitHub release exists on that channel. A banner also appears after launch if an update is waiting. Automatic checks are skipped when you run the app from source. **Check for updates** still talks to GitHub.
30+
**Updates:** choose **Stable** or **Pre-release**, then **Check for updates**. The packaged app downloads a newer build in the background. When the file is ready, **Restart to update** applies it. If in-app install cannot run (common on unsigned macOS builds), **Download update** still opens the installer from GitHub. A banner also appears after launch if an update is waiting. Automatic checks are skipped when you run the app from source. **Check for updates** still talks to GitHub.
3131

3232
**Media:** **GIFs on hover only** keeps GIFs still until you move the pointer over them.
3333

web/electron/main/index.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import { Notification, app, BrowserWindow, ipcMain, nativeTheme, shell } from 'electron'
2-
import { checkForUpdates, openUpdateUrl } from './updates'
2+
import {
3+
checkForUpdates,
4+
installDownloadedUpdate,
5+
openUpdateUrl,
6+
subscribeUpdateState,
7+
type UpdateCheckResult,
8+
} from './updates'
39
import { existsSync, readFileSync } from 'node:fs'
410
import { fileURLToPath } from 'node:url'
511
import path from 'node:path'
@@ -187,6 +193,11 @@ function focusMainWindow() {
187193
win.focus()
188194
}
189195

196+
function sendUpdateState(state: UpdateCheckResult) {
197+
if (!win || win.isDestroyed()) return
198+
win.webContents.send('updates:state', state)
199+
}
200+
190201
app.whenReady().then(() => {
191202
configureAboutPanel()
192203

@@ -210,6 +221,8 @@ app.whenReady().then(() => {
210221
return { ok: true, count: next }
211222
})
212223

224+
subscribeUpdateState(sendUpdateState)
225+
213226
ipcMain.handle('updates:check', async (_event, payload: unknown) => {
214227
const body =
215228
typeof payload === 'object' && payload !== null
@@ -221,6 +234,11 @@ app.whenReady().then(() => {
221234
})
222235
})
223236

237+
ipcMain.handle('updates:install', async (_event, target: unknown) => {
238+
const url = typeof target === 'string' ? target : undefined
239+
return installDownloadedUpdate(url)
240+
})
241+
224242
ipcMain.handle('updates:open', async (_event, target: unknown) => {
225243
const url = typeof target === 'string' ? target : undefined
226244
return openUpdateUrl(url)

0 commit comments

Comments
 (0)