Skip to content

ADFA-5051: dash-node 1.2.0 live self-update + version-gated update routing - #357

Merged
luisguzman-adfa merged 4 commits into
mainfrom
feat/ADFA-5051-dashboard-live-self-update-1.2.0
Aug 7, 2026
Merged

ADFA-5051: dash-node 1.2.0 live self-update + version-gated update routing#357
luisguzman-adfa merged 4 commits into
mainfrom
feat/ADFA-5051-dashboard-live-self-update-1.2.0

Conversation

@luisguzman-adfa

@luisguzman-adfa luisguzman-adfa commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

ADFA-5051: dash-node 1.2.0 live self-update, version-gated routing + rebuild hardening

Makes 1.2.0 the self-update cutover baseline. From 1.2.0 the app updates the dash-node core
LIVE over REST (POST /system/dashboard/rebuild — blue-green stage/smoke/atomic-swap/rollback);
installs on < 1.2.0 take the proot rebuild once as a bridge to 1.2.0.

Server (dash-node 1.2.0):

  • Cutover baseline + CHANGELOG (no new endpoint).
  • K2GO_DASH_BRANCH override: update-check and the rebuild track the same branch (default main),
    so a test box can exercise the live update off a feature branch without code changes.

App:

  • DashboardClient.rebuildStart / rebuildStatus (REST trigger + poll).
  • DashboardVersion.atLeast() semver gate (null -> proot, the safe default).
  • DashboardRebuild: version-gated start() -> live REST rebuild (progress dialog, tolerant of the
    restart window; distinct timeout copy) vs the existing proot bridge. New strings + 33-locale l10n.

rebuild-dashboard.sh hardening (found + fixed by on-device testing):

  • proot ".l2s." symlink-loop artifacts no longer break the node_modules copy or staging cleanup
    (tar --exclude + purge_staging with unlink-then-rm).
  • Rollback completeness: swap dist -> verify -> only THEN advance source + package.json + vhost,
    so a failed update leaves ZERO version/source drift (was: box ran old code but reported the
    failed version).
  • Re-verify the rolled-back build actually recovered; clean the dist backup on every path.

Validated on-device: live upgrade (1.2.0->1.2.1), bad build never ships (live untouched),
bad-live update rolls back with no drift and the box keeps serving. tsc + javalang + XML clean.

…uting

Sets 1.2.0 as the self-update cutover baseline. From 1.2.0 the app updates the
dash-node core LIVE over REST (POST /system/dashboard/rebuild — the blue-green
staged/smoke-tested/atomic-swap/rollback rebuild from ADFA-5011); installs on
< 1.2.0 take the proot rebuild once as a bridge to 1.2.0.

Server: bump package.json + lock to 1.2.0 + CHANGELOG (no endpoint change).

App:
- DashboardClient: rebuildStart (POST, maps 409 = already running) + rebuildStatus.
- DashboardVersion.atLeast(): semver gate (null -> false, defaults to proot).
- DashboardRebuild: version-gated start() -> startRest (trigger + poll status in a
  progress dialog, tolerating the brief restart window) vs startProot (existing).
- New live-update strings + 33-locale l10n.

Reviewed via /engineering:code-review; fixes applied: version read moved off the
main thread; poll timeout shows a distinct "finishing in background" message
instead of the rollback/failure copy; single reused poller Handler; dropped the
unnecessary FixedLengthStreamingMode on the bodyless POST.

Static-verified only (tsc + javalang + XML). NOT yet run on a device: the live
REST rebuild flow (trigger/poll/restart tolerance/rollback) is pending a
controlled test.
@luisguzman-adfa luisguzman-adfa changed the title ADFA-5051: dash-node 1.2.0 live self-update + version-gated update ro… ADFA-5051: dash-node 1.2.0 live self-update + version-gated update routing Aug 6, 2026
update-check and the REST rebuild now read the tracked branch from
K2GO_DASH_BRANCH (default "main"), and the rebuild spawn is passed the same
branch so both always agree on the source. Lets a test box point at a feature
branch to exercise the live self-update before merging, without code changes;
unset in production it tracks main exactly as before. Rides in the unreleased
1.2.0 (prod-safe, no version bump).
@luisguzman-adfa
luisguzman-adfa force-pushed the feat/ADFA-5051-dashboard-live-self-update-1.2.0 branch from 4fffc11 to aa009c6 Compare August 7, 2026 00:34
…pleteness, re-verify)

Fixes found by on-device testing of the self-update:
- proot ".l2s." symlink-loop artifacts (better-sqlite3 build) made cp -a / rm -rf choke and
  left staging cruft -> copy node_modules with tar --exclude='*.l2s.*' + purge_staging().
- rollback was dist-only: source + package.json synced BEFORE the live verify, so a bad-live
  update rolled back the binary but reported the failed version. Reorder: swap dist -> verify
  -> only THEN advance source + package.json + vhost. A failed verify leaves zero drift.
- re-verify the rolled-back build actually recovered (log healthy/degraded).
- clean the dist backup on every path.

Folds into the unreleased 1.2.0 (no API change, no version bump).
@luisguzman-adfa
luisguzman-adfa force-pushed the feat/ADFA-5051-dashboard-live-self-update-1.2.0 branch from 6930094 to 5592dcf Compare August 7, 2026 01:07
From on-device UI testing:
- POST /system/dashboard/rebuild writes status="running" synchronously before returning, so a
  client polling immediately can't read the PREVIOUS run's "done" and report a false instant
  success (the detached script set "running" only after it started).
- After a successful live REST update, the dashboard card refreshes its version chip + update pill
  in place (fetchVersionChip reuses one chip, no duplicate) so it flips to "Up to date"/new version
  without leaving and re-opening.

Folds into the unreleased 1.2.0 (no API change).
@luisguzman-adfa
luisguzman-adfa force-pushed the feat/ADFA-5051-dashboard-live-self-update-1.2.0 branch from b2feadb to 64f3be3 Compare August 7, 2026 02:37
@luisguzman-adfa
luisguzman-adfa merged commit e61f281 into main Aug 7, 2026
4 checks passed
@luisguzman-adfa
luisguzman-adfa deleted the feat/ADFA-5051-dashboard-live-self-update-1.2.0 branch August 8, 2026 08:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant