App Updates — TheTechIdea.Beep.Updates
Self-update for any Beep-based app: a static hash-verified feed, delta & side-by-side app updates, rollback, and a feed-pinned NuGet module channel. Lives in BeepDM (decision D12).
Register once
services.AddBeepAppUpdates(); // reads update-settings.json beside the app
// or explicitly:
services.AddBeepAppUpdates(new UpdateSettings {
FeedUrl = "https://updates.example.com/stable/feed.json",
Channel = "stable",
Mode = UpdateMode.Optional, // Required blocks the app until applied
CurrentVersion = "1.2.0",
InstallRoot = @"C:\Program Files\MyApp"
});
var updates = provider.GetRequiredService<IAppUpdateService>();
var check = await updates.CheckAsync();
if (check.AppUpdateAvailable) await updates.ApplyAppUpdateAsync(check, progress);
if (check.StaleModules.Count > 0) await updates.ApplyModuleUpdatesAsync(check);
await updates.RollbackAsync(); // flip current back to the previous version
The pieces
| Component | Role |
|---|---|
UpdateFeedClient | Async fetch/parse of feed.json and the payload manifest; every artifact SHA-256-verified before use (a mismatch is discarded). Malformed input → a named UpdateFeedException, never a silent null. Transport is injectable (HTTPS with a transparent local/UNC-folder fallback). |
DeltaPlanner | Pure diff of the new manifest against the installed one over blob hashes, not files — so a rename or duplicate downloads nothing. Emits blobs-to-fetch, files-to-write/delete, and download-vs-full bytes. |
SideBySideApplier | Stages into app-<ver>, verifies each blob, flips the current junction (IDirectoryLink). Running version never written; corrupt blob aborts pre-flip; rollback + retire. |
ModuleUpdater | Governs the existing NuGet UpdateService: the feed's pinned version wins over "latest", a required stale module blocks start, each fetched package is hash-verified. Applies on next launch. |
AppUpdateService | The IAppUpdateService façade composing all of the above, plus best-effort telemetry (check/apply-*/modules-*) to a configured endpoint. |
What the check tells you
UpdateCheckResult is a data snapshot: AppUpdateAvailable, RequiresFullInstall (installed version is below minSupportedVersion), StaleModules, and AnyUpdateAvailable. Subscribe to IAppUpdateService.UpdateAvailable to drive an Optional-mode notification.
Two ways to drive the UI
Use the WinForms/WPF extensions for a drop-in dialog, or the /CHECKUPDATE and /UPDATE CLI verbs, or call IAppUpdateService directly from your own UI. All three share the same engine.