mirror of
https://github.com/eigent-ai/eigent.git
synced 2026-05-22 19:47:28 +00:00
193 lines
5.8 KiB
TypeScript
193 lines
5.8 KiB
TypeScript
// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
|
|
|
|
import { app, ipcMain } from 'electron';
|
|
import type {
|
|
ProgressInfo,
|
|
UpdateDownloadedEvent,
|
|
UpdateInfo,
|
|
} from 'electron-updater';
|
|
import { createRequire } from 'node:module';
|
|
import {
|
|
DEFAULT_CDN_RELEASE_BASE_URL,
|
|
getGitHubReleaseChannel,
|
|
getUpdatePlatformDirectory,
|
|
GitHubReleaseCdnProvider,
|
|
} from './githubReleaseCdnProvider';
|
|
|
|
const { autoUpdater } = createRequire(import.meta.url)('electron-updater');
|
|
|
|
export function update(win: Electron.BrowserWindow) {
|
|
// When set to false, the update download will be triggered through the API
|
|
autoUpdater.verifyUpdateCodeSignature = false;
|
|
autoUpdater.autoDownload = false;
|
|
autoUpdater.disableWebInstaller = false;
|
|
autoUpdater.allowDowngrade = false;
|
|
|
|
autoUpdater.forceDevUpdateConfig = true;
|
|
|
|
// start check
|
|
autoUpdater.on('checking-for-update', function () {});
|
|
// update available
|
|
autoUpdater.on('update-available', (arg: UpdateInfo) => {
|
|
if (win && !win.isDestroyed()) {
|
|
win.webContents.send('update-can-available', {
|
|
update: true,
|
|
version: app.getVersion(),
|
|
newVersion: arg?.version,
|
|
});
|
|
}
|
|
});
|
|
// update not available
|
|
autoUpdater.on('update-not-available', (arg: UpdateInfo) => {
|
|
if (win && !win.isDestroyed()) {
|
|
win.webContents.send('update-can-available', {
|
|
update: false,
|
|
version: app.getVersion(),
|
|
newVersion: arg?.version,
|
|
});
|
|
}
|
|
});
|
|
console.log('Current version:', autoUpdater.currentVersion.version);
|
|
console.log('Update config path:', autoUpdater.getUpdateConfigPath?.());
|
|
console.log('User data path (where config lives):', app.getPath('userData'));
|
|
const platformDir = getUpdatePlatformDirectory(
|
|
process.platform,
|
|
process.arch
|
|
);
|
|
|
|
if (!platformDir) {
|
|
console.warn(
|
|
`[AutoUpdater] Updates are not configured for ${process.platform}/${process.arch}`
|
|
);
|
|
return;
|
|
}
|
|
|
|
const cdnBaseUrl =
|
|
process.env.EIGENT_UPDATER_CDN_BASE_URL || DEFAULT_CDN_RELEASE_BASE_URL;
|
|
const channel = getGitHubReleaseChannel(process.platform, process.arch);
|
|
const feed = {
|
|
provider: 'custom' as const,
|
|
updateProvider: GitHubReleaseCdnProvider,
|
|
owner: 'eigent-ai',
|
|
repo: 'eigent',
|
|
releaseType: 'release' as const,
|
|
channel,
|
|
cdnBaseUrl,
|
|
platformDir,
|
|
};
|
|
|
|
autoUpdater.setFeedURL(feed);
|
|
console.log('[AutoUpdater] setFeedURL:', feed);
|
|
|
|
if (app.isPackaged) {
|
|
autoUpdater.checkForUpdatesAndNotify().catch((err: Error) => {
|
|
console.log('[AutoUpdater] Initial update check failed:', err.message);
|
|
});
|
|
}
|
|
|
|
if (!app.isPackaged) {
|
|
// In development, check for updates but don't fail if it errors
|
|
autoUpdater.checkForUpdates().catch((err: Error) => {
|
|
console.log(
|
|
'[DEV] Update check failed (expected in dev environment):',
|
|
err.message
|
|
);
|
|
});
|
|
}
|
|
|
|
// Handle errors globally to prevent crashes
|
|
autoUpdater.on('error', (error: Error) => {
|
|
console.error('[AutoUpdater] Update error:', error.message);
|
|
// Don't crash the app on update errors
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Registers update-related IPC handlers
|
|
* Should be called once when the app starts
|
|
*/
|
|
export function registerUpdateIpcHandlers() {
|
|
// Checking for updates - errors are silent since users can't act on them
|
|
ipcMain.handle('check-update', async () => {
|
|
try {
|
|
return await autoUpdater.checkForUpdatesAndNotify();
|
|
} catch (error) {
|
|
console.log(
|
|
'[AutoUpdater] Update check failed:',
|
|
(error as Error).message
|
|
);
|
|
return null;
|
|
}
|
|
});
|
|
|
|
// Start downloading and feedback on progress
|
|
ipcMain.handle('start-download', (event: Electron.IpcMainInvokeEvent) => {
|
|
startDownload(
|
|
(error, progressInfo) => {
|
|
if (error) {
|
|
// feedback download error message
|
|
if (!event.sender.isDestroyed()) {
|
|
event.sender.send('update-error', {
|
|
message: error.message,
|
|
error,
|
|
});
|
|
}
|
|
} else {
|
|
// feedback update progress message
|
|
if (!event.sender.isDestroyed()) {
|
|
event.sender.send('download-progress', progressInfo);
|
|
}
|
|
}
|
|
},
|
|
() => {
|
|
// feedback update downloaded message
|
|
if (!event.sender.isDestroyed()) {
|
|
event.sender.send('update-downloaded');
|
|
}
|
|
}
|
|
);
|
|
});
|
|
|
|
// Install now
|
|
ipcMain.handle('quit-and-install', () => {
|
|
autoUpdater.quitAndInstall(false, true);
|
|
});
|
|
}
|
|
|
|
function startDownload(
|
|
callback: (error: Error | null, info: ProgressInfo | null) => void,
|
|
complete: (event: UpdateDownloadedEvent) => void
|
|
) {
|
|
const nativeMacUpdater =
|
|
process.platform === 'darwin'
|
|
? ((autoUpdater as { nativeUpdater?: NodeJS.EventEmitter })
|
|
.nativeUpdater ?? null)
|
|
: null;
|
|
|
|
autoUpdater.on('download-progress', (info: ProgressInfo) =>
|
|
callback(null, info)
|
|
);
|
|
autoUpdater.on('error', (error: Error) => callback(error, null));
|
|
|
|
if (nativeMacUpdater) {
|
|
nativeMacUpdater.once('update-downloaded', () =>
|
|
complete({} as UpdateDownloadedEvent)
|
|
);
|
|
} else {
|
|
autoUpdater.on('update-downloaded', complete);
|
|
}
|
|
|
|
autoUpdater.downloadUpdate();
|
|
}
|