mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-20 23:32:19 +00:00
fix: bind the node-update changelog to the advertised release version (#1492)
The changelog tab fetched release notes once and held them in component state without tying them to a version, and the endpoint did not report which release the notes belonged to. When a newer release surfaced while the sheet stayed mounted, reopening the changelog could show the previous version's notes, and a GitHub/Docker Hub fallback or independent cache timing could leave the notes out of sync with the advertised latest version. The release-notes endpoint now returns the release version (normalized tag_name). The changelog keys its loaded notes to the advertised latest version, refetching when that version changes, and labels the notes with the version they belong to so the displayed content is always explicit.
This commit is contained in:
@@ -276,3 +276,35 @@ describe('forced-recheck throttle', () => {
|
||||
expect(FleetUpdateTrackerService.getInstance().get(proxyNodeId)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /api/fleet/update-status/release-notes', () => {
|
||||
// Each case uses ?recheck=true so getLatestRelease force-invalidates the cache
|
||||
// and fetches fresh, keeping the assertion independent of prior cache state.
|
||||
it('binds the returned notes to the release version (normalized tag_name)', async () => {
|
||||
vi.spyOn(globalThis, 'fetch').mockImplementation(async () =>
|
||||
new Response(JSON.stringify({
|
||||
tag_name: 'v0.93.0',
|
||||
body: '## Notes for 0.93.0',
|
||||
html_url: 'https://github.com/studio-saelix/sencho/releases/tag/v0.93.0',
|
||||
}), { status: 200, headers: { 'content-type': 'application/json' } }),
|
||||
);
|
||||
const res = await request(app)
|
||||
.get('/api/fleet/update-status/release-notes?recheck=true')
|
||||
.set('Authorization', adminAuth);
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body.version).toBe('0.93.0');
|
||||
expect(res.body.releaseNotes).toBe('## Notes for 0.93.0');
|
||||
expect(res.body.htmlUrl).toContain('v0.93.0');
|
||||
});
|
||||
|
||||
it('returns null fields when the upstream release lookup fails', async () => {
|
||||
vi.spyOn(globalThis, 'fetch').mockResolvedValue(new Response('', { status: 500 }));
|
||||
const res = await request(app)
|
||||
.get('/api/fleet/update-status/release-notes?recheck=true')
|
||||
.set('Authorization', adminAuth);
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body.version).toBeNull();
|
||||
expect(res.body.releaseNotes).toBeNull();
|
||||
expect(res.body.htmlUrl).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1070,6 +1070,9 @@ fleetRouter.get('/update-status/release-notes', authMiddleware, async (req: Requ
|
||||
const forceRefresh = req.query.recheck === 'true';
|
||||
const release = await getLatestRelease(forceRefresh);
|
||||
res.json({
|
||||
// Bind the notes to the release they belong to so the frontend can tell
|
||||
// when the advertised latest version has moved past the loaded notes.
|
||||
version: release ? release.tag_name.replace(/^v/, '') : null,
|
||||
releaseNotes: release?.body ?? null,
|
||||
htmlUrl: release?.html_url ?? null,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user