cache update center status snapshots (#349)

This commit is contained in:
Cita
2026-03-31 20:47:02 +08:00
committed by GitHub
parent d930b87762
commit baa11d7787
9 changed files with 657 additions and 81 deletions
@@ -136,6 +136,18 @@ describe('UpdateCenterSection', () => {
},
});
apiMock.checkUpdateCenter.mockResolvedValue({
currentVersion: '1.2.3',
config: {
enabled: true,
helperBaseUrl: 'http://metapi-deploy-helper.ai.svc.cluster.local:9850',
namespace: 'ai',
releaseName: 'metapi',
chartRef: 'oci://ghcr.io/cita-777/charts/metapi',
imageRepository: '1467078763/metapi',
githubReleasesEnabled: true,
dockerHubTagsEnabled: true,
defaultDeploySource: 'github-release',
},
githubRelease: {
normalizedVersion: '1.3.0',
displayVersion: '1.3.0',
@@ -147,6 +159,25 @@ describe('UpdateCenterSection', () => {
displayVersion: 'latest @ sha256:efb2ee655386',
publishedAt: '2026-03-29T11:54:35.591877Z',
},
helper: {
ok: true,
healthy: true,
revision: '18',
imageTag: 'latest',
imageDigest: 'sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd',
history: [],
},
runtime: {
lastCheckedAt: '2026-03-30 20:35:00',
lastCheckError: null,
lastResolvedSource: 'github-release',
lastResolvedDisplayVersion: '1.3.0',
lastResolvedCandidateKey: 'github-release:v1.3.0',
lastNotifiedCandidateKey: 'github-release:v1.3.0',
lastNotifiedAt: '2026-03-30 20:31:00',
},
runningTask: null,
lastFinishedTask: null,
});
apiMock.deployUpdateCenter.mockResolvedValue({
success: true,
@@ -259,6 +290,7 @@ describe('UpdateCenterSection', () => {
targetDigest: null,
});
expect(apiMock.streamUpdateCenterTaskLogs).toHaveBeenCalledWith('task-1', expect.any(Object));
expect(apiMock.checkUpdateCenter).toHaveBeenCalledTimes(1);
const text = collectText(root.root);
expect(text).toContain('latest @ sha256:efb2ee655386');
@@ -501,10 +533,10 @@ describe('UpdateCenterSection', () => {
targetRevision: '16',
});
expect(apiMock.streamUpdateCenterTaskLogs).toHaveBeenCalledWith('task-2', expect.any(Object));
expect(apiMock.checkUpdateCenter).toHaveBeenCalledTimes(1);
const text = collectText(root.root);
expect(text).toContain('sha256:bbbbbbbbbbbb');
expect(text).toContain('Rollback to stable digest');
expect(text).toContain('最近状态:succeeded');
} finally {
root?.unmount();
}
+24 -9
View File
@@ -228,12 +228,16 @@ export default function UpdateCenterSection() {
const [historyModalOpen, setHistoryModalOpen] = useState(false);
const streamAbortRef = useRef<AbortController | null>(null);
const applyStatus = (next: UpdateCenterStatus) => {
setStatus(next);
setConfig(next.config || DEFAULT_CONFIG);
};
const loadStatus = async () => {
setLoading(true);
try {
const next = await api.getUpdateCenterStatus() as UpdateCenterStatus;
setStatus(next);
setConfig(next.config || DEFAULT_CONFIG);
applyStatus(next);
} catch (error: any) {
toast.error(error?.message || '加载更新中心失败');
} finally {
@@ -241,6 +245,19 @@ export default function UpdateCenterSection() {
}
};
const refreshStatus = async (showErrorToast = true) => {
try {
const next = await api.checkUpdateCenter() as UpdateCenterStatus;
applyStatus(next);
return next;
} catch (error: any) {
if (showErrorToast) {
toast.error(error?.message || '检查更新失败');
}
throw error;
}
};
useEffect(() => {
void loadStatus();
return () => {
@@ -269,12 +286,10 @@ export default function UpdateCenterSection() {
const checkNow = async () => {
setChecking(true);
try {
const next = await api.checkUpdateCenter() as UpdateCenterStatus;
setStatus(next);
setConfig(next.config || DEFAULT_CONFIG);
await refreshStatus(true);
toast.success('已刷新更新信息');
} catch (error: any) {
toast.error(error?.message || '检查更新失败');
} catch {
// refreshStatus already handled the toast
} finally {
setChecking(false);
}
@@ -343,7 +358,7 @@ export default function UpdateCenterSection() {
toast.error(error?.message || '部署失败');
} finally {
setDeploying(false);
void loadStatus();
void refreshStatus(false).catch(() => {});
}
};
@@ -378,7 +393,7 @@ export default function UpdateCenterSection() {
toast.error(error?.message || '回退失败');
} finally {
setDeploying(false);
void loadStatus();
void refreshStatus(false).catch(() => {});
}
};