diff --git a/frontend/src/lib/panel-version.ts b/frontend/src/lib/panel-version.ts index 598a1e978..17450e50a 100644 --- a/frontend/src/lib/panel-version.ts +++ b/frontend/src/lib/panel-version.ts @@ -28,6 +28,9 @@ export function formatPanelVersion(version: string | undefined | null): string { export function isPanelUpdateAvailable(latest: string, current: string): boolean { if (!latest || !current) return false; + // A dev+ label and a release tag sit on different channels and carry no + // order, so a node moved to the other channel is not "behind" the master's latest. + if (latest.trim().startsWith('dev+') !== current.trim().startsWith('dev+')) return false; const a = parseVersionParts(latest); const b = parseVersionParts(current); if (!a || !b) { diff --git a/frontend/src/test/panel-version.test.ts b/frontend/src/test/panel-version.test.ts index 5f628968f..94760b57d 100644 --- a/frontend/src/test/panel-version.test.ts +++ b/frontend/src/test/panel-version.test.ts @@ -30,6 +30,13 @@ describe('isPanelUpdateAvailable', () => { expect(isPanelUpdateAvailable('nightly-2', 'nightly-1')).toBe(true); expect(isPanelUpdateAvailable('nightly-1', 'nightly-1')).toBe(false); }); + + it('compares dev builds by commit and never across channels', () => { + expect(isPanelUpdateAvailable('dev+1a2b3c4d', 'dev+0f0f0f0f')).toBe(true); + expect(isPanelUpdateAvailable('dev+1a2b3c4d', 'dev+1a2b3c4d')).toBe(false); + expect(isPanelUpdateAvailable('v3.5.0', 'dev+1a2b3c4d')).toBe(false); + expect(isPanelUpdateAvailable('dev+1a2b3c4d', '3.5.0')).toBe(false); + }); }); describe('formatPanelVersion', () => {