feat: add trusted mirror update source

Version checks and downloads previously depended on GitHub Release. About & Updates now offers GitHub or a validated mirror source, keeps the selector beneath the startup-check switch, and disables it when startup checks are off.

The website resolves platform downloads from a bounded OSS release index with a GitHub fallback. Tagged releases publish and verify immutable OSS assets through OIDC before switching the latest-version index; deployment requires the configured Alibaba Cloud environment variables and role.

Release note: “关于与更新”新增 GitHub 与镜像节点选择,启动检查、手动检查和下载页使用同一可信来源;官网下载也可按系统、架构和安装包类型直接选择。
This commit is contained in:
mesalogo
2026-08-17 17:20:24 +08:00
parent ce15e7021c
commit dc8f86ff3e
32 changed files with 1680 additions and 66 deletions
+57 -3
View File
@@ -62,19 +62,22 @@ describe('ApplicationSettingsStore', () => {
})
).resolves.toEqual({
checkUpdatesOnStartup: false,
updateSource: 'github',
magicNotesEnabled: false,
magicNoteCommentMode: 'immediate',
magicNoteCommentFormat: 'combined'
})
await expect(store.get()).resolves.toEqual({
checkUpdatesOnStartup: false,
updateSource: 'github',
magicNotesEnabled: false,
magicNoteCommentMode: 'immediate',
magicNoteCommentFormat: 'combined'
})
expect(JSON.parse(await readFile(filePath, 'utf8'))).toEqual({
version: 5,
version: 6,
checkUpdatesOnStartup: false,
updateSource: 'github',
magicNotesEnabled: false,
magicNoteCommentMode: 'immediate',
magicNoteCommentFormat: 'combined',
@@ -98,6 +101,7 @@ describe('ApplicationSettingsStore', () => {
new ApplicationSettingsStore(filePath).get()
).resolves.toEqual({
checkUpdatesOnStartup: false,
updateSource: 'github',
magicNotesEnabled: false,
magicNoteCommentMode: 'immediate',
magicNoteCommentFormat: 'combined'
@@ -119,6 +123,7 @@ describe('ApplicationSettingsStore', () => {
await expect(store.get()).resolves.toEqual({
checkUpdatesOnStartup: false,
updateSource: 'github',
magicNotesEnabled: false,
magicNoteCommentMode: 'immediate',
magicNoteCommentFormat: 'combined'
@@ -140,6 +145,7 @@ describe('ApplicationSettingsStore', () => {
await expect(store.get()).resolves.toEqual({
checkUpdatesOnStartup: false,
updateSource: 'github',
magicNotesEnabled: true,
magicNoteCommentMode: 'immediate',
magicNoteCommentFormat: 'combined'
@@ -161,6 +167,7 @@ describe('ApplicationSettingsStore', () => {
await expect(store.get()).resolves.toEqual({
checkUpdatesOnStartup: false,
updateSource: 'github',
magicNotesEnabled: true,
magicNoteCommentMode: 'after-save-manual',
magicNoteCommentFormat: 'combined'
@@ -187,8 +194,9 @@ describe('ApplicationSettingsStore', () => {
new ApplicationSettingsStore(filePath).getLastSeenReleaseNotesVersion()
).resolves.toBe('0.8.18')
expect(JSON.parse(await readFile(filePath, 'utf8'))).toEqual({
version: 5,
version: 6,
checkUpdatesOnStartup: false,
updateSource: 'github',
magicNotesEnabled: true,
magicNoteCommentMode: 'after-save-manual',
magicNoteCommentFormat: 'narrative',
@@ -196,6 +204,33 @@ describe('ApplicationSettingsStore', () => {
})
})
it('migrates version 5 settings to the default GitHub update source', async () => {
const { filePath, store } = await createStore()
await writeFile(
filePath,
JSON.stringify({
version: 5,
checkUpdatesOnStartup: false,
magicNotesEnabled: true,
magicNoteCommentMode: 'after-save-auto',
magicNoteCommentFormat: 'structured',
lastSeenReleaseNotesVersion: '0.8.18'
}),
'utf8'
)
await expect(store.get()).resolves.toEqual({
checkUpdatesOnStartup: false,
updateSource: 'github',
magicNotesEnabled: true,
magicNoteCommentMode: 'after-save-auto',
magicNoteCommentFormat: 'structured'
})
await expect(store.getLastSeenReleaseNotesVersion()).resolves.toBe(
'0.8.18'
)
})
it('strictly rejects incomplete full settings', () => {
for (const input of [
{},
@@ -238,12 +273,28 @@ describe('ApplicationSettingsStore', () => {
store.update({ checkUpdatesOnStartup: false })
).resolves.toEqual({
checkUpdatesOnStartup: false,
updateSource: 'github',
magicNotesEnabled: true,
magicNoteCommentMode: 'immediate',
magicNoteCommentFormat: 'combined'
})
})
it('persists the selected mirror update source', async () => {
const { filePath, store } = await createStore()
await expect(store.update({ updateSource: 'mirror' })).resolves.toEqual({
...defaultApplicationSettings,
updateSource: 'mirror'
})
await expect(
new ApplicationSettingsStore(filePath).get()
).resolves.toEqual({
...defaultApplicationSettings,
updateSource: 'mirror'
})
})
it.each([
'{not-json',
JSON.stringify({
@@ -335,13 +386,15 @@ describe('ApplicationSettingsStore', () => {
await expect(store.get()).resolves.toEqual({
checkUpdatesOnStartup: false,
updateSource: 'github',
magicNotesEnabled: false,
magicNoteCommentMode: 'immediate',
magicNoteCommentFormat: 'combined'
})
expect(JSON.parse(await readFile(filePath, 'utf8'))).toEqual({
version: 5,
version: 6,
checkUpdatesOnStartup: false,
updateSource: 'github',
magicNotesEnabled: false,
magicNoteCommentMode: 'immediate',
magicNoteCommentFormat: 'combined',
@@ -365,6 +418,7 @@ describe('ApplicationSettingsStore', () => {
})
).resolves.toEqual({
checkUpdatesOnStartup: false,
updateSource: 'github',
magicNotesEnabled: true,
magicNoteCommentMode: 'immediate',
magicNoteCommentFormat: 'combined'