From c498dd7cc1d2839ad10db859f82c4f678fc8e14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 23 Apr 2024 16:03:07 +0800 Subject: [PATCH] =?UTF-8?q?feature:=201=EF=BC=89=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=20github=20api=EF=BC=8C=E6=9D=A5=E8=8E=B7=E5=8F=96=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E6=95=B0=E6=8D=AE=EF=BC=9B2=EF=BC=89=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=A3=80=E6=9F=A5=E6=9B=B4=E6=96=B0=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E5=8F=AF=E9=85=8D=E7=BD=AE=E5=8C=96=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/config/index.js | 2 + packages/gui/src/bridge/update/backend.js | 132 ++++++++++++++++++++-- packages/gui/src/bridge/update/front.js | 109 ++++++++++-------- packages/gui/src/view/pages/index.vue | 10 +- packages/gui/src/view/pages/setting.vue | 23 ++++ 5 files changed, 211 insertions(+), 65 deletions(-) diff --git a/packages/core/src/config/index.js b/packages/core/src/config/index.js index c4753a1..1a63b82 100644 --- a/packages/core/src/config/index.js +++ b/packages/core/src/config/index.js @@ -24,6 +24,8 @@ module.exports = { url: 'https://gitee.com/wangliang181230/dev-sidecar/raw/docmirror/packages/core/src/config/remote_config.json5' }, theme: 'light', // 主题:light=亮色, dark=暗色 + autoChecked: true, // 是否自动检查更新 + skipPreRelease: true, // 是否忽略预发布版本 dock: { hideWhenWinClose: false }, diff --git a/packages/gui/src/bridge/update/backend.js b/packages/gui/src/bridge/update/backend.js index f0e6195..43b3f07 100644 --- a/packages/gui/src/bridge/update/backend.js +++ b/packages/gui/src/bridge/update/backend.js @@ -3,17 +3,19 @@ import { autoUpdater } from 'electron-updater' import path from 'path' import request from 'request' import progress from 'request-progress' -// win是所有窗口的引用 import fs from 'fs' import AdmZip from 'adm-zip' -import logger from '../../utils/util.log' +import log from '../../utils/util.log' import appPathUtil from '../../utils/util.apppath' +import pkg from '../../../package.json' +import DevSidecar from '@docmirror/dev-sidecar' + // eslint-disable-next-line no-unused-vars const isMac = process.platform === 'darwin' const isLinux = process.platform === 'linux' function downloadFile (uri, filePath, onProgress, onSuccess, onError) { - logger.info('download url', uri) + log.info('download url', uri) progress(request(uri), { // throttle: 2000, // Throttle the progress event to 2000ms, defaults to 1000ms // delay: 1000, // Only start to emit after 1000ms delay, defaults to 0ms @@ -21,11 +23,11 @@ function downloadFile (uri, filePath, onProgress, onSuccess, onError) { }) .on('progress', function (state) { onProgress(state.percent * 100) - logger.log('progress', state.percent) + log.log('progress', state.percent) }) .on('error', function (err) { // Do something with err - logger.error('下载升级包失败', err) + log.error('下载升级包失败', err) onError(err) }) .on('end', function () { @@ -35,7 +37,11 @@ function downloadFile (uri, filePath, onProgress, onSuccess, onError) { .pipe(fs.createWriteStream(filePath)) } -// 检测更新,在你想要检查更新的时候执行,renderer事件触发后的操作自行编写 +/** + * 检测更新,在你想要检查更新的时候执行,renderer事件触发后的操作自行编写 + * + * @param win win是所有窗口的引用 + */ function updateHandle (app, api, win, beforeQuit, quit, log) { // // 更新前,删除本地安装包 ↓ // const updaterCacheDirName = 'dev-sidecar-updater' @@ -64,15 +70,115 @@ function updateHandle (app, api, win, beforeQuit, quit, log) { } } - logger.info('auto updater', autoUpdater.getFeedURL()) + log.info('auto updater', autoUpdater.getFeedURL()) autoUpdater.autoDownload = false let partPackagePath = null + // 检查更新 + const releasesApiUrl = 'https://api.github.com/repos/docmirror/dev-sidecar/releases' + async function checkForUpdatesFromGitHub () { + log.info('DevSidecar.api.config.app.skipPreRelease:', DevSidecar.api.config.get().app.skipPreRelease) + request(releasesApiUrl, { headers: { 'User-Agent': 'DS/' + pkg.version } }, (error, response, body) => { + try { + if (error) { + log.error('检查更新失败:', error) + const errorMsg = '检查更新失败:' + error + win.webContents.send('update', { key: 'error', error: errorMsg }) + return + } + if (response && response.statusCode === 200) { + if (body == null || body.length < 2) { + log.warn('检查更新失败,github API返回数据为空:', body) + win.webContents.send('update', { key: 'error', error: '检查更新失败,github 返回数据为空' }) + return + } + + // 尝试解析API响应内容 + let data + try { + data = JSON.parse(body) + } catch (e) { + log.error(`检查更新失败,github API返回数据格式不正确, url: ${releasesApiUrl}, body: ${body}`) + win.webContents.send('update', { key: 'error', error: '检查更新失败,github API返回数据格式不正确' }) + return + } + + if (typeof data !== 'object' || data.length === undefined) { + win.webContents.send('update', { key: 'error', error: '检查更新失败,github API返回数据格式不正确' }) + return + } + + log.info('github api返回的release数据:', JSON.stringify(data, null, '\t')) + + // 检查更新 + for (let i = 0; i < data.length; i++) { + const versionData = data[i] + + if (!versionData.assets || versionData.assets.length === 0) { + continue // 跳过空版本,即上传过安装包 + } + if (DevSidecar.api.config.app.skipPreRelease && versionData.name.indexOf('Pre-release') >= 0) { + continue // 跳过预发布版本 + } + + // log.info('最近正式版本数据:', versionData) + + let version = versionData.tag_name + if (version.indexOf('v') === 0) { + version = version.substring(1) + } + if (version !== pkg.version) { + log.info('检查更新-发现新版本:', version) + win.webContents.send('update', { + key: 'available', + value: { + version: versionData.tag_name, + releaseNotes: [ + '请查看发布公告:' + versionData.html_url + ] + } + }) + } else { + log.info('检查更新-没有新版本,最新版本号为:', version) + win.webContents.send('update', { key: 'notAvailable' }) + } + + return // 只检查最近一个正式版本 + } + + log.info('检查更新-没有正式版本数据') + win.webContents.send('update', { key: 'notAvailable' }) + } else { + log.error('检查更新失败, status:', response.statusCode, ', body:', body) + + let bodyObj + try { + bodyObj = JSON.parse(body) + } catch (e) { + bodyObj = null + } + + let message + if (response) { + message = '检查更新失败: ' + (bodyObj && bodyObj.message ? bodyObj.message : response.message) + ', code: ' + response.statusCode + } else { + message = '检查更新失败: ' + (bodyObj && bodyObj.message ? bodyObj.message : body) + } + win.webContents.send('update', { key: 'error', error: message }) + } + } catch (e) { + log.error('检查更新失败:', e) + win.webContents.send('update', { key: 'error', error: '检查更新失败:' + e.message }) + } + }) + } + + // 下载升级包 function downloadPart (app, value) { const appPath = appPathUtil.getAppRootPath(app) const fileDir = path.join(appPath, 'update') - logger.info('download dir', fileDir) + log.info('download dir', fileDir) try { fs.accessSync(fileDir, fs.constants.F_OK) } catch (e) { @@ -85,7 +191,7 @@ function updateHandle (app, api, win, beforeQuit, quit, log) { }, () => { // 文件下载完成 win.webContents.send('update', { key: 'progress', value: 100 }) - logger.info('升级包下载成功:', filePath) + log.info('升级包下载成功:', filePath) partPackagePath = filePath win.webContents.send('update', { key: 'downloaded', @@ -168,8 +274,11 @@ function updateHandle (app, api, win, beforeQuit, quit, log) { }) } else if (arg.key === 'checkForUpdate') { // 执行自动更新检查 - log.info('autoUpdater checkForUpdates') - autoUpdater.checkForUpdates() + log.info('autoUpdater checkForUpdates:', arg.fromUser) + + // 调用 github API,获取release数据,来检查更新 + // autoUpdater.checkForUpdates() + checkForUpdatesFromGitHub() } else if (arg.key === 'downloadUpdate') { // 下载新版本 log.info('autoUpdater downloadUpdate') @@ -177,7 +286,6 @@ function updateHandle (app, api, win, beforeQuit, quit, log) { } else if (arg.key === 'downloadPart') { // 下载增量更新版本 log.info('autoUpdater downloadPart') - // autoUpdater.downloadUpdate() downloadPart(app, arg.value) } }) diff --git a/packages/gui/src/bridge/update/front.js b/packages/gui/src/bridge/update/front.js index 0ba5e91..c5e1d5c 100644 --- a/packages/gui/src/bridge/update/front.js +++ b/packages/gui/src/bridge/update/front.js @@ -1,5 +1,5 @@ function install (app, api) { - const updateParams = app.$global.update = { fromUser: false, autoDownload: false, progress: 0, downloading: false, newVersion: false, isFullUpdate: true } + const updateParams = app.$global.update = { fromUser: false, autoDownload: false, progress: 0, checking: false, downloading: false, newVersion: false, isFullUpdate: true } api.ipc.on('update', (event, message) => { console.log('on message', event, message) handleUpdateMessage(message, app) @@ -10,7 +10,10 @@ function install (app, api) { if (fromUser != null) { updateParams.fromUser = fromUser } - api.ipc.send('update', { key: 'checkForUpdate' }) + if (updateParams.fromUser) { + updateParams.checking = true + } + api.ipc.send('update', { key: 'checkForUpdate', fromUser }) }, downloadUpdate () { api.ipc.send('update', { key: 'downloadUpdate' }) @@ -27,8 +30,10 @@ function install (app, api) { function handleUpdateMessage (message) { const type = message.key if (type === 'available') { + updateParams.checking = false foundNewVersion(message.value) } else if (type === 'notAvailable') { + updateParams.checking = false noNewVersion() } else if (type === 'downloaded') { // 更新包已下载完成,让用户确认是否更新 @@ -38,12 +43,14 @@ function install (app, api) { } else if (type === 'progress') { progressUpdate(message.value) } else if (type === 'error') { + updateParams.checking = false + updateParams.downloading = false const error = message.error - app.$message.error('Error: ' + (error == null ? '未知错误' : (error.stack || error).toString())) + app.$message.error((error == null ? '未知错误' : (error.stack || error).toString())) } } - function noNewVersion (value) { + function noNewVersion () { updateParams.newVersion = false if (updateParams.fromUser) { app.$message.info('当前已经是最新版本') @@ -55,8 +62,10 @@ function install (app, api) { } function goManualUpdate (value) { + updateParams.newVersion = false app.$confirm({ - title: '暂不支持自动升级', + // title: '暂不支持自动升级', + title: '暂不提供自动升级', cancelText: '取消', okText: '确定', content: h => { @@ -64,50 +73,49 @@ function install (app, api) { api.ipc.openExternal('https://github.com/docmirror/dev-sidecar/releases') } return
} }) } - /** - * 是否小版本升级 - * @param version1 - * @param version2 - */ - async function isSupportPartUpdate (value) { - const info = await api.info.get() - console.log('升级版本:', value.version) - console.log('增量更新最小版本:', value.partMiniVersion) - console.log('当前版本:', info.version) - if (!value.partPackage) { - return false - } - return !!(value.partMiniVersion && value.partMiniVersion < info.version) - } + // /** + // * 是否小版本升级 + // * @param value + // */ + // async function isSupportPartUpdate (value) { + // const info = await api.info.get() + // console.log('升级版本:', value.version) + // console.log('增量更新最小版本:', value.partMiniVersion) + // console.log('当前版本:', info.version) + // if (!value.partPackage) { + // return false + // } + // return !!(value.partMiniVersion && value.partMiniVersion < info.version) + // } async function downloadNewVersion (value) { - const platform = await api.shell.getSystemPlatform() - console.log('download new version platform', platform) - if (platform === 'linux') { - goManualUpdate(app, value) - return - } - const partUpdate = await isSupportPartUpdate(value) - if (partUpdate) { - // 有增量更新 - api.update.downloadPart(value) - } else { - if (platform === 'mac') { - goManualUpdate(value) - return - } - updateParams.downloading = true - api.update.downloadUpdate() - } + // 暂时取消自动更新功能 + goManualUpdate(value) + + // const platform = await api.shell.getSystemPlatform() + // console.log(`download new version: ${JSON.stringify(value)}, platform: ${platform}`) + // if (platform === 'linux') { + // goManualUpdate(value) + // return + // } + // const partUpdate = await isSupportPartUpdate(value) + // if (partUpdate) { + // // 有增量更新 + // api.update.downloadPart(value) + // } else { + // if (platform === 'mac') { + // goManualUpdate(value) + // return + // } + // updateParams.downloading = true + // api.update.downloadUpdate() + // } } function foundNewVersion (value) { updateParams.newVersion = true @@ -118,18 +126,23 @@ function install (app, api) { downloadNewVersion(value) return } + console.log(value) app.$confirm({ - title: '发现新版本', + title: '发现新版本:' + value.version, cancelText: '暂不升级', okText: '升级', + width: 600, content: h => { - console.log(value) if (value.releaseNotes) { - const notes = [] - for (const note of value.releaseNotes) { - notes.push(