Skip to content

Add daily update check and upgrade command to handle upgrading from CLI#424

Open
zateutsch wants to merge 30 commits intomainfrom
zt/392-upgrade-command
Open

Add daily update check and upgrade command to handle upgrading from CLI#424
zateutsch wants to merge 30 commits intomainfrom
zt/392-upgrade-command

Conversation

@zateutsch
Copy link
Copy Markdown
Contributor

@zateutsch zateutsch commented Apr 13, 2026

fixes #392

This PR adds a daily check for a new version of WinAppCli and adds an upgrade command that handles upgrading the user's CLI to the latest version with whatever original installation method they used.

Copilot AI review requested due to automatic review settings April 13, 2026 23:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a daily “new version available” notification and a winapp upgrade command so the CLI can guide (and in some cases perform) self-upgrades based on install channel, addressing issue #392.

Changes:

  • Introduces ICliUpgradeService / CliUpgradeService and wires it into startup to check for updates once per day.
  • Adds a new upgrade command and registers it in the root command/help categories and CLI schema output.
  • Updates the npm-generated command wrappers (including run --symbols) and refreshes schema references.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
src/winapp-npm/src/winapp-commands.ts Regenerated npm command wrappers/docs; adds run --symbols and updates manifest wording.
src/winapp-CLI/WinApp.Cli/Services/ICliUpgradeService.cs New interface + InstallChannel enum for upgrade/update-check behavior.
src/winapp-CLI/WinApp.Cli/Services/CliUpgradeService.cs Implements daily update check + upgrade flows for MSIX/exe and instructions for npm/NuGet.
src/winapp-CLI/WinApp.Cli/Program.cs Invokes update check during startup (non-quiet, non-json/schema modes).
src/winapp-CLI/WinApp.Cli/NativeMethods.txt Adds GetCurrentPackageFullName for MSIX identity detection.
src/winapp-CLI/WinApp.Cli/Helpers/HostBuilderExtensions.cs Registers CliUpgradeService and hooks up UpgradeCommand handler.
src/winapp-CLI/WinApp.Cli/Commands/WinAppRootCommand.cs Adds upgrade to root command and “Setup” help category.
src/winapp-CLI/WinApp.Cli/Commands/UpgradeCommand.cs New winapp upgrade command delegating to ICliUpgradeService.
src/winapp-CLI/WinApp.Cli.Tests/CliUpgradeServiceTests.cs Adds tests for install channel detection, cache file behavior, and command registration.
docs/cli-schema.json Adds upgrade command metadata to the published CLI schema.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/winapp-CLI/WinApp.Cli/Services/CliUpgradeService.cs
Comment thread src/winapp-npm/src/winapp-commands.ts Outdated
Comment thread src/winapp-CLI/WinApp.Cli/Program.cs Outdated
Comment thread src/winapp-CLI/WinApp.Cli/Services/CliUpgradeService.cs
Comment thread src/winapp-CLI/WinApp.Cli/Services/CliUpgradeService.cs Outdated
Comment thread src/winapp-npm/src/winapp-commands.ts Outdated
Comment thread src/winapp-npm/src/winapp-commands.ts Outdated
Comment thread src/winapp-CLI/WinApp.Cli/Program.cs
Comment thread src/winapp-CLI/WinApp.Cli/Services/CliUpgradeService.cs Outdated
Comment thread src/winapp-CLI/WinApp.Cli/Services/CliUpgradeService.cs Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 13, 2026

Build Metrics Report

Binary Sizes

Artifact Baseline Current Delta
CLI (ARM64) 30.66 MB 30.71 MB 📈 +55.5 KB (+0.18%)
CLI (x64) 31.02 MB 31.08 MB 📈 +53.5 KB (+0.17%)
MSIX (ARM64) 12.94 MB 12.95 MB 📈 +2.8 KB (+0.02%)
MSIX (x64) 13.74 MB 13.75 MB 📈 +13.5 KB (+0.10%)
NPM Package 26.90 MB 26.95 MB 📈 +52.5 KB (+0.19%)
NuGet Package 26.98 MB 27.03 MB 📈 +48.1 KB (+0.17%)
VS Code Extension 19.72 MB 19.76 MB 📈 +45.8 KB (+0.23%)

Test Results

843 passed, 2 skipped out of 845 tests in 474.1s (+61 tests, +83.4s vs. baseline)

Test Coverage

21.6% line coverage, 36.8% branch coverage · ✅ +0.2% vs. baseline

CLI Startup Time

37ms median (x64, winapp --version) · ✅ no change vs. baseline


Updated 2026-04-22 00:41:32 UTC · commit 666debd · workflow run

@zateutsch
Copy link
Copy Markdown
Contributor Author

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 14, 2026

@copilot apply changes based on the comments in this thread

Implemented the requested review-thread fixes in commit d62b629. This includes startup timeout + early caller parsing in Program, culture-safe update-cache timestamp parsing, nodejs-package caller detection, corrected npm upgrade package name, unsafe package-identity P/Invoke usage, network-isolated upgrade service tests, and regenerated schema/npm wrapper docs (including manifest wording alignment and the upgrade-options generator lint fix).

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/microsoft/msstore-cli/releases/latest
    • Triggering command: /home/REDACTED/work/winappCli/winappCli/src/winapp-CLI/WinApp.Cli.Tests/bin/Debug/net10.0-windows10.0.19041.0/WinApp.Cli.Tests /home/REDACTED/work/winappCli/winappCli/src/winapp-CLI/WinApp.Cli.Tests/bin/Debug/net10.0-windows10.0.19041.0/WinApp.Cli.Tests --server dotnettestcli --dotnet-test-pipe /tmp/0842e64278ef4ec498d33984d795b83c (http block)
  • https://api.github.com/repos/microsoft/winappcli/releases/latest
    • Triggering command: /home/REDACTED/work/winappCli/winappCli/src/winapp-CLI/WinApp.Cli.Tests/bin/Debug/net10.0-windows10.0.19041.0/WinApp.Cli.Tests /home/REDACTED/work/winappCli/winappCli/src/winapp-CLI/WinApp.Cli.Tests/bin/Debug/net10.0-windows10.0.19041.0/WinApp.Cli.Tests --server dotnettestcli --dotnet-test-pipe /tmp/0842e64278ef4ec498d33984d795b83c (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@zateutsch zateutsch requested a review from nmetulev April 16, 2026 02:21
@zateutsch
Copy link
Copy Markdown
Contributor Author

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 16, 2026

@copilot apply changes based on the comments in this thread

Applied the requested review-thread updates in commit 0ed5dfb. This re-aligns init wording with appxmanifest.xml, updates run/unregister --manifest descriptions to include both appxmanifest.xml and Package.appxmanifest, and regenerates docs/cli-schema.json, src/winapp-npm/src/winapp-commands.ts, and the affected generated setup skill docs so validate-docs stays in sync.

Copy link
Copy Markdown
Member

@nmetulev nmetulev left a comment

Choose a reason for hiding this comment

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

Can you update the description of the pr - we use the description for release notes and blog posts and the more info we have the better.

Looks like the upgrade command needs to be added to the generate-llm-docs.ps1 script so it's added to the skills

Comment thread src/winapp-CLI/WinApp.Cli/Services/CliUpgradeService.cs Outdated
Comment thread src/winapp-npm/package.json
Comment thread src/winapp-CLI/WinApp.Cli/Services/CliUpgradeService.cs Outdated
Comment thread src/winapp-CLI/WinApp.Cli/Services/CliUpgradeService.cs Outdated
Comment thread src/winapp-CLI/WinApp.Cli/Services/CliUpgradeService.cs Outdated
@zateutsch zateutsch requested a review from nmetulev April 18, 2026 00:23
zateutsch and others added 3 commits April 18, 2026 17:16
Add upgrade skill template and register it in generate-llm-docs.ps1 so
the upgrade command appears in the auto-generated agent skills.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The recent merge of main dropped the declarations of rootCommand and
parseResult in Program.cs while leaving call sites that reference them,
causing five CS0103 "name does not exist in the current context" errors.

Restore the canonical structure from main:
  - resolve rootCommand from the service provider just before the
    args.Length == 0 short-circuit (so it can serve --help too)
  - call rootCommand.Parse(args) once and assign to parseResult
  - re-add the WINAPP_CLI_CALLER env var setup

Also drop the leftover effectiveParseResult = parseResult ?? ... that
guarded against a nullable parseResult that no longer exists in this
control flow.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@nmetulev
Copy link
Copy Markdown
Member

Pushed 03c5835 to fix the build break. The recent merge of main dropped the declarations of
ootCommand\ and \parseResult\ in Program.cs while leaving 5 call sites that referenced them. Restored the canonical pattern from main (single
ootCommand\ + \parseResult, including the \WINAPP_CLI_CALLER\ env var setup) and removed the leftover \�ffectiveParseResult ??\ guard that had no nullable input. Local build clean; full test suite 787/787 passing.

Copy link
Copy Markdown
Member

@nmetulev nmetulev left a comment

Choose a reason for hiding this comment

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

Did an end-to-end review (code + manual smoke test on a Release-published build). Full test suite is green (787/787). Findings below — one is a blocker, a few others worth addressing before merge.

🔴 Critical — must fix before merge

1. winapp upgrade can silently DOWNGRADE users. UpgradeAsync (CliUpgradeService.cs:136) never calls IsNewerVersion — it unconditionally downloads and installs whatever /releases/latest returns. I reproduced this: published a fresh Release build (v1.0.0+<sha>, 23 MB), ran winapp upgrade, and my binary was replaced with v0.2.1 (18 MB), leaving a .old backup. Anyone on a nightly/dev/preview build running winapp upgrade will be silently downgraded. Suggested fix: gate UpgradeMsixAsync/UpgradeExeAsync on IsNewerVersion(latest, current) and print "already up to date" otherwise, and/or add a --force flag.

2. No signature/checksum verification on the downloaded MSIX/EXE (lines ~180 and ~230). The exe rename trick then puts an unverified binary in place. Given this is an auto-update path, at minimum the downloaded artifact should have its Authenticode signature verified before install.

🟡 Should-fix

3. No overall timeout on UpgradeAsync. The static HttpClient has no Timeout; only CheckAndNotifyAsync is gated by the 2s WaitAsync in Program.cs. A slow/hung download from upgrade will hang indefinitely.

4. Notification uses static AnsiConsole.MarkupLine (line 335) instead of the DI'd IAnsiConsole — same testability issue I just fixed in #485. No test actually asserts the notification text is shown.

5. No tests for the risky paths (MSIX install, standalone exe swap, GitHub API parsing, IsNewerVersion edge cases). Tests today cover npm/nuget (which just log) + channel detection + cache behavior.

🟢 Minor

6. Cache file's second line is dead dataWriteCacheFile writes {timestamp}\n{newVersion}, but CheckAndNotifyAsync reads only lines[0]. Either use the version (e.g., to avoid re-notifying the same version next day) or drop it.

7. UpgradeCommand_HasCorrectDescription asserts on exact description text → brittle.

8. Update check fires on winapp --version, potentially adding up to 2 s to a query that should be instant.

✅ Verified working

  • Channel detection (npm/nuget/standalone via WINAPP_CLI_CALLER)
  • 24-hour cache debounce
  • --quiet / --json / --cli-schema correctly skip the check
  • Notification renders correctly ("v99.0.0 is available...")
  • Exe rename self-update actually works on Windows
  • PR #485's clean stdout for get-winapp-path still holds
  • Full suite: 787/787 passing

Happy to approve once #1 is addressed — that's an active regression risk. #2#5 are worth doing before merge; the rest are follow-up candidates.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 9 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/winapp-CLI/WinApp.Cli/Program.cs Outdated
Comment thread src/winapp-CLI/WinApp.Cli/Program.cs
Comment thread .github/plugin/skills/winapp-cli/upgrade/SKILL.md
Comment thread src/winapp-CLI/WinApp.Cli/Services/CliUpgradeService.cs Outdated
Comment thread src/winapp-CLI/WinApp.Cli/Services/CliUpgradeService.cs Outdated
Comment thread src/winapp-CLI/WinApp.Cli/Services/CliUpgradeService.cs Outdated
Comment thread src/winapp-npm/src/winapp-commands.ts
Comment thread docs/npm-usage.md Outdated
Comment thread docs/fragments/skills/winapp-cli/upgrade.md
zateutsch and others added 4 commits April 21, 2026 19:16
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@zateutsch
Copy link
Copy Markdown
Contributor Author

@copilot apply changes based on the comments in this thread

Comment thread src/winapp-CLI/WinApp.Cli/Services/CliUpgradeService.cs
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 21, 2026

@copilot apply changes based on the comments in this thread

Applied the remaining thread changes in commits 0f84faf and 2f53f0c. This moves --caller parsing/env setup ahead of the startup update check in Program.cs, and hardens EXE swap backup handling in CliUpgradeService.SwapExecutable so locked stale .old files don’t block upgrade.

Can you update the description of the pr - we use the description for release notes and blog posts and the more info we have the better.

Looks like the upgrade command needs to be added to the gener...

Updated in this branch: upgrade is now mapped in scripts/generate-llm-docs.ps1 ("upgrade" = @("upgrade")) and validated in docs/skills generation. I also expanded the PR description content via the progress checklist updates for release-notes context. Latest addressing commit: 2f53f0c.

Did an end-to-end review (code + manual smoke test on a Release-published build). Full test suite is green (787/787). Findings below — one is a blocker, a few others worth addressing before merge.
...

Addressed the critical/should-fix upgrade items in this branch, including downgrade guard + --force, signature verification, overall upgrade timeout, DI console usage for notifications, and follow-up startup caller parsing + backup-swap hardening. Latest follow-up commits are 0f84faf and 2f53f0c.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/microsoft/msstore-cli/releases/latest
    • Triggering command: /home/REDACTED/work/winappCli/winappCli/src/winapp-CLI/WinApp.Cli.Tests/bin/Debug/net10.0-windows10.0.19041.0/WinApp.Cli.Tests /home/REDACTED/work/winappCli/winappCli/src/winapp-CLI/WinApp.Cli.Tests/bin/Debug/net10.0-windows10.0.19041.0/WinApp.Cli.Tests --server dotnettestcli --dotnet-test-pipe /tmp/9c1347629a5243bbb9732ad82af68fb0 (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Comment thread src/winapp-CLI/WinApp.Cli.Tests/CliUpgradeServiceTests.cs Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: CLI should check for updates

4 participants