diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index 96ca4bd89e..9725c24f5b 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -700,12 +700,15 @@ function dispatchMenuAction(action: string): void { } function handleCheckForUpdatesMenuClick(): void { + const hasUpdateFeedConfig = + readAppUpdateYml() !== null || Boolean(process.env.T3CODE_DESKTOP_MOCK_UPDATES); const disabledReason = getAutoUpdateDisabledReason({ isDevelopment, isPackaged: app.isPackaged, platform: process.platform, appImage: process.env.APPIMAGE, disabledByEnv: process.env.T3CODE_DISABLE_AUTO_UPDATE === "1", + hasUpdateFeedConfig, }); if (disabledReason) { console.info("[desktop-updater] Manual update check requested, but updates are disabled."); @@ -942,6 +945,8 @@ function setUpdateState(patch: Partial): void { } function shouldEnableAutoUpdates(): boolean { + const hasUpdateFeedConfig = + readAppUpdateYml() !== null || Boolean(process.env.T3CODE_DESKTOP_MOCK_UPDATES); return ( getAutoUpdateDisabledReason({ isDevelopment, @@ -949,6 +954,7 @@ function shouldEnableAutoUpdates(): boolean { platform: process.platform, appImage: process.env.APPIMAGE, disabledByEnv: process.env.T3CODE_DISABLE_AUTO_UPDATE === "1", + hasUpdateFeedConfig, }) === null ); } @@ -1032,17 +1038,6 @@ async function installDownloadedUpdate(): Promise<{ accepted: boolean; completed } function configureAutoUpdater(): void { - const enabled = shouldEnableAutoUpdates(); - setUpdateState({ - ...createInitialDesktopUpdateState(app.getVersion(), desktopRuntimeInfo), - enabled, - status: enabled ? "idle" : "disabled", - }); - if (!enabled) { - return; - } - updaterConfigured = true; - const githubToken = process.env.T3CODE_DESKTOP_UPDATE_GITHUB_TOKEN?.trim() || process.env.GH_TOKEN?.trim() || ""; if (githubToken) { @@ -1067,6 +1062,17 @@ function configureAutoUpdater(): void { }); } + const enabled = shouldEnableAutoUpdates(); + setUpdateState({ + ...createInitialDesktopUpdateState(app.getVersion(), desktopRuntimeInfo), + enabled, + status: enabled ? "idle" : "disabled", + }); + if (!enabled) { + return; + } + updaterConfigured = true; + autoUpdater.autoDownload = false; autoUpdater.autoInstallOnAppQuit = false; // Keep alpha branding, but force all installs onto the stable update track. diff --git a/apps/desktop/src/updateState.test.ts b/apps/desktop/src/updateState.test.ts index 43b718bd00..8db92e1915 100644 --- a/apps/desktop/src/updateState.test.ts +++ b/apps/desktop/src/updateState.test.ts @@ -71,10 +71,37 @@ describe("getAutoUpdateDisabledReason", () => { platform: "darwin", appImage: undefined, disabledByEnv: false, + hasUpdateFeedConfig: true, }), ).toContain("packaged production builds"); }); + it("reports packaged local builds without an update feed as disabled", () => { + expect( + getAutoUpdateDisabledReason({ + isDevelopment: false, + isPackaged: true, + platform: "darwin", + appImage: undefined, + disabledByEnv: false, + hasUpdateFeedConfig: false, + }), + ).toContain("no update feed"); + }); + + it("allows packaged builds with an update feed", () => { + expect( + getAutoUpdateDisabledReason({ + isDevelopment: false, + isPackaged: true, + platform: "darwin", + appImage: undefined, + disabledByEnv: false, + hasUpdateFeedConfig: true, + }), + ).toBeNull(); + }); + it("reports env-disabled auto updates", () => { expect( getAutoUpdateDisabledReason({ @@ -83,6 +110,7 @@ describe("getAutoUpdateDisabledReason", () => { platform: "darwin", appImage: undefined, disabledByEnv: true, + hasUpdateFeedConfig: true, }), ).toContain("T3CODE_DISABLE_AUTO_UPDATE"); }); @@ -95,6 +123,7 @@ describe("getAutoUpdateDisabledReason", () => { platform: "linux", appImage: undefined, disabledByEnv: false, + hasUpdateFeedConfig: true, }), ).toContain("AppImage"); }); diff --git a/apps/desktop/src/updateState.ts b/apps/desktop/src/updateState.ts index 8c8ef1ddc9..928bb40886 100644 --- a/apps/desktop/src/updateState.ts +++ b/apps/desktop/src/updateState.ts @@ -34,7 +34,11 @@ export function getAutoUpdateDisabledReason(args: { platform: NodeJS.Platform; appImage?: string | undefined; disabledByEnv: boolean; + hasUpdateFeedConfig: boolean; }): string | null { + if (!args.hasUpdateFeedConfig) { + return "Automatic updates are not available because no update feed is configured."; + } if (args.isDevelopment || !args.isPackaged) { return "Automatic updates are only available in packaged production builds."; }