From 327dc85d14593c7fa4f963484a7de3d29e0f0ab1 Mon Sep 17 00:00:00 2001 From: cc <98377878+hicccc77@users.noreply.github.com> Date: Fri, 3 Apr 2026 20:05:23 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=80=9A=E9=81=93=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/dev-daily-fixed.yml | 3 +- .github/workflows/preview-nightly-main.yml | 17 +++++++-- electron/main.ts | 41 ++++++++++++++++------ src/pages/SettingsPage.tsx | 4 +-- 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/.github/workflows/dev-daily-fixed.yml b/.github/workflows/dev-daily-fixed.yml index d84e1f0..124c7d1 100644 --- a/.github/workflows/dev-daily-fixed.yml +++ b/.github/workflows/dev-daily-fixed.yml @@ -36,11 +36,10 @@ jobs: shell: bash run: | set -euo pipefail - BASE_VERSION="$(node -p "require('./package.json').version.split('-')[0]")" YEAR_2="$(TZ=Asia/Shanghai date +%y)" MONTH="$(TZ=Asia/Shanghai date +%-m)" DAY="$(TZ=Asia/Shanghai date +%-d)" - DEV_VERSION="${BASE_VERSION}-dev.${YEAR_2}.${MONTH}.${DAY}" + DEV_VERSION="${YEAR_2}.${MONTH}.${DAY}" echo "dev_version=$DEV_VERSION" >> "$GITHUB_OUTPUT" echo "Dev version: $DEV_VERSION" diff --git a/.github/workflows/preview-nightly-main.yml b/.github/workflows/preview-nightly-main.yml index 5ccb22d..dd733e3 100644 --- a/.github/workflows/preview-nightly-main.yml +++ b/.github/workflows/preview-nightly-main.yml @@ -34,6 +34,8 @@ jobs: - name: Decide whether to build and generate preview version id: meta + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash run: | set -euo pipefail @@ -49,13 +51,22 @@ jobs: SHOULD_BUILD=false fi - BASE_VERSION="$(node -p "require('./package.json').version.split('-')[0]")" YEAR_2="$(TZ=Asia/Shanghai date +%y)" - PREVIEW_VERSION="${BASE_VERSION}-preview.${YEAR_2}.${GITHUB_RUN_NUMBER}" + YEARLY_RUN_COUNT=1 + LAST_VERSION="$(gh release view "$FIXED_PREVIEW_TAG" --repo "$GITHUB_REPOSITORY" --json body --jq '.body' 2>/dev/null | grep -Eo '0\.[0-9]{2}\.[0-9]+' | head -n 1 || true)" + if [[ "$LAST_VERSION" =~ ^0\.([0-9]{2})\.([0-9]+)$ ]]; then + LAST_YEAR="${BASH_REMATCH[1]}" + LAST_COUNT="${BASH_REMATCH[2]}" + if [ "$LAST_YEAR" = "$YEAR_2" ]; then + YEARLY_RUN_COUNT=$((LAST_COUNT + 1)) + fi + fi + + PREVIEW_VERSION="0.${YEAR_2}.${YEARLY_RUN_COUNT}" echo "should_build=$SHOULD_BUILD" >> "$GITHUB_OUTPUT" echo "preview_version=$PREVIEW_VERSION" >> "$GITHUB_OUTPUT" - echo "Preview version: $PREVIEW_VERSION (commits in last 24h on main: $COMMITS_24H)" + echo "Preview version: $PREVIEW_VERSION (commits in last 24h on main: $COMMITS_24H, yearly count: $YEARLY_RUN_COUNT)" - name: Ensure fixed preview prerelease exists env: diff --git a/electron/main.ts b/electron/main.ts index c4eef38..980c972 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -38,18 +38,28 @@ autoUpdater.autoInstallOnAppQuit = true autoUpdater.disableDifferentialDownload = true // 禁用差分更新,强制全量下载 // 更新通道策略: // - 稳定版(如 4.3.0)默认走 latest -// - 预览版(如 4.3.0-preview.26.1)默认走 preview -// - 开发版(如 4.3.0-dev.26.3.4)默认走 dev +// - 预览版(如 0.26.2)默认走 preview(0.年.当年发布序号) +// - 开发版(如 26.4.5)默认走 dev(年.月.日) // - 用户可在设置页切换稳定/预览/开发,切换后即时生效 // 同时区分 Windows x64 / arm64,避免更新清单互相覆盖。 const appVersion = app.getVersion() +const inferUpdateTrackFromVersion = (version: string): 'stable' | 'preview' | 'dev' => { + const normalized = String(version || '').trim().replace(/^v/i, '') + if (/^0\.\d{2}\.\d+$/i.test(normalized)) return 'preview' + if (/^\d{2}\.\d{1,2}\.\d{1,2}$/i.test(normalized)) return 'dev' + // 兼容旧版命名(如 4.3.0-preview.26.1 / 4.3.0-dev.26.3.4) + if (/-preview\.\d+\.\d+$/i.test(normalized)) return 'preview' + if (/-dev\.\d+\.\d+\.\d+$/i.test(normalized)) return 'dev' + // 兼容 alpha/beta/rc 预发布 + if (/(alpha|beta|rc)/i.test(normalized)) return 'dev' + return 'stable' +} + const defaultUpdateTrack: 'stable' | 'preview' | 'dev' = (() => { - if (/-preview\.\d+\.\d+$/i.test(appVersion)) return 'preview' - if (/-dev\.\d+\.\d+\.\d+$/i.test(appVersion)) return 'dev' - if (/(alpha|beta|rc)/i.test(appVersion)) return 'dev' + const inferred = inferUpdateTrackFromVersion(appVersion) + if (inferred === 'preview' || inferred === 'dev') return inferred return 'stable' })() -const isPrereleaseBuild = defaultUpdateTrack !== 'stable' let configService: ConfigService | null = null const normalizeUpdateTrack = (raw: unknown): 'stable' | 'preview' | 'dev' | null => { @@ -116,16 +126,27 @@ const isRemoteVersionNewer = (latestVersion: string, currentVersion: string): bo } } +const shouldOfferUpdateForTrack = (latestVersion: string, currentVersion: string): boolean => { + if (isRemoteVersionNewer(latestVersion, currentVersion)) return true + const effectiveTrack = getEffectiveUpdateTrack() + const currentTrack = inferUpdateTrackFromVersion(currentVersion) + // 切换通道后,目标通道最新版本与当前版本不同即提示更新(即使是降级) + if (effectiveTrack !== currentTrack && latestVersion !== currentVersion) return true + return false +} + const applyAutoUpdateChannel = (reason: 'startup' | 'settings' = 'startup') => { const track = getEffectiveUpdateTrack() + const currentTrack = inferUpdateTrackFromVersion(appVersion) const baseUpdateChannel = track === 'stable' ? 'latest' : track autoUpdater.allowPrerelease = track !== 'stable' - autoUpdater.allowDowngrade = isPrereleaseBuild && track === 'stable' + // 只要用户当前选择的目标通道与当前安装版本所属通道不同,就允许跨通道更新(含降级) + autoUpdater.allowDowngrade = track !== currentTrack autoUpdater.channel = process.platform === 'win32' && process.arch === 'arm64' ? `${baseUpdateChannel}-arm64` : baseUpdateChannel - console.log(`[Update](${reason}) 当前版本 ${appVersion},渠道偏好: ${track},更新通道: ${autoUpdater.channel}`) + console.log(`[Update](${reason}) 当前版本 ${appVersion},当前轨道: ${currentTrack},渠道偏好: ${track},更新通道: ${autoUpdater.channel},allowDowngrade=${autoUpdater.allowDowngrade}`) } applyAutoUpdateChannel('startup') @@ -1338,7 +1359,7 @@ function registerIpcHandlers() { if (result && result.updateInfo) { const currentVersion = app.getVersion() const latestVersion = result.updateInfo.version - if (isRemoteVersionNewer(latestVersion, currentVersion)) { + if (shouldOfferUpdateForTrack(latestVersion, currentVersion)) { return { hasUpdate: true, version: latestVersion, @@ -2796,7 +2817,7 @@ function checkForUpdatesOnStartup() { const latestVersion = result.updateInfo.version // 检查是否有新版本 - if (isRemoteVersionNewer(latestVersion, currentVersion) && mainWindow) { + if (shouldOfferUpdateForTrack(latestVersion, currentVersion) && mainWindow) { // 检查该版本是否被用户忽略 const ignoredVersion = configService?.get('ignoredUpdateVersion') if (ignoredVersion === latestVersion) { diff --git a/src/pages/SettingsPage.tsx b/src/pages/SettingsPage.tsx index 55c5779..98fe8b3 100644 --- a/src/pages/SettingsPage.tsx +++ b/src/pages/SettingsPage.tsx @@ -392,9 +392,9 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { setUpdateChannel(savedUpdateChannel) } else { const currentVersion = await window.electronAPI.app.getVersion() - if (/-preview\.\d+\.\d+$/i.test(currentVersion)) { + if (/^0\.\d{2}\.\d+$/i.test(currentVersion) || /-preview\.\d+\.\d+$/i.test(currentVersion)) { setUpdateChannel('preview') - } else if (/-dev\.\d+\.\d+\.\d+$/i.test(currentVersion) || /(alpha|beta|rc)/i.test(currentVersion)) { + } else if (/^\d{2}\.\d{1,2}\.\d{1,2}$/i.test(currentVersion) || /-dev\.\d+\.\d+\.\d+$/i.test(currentVersion) || /(alpha|beta|rc)/i.test(currentVersion)) { setUpdateChannel('dev') } else { setUpdateChannel('stable')