fix(update): make remote-update flow usable for portable builds#22
Merged
Conversation
Velopack-based auto-update only works for users who installed via WRAITH-Setup.exe; the README only documented the portable zip path, so most users hit a silent-fail flow where CheckForUpdatesAsync threw, the exception was swallowed, and nothing surfaced in the UI. - UpdateService: log IsInstalled, skip DownloadUpdatesAsync on portable builds (saves ~50 MB), still raise UpdateDownloaded so the dialog can offer a manual path. - UpdateAvailableWindow: when canApply is false, repurpose the primary button as "Open Release Page" instead of leaving it disabled with a tooltip nobody reads. - deploy.yml: pass --releaseNotes (extracted from CHANGELOG.md's top section) to vpk pack so TargetFullRelease.NotesMarkdown is populated and the dialog shows real notes. - README: split Installation into Installer vs Portable, call out which path enables auto-update, fix YOUR_USERNAME placeholder.
There was a problem hiding this comment.
Pull request overview
This PR adjusts WRAITH’s update UX and update-check behavior so “portable” (ZIP/START.bat) builds can still guide users to update manually, while avoiding wasted bandwidth/storage by skipping Velopack payload downloads when updates can’t be applied in-place.
Changes:
- Repurposes the update dialog’s primary action for portable builds to open the GitHub releases page.
- Skips downloading Velopack update payloads when
IsInstalled=false(portable builds). - Updates documentation/workflow to better surface release notes and clarify install paths.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| WRAITH/UpdateAvailableWindow.xaml.cs | Changes update dialog behavior for non-installable builds to open the release page instead of applying. |
| WRAITH/Services/UpdateService.cs | Avoids downloading update payloads when running as a portable build; adds a public releases URL. |
| README.md | Documents installer vs portable installation paths and auto-update availability. |
| .github/workflows/deploy.yml | Adds a step to generate release-notes.md for Velopack packaging. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+39
to
+44
| // Portable (zip + START.bat) build — Velopack can't apply in-place. | ||
| // Repurpose the primary action to send the user to the download page. | ||
| UpdateBtn.Content = "🌐 Open Release Page"; | ||
| UpdateBtn.ToolTip = "This is a portable build — download the new release manually."; | ||
| SubtitleBlock.Text = "A new version of WRAITH is available. This is a portable build, " + | ||
| "so updates can't be applied in-place — open the release page to download."; |
| UseShellExecute = true, | ||
| }); | ||
| } | ||
| catch { /* best-effort — never block close */ } |
Comment on lines
+19
to
+20
| /// <summary>Public link to the latest release — surfaced when auto-apply is unavailable.</summary> | ||
| public const string ReleasesUrl = RepoUrl + "/releases/latest"; |
Comment on lines
+403
to
+412
| $notes = "" | ||
| if (Test-Path CHANGELOG.md) { | ||
| $lines = Get-Content CHANGELOG.md | ||
| $start = ($lines | Select-String -Pattern '^##\s' | Select-Object -First 1).LineNumber | ||
| if ($start) { | ||
| $tail = $lines[$start..($lines.Length - 1)] | ||
| $stop = ($tail | Select-String -Pattern '^##\s' | Select-Object -First 1).LineNumber | ||
| $notes = if ($stop) { $tail[0..($stop - 2)] -join "`n" } else { $tail -join "`n" } | ||
| } | ||
| } |
Five bugs in the quarantine + delete pipeline: - Restore only handled the first selected row even though the grid is multi-select. Now iterates the selection like Delete does, with a per-item try/catch and an accurate counter. - Delete's try/catch wrapped the whole loop, so one locked vault file (AV holding a handle, common case) aborted the rest of the batch and the user got "Delete failed" instead of partial counts. Moved the catch inside the loop and surface the last error. - DeleteFromVault returned true for no-op deletes on already restored/deleted records. UI then reported "Deleted N item(s)" for work that didn't happen. Now returns false for no-ops. - Restored records had no state in the model — QuarantinedPath was cleared, Deleted stayed false, the row sat in the grid with empty fields forever. Added Restored + PendingRebootDelete + a State computed property; XAML now shows a "State" column instead of the boolean "Deleted". - SaveIndex used File.WriteAllText with no atomicity — a crash mid-write truncated the index and made the whole vault appear empty. Now writes to .tmp and File.Replace into place. Also adds a locked-source fallback in QuarantineFile: when File.Move throws IOException because the original is mapped into a running process (the exact case that matters most for malware), the bytes are copied into the vault and the source is scheduled for deletion at next boot via MoveFileEx(MOVEFILE_DELAY_UNTIL_REBOOT). The record is tagged PendingRebootDelete so the UI can show that.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.