The self-update progress screen reset its elapsed timer to 0 and dropped the
phase checklist back to step one on every browser refresh — and the long image
build made it look like the update had restarted. Root causes: the timer and
phase state lived only in page JS (Date.now() at page load), and a
30s-before-page-load staleness guard rejected the real phase feed whenever a
stage had run longer than 30s (which the image build always does).
- DeploymentService: requestUpdate() now also writes a best-effort
run/update-started.json {at,from}. New updateStartedAt()/updatePhase() expose
the server-side start + current macro-stage; updatePhase() requires a positive
timestamp so a corrupt or stale 'done' can never drive a premature finish.
clearUpdateRequest() also removes the start marker.
- routes: /update-status.json delegates to updatePhase(); /update-progress
passes startedAt/initialPhase/hasFeed. A stage is trusted only when tied to
THIS update's start (startedAt) and written at/after it — a leftover stage from
a previous run can no longer resume or trigger a premature completion.
- update-progress.blade.php: the elapsed timer is anchored to the server-side
start (counts the real elapsed across a refresh); the checklist resumes at the
live stage; the live feed is authoritative (corrects any time-heuristic
overshoot) and the heuristic stays off once a real stage is known.
Verified: 28 UpdateProgressTest cases + full suite (426) green, pint clean, and a
headless browser load+reload mid-update keeps the timer counting and the phase in
place with zero console errors. Codex review: two premature-completion edge cases
found and fixed (timestamp validation + start-anchored freshness).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| Console/Commands | ||
| Events | ||
| Http | ||
| Jobs | ||
| Livewire | ||
| Models | ||
| Notifications | ||
| Providers | ||
| Rules | ||
| Services | ||
| Support | ||