feat: recognize .msix / .msixbundle assets and 'msix' package format#46
Open
dopry wants to merge 4 commits into
Open
feat: recognize .msix / .msixbundle assets and 'msix' package format#46dopry wants to merge 4 commits into
dopry wants to merge 4 commits into
Conversation
Reimplementation of #26 on the unified ReleaseService resolution pipeline (msix as a first-class package format on the discrete {os, arch, pkg} model): - SUPPORTED_FILE_EXTENSIONS gains .msix / .msixbundle; getDownloadExtensionsByOs("windows", "msix") returns [".msixbundle", ".msix"], preferring the multi-arch bundle. - PACKAGE_FORMATS gains "msix"; filenameToPackageFormat detects both extensions; new filetypeToPackageFormat maps ?filetype=msix|msixbundle to the msix pkg at the HTTP edge (other filetypes keep their platform-default semantics). - filenameToOperatingSystem maps .msix / .msixbundle to windows; filenameToArchitecture treats .msixbundle as universal (multi-arch by definition), single-arch .msix derives arch from the filename suffix. - New composite platform ids windows_msix{,_32,_64,_universal} so msix assets survive ingestion; arm64 .msix drops like any arm64 windows asset. - assetMatchesPlatform: a universal msix asset satisfies any windows arch when msix is explicitly requested; default windows flows (pkg "default") never widen to msix, so Squirrel clients keep resolving the .exe when msix assets are published alongside it. - /update/:platform/:version?filetype=msix serves the existing Squirrel.Mac-shaped JSON that Electron 41+'s MSIX autoUpdater consumes; /download/...?filetype=msix and /dl/windows/:arch?pkg=msix route to the assets. The Squirrel.Windows RELEASES/.nupkg path is untouched. Co-Authored-By: Jeff Robbins <321284+jjeff@users.noreply.github.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019F5tixJXBm2R1FAjAfH1se
4 tasks
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019F5tixJXBm2R1FAjAfH1se
There was a problem hiding this comment.
Pull request overview
Adds first-class MSIX support to Pecans’ discrete {os, arch, pkg} resolution pipeline so Electron 41+ MSIX autoUpdater clients can request updates via ?filetype=msix|msixbundle and resolve to .msix / .msixbundle assets without affecting default Windows (Squirrel/.exe) behavior.
Changes:
- Extend detection + platform modeling to recognize
.msix/.msixbundle, introducepkg: "msix", and ingest MSIX assets aswindows_msix_*platforms. - Update resolution semantics so universal
.msixbundlecan satisfy arch-specific Windows requests only whenpkg: "msix"is requested, while default Windows flows remain.exe. - Add end-to-end integration coverage and documentation for MSIX update/download routes.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| test/unit/SupportedFileExtension.spec.ts | Adds MSIX/MSIXBUNDLE extension coverage and Windows msix download-extension expectations. |
| test/unit/service.spec.ts | Adds parsePlatform, matching, and resolution tests for msix (including universal bundle widening under pkg: "msix"). |
| test/unit/platforms.spec.ts | Verifies filename→platform resolution for .msix/.msixbundle including arm64 drop behavior. |
| test/unit/PackageFormat.spec.ts | Expands PackageFormat to include msix and tests filetypeToPackageFormat. |
| test/unit/OperatingSystem.spec.ts | Adds OS detection expectations for .msix/.msixbundle as Windows. |
| test/unit/github.spec.ts | Ensures GitHub backend normalization retains msix assets alongside exe assets. |
| test/unit/Architecture.spec.ts | Adds .msixbundle→universal and .msix suffix arch detection tests. |
| test/integration/msix.spec.ts | New integration suite covering update/download/dl behavior for MSIX end-to-end. |
| src/utils/SupportedFileExtension.ts | Adds supported extensions and Windows pkg=msix download-extension preference ordering. |
| src/utils/platforms.ts | Adds windows_msix* platform IDs and allows filenameToPlatform to encode msix as a pkg segment. |
| src/utils/PackageFormat.ts | Adds msix package format detection + filetypeToPackageFormat mapping for HTTP filetype. |
| src/utils/OperatingSystem.ts | Recognizes .msix/.msixbundle as Windows. |
| src/utils/Architecture.ts | Treats .msixbundle as universal by definition. |
| src/service.ts | Allows universal msix assets to satisfy arch-specific Windows filters when pkg: "msix". |
| src/http/updates.ts | Applies msix pkg implication based on ?filetype=... for the Squirrel.Mac-shaped update feed. |
| src/http/downloads.ts | Applies msix pkg implication at the legacy /download/* HTTP edge when ?filetype=msix*. |
| docs/update-windows.md | Documents Electron 41+ MSIX update usage and how it interacts with default Windows behavior. |
filetypeToPackageFormat accepts ?filetype=MSIX case-insensitively, but the handler embedded the caller's casing into the generated download url, which the download route's case-sensitive filetype validation then rejects with a 400. Lowercase the filetype before both the pkg mapping and the feed url. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019F5tixJXBm2R1FAjAfH1se
The filetype->pkg implication belongs to platform-based resolution; an explicit :filename already identifies the asset and its package format, so a stray ?filetype=msix on an .exe filename request must not narrow release resolution (previously a 404 when no msix assets exist). Also reword the filetypeToPackageFormat doc comment: internal windows_msix* composite ids exist for ingestion, they're just not part of the legacy request vocabulary. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019F5tixJXBm2R1FAjAfH1se
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.
Summary
Supersedes #26 (thanks @jjeff for the original contribution — authorship is credited via
Co-Authored-Byon the commit). That PR was written against the pre-refactor codebase and can't be rebased mechanically:nexthas since replacedversions.ts/resolveForVersion.tswith the unifiedReleaseServicepipeline on the discrete{os, arch, pkg}model (#41–#45), and the PR's head lives on a fork branch this session can't push to. This PR reimplements the same feature idiomatically on the new architecture, preserving the external contract #26 established.Pecans can now act as the update server for an Electron 41+ app packaged as MSIX: the
/update/:platform/:versionendpoint already emits the Squirrel.Mac-shaped{url, name, notes, pub_date}JSON that Electron's MSIXautoUpdaterconsumes — Pecans just needs to recognize.msix/.msixbundleassets and route to them when the client asks for themsixfiletype.Changes
SUPPORTED_FILE_EXTENSIONSgains.msix/.msixbundle;PACKAGE_FORMATSgainsmsix;filenameToOperatingSystemmaps both extensions towindows;filenameToArchitecturetreats.msixbundleasuniversal(multi-arch by definition) while single-arch.msixderives arch from the filename suffix (_x64,_arm64,_x86);getDownloadExtensionsByOs("windows", "msix")returns[".msixbundle", ".msix"], preferring the bundle.windows_msix_64/windows_msix_32/windows_msix_universal(newPLATFORMSentries), exactly likelinux_deb_64. This is what makes them reachparsePlatform/assetMatchesPlatformcleanly. arm64.msixassets drop at ingestion like any other arm64 windows asset.assetMatchesPlatform): a universal msix asset satisfies any windows arch only when msix is explicitly requested (pkg: "msix"); default windows flows (pkg: "default") never widen to msix, so a.msixbundle-only release counts toward msix availability but never toward default availability. (feat: recognize .msix / .msixbundle assets and 'msix' package format #26's ingestion-order fix made bundle availability unconditional — a bundle-only release would 200 on a default update request and then 404 on the download; the discrete model lets us return an honest 204 instead.)filetypeToPackageFormatmaps?filetype=msix|msixbundletopkg: "msix"on the update and composite download routes. Other filetypes (deb,rpm,zip…) deliberately imply no pkg, preserving their existing platform-default semantics. The discrete route gets msix for free:/dl/windows/64?pkg=msixand/dl/windows/universal?pkg=msix.docs/update-windows.md.Downstream compatibility
[".exe"]unless msix is explicitly requested — pinned by a regression test with.exe+.msix+.msixbundlepublished side by side.RELEASES/.nupkgpath is untouched.PackageFormat/SupportedFileExtension/Platformunions widen, which only affects TypeScript consumers doing exhaustive switches — semver-minor.Test plan
normalizeReleaseingestion seam, service-level resolution semantics)test/integration/msix.spec.tscovers the feature end-to-end through the HTTP surface: Squirrel.Mac-shaped 200/204s for?filetype=msix|msixbundle, feed-url → bundle download resolution, bundle-only releases satisfying arch-specific clients, default flows still serving the.exe, and the/dl+/dl/:filenameroutesnext),tsc --noEmitclean,eslintcleanNotes
Server-side half of MSIX support for spaceagetv/missioncontrol (Visibox). References: Electron 41 release notes, electron/electron#49230.
🤖 Generated with Claude Code
https://claude.ai/code/session_019F5tixJXBm2R1FAjAfH1se
Generated by Claude Code