mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-27 18:57:09 +00:00
fix: reconcile sticky update indicators with Anatomy preview (#1698)
* fix: reconcile sticky update indicators with Anatomy preview Sidebar, Updates filter, and Fleet treated retained partial/failed scanner has_update as confirmed. Keep raw state for retention/notifications, project confirmed-only to APIs, show distinct incomplete indicators, and clear sticky rows only after an authoritative-negative preview. Closes #1685 * test: align sidebar truncate E2E with failed-over-retained precedence Purple update indicators are confirmed-only; hasUpdate with a failed check correctly shows the failed trailing icon. * fix: clear confirmed update rows on authoritative-negative preview Address audit SF-1/SF-2/SF-3: observation-watermark clears for older ok+has_update rows (DB + memory gens), Fleet checkability parity with backend not_checkable, and Updates chip confirmed-only regressions. * fix: tombstone equal-generation writers on preview clear Advance the per-stack write generation when clearing at the observation watermark so a scanner reserved before preview cannot recreate the row after an authoritative-negative reconcile. * fix: clear sticky updates with digest and tag preview parity Share detection across scanner and preview, keep GET read-only with POST reconcile, gate Apply to digest and rebuild updates, and invalidate the hub fleet cache on clear. * test: set digestUpdate on auto-update checkImage mocks Scheduler and execute routes now gate Compose on digest drift; fixtures that expect an apply need digestUpdate so they exercise the update path. * fix: clear unused lint errors on sticky update branch Drop unused partial helper and fleet invalidate import; keep the CacheService inflight self-ref as let with an eslint exception so tsc stays green. * fix: use inflight holder for CacheService prefer-const Keep generation-aware ownership without a let self-reference that fights ESLint and tsc.
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import type { ImageCheckResult } from '../services/ImageUpdateService';
|
||||
|
||||
/** Accumulator for auto-update image checks (digest vs tag-only vs error). */
|
||||
export interface AutoUpdateDigestGateState {
|
||||
hasDigestUpdate: boolean;
|
||||
hasTagOnlyUpdate: boolean;
|
||||
updatedImages: string[];
|
||||
checkErrors: string[];
|
||||
}
|
||||
|
||||
export function createAutoUpdateDigestGateState(): AutoUpdateDigestGateState {
|
||||
return {
|
||||
hasDigestUpdate: false,
|
||||
hasTagOnlyUpdate: false,
|
||||
updatedImages: [],
|
||||
checkErrors: [],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Record one image check into the digest gate. Only digest drift is Compose-
|
||||
* actionable for auto-update; tag bumps stay advisory.
|
||||
*/
|
||||
export function recordAutoUpdateImageCheck(
|
||||
state: AutoUpdateDigestGateState,
|
||||
imageRef: string,
|
||||
result: ImageCheckResult,
|
||||
): void {
|
||||
if (result.digestUpdate) {
|
||||
state.hasDigestUpdate = true;
|
||||
state.updatedImages.push(imageRef);
|
||||
return;
|
||||
}
|
||||
if (result.tagUpdate) {
|
||||
state.hasTagOnlyUpdate = true;
|
||||
return;
|
||||
}
|
||||
if (result.error || result.checkStatus === 'failed' || result.checkStatus === 'partial') {
|
||||
state.checkErrors.push(result.error ?? 'Update check incomplete');
|
||||
}
|
||||
}
|
||||
|
||||
/** Operator message when no digest-actionable update was found. */
|
||||
export function messageWhenNoDigestUpdate(
|
||||
stackName: string,
|
||||
state: Pick<AutoUpdateDigestGateState, 'hasTagOnlyUpdate' | 'checkErrors'>,
|
||||
imageRefCount: number,
|
||||
): string {
|
||||
if (state.hasTagOnlyUpdate) {
|
||||
const errNote = state.checkErrors.length > 0
|
||||
? ` (${state.checkErrors.length} check(s) failed)`
|
||||
: '';
|
||||
return `Stack "${stackName}": newer tag available but Compose pin unchanged; skipped auto-update${errNote}.`;
|
||||
}
|
||||
if (state.checkErrors.length > 0 && state.checkErrors.length === imageRefCount) {
|
||||
return `Stack "${stackName}": WARNING - all image checks failed (${state.checkErrors.join('; ')}). Unable to determine update status.`;
|
||||
}
|
||||
if (state.checkErrors.length > 0) {
|
||||
return `Stack "${stackName}": all reachable images up to date (${state.checkErrors.length} check(s) failed).`;
|
||||
}
|
||||
return `Stack "${stackName}": all images up to date.`;
|
||||
}
|
||||
Reference in New Issue
Block a user