Skip to content

Support MSIX .appinstaller updates for FW Lite testers - #2496

Merged
hahn-kev merged 2 commits into
developfrom
fwlite-appinstaller
Jul 30, 2026
Merged

Support MSIX .appinstaller updates for FW Lite testers#2496
hahn-kev merged 2 commits into
developfrom
fwlite-appinstaller

Conversation

@hahn-kev-bot

@hahn-kev-bot hahn-kev-bot commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

worked with Claude today to figure this out. The plan is that nothing will change for anyone once this is released. But we can test out the app installer ourselves, and with some testers who were having issues with the previous update path. Once we're happy we will remove the if (appInstallerUri is null) path which installs the package directly, and install via the appInstaller, this will register the windows auto update.

This PR is in conflict with #2468 because it only works if we're using AddPackageByUriAsync but that would disconnect the app installer.


🤖 AI summary

Enables the OS-driven Windows .appinstaller update track for FW Lite, so a subset of testers can be moved onto it without disturbing the majority who install the plain .msixbundle. Whether an existing bare-bundle install can be migrated onto the track was verified by hand (install once through the .appinstaller → in-place update, project data preserved, GetAppInstallerInfo().Uri populated), as was serving the bundle straight from GitHub (application/octet-stream + 302 redirect both work — no proxy needed).

Changes

  • GenerateAppInstaller — drop <OnLaunch> so Windows never checks on start: no update popup, and no race with the in-app updater. Keep the silent <AutomaticBackgroundTask> (~8h). Harden ConvertVersionToAppInstallerVersion (int.Parse instead of TrimStart('0'), now public static) and lock the format with a test — a mismatch with the bundle's manifest identity version is a hard install failure.
  • AppUpdateService.ApplyUpdate (FwLiteMaui/Windows) — pick the update path at runtime:
    • On the App Installer track (Package.Current.GetAppInstallerInfo()?.Uri non-null) → AddPackageByAppInstallerFileAsync.
    • Otherwise (plain .msixbundle, most users today) → the existing AddPackageByUriAsync path, unchanged.
      Using the bundle API on a tracked install would detach it from the track, so this branch is required.
  • Remove the now-false controller comment claiming the appinstaller path can't work (octet-stream/range were the concerns; both verified fine).
  • Add docs/research/msix-appinstaller-fwlite.md documenting the primary-source research, the hands-on verification results, the rollout plan, and a MAUI gotcha (the desktop app reads no env/appsettings config, so behaviour changes there require a code + signed build).

Rollout — intentionally not rolled out to everyone. This keeps two install paths coexisting: most users on bundle + in-app updater; a few testers on the .appinstaller. Shipping a later build migrates the fleet automatically (their in-app updater installs through the appinstaller, attaching them). Coexistence is safe because the in-app updater now uses the App Installer API when on the track.

For testers (once merged + deployed). Install/migrate onto the track with a single command; existing project data is preserved:

Add-AppxPackage -AppInstallerFile https://lexbox.org/api/fwlite-release/download-latest?edition=windowsAppInstaller

Kept private for now — the public download page is not updated.

Watch items (see the research doc): if a tester's first in-app update fails with a capability/access error, add the packageManagement rescap capability to Package.appxmanifest; GetLatestRelease(WindowsAppInstaller) still throws (harmless — the controller special-cases that edition).

Test plan

  • ConvertVersionToAppInstallerVersion unit test passes (v2026-07-06-… → 2026.7.6.1, incl. the October 10 case).
  • FwLiteMaui Windows target builds clean (0 warnings).
  • Manual: install via .appinstaller → publish newer version → auto-updates.
  • Manual: retroactive attach — bare .msixbundle install, then install once via .appinstaller → in-place update, data preserved, now on the track.
  • Manual: <MainBundle Uri> pointing directly at the GitHub asset installs (octet-stream + 302).
  • After merge + deploy: confirm …/download-latest?edition=windowsAppInstaller serves the generated .appinstaller and a tester machine updates via AddPackageByAppInstallerFileAsync.

Enables the OS-driven .appinstaller update track alongside the existing
in-app updater, so a subset of testers can be moved onto it without
disrupting the majority who install the plain .msixbundle.

- GenerateAppInstaller: drop <OnLaunch> (no on-launch check, so no update
  popup and no race with the in-app updater); keep the silent background
  task. Harden ConvertVersionToAppInstallerVersion (int.Parse over
  TrimStart('0')) and lock the format with a test, since a mismatch with
  the bundle manifest is a hard install failure.
- AppUpdateService: pick the update path at runtime. When the install is
  on the App Installer track (GetAppInstallerInfo() is non-null), update
  via AddPackageByAppInstallerFileAsync; otherwise keep the existing
  AddPackageByUriAsync bundle path. Using the bundle API on a tracked
  install would detach it from the track.
- Remove the stale controller comment: octet-stream + 302 from GitHub was
  verified working, so no proxy is needed.
- Document the verification results and rollout plan in docs/research.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added 💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related 📦 Lexbox issues related to any server side code, fw-headless included labels Jul 29, 2026
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 90d6f0e4-6e42-47c9-b611-fe559a06083e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Changes

App Installer update integration

Layer / File(s) Summary
Manifest and version contract
backend/LexBoxApi/Services/FwLiteReleases/FwLiteReleaseService.cs, backend/Testing/LexCore/Services/FwLiteReleaseServiceTests.cs, backend/LexBoxApi/Controllers/FwLiteReleaseController.cs
App Installer updates are silent/background-oriented, version conversion is publicly exposed and numerically normalized, and representative tag conversions are tested.
Runtime update routing
backend/FwLite/FwLiteMaui/Platforms/Windows/AppUpdateService.cs
Associated App Installer installations use AddPackageByAppInstallerFileAsync; other installations retain the direct URI path.
Research and integration record
docs/research/msix-appinstaller-fwlite.md
Documents App Installer requirements, migration behavior, hosting constraints, updater coexistence, verification results, and remaining work items.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Poem

I’m a rabbit with updates tucked neat,
App Installer hops on silent feet.
Versions line up, bundles fly,
Background checks drift through the sky—
Carrots for tests, and releases complete!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed It clearly summarizes the main change: adding MSIX .appinstaller update support for FW Lite testers.
Description check ✅ Passed It describes the rollout plan and the .appinstaller update-path changes in the PR.
✨ 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 fwlite-appinstaller

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@argos-ci

argos-ci Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Jul 29, 2026, 4:07 AM
e2e (Inspect) ✅ No changes detected - Jul 29, 2026, 4:14 AM

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/FwLite/FwLiteMaui/Platforms/Windows/AppUpdateService.cs`:
- Around line 176-187: Update GetAppInstallerUri and its caller so only a
successful lookup returning null triggers the direct bundle fallback. When
Package.Current or GetAppInstallerInfo throws, preserve the tracked-install
path, log the exception, and return UpdateResult.Failed instead of passing null
to AddPackageByUriAsync.

In `@docs/research/msix-appinstaller-fwlite.md`:
- Around line 31-35: Update the research document to remove stale verification
findings and completed action items across the referenced sections. Align all
migration, redirect/octet-stream, and version-conversion descriptions with the
current GenerateAppInstaller and ConvertVersionToAppInstallerVersion
implementations, including int.Parse rather than TrimStart; retain only
genuinely unresolved work such as capability validation and download-page
rollout.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4955cea1-3ee1-4a59-832e-8f68a082b1c2

📥 Commits

Reviewing files that changed from the base of the PR and between 562404a and b5b8c53.

📒 Files selected for processing (5)
  • backend/FwLite/FwLiteMaui/Platforms/Windows/AppUpdateService.cs
  • backend/LexBoxApi/Controllers/FwLiteReleaseController.cs
  • backend/LexBoxApi/Services/FwLiteReleases/FwLiteReleaseService.cs
  • backend/Testing/LexCore/Services/FwLiteReleaseServiceTests.cs
  • docs/research/msix-appinstaller-fwlite.md
💤 Files with no reviewable changes (1)
  • backend/LexBoxApi/Controllers/FwLiteReleaseController.cs

Comment thread backend/FwLite/FwLiteMaui/Platforms/Windows/AppUpdateService.cs
Comment thread docs/research/msix-appinstaller-fwlite.md
Address CodeRabbit: the detailed-findings body was still written in
pre-implementation tense (UNCERTAIN markers, action items, and a section
describing the removed TrimStart code). Add a banner marking those
sections as the original 2026-07-28 research, and annotate sections D/E/F
with their resolved status so nothing instructs already-done work.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@hahn-kev
hahn-kev requested a review from myieye July 29, 2026 10:23

@myieye myieye left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM 👍 (I did not test anything)

@hahn-kev
hahn-kev merged commit e6fe885 into develop Jul 30, 2026
27 checks passed
@hahn-kev
hahn-kev deleted the fwlite-appinstaller branch July 30, 2026 08:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related 📦 Lexbox issues related to any server side code, fw-headless included

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants