Skip to content

Add Velopack auto-update + v1.2.1 (#635)#115

Merged
erikdarlingdata merged 1 commit intodevfrom
feature/velopack-auto-update
Mar 19, 2026
Merged

Add Velopack auto-update + v1.2.1 (#635)#115
erikdarlingdata merged 1 commit intodevfrom
feature/velopack-auto-update

Conversation

@erikdarlingdata
Copy link
Owner

@erikdarlingdata erikdarlingdata commented Mar 19, 2026

Summary

Adds Velopack auto-update for Windows. First release to test the full pipeline before porting to PerformanceMonitor.

App changes

  • Velopack NuGet package + VelopackApp.Build().Run() in Main()
  • About > Check for Updates: Velopack download+apply on Windows, browser fallback on Mac/Linux
  • Version bump to 1.2.1 across all projects

Pipeline changes

  • vpk download github fetches previous release for delta generation
  • vpk pack produces Setup.exe, full nupkg, delta nupkg
  • vpk upload github --merge attaches Velopack artifacts to the release alongside existing zips

Expected release artifacts

  • Existing: PerformanceStudio-win-x64.zip, linux-x64.zip, osx-x64.zip, osx-arm64.zip, SHA256SUMS.txt
  • New: PerformanceStudio-1.2.1-win-full.nupkg, PerformanceStudio-1.2.1-win-delta.nupkg, PerformanceStudio-win-Setup.exe, RELEASES, releases.win.json

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Integrated Velopack for optimized Windows update delivery with fallback to existing update mechanism
  • Chores

    • Bumped version to 1.2.1 across all projects
    • Enhanced CI/CD pipeline to generate and upload Velopack release artifacts

- Velopack NuGet package added
- VelopackApp.Build().Run() in Program.Main() (proper entry point)
- About > Check for Updates tries Velopack first (download + apply),
  falls back to browser-based GitHub check on Mac/Linux or when
  Velopack packages aren't available
- Release pipeline: vpk pack produces Setup.exe, full/delta nupkg,
  uploaded alongside existing zip artifacts
- Version bumped to 1.2.1 across all 4 projects

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Mar 19, 2026

📝 Walkthrough

Walkthrough

This PR introduces Velopack integration for Windows application updates, bumps version numbers across all project files from 1.2.0 to 1.2.1, and updates the release workflow to build and upload Velopack artifacts alongside existing release assets.

Changes

Cohort / File(s) Summary
Velopack CI/CD Integration
.github/workflows/release.yml
Added Windows-specific "Create Velopack release" step that installs the vpk tool, prepares release directory, downloads prior artifacts for delta generation, and runs vpk pack against published Win-x64 output. Extended upload process to upload Velopack artifacts via vpk upload in addition to .zip assets and checksums.
Velopack Update Logic
src/PlanViewer.App/AboutWindow.axaml.cs
Integrated Velopack update manager with Windows platform check in CheckUpdate_Click. Converted UpdateLink_Click to async handler supporting Velopack update download/apply workflow with fallback to existing GitHub-based update checking when Velopack is unavailable.
Velopack Startup Initialization
src/PlanViewer.App/Program.cs
Added VelopackApp.Build().Run() call at beginning of Main, placed before existing single-instance and Avalonia startup logic.
Velopack Dependency
src/PlanViewer.App/PlanViewer.App.csproj
Added Velopack NuGet package reference (version 0.0.1298).
Version Bumps
src/PlanViewer.Cli/PlanViewer.Cli.csproj, src/PlanViewer.Core/PlanViewer.Core.csproj, src/PlanViewer.Ssms.Installer/PlanViewer.Ssms.Installer.csproj
Incremented version from 1.2.0 to 1.2.1 across all project files.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Bump version to 1.2.0 #99: Updates project version properties in the same csproj files, indicating coordinated version management across releases.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add Velopack auto-update + v1.2.1' clearly and concisely summarizes the main changes: adding Velopack-based auto-update functionality and bumping the version to 1.2.1, which matches the primary objectives of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/velopack-auto-update
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/release.yml (1)

38-45: ⚠️ Potential issue | 🔴 Critical

The release creation order is correct, but the workflow will fail on the first release.

vpk download github resolves the latest entry from the channel feed (releases.{channel}.json), not the latest Git tag. Since v1.2.1 is the first release with win channel assets, that feed won't exist yet, and the command at line 78 will fail with a 404 error.

Add error handling to skip the download step on first release (when the channel feed doesn't yet exist), or check for the existence of the channel feed before attempting to download.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release.yml around lines 38 - 45, The workflow fails on
first release because "vpk download github" expects an existing channel feed
(releases.{channel}.json); add a pre-check or error handling so the download is
skipped when that feed doesn't exist. Specifically, around the step that runs
the vpk download github command (referenced as "vpk download github" and the
channel feed releases.{channel}.json), test for the feed's existence (e.g., an
HTTP HEAD or curl -f) and only run vpk if it exists, or wrap the download in a
conditional/try-fail-safe so a 404 does not fail the job; ensure the Create
release step remains unchanged but downstream download logic handles missing
feeds gracefully.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/PlanViewer.App/AboutWindow.axaml.cs`:
- Around line 81-110: CheckUpdate_Click can reuse stale
_velopackUpdate/_velopackMgr from a prior run if the new Velopack check throws;
reset the cached state at the start of the method (set _velopackUpdate and
_velopackMgr to null) and also ensure the exception path does not leave a prior
value in place, and add a defensive check in UpdateLink_Click to verify
_velopackUpdate is non-null before attempting to apply a Velopack release (and
show a friendly error if it is null).

---

Outside diff comments:
In @.github/workflows/release.yml:
- Around line 38-45: The workflow fails on first release because "vpk download
github" expects an existing channel feed (releases.{channel}.json); add a
pre-check or error handling so the download is skipped when that feed doesn't
exist. Specifically, around the step that runs the vpk download github command
(referenced as "vpk download github" and the channel feed
releases.{channel}.json), test for the feed's existence (e.g., an HTTP HEAD or
curl -f) and only run vpk if it exists, or wrap the download in a
conditional/try-fail-safe so a 404 does not fail the job; ensure the Create
release step remains unchanged but downstream download logic handles missing
feeds gracefully.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bfffe1ee-1ba9-46bc-81e7-dd827a3dc24c

📥 Commits

Reviewing files that changed from the base of the PR and between 78e3e98 and 18b3092.

📒 Files selected for processing (7)
  • .github/workflows/release.yml
  • src/PlanViewer.App/AboutWindow.axaml.cs
  • src/PlanViewer.App/PlanViewer.App.csproj
  • src/PlanViewer.App/Program.cs
  • src/PlanViewer.Cli/PlanViewer.Cli.csproj
  • src/PlanViewer.Core/PlanViewer.Core.csproj
  • src/PlanViewer.Ssms.Installer/PlanViewer.Ssms.Installer.csproj

Comment on lines 81 to +110
private async void CheckUpdate_Click(object? sender, RoutedEventArgs e)
{
CheckUpdateButton.IsEnabled = false;
UpdateStatusText.Text = "Checking...";
UpdateLink.IsVisible = false;

// Try Velopack first (Windows only, supports download + apply)
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
try
{
_velopackMgr = new UpdateManager(
new Velopack.Sources.GithubSource(
"https://github.com/erikdarlingdata/PerformanceStudio", null, false));

_velopackUpdate = await _velopackMgr.CheckForUpdatesAsync();
if (_velopackUpdate != null)
{
UpdateStatusText.Text = "Update available:";
UpdateLink.Text = $"v{_velopackUpdate.TargetFullRelease.Version} — click to download and install";
UpdateLink.IsVisible = true;
CheckUpdateButton.IsEnabled = true;
return;
}
}
catch
{
// Velopack packages may not exist yet — fall through
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Clear cached update state before each check.

If a prior Windows check populated _velopackUpdate and a later Velopack check throws before Line 96 assigns a new value, the fallback branch can show a browser update while UpdateLink_Click still applies the stale Velopack release.

🛠️ Proposed fix
 private async void CheckUpdate_Click(object? sender, RoutedEventArgs e)
 {
     CheckUpdateButton.IsEnabled = false;
     UpdateStatusText.Text = "Checking...";
     UpdateLink.IsVisible = false;
+    _updateUrl = null;
+    _velopackMgr = null;
+    _velopackUpdate = null;
 
     // Try Velopack first (Windows only, supports download + apply)
     if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
     {
         try
         {
-            _velopackMgr = new UpdateManager(
+            var velopackMgr = new UpdateManager(
                 new Velopack.Sources.GithubSource(
                     "https://github.com/erikdarlingdata/PerformanceStudio", null, false));
 
-            _velopackUpdate = await _velopackMgr.CheckForUpdatesAsync();
-            if (_velopackUpdate != null)
+            var velopackUpdate = await velopackMgr.CheckForUpdatesAsync();
+            if (velopackUpdate != null)
             {
+                _velopackMgr = velopackMgr;
+                _velopackUpdate = velopackUpdate;
                 UpdateStatusText.Text = "Update available:";
-                UpdateLink.Text = $"v{_velopackUpdate.TargetFullRelease.Version} — click to download and install";
+                UpdateLink.Text = $"v{velopackUpdate.TargetFullRelease.Version} — click to download and install";
                 UpdateLink.IsVisible = true;
                 CheckUpdateButton.IsEnabled = true;
                 return;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private async void CheckUpdate_Click(object? sender, RoutedEventArgs e)
{
CheckUpdateButton.IsEnabled = false;
UpdateStatusText.Text = "Checking...";
UpdateLink.IsVisible = false;
// Try Velopack first (Windows only, supports download + apply)
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
try
{
_velopackMgr = new UpdateManager(
new Velopack.Sources.GithubSource(
"https://github.com/erikdarlingdata/PerformanceStudio", null, false));
_velopackUpdate = await _velopackMgr.CheckForUpdatesAsync();
if (_velopackUpdate != null)
{
UpdateStatusText.Text = "Update available:";
UpdateLink.Text = $"v{_velopackUpdate.TargetFullRelease.Version} — click to download and install";
UpdateLink.IsVisible = true;
CheckUpdateButton.IsEnabled = true;
return;
}
}
catch
{
// Velopack packages may not exist yet — fall through
}
}
private async void CheckUpdate_Click(object? sender, RoutedEventArgs e)
{
CheckUpdateButton.IsEnabled = false;
UpdateStatusText.Text = "Checking...";
UpdateLink.IsVisible = false;
_updateUrl = null;
_velopackMgr = null;
_velopackUpdate = null;
// Try Velopack first (Windows only, supports download + apply)
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
try
{
var velopackMgr = new UpdateManager(
new Velopack.Sources.GithubSource(
"https://github.com/erikdarlingdata/PerformanceStudio", null, false));
var velopackUpdate = await velopackMgr.CheckForUpdatesAsync();
if (velopackUpdate != null)
{
_velopackMgr = velopackMgr;
_velopackUpdate = velopackUpdate;
UpdateStatusText.Text = "Update available:";
UpdateLink.Text = $"v{velopackUpdate.TargetFullRelease.Version} — click to download and install";
UpdateLink.IsVisible = true;
CheckUpdateButton.IsEnabled = true;
return;
}
}
catch
{
// Velopack packages may not exist yet — fall through
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/PlanViewer.App/AboutWindow.axaml.cs` around lines 81 - 110,
CheckUpdate_Click can reuse stale _velopackUpdate/_velopackMgr from a prior run
if the new Velopack check throws; reset the cached state at the start of the
method (set _velopackUpdate and _velopackMgr to null) and also ensure the
exception path does not leave a prior value in place, and add a defensive check
in UpdateLink_Click to verify _velopackUpdate is non-null before attempting to
apply a Velopack release (and show a friendly error if it is null).

@erikdarlingdata erikdarlingdata merged commit 8bc4365 into dev Mar 19, 2026
4 checks passed
This was referenced Mar 19, 2026
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