From 084e3dd8867ae16ebbe9227d647b81ea9958592f 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 17:10:37 +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=20=E6=9D=A5=E8=8E=B7=E5=8F=96=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=EF=BC=9B2=EF=BC=89=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E6=9B=B4=E6=96=B0=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E5=8F=AF=E9=85=8D=E7=BD=AE=E5=8C=96=E3=80=82=20(#303)?= 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 | 108 +++++++++++++++++- packages/gui/src/bridge/update/front.js | 127 +++++++++++++--------- packages/gui/src/view/pages/index.vue | 10 +- packages/gui/src/view/pages/setting.vue | 26 +++++ 5 files changed, 215 insertions(+), 58 deletions(-) diff --git a/packages/core/src/config/index.js b/packages/core/src/config/index.js index c4753a1b..1a63b822 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 62e633d9..7814f8fe 100644 --- a/packages/gui/src/bridge/update/backend.js +++ b/packages/gui/src/bridge/update/backend.js @@ -7,6 +7,9 @@ import fs from 'fs' import AdmZip from 'adm-zip' 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' @@ -72,6 +75,104 @@ function updateHandle (app, api, win, beforeQuit, quit, log) { let partPackagePath = null + // 检查更新 + const releasesApiUrl = 'https://api.github.com/repos/docmirror/dev-sidecar/releases' + async function checkForUpdatesFromGitHub () { + 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', action: 'checkForUpdate', 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', action: 'checkForUpdate', error: '检查更新失败,github 返回数据为空' }) + return + } + + // 尝试解析API响应内容 + let data + try { + data = JSON.parse(body) + } catch (e) { + log.error('检查更新失败,github API返回数据格式不正确:', body) + win.webContents.send('update', { key: 'error', action: 'checkForUpdate', error: '检查更新失败,github API返回数据格式不正确' }) + return + } + + if (typeof data !== 'object' || data.length === undefined) { + log.error('检查更新失败,github API返回数据不是数组:', body) + win.webContents.send('update', { key: 'error', action: 'checkForUpdate', 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.get().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, + releaseNotes: '发布公告:' + (versionData.html_url || ('https://github.com/docmirror/dev-sidecar/releases/tag/' + versionData.tag_name)) + } + }) + } 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', action: 'checkForUpdate', error: message }) + } + } catch (e) { + log.error('检查更新失败:', e) + win.webContents.send('update', { key: 'error', action: 'checkForUpdate', error: '检查更新失败:' + e.message }) + } + }) + } + + // 下载升级包 function downloadPart (app, value) { const appPath = appPathUtil.getAppRootPath(app) const fileDir = path.join(appPath, 'update') @@ -171,8 +272,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') diff --git a/packages/gui/src/bridge/update/front.js b/packages/gui/src/bridge/update/front.js index 9f98dc23..85e5282e 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,6 +10,7 @@ function install (app, api) { if (fromUser != null) { updateParams.fromUser = fromUser } + updateParams.checking = true api.ipc.send('update', { key: 'checkForUpdate', fromUser }) }, downloadUpdate () { @@ -27,8 +28,11 @@ function install (app, api) { function handleUpdateMessage (message) { const type = message.key if (type === 'available') { + updateParams.checking = false + updateParams.newVersionData = message.value foundNewVersion(message.value) } else if (type === 'notAvailable') { + updateParams.checking = false noNewVersion() } else if (type === 'downloaded') { // 更新包已下载完成,让用户确认是否更新 @@ -38,9 +42,15 @@ 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 == null ? '未知错误' : (error.stack || error).toString())) + if (message.action === 'checkForUpdate' && updateParams.newVersionData) { + // 如果检查更新报错了,但刚才成功拿到过一次数据,就拿之前的数据 + foundNewVersion(updateParams.newVersionData) + } else { + const error = message.error + app.$message.error((error == null ? '未知错误' : (error.stack || error).toString())) + } } } @@ -55,55 +65,67 @@ function install (app, api) { updateParams.progress = value } + function openGithubUrl () { + api.ipc.openExternal('https://github.com/docmirror/dev-sidecar/releases') + } + function goManualUpdate (value) { updateParams.newVersion = false app.$confirm({ - title: '暂不支持自动升级', + // title: '暂不支持自动升级', + title: '暂不提供自动升级', cancelText: '取消', - okText: '确定', + okText: '打开链接', + width: 420, content: h => { - function openGithubUrl () { - api.ipc.openExternal('https://github.com/docmirror/dev-sidecar/releases') - } - return
请前往 github项目release页面 下载新版本手动安装
+ return
+
请前往 github项目release页面 下载新版本手动安装
+
https://github.com/docmirror/dev-sidecar/releases
+
+ }, + onOk () { + openGithubUrl() } }) } - /** - * 是否小版本升级 - * @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) - } + // /** + // * 是否小版本升级 + // * @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: ${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() - } + // 暂时取消自动更新功能 + 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 @@ -116,13 +138,14 @@ function install (app, api) { } console.log(value) app.$confirm({ - title: '发现新版本:' + value.version, + title: '发现新版本:v' + value.version, cancelText: '暂不升级', okText: '升级', + width: 710, content: h => { if (value.releaseNotes) { if (typeof value.releaseNotes === 'string') { - return
更新内容:
{value.releaseNotes}
+ return
{value.releaseNotes}
} else { const notes = [] for (const note of value.releaseNotes) { @@ -144,24 +167,26 @@ function install (app, api) { function newUpdateIsReady (value) { updateParams.downloading = false + console.log(value) app.$confirm({ - title: `新版本(v${value.version})已准备好,是否立即升级?`, + title: `新版本(v${value.version})已准备好,是否立即升级?`, cancelText: '暂不升级', okText: '立即升级', content: h => { - console.log(value) if (value.releaseNotes) { - const notes = [] - for (const note of value.releaseNotes) { - notes.push(
  • {note}
  • ) + if (typeof value.releaseNotes === 'string') { + return
    {value.releaseNotes}
    + } else { + const notes = [] + for (const note of value.releaseNotes) { + notes.push(
  • {note}
  • ) + } + return
    更新内容:
      {notes}
    } - return
    更新内容:
      {notes}
    } }, onOk () { api.update.doUpdateNow() - }, - onCancel () { } }) } diff --git a/packages/gui/src/view/pages/index.vue b/packages/gui/src/view/pages/index.vue index 718e2f46..de21ec55 100644 --- a/packages/gui/src/view/pages/index.vue +++ b/packages/gui/src/view/pages/index.vue @@ -7,10 +7,10 @@ 安装根证书 - - {{ update.progress }}%{{ update.downloading ? '新版本下载中' : '检查更新' }} + {{ update.progress }}%{{ update.downloading ? '新版本下载中' : ('检查更新' + (update.checking ? '中' : '')) }} @@ -161,7 +161,7 @@ export default { setupCa: { visible: false }, - update: { downloading: false, progress: 0, newVersion: false } + update: { checking: false, downloading: false, progress: 0, newVersion: false } } }, async created () { @@ -170,8 +170,8 @@ export default { this.$set(this, 'status', this.$status) this.switchBtns = this.createSwitchBtns() this.$set(this, 'update', this.$global.update) - if (!this.update.autoChecked) { - this.update.autoChecked = true + if (!this.update.autoChecked && this.config.app.autoChecked) { + this.update.autoChecked = true // 应用启动时,执行一次 this.doCheckUpdate(false) } this.$api.info.get().then(ret => { diff --git a/packages/gui/src/view/pages/setting.vue b/packages/gui/src/view/pages/setting.vue index 3ece6c57..0c205efa 100644 --- a/packages/gui/src/view/pages/setting.vue +++ b/packages/gui/src/view/pages/setting.vue @@ -52,6 +52,32 @@ + + + + 开启 + + + 关闭 + + +
    + 开启自动检查更新后,每次应用启动时会检查一次更新,如有新版本,则会弹出提示。 +
    +
    + + + + 忽略 + + + 不忽略 + +
    + 预发布版本为版本号带有 “Pre-release” 的版本 +
    +
    +