diff --git a/specs/Deployment/MSIXPackageVersioning.md b/specs/Deployment/MSIXPackageVersioning.md index 3c97e715af..02d10b0058 100644 --- a/specs/Deployment/MSIXPackageVersioning.md +++ b/specs/Deployment/MSIXPackageVersioning.md @@ -255,17 +255,12 @@ version 89 and 92+ are under development. * Compatible with MSIX * Does not align with common practices and expectations across the industry -***Recommendation:*** Option B. - -Option B provides a stronger degree of compatibility and risk management than Option A (Major -version) while still affording a reasonable way for developers to adopt updates. +***Recommendation:*** +For all 1.x, option B was selected, while waiting on tooling to be able to handle the rapid development we want. -Windows App SDK aspires to adopt Option A (Major version) but more tooling and infrastructure is -desired before making that level of guarantee. Option B provides a good balance of rapid -development and compatibility assurance. - -Option A can (and will) be adopted in a future release (no sooner than 2.0) once tooling and -infrastructure are ready to embrace it. +## Decision 2.1: Breaking Change for version 2.x +Starting 2.x, option A is selected. This will allow for better stability for external developers. They will +know that as long as they are on the same Major, then things will be compatible. ### 2.2.1. Current practices in Microsoft-authored Framework packges. @@ -289,8 +284,10 @@ Windows App SDK 0.5 adds a "-preview" tag to the package Name. Windows App SDK 1.x adds a -channel# tag (e.g. "-preview1") to the package name. -***Do we need a shorter tag?*** "-preview1" adds 9 characters to package Name. "-experiental1" adds -13 characters. Package Name is restricted to 50 characters maximum. +Windows App SDK 2.x goes back to just a "-preview" tag on the package Name. + +***Shorter Tags as needed*** "-preview" adds 8 characters to package Name. "-experiental" adds +12 characters. Package Name is restricted to 50 characters maximum. **Option A: `-preview`** **Option B: `-pre`** @@ -340,10 +337,12 @@ Examples are provided for the following theoretical versions... |D|NPPP.E.B.0|8001.154.123
2003.364.123
17014.3944.123.0|Minor Patch Elapsed Build|Minor max is 64
Patch max is 999
Build max is 65535| |E|NPP.E.B.0|801.154.123
203.364.123
1714.3944.123.0|Minor Patch Elapsed Build|Minor max is 99
Patch max is 99
Build max is 65535| -***Recommendation:*** Option D with Epoch=January 1, 2021. +***Recommendation:*** +For 1.x, Option D was selected. +For 2.x, Option A is selected. -Option A works for a simple release strategy but doesn't work when there's regular -(e.g. daily) builds. +Option A works is the simplest to release and understand. As long as we don't hit 999 Patches for the same Major.Minor, +then we will not run out of space in the DDLM package (more on that in 2.5) Option B worked for WinUI 2.x and Windows App SDK 0.5 but is too limiting given it can't support Minor versions beyond 6. It's also a complicated encoding scheme with date injected between Minor @@ -397,7 +396,7 @@ following naming patterns release 0.x... * WARfwk: `Microsoft.WindowsAppRuntime..[-tag]` * WARmain: `Microsoft.WindowsAppRuntime.Main..[-tag]` -* WARddlm: `Microsoft.WindowsAppRuntime.DDLM....-[-shorttag]` +* WARddlm: `Microsoft.WindowsAppRuntime.DDLM....-[-shorttag]` and release 1.x... @@ -406,22 +405,62 @@ and release 1.x... * WARsingleton: `MicrosoftCorporationII.WinAppRuntime.Singleton[-shorttag]` * WARddlm: `Microsoft.WinAppRuntime.DDLM....-[-shorttag]` +and release 2.x, when Breaking Change Boundary changed to 'Major' version... + +* WARfwk: `Microsoft.WindowsAppRuntime.[-tag##]` +* WARmain: `MicrosoftCorporationII.WinAppRuntime.Main.[-shorttag##]` +* WARsingleton: `MicrosoftCorporationII.WinAppRuntime.Singleton[-shorttag##]` +* WARddlm: `Microsoft.WinAppRuntime.DDLM....-[-shorttag##]` + where * rmajor = Major version number of the project release, base-10, no leading zeros (e.g. "1" for WindowsAppSDK 1.2) * rminor = Minor version number of the project release, base-10, no leading zeros (e.g. "2" for WindowsAppSDK 1.2) +* patch = Patch version number of the project release, base-10, no leading zeros * major = Major version number of the release, base-10, no leading zeros * minor = Minor version number of the release, base-10, no leading zeros * build = Build version number, base-10, no leading zeros * revision = Revision version number, base-10, no leading zeros * architecture = Allowed values: "x86", "x64", "arm64" * shortarchitecture = Allowed values: "x8", "x6", "a6" -* tag = Allowed values: "", "preview[#]", "experimental[#]" -* shorttag = Allowed values: "", "p[#]", "e[#]" +* tag = Allowed values: "", "preview", "experimental" +* shorttag = Allowed values: "", "p", "e" +* "##" = the current build bumber for that release type. 2 characters long. Each caharacter could be [a-z,0-9]. -**NOTE:** rmajor/rminor are the release version, major/minor/build/revision are the MSIX package +**NOTE:** rmajor/rminor/patch are the release version, major/minor/build/revision are the MSIX package version (Microsoft.ProjectReunion.0.8-preview had a release version of 0.8 -but an MSIX package version of 8000.146.628.0). +but an MSIX package version of 8000.146.628.0). Starting 2.0, these will now be the same numbers. The exception to that is +Singleton, since there is one package covering all releases. That package can't "go back" to Major=2, so we will add a +8000 to the Major for that package. + +Since we will now match the release version with the MSIX, it is worth explaining how that is going to increment. +* Major will increase when a stable or preview release contains Breaking Changes from the previous Stable release. This will happen +no more than once per year. +* Minor will increase when a stable release contains new Functionality from the previous Stable release. This will happen no more than once +per month. +* Every potential released build (stable, preview, experimental) will increase the Patch, unless the Major or Minor is increased. +No 2 builds will share the same Major.Minor.Patch version. +If we notice an issue after building a canditate(stable, preview, or experimental), we will choose not to release it, at which +point the patch will bump again. +This means that there will be times when there is a patch number that will not be released at all. +* Note: We see experimental releases as "containing" the closest stable + some experimental stuff, rather than "previewing" what is coming. We +do not bump the Major/Minor for experimental things because the new/breaking things will at least sometimes not be in the next stable release, +and may even be removed before the next experimental release. +* Preview releases are optional if we feel the need to have a preview of nearly stable things without anything currently marked experimental. +This will only happen on the next Major release before making an official stable release. + +A simplified example is this: +* 2.0.0 is the first stable release. +* 2.0.1-experimental is the first experimental. (contains 2.0.0 + some exp APIs, and some bug fixes) +* 2.0.2 is the 2nd stable release. (bug fixes moved into 2) +* 2.0.3-experimental is the 2nd experimental. (contains 2.0.1 + some exp APIs, and some more bug fixes) +* 2.0.4-experimental is the 3rd experimental. (contains 2.0.1 + some Breaking Changes, some exp APIs, and some more bug fixes) +* 2.1.0 is the 3rd stable release (some of the exp APIs went stable, and some bug fixes) +* 2.1.1-experimental is the 4th experimental. (contains 2.1.0 + some Breaking Changes, and some more bug fixes) +* 3.0.0-preview is the preview 3 public release +* 3.0.1-experimental (contains 3.0.1-preview + some new APIs not in the preview build) +* 3.0.3 is the first 3 stable release (we made 3.0.2, noticed issues we had not seen in preview, fixed and rebuilt) +* 3.0.4-experimental (contains 3.0.3 + the new APIs from 3.0.1-experimental) Version's fields have values 0-65535. @@ -433,24 +472,24 @@ This leads to package Name length issues even for common cases: |Package|Average|AverageLength| | --- | :--- | :---: | -|WARfwk |Microsoft.WindowsAppRuntime.1.15-preview1|41| -|WARmain|Microsoft.WindowsAppRuntime.Main.1.15-preview1|46| -|WARsingleton|Microsoft.WindowsAppRuntime.Singleton-preview1|46| -|WARddlm|Microsoft.WinAppRuntime.DDLM.1.15.12345.24680-arm64-preview1|**64**| +|WARfwk |Microsoft.WindowsAppRuntime.2-preview00|39| +|WARmain|Microsoft.WindowsAppRuntime.Main.2-preview00|44| +|WARsingleton|Microsoft.WindowsAppRuntime.Singleton-preview00|47| +|WARddlm|Microsoft.WinAppRuntime.DDLM.1.15.12345.24680-arm64-preview00|**61**| |Package|Min|MinLength| | --- | :--- | :---: | -|WARfwk |Microsoft.WindowsAppRuntime.1.0-preview1|40| -|WARmain|Microsoft.WindowsAppRuntime.Main.1.0-preview1|45| -|WARsingleton|Microsoft.WindowsAppRuntime.Singleton-preview1|46| -|WARddlm|Microsoft.WinAppRuntime.DDLM.1.0.0.0-arm64-preview1|**52**| +|WARfwk |Microsoft.WindowsAppRuntime.2-preview00|39| +|WARmain|Microsoft.WindowsAppRuntime.Main.1-preview00|44| +|WARsingleton|Microsoft.WindowsAppRuntime.Singleton-preview00|47| +|WARddlm|Microsoft.WinAppRuntime.DDLM.1.0.0.0-arm64-preview00|**52**| |Package|Max|MaxLength| | --- | :--- | :---: | -|WARfwk |Microsoft.WindowsAppRuntime.65535.65535-preview1|48| -|WARmain|Microsoft.WindowsAppRuntime.Main.65535.65535-preview1|53| -|WARsingleton|Microsoft.WindowsAppRuntime.Singleton-preview1|46| -|WARddlm|Microsoft.WinAppRuntime.DDLM.65535.65535.65535.65535-arm64-preview1|**71**| +|WARfwk |Microsoft.WindowsAppRuntime.65535-preview00|43| +|WARmain|Microsoft.WindowsAppRuntime.Main.65535-preview00|48| +|WARsingleton|Microsoft.WindowsAppRuntime.Singleton-preview00|47| +|WARddlm|Microsoft.WinAppRuntime.DDLM.65535.65535.65535.65535-arm64-preview00|**68**| Possible options we can use to shorten package Name: @@ -458,43 +497,46 @@ Possible options we can use to shorten package Name: * Dictate max values e.g. Major=0-99 * Encode values as base-16 * Replace -channel with a shorter string e.g. replace "-preview" with "-pre", "-p", "p" -* Encode the channel name in the delimiter between name+version e.g. Microsoft.WinAppRuntime.DDLM.preview1.1.0.0.0-arm64 -* Encode tag in the delimiter between version+architecture e.g. Microsoft.WinAppRuntime.DDLM.1.0.0.0p1arm64 using P1 for Preview1, E1=Experimental1, ... -* Name WARddlm differently from WARfwk and WARmain e.g. use "-p1" for WARddlm regardless if WARfwk and WARmain use "-preview1" -* ??? +* Encode the channel name in the delimiter between name+version e.g. Microsoft.WinAppRuntime.DDLM.preview01.1.0.0.0-arm64 +* Encode tag in the delimiter between version+architecture e.g. Microsoft.WinAppRuntime.DDLM.1.0.0.0p1arm64 using P01 for Preview1, E01=Experimental1, ... +* Name WARddlm differently from WARfwk and WARmain e.g. use "-p01" for WARddlm regardless if WARfwk and WARmain use "-preview01" WARddlm is needed until Dynamic Dependencies is 100% based on OS DynDep. Best case (!) WARddlm exists until the minimum supported Windows release is Cobalt. ***Recommendation:*** The general package naming syntax is -`Microsoft.ProjectReunion[.SubName]-.[-tag]`. WARddlm and WARsingleton are +`Microsoft.ProjectReunion[.SubName]-[-tag]`. WARddlm and WARsingleton are exceptions to the rule (see below). -Windows App SDK 0.8 will use package Names of... +Windows App SDK 2.0 will use package Names of... -* WARfwk: `Microsoft.WindowsAppRuntime..[-tag]` -* WARmain: `Microsoft.WindowsAppRuntime.Main..[-tag]` +* WARfwk: `Microsoft.WindowsAppRuntime.[-tag]` +* WARmain: `Microsoft.WindowsAppRuntime.Main.[-tag]` * WARsingleton: `Microsoft.WindowsAppRuntime.Singleton[-tag]` -* WARddlm: `Microsoft.WinAppRuntime.DDLM....-[-shorttag]` +* WARddlm: `Microsoft.WinAppRuntime.DDLM....-[-shorttag]` -Using Decision 5: Version Encoding = Option D (NPPP.E.B.0) WARddlm's maximum package Name length is -`Microsoft.WinAppRuntime.DDLM.1714.3944.123.24680-arm64-p3` = 58 characters. This can be reduced +Using Decision 5: Version Encoding = Option D (M.N.P.0) WARddlm's maximum package Name length is +`Microsoft.WinAppRuntime.DDLM.12345.12345.12345.12345-arm64-p01` = 62 characters. This can be reduced with the following rules: -* Major version <= 99 +* Major version <= 999 * Minor version <= 999 -* Build number <= 9999 +* Patch number <= 999 * Revision (security update) <= 99 * Architecture = 2 characters (x8=x86, x6=x64, a6=arm64) -This produces a worst case for WARddlm in Windows App SDK 99.888.7777.66 ARM64 Preview 3 to the following identifiers: +In the unlikely event that Minor or Patch reach these limits, then the Major (for the Minor) +or Minor (for the Patch) will bump for all packages in order to keep these restrictions. If\When we reach Major version 1000, then +the Major version will be the Actual Major %1000. This works, since the Major is also included in the name. + +This produces a worst case for WARddlm in Windows App SDK 99.888.777.66 ARM64 Preview 3 to the following identifiers: -* Package Name = `Microsoft.WinAppRuntime.DDLM.99.888.7777.66-a6-p3` = 49 characters -* PackageFullName = `"Microsoft.WinAppRuntime.DDLM.99.888.7777.66-a6-p3_99.888.7777.66_arm64__8wekyb3d8bbwe"` -* PackageFamilyName = `"Microsoft.WinAppRuntime.DDLM.99.888.7777.66-a6-p3_8wekyb3d8bbwe"` -* PACKAGE_VERSION struct = `99.888.7777.66` -* PACKAGE_VERSION uint64 = `0x006303781E610042` +* Package Name = `Microsoft.WinAppRuntime.DDLM.999.888.777.66-a6-p03` = 50 characters +* PackageFullName = `"Microsoft.WinAppRuntime.DDLM.999.888.777.66-a6-p03_999.888.7777.66_arm64__8wekyb3d8bbwe"` +* PackageFamilyName = `"Microsoft.WinAppRuntime.DDLM.999.888.777.66-a6-p03_8wekyb3d8bbwe"` +* PACKAGE_VERSION struct = `999.888.777.66` +* PACKAGE_VERSION uint64 = `0x03E7037803090042` # 3. Conclusions @@ -502,20 +544,22 @@ This produces a worst case for WARddlm in Windows App SDK 99.888.7777.66 ARM64 P **Decision 2:** Windows App SDK version 1.* encodes `Major.Minor` into MSIX package Names. +**Decision 2.1:** Windows App SDK version 2.* encodes `Major` into MSIX package Names. + **Decision 3:** Windows App SDK supports an optional 'tag' to indicate a non-Stable channel. A 'tag' comes in long and short (1-2 character) forms e.g. `-preview` and `-p`, or `-preview1` and `-p1` (the digit suffix is optional). -**Decision 4:** Windows App SDK encodes version as `...` -i.e. format encoding `NPPP.E.B.0`. See +**Decision 4:** Windows App SDK encodes version as `...` +i.e. format encoding `M.N.P.0`. See [2.4. Decision 4: Version Encoding](#24-decision-4-version-encoding) for more details. **Decision 5:** MSIX package Names use the format -`Microsoft.WindowsAppRuntime[.SubName]-.[-tag]`. WARddlm is an exception due to Name -length constraints. The specific packages Names in Windows App SDK 1.0: +`Microsoft.WindowsAppRuntime[.SubName]-[-tag]`. WARddlm is an exception due to Name +length constraints. The specific packages Names in Windows App SDK 2.0: -* WARfwk: `Microsoft.WindowsAppRuntime..[-tag]` -* WARmain: `MicrosoftCorporationII.WinAppRuntime.Main..[-shorttag]` +* WARfwk: `Microsoft.WindowsAppRuntime.[-tag]` +* WARmain: `MicrosoftCorporationII.WinAppRuntime.Main.[-shorttag]` * WARsingleton: `MicrosoftCorporationII.WinAppRuntime.Singleton[-shorttag]` * WARddlm: `Microsoft.WinAppRuntime.DDLM....-[-shorttag]` diff --git a/specs/Deployment/MSIXPackages.md b/specs/Deployment/MSIXPackages.md index b23d63612c..f56d747889 100644 --- a/specs/Deployment/MSIXPackages.md +++ b/specs/Deployment/MSIXPackages.md @@ -110,10 +110,10 @@ SDK 1.0, 1.1 and 2.0 (Stable) are installed on an x86 system, the user will have * Microsoft.WindowsAppRuntime.1.0 * Microsoft.WindowsAppRuntime.1.1 -* Microsoft.WindowsAppRuntime.2.0 +* Microsoft.WindowsAppRuntime.2 * MicrosoftCorporationII.WinAppRuntime.Main.1.0 * MicrosoftCorporationII.WinAppRuntime.Main.1.1 -* MicrosoftCorporationII.WinAppRuntime.Main.2.0 +* MicrosoftCorporationII.WinAppRuntime.Main.2 * MicrosoftCorporationII.WinAppRuntime.Singleton (version 2.0) * Microsoft.WinAppRuntime.DDLM.0.146.711.0-x8 * Microsoft.WinAppRuntime.DDLM.1000.328.1510.0-x8 @@ -143,15 +143,14 @@ for more details. Windows App SDK's MSIX packages use the following naming rules for package identity: -* Name = Microsoft.WindowsAppRuntime[.SubName].\.\[-VersionTag] +* Name = Microsoft.WindowsAppRuntime[.SubName].\[-VersionTag] * Publisher = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" where * SubName -- optional package sub-name. Use to distinguish amongst the different packages * Major -- major version of the release, e.g. "1" for Windows App SDK 1.0 -* Minor -- minor version of the release, e.g. "0" for Windows App SDK 1.0 -* VersionTag -- optional version tag to distinguish amongst channels and releases of a channel, e.g. "-preview2" for Windows App SDK 1.0 Preview 2 +* VersionTag -- optional version tag to distinguish amongst channels, e.g. "-preview" for Windows App SDK Preview ## 3.1. Package Naming - SubName @@ -159,20 +158,20 @@ The following SubName values are used: | SubName | Package | Example | |-|-|-| -| | Framework | Microsoft.WindowsAppRuntime.1.0-experimental1 | -| Main | Main | MicrosoftCorporationII.WinAppRuntime.Main.1.0-e1 | -| Singleton | Singleton | MicrosoftCorporationII.WinAppRuntime.Singleton-e1 | -| DDLM | Dynamic Dependency Lifetime Manager (DDLM) | Microsoft.WinAppRuntime.DDLM.0.146.711.0-x6-e1 | +| | Framework | Microsoft.WindowsAppRuntime.2-experimental00 | +| Main | Main | MicrosoftCorporationII.WinAppRuntime.Main.2-e00 | +| Singleton | Singleton | MicrosoftCorporationII.WinAppRuntime.Singleton-e00 | +| DDLM | Dynamic Dependency Lifetime Manager (DDLM) | Microsoft.WinAppRuntime.DDLM.2.3.11.0-x6-e00 | ## 3.2. Package Naming - Main The Main package follows a different naming scheme -* Name = MicrosoftCcorporationII.WinAppRuntime.Main.\[-ShortVersionTag] +* Name = MicrosoftCcorporationII.WinAppRuntime.Main.\[-ShortVersionTag] where -* ReleaseMajorMinor = project release major.minor version number. See the [MSIX Package Versioning](https://github.com/microsoft/WindowsAppSDK/blob/main/specs/deployment/MSIXPackageVersioning.md) for more details. +* ReleaseMajor = project release major version number. See the [MSIX Package Versioning](https://github.com/microsoft/WindowsAppSDK/blob/main/specs/deployment/MSIXPackageVersioning.md) for more details. * ShortVersionTag = short form of the VersionTag ShortVersionTag is derived from a VersionTag by combining the 1st letter and the last digit (if any) for non-Stable channels (ShortVeresionTag is blank for the Stable channel, just like VersionTag). @@ -202,7 +201,7 @@ where * ShortArchitecture = short form of the Architecture (x6=x64, x8=x86, a6=arm64) * ShortVersionTag = short form of the VersionTag -ShortVersionTag is derived from a VersionTag by combining the 1st letter and the last digit (if any) for non-Stable channels (ShortVeresionTag is blank for the Stable channel, just like VersionTag). +ShortVersionTag is derived from a VersionTag by using the 1st letter for non-Stable channels (ShortVeresionTag is blank for the Stable channel, just like VersionTag). ```C# string ToShortVersionTag(string versionTag) diff --git a/specs/Deployment/deprecated/MSIXPackageVersioning.md b/specs/Deployment/deprecated/MSIXPackageVersioning.md new file mode 100644 index 0000000000..8a0b3ff51b --- /dev/null +++ b/specs/Deployment/deprecated/MSIXPackageVersioning.md @@ -0,0 +1,522 @@ +- [1. Background](#1-background) + - [1.1. Scope](#11-scope) + - [1.2. Terminology](#12-terminology) + - [1.2.1. Project Reunion vs Windows App SDK](#121-project-reunion-vs-windows-app-sdk) + - [1.2.2. Version Number = MSIX](#122-version-number--msix) + - [1.2.3. Windows App SDK's MSIX Packages](#123-windows-app-sdks-msix-packages) + - [1.2.4. Binary Compatibility](#124-binary-compatibility) + - [1.2.5. Source Compatibility](#125-source-compatibility) + - [1.3. Impacted Components](#13-impacted-components) + - [1.4. MSIX and SemVer](#14-msix-and-semver) + - [1.5. Dynamic Dependencies](#15-dynamic-dependencies) + - [1.6. Windows App SDK Versioning Requirements](#16-windows-app-sdk-versioning-requirements) +- [2. Decisions](#2-decisions) + - [2.1. Decision 1: Breaking Change Boundary for Version 0.*](#21-decision-1-breaking-change-boundary-for-version-0) + - [2.2. Decision 2: Breaking Change Boundary for Version 1.x](#22-decision-2-breaking-change-boundary-for-version-1x) + - [2.2.1. Current practices in Microsoft-authored Framework packges.](#221-current-practices-in-microsoft-authored-framework-packges) + - [2.3. Decision 3: Release Tags (Stable, Preview, ...)](#23-decision-3-release-tags-stable-preview-) + - [2.4. Decision 4: Version Encoding](#24-decision-4-version-encoding) + - [2.4.1. Windows App SDK 0.5 Notation](#241-windows-app-sdk-05-notation) + - [2.4.2. WinUI 2.x Notation](#242-winui-2x-notation) + - [2.5. Decision 5: Package Names](#25-decision-5-package-names) +- [3. Conclusions](#3-conclusions) + +# 1. Background + +This document answers the question: "How are MSIX and Dynamic Dependencies defined and implemented +to meet versioning requirements for Windows App SDK 0.8 through 1.x?" + +This document defines how Windows App SDK packages are named and versioned. + +## 1.1. Scope + +This decision focuses on install- and run-time beyond 0.5 and, +in particular, MSIX and Dynamic Dependencies in 0.8 and 1.x. + +Development- and build-time issues are out-of-scope for this decision. Windows App SDK's +requirements for dev- and build-time and how NuGet, VISX and other tech are handled do not +impact this decision. + +As this spec is focused on install- and run-time it results in a stance on binary compatibility. +Source compatibility is only significant at development- and build-time so a decision on source +compatibility is out-of-scope for this decision. + +## 1.2. Terminology + +### 1.2.1. Project Reunion vs Windows App SDK + +This document defines the MSIX versioning details for version 0.8 thru 1.x. + +The project went thru a name change from "Project Reunion" in 0.8 to "Windows +App SDK" in 1.0. Artifact names are kept historically accurate. Textual prose +has been updated to use the new "Windows App SDK" name for consistency, even +when referring to earlier versions. + +Similarly, examples may cite ProjectReunion but the same logic applies to 1.x despite name changes. + +### 1.2.2. Version Number = MSIX + +SemVer defines a version number as `MAJOR.MINOR.PATCH[-prerelease][+build]`. + +MSIX defines a version number as `Major.Minor.Build.Revision`. + +To avoid ambiguity this document uses MSIX's definition and terms unless stated otherwise. + +### 1.2.3. Windows App SDK's MSIX Packages + +Windows App SDK 0.5 has 1 MSIX package: `Microsoft.ProjectReunion.0.5` aka WARfwk (formerly PRfwk). +This contains the vast majority of Windows App SDK. + +Windows App SDK 0.8 has 3 MSIX packages + +* `Microsoft.WindowsAppRuntime` aka **WARfwk** +* `Microsoft.WindowsAppRuntime.Main` aka **WARmain** +* `Microsoft.WindowsAppRuntime.DDLM` aka **WARddlm** + +WARmain and WARddlm supplement WARfwk to do things a Framework packge can't (e.g. Packaged COM). +See the [Dynamic Dependencies spec](https://github.com/microsoft/WindowsAppSDK/blob/main/specs/dynamicdependencies/DynamicDependencies.md) +and [Windows App SDK: MSIX Packages](https://github.com/microsoft/WindowsAppSDK/blob/main/specs/Deployment/MSIXPackage.md) +for more details. + +Windows App SDK 1.0 has 4 MSIX packages + +* `Microsoft.WindowsAppRuntime` aka **WARfwk** +* `MicrosoftCorporationII.WinAppRuntime.Main` aka **WARmain** +* `MicrosoftCorporationII.WinAppRuntime.Singleton` aka **WARsingleton** +* `Microsoft.WinAppRuntime.DDLM` aka **WARddlm** + +WARsingleton supplements WARmain to provide a mechanism for features needing singular global +behavior across all versions of Windows App SDK. See [Windows App SDK: MSIX Packages](https://github.com/microsoft/WindowsAppSDK/blob/main/specs/Deployment/MSIXPackage.md) +for more details. + +### 1.2.4. Binary Compatibility + +**"Binary Compatibility"**: Existing, compiled code can rely on new version of compiled library code +without change, and expect to run without issue. Binary compatibility relies on a strong contract +between the library and caller including both the shape and behavior of the API. + +If an application relies on unspecified behavior, intentionally or otherwise, binary compatibility +can be hard to maintain. Nonetheless, Windows has demonstrated that it is possible, with effort, to +maintain a high degree of binary compatibility over an extended period of time. + +### 1.2.5. Source Compatibility + +**"Source Compatibility"**: The version of the library can be changed, and the code will build +without issue. + +In practice, perfect source compatibility is unachievable in most programming languages. E.g. +"using" statements can lead to name collisions when a library introduces new types. In contrast, a +project that does not commit to source compatibility may require significant code changes when +building with later versions, due to changes in the public surface area of the API. + +## 1.3. Impacted Components + +[Dynamic Dependencies](https://github.com/microsoft/WindowsAppSDK/blob/main/specs/dynamicdependencies/DynamicDependencies.md), +[ProjectReunionInstaller.exe](https://github.com/microsoft/WindowsAppSDK/issues/443) and the build +pipeline are not currently in sync. Work is required (regardless the +decision) to align on a common solution. + +Demos, samples, documentation, functional testing and E2E integrated testing are impacted. + +## 1.4. MSIX and SemVer + +MSIX's versioning model overlaps with SemVer but isn't fully compatible. See [here](https://github.com/microsoft/WindowsAppSDK/issues/148) for more details. + +## 1.5. Dynamic Dependencies + +Windows App SDK's DynamicDependencies (DynDep) relies on an elegant dance with Windows' inbox +behavior to provide the expected outcome (without servicing Windows). This requires a deep +understanding of MSIX's behavior and Windows App SDK's versioning model to correctly identify and +select the appropriate Windows App SDK framework package (aka WARfwk) at runtime. More details are +available [here](https://github.com/microsoft/WindowsAppSDK/blob/main/specs/dynamicdependencies/DynamicDependencies.md). + +Dynamic Dependencies support is being added to Windows, aka OS DynDep. Care has been taken to keep +WinAppSDK+OS behavior aligned to facilitate eventual use and migration from Windows App SDK's +implementation to Windows'. OS DynDep provides a richer, more efficient and reliable solution with +less developer friction than WinAppSDK DynDep. We will eventually polyfill WinAppSDK DynDep's +implementation to use OS DynDep when available and (someday) rely entirely on OS DynDep when +downlevel support is no longer relevant. + +## 1.6. Windows App SDK Versioning Requirements + +Windows App SDK's versioning model has been discussed in detail but not documented in one place. +This spec pulls together that disparate information into a unified whole. + +The versioning meta-requirements are briefly summarized here: + +* Require no Windows servicing +* Support [Semantic Versioning (SemVer)](https://semver.org/) +* Support a clear division of incompatibility (Breaking Change) across major/disruptive releases +* Support servicing across minor/less-disruptive releases +* Support critical servicing e.g. MSRC security fixes +* Support packaged and unpackaged apps +* Support multiple tags of 'release' (Stable, Preview, ...) aka Channels +* Be implementable across our key technologies including Dynamic Dependencies, NuGet, MSIX, MS Store and VSIX +* Support WinAppSDK DynDep leveraging OS DynDep (in future Windows versions) via polyfill (initially where available, eventually 100%) + +These requirements need careful balance and multiple mechanisms to meet them all. This spec focuses +on install- and run-time needs, specifically MSIX and Dynamic Dependencies (DynDep) for unpackaged +apps. + +The versioning solution used in 0.5 is insufficient for Windows App SDK's support for +unpackaged apps (e.g. MSIX naming patterns don't work for the DynamicDependency Lifetime Manager +(DDLM) package). See section 2. Decisions for more details. Past decisions are incorporated to the +extent possible but additions and changes are needed. + +Packaged apps bring a subset of requirements vs unpackaged apps so this decision is expected to +work equally well for packaged apps. + +MS Store brings similar needs and constraints as MSIX so this decision is expected to work equally +well for MS Store distribution. + +# 2. Decisions + +Current versioning design and practice has some areas of ambiguity or gaps for new scenarios (e.g. +unpackaged apps). These issues are noted with solutions and the recommended path forward. + +Jump ahead to [3. Conclusions](#3-conclusions) to skip the alternatives considered, +detailed explanations and why the recommended solutions are chosen. + +## 2.1. Decision 1: Breaking Change Boundary for Version 0.* + +Per [SemVer section 4](https://semver.org/#spec-item-4) + +> Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public +API SHOULD NOT be considered stable. + +There's no mention if this requires or assumes any technical enforcement. + +This does not guarantee incompatibility across version 0.y.z but it doesn't guarantee compatibility +either. Windows App SDK defines specific rules for Windows App SDK to address this ambiguity. + +**Option A: MSIX package Name includes `Major.Minor.Build` if `Major=0`**. Servicing can be done +via changes to `.Revision` e.g. `Microsoft.ProjectReunion.0.8.0` for version 0.8.0.0. + +Servicing (bugfix) increment the `.Build` value e.g. 0.8.1.0, 0.8.2.0, etc with package Name +`Microsoft.ProjectReunion.0.8.1` etc. Applications are required to rebuild to use the update at +runtime. + +MSRC updates would be 0.8.0.1, 0.8.0.2, 0.8.1.1, etc. Applications always use MSRC updates on a +system matching their `Major.Minor.Build`. + +**Option B: MSIX package Name includes `Major.Minor` if `Major=0`**. Servicing can be done via +changes to `.Build` and `.Revision` e.g. Project `Microsoft.ProjectReunion.0.8` for version 0.8.0.0. + +Servicing (bugfix) increment the `.Build` value e.g. 0.8.1.0, 0.8.2.0, etc with package Name +`Microsoft.ProjectReunion.0.8.1` etc. Applications use the latest update on a system +matching their `Major.Minor`. No rebuild is necessary. Applications cannot block running with +servicing updates. + +MSRC updates would be 0.8.0.1, 0.8.0.2, 0.8.1.1, etc. Applications always use MSRC updates on a +system matching their `Major.Minor`. + +**Option C: Never make MSIX Framework packages with version `Major=0`**. + +Deployment does not support SemVer section 4. Deployment doesn't treat version 0 different than any +other version. If Deployment finds multiple applicable packages satisfying a dependency it chooses +the highest version (per `VersionSupercedence`1). + +1 VersionSupercedence can be defeated in very narrow cases e.g. Packages installed with +[DeploymentOptions.ForceUpdateFromAnyVersion](https://docs.microsoft.com/uwp/api/Windows.Management.Deployment.DeploymentOptions?view=winrt-19041) +are always used, even if a lower version than other applicable packages. Other exotic cases exist but +the overwhelming norm without exception is 'highest version wins'. + +***Recommendation:*** Option B. + +This provides for rapid evolution balanced with stability for supported use. + +## 2.2. Decision 2: Breaking Change Boundary for Version 1.x + +SemVer defines the binary incompatibility (breaking change) boundary as the MAJOR version. + +MSIX defines the binary incompatibility (breaking change) boundary as the package family. The +version number has no inherent binary incompatibility boundary but one can vary package family name +to provide an incompatibility boundary. We can include as much (or little) of the version number in +the package Name as we desire to provide a compatibility boundary. + +**Option A: Incompatibility boundary is the `Major` version** + +* Aligns with SemVer +* Compatible with MSIX +* Aligns with common practices and expectations across the industry (glibc, Linux kernel, many more) + +Chrome and Edge are clear examples of Option A. Stable Chrome and Edge releases are currently +version 89 and 92+ are under development. + +**Option B: Incompatibility boundary is the `Major.Minor` version** + +* Does not align with SemVer +* Compatible with MSIX +* Aligns with some practices and expectations across the industry + +**Option C: Incompatibility boundary is the `Major.Minor.Build` version** + +* Does not align with SemVer +* Compatible with MSIX +* Does not align with common practices and expectations across the industry + +***Recommendation:*** Option B. + +Option B provides a stronger degree of compatibility and risk management than Option A (Major +version) while still affording a reasonable way for developers to adopt updates. + +Windows App SDK aspires to adopt Option A (Major version) but more tooling and infrastructure is +desired before making that level of guarantee. Option B provides a good balance of rapid +development and compatibility assurance. + +Option A can (and will) be adopted in a future release (no sooner than 2.0) once tooling and +infrastructure are ready to embrace it. + +### 2.2.1. Current practices in Microsoft-authored Framework packges. + +There is no consistency of version in package Name amongst existing Framework packages. Per +`powershell -c "$(get-appxpackage -packagetypefilter framework).packagefamilyname|sort"` one can see +some of the more common frameworks: + +* None: Microsoft.Advertising.JavaScript, Microsoft.Advertising.Xaml, Microsoft.DirectXRuntime, Microsoft.Media.PlayReadyClient, Microsoft.Services.Store.Engagement +* Minor: Microsoft.NET.CoreRuntime, Microsoft.NET.Native.Framework, Microsoft.NET.Native.Runtime, Microsoft.UI.Xaml, Microsoft.VCLibs, Microsoft.WinJS + +VCLibs sometimes goes further with additional qualifiers in their Name including: .debug, .Universal, .UWPDesktop. + +No version in Name implies the framework has yet to produce a breaking change, i.e. in SemVer-speak +these frameworks are still MAJOR=X and yet to produce MAJOR=X+1. + +## 2.3. Decision 3: Release Tags (Stable, Preview, ...) + +How do we distinguish release across channels, e.g. a 'Stable' package from a 'Preview' package? + +Windows App SDK 0.5 adds a "-preview" tag to the package Name. + +Windows App SDK 1.x adds a -channel# tag (e.g. "-preview1") to the package name. + +***Do we need a shorter tag?*** "-preview1" adds 9 characters to package Name. "-experiental1" adds +13 characters. Package Name is restricted to 50 characters maximum. + +**Option A: `-preview`** +**Option B: `-pre`** +**Option C: `-p`** + +These may optionally include a trailing digit indicating the Nth release of a channel for a version +of the project. + +***Recommendation:*** Option A and C (when necessary). + +All tags have a long name (Option A) and a short (1-2 characters) name (Option C). + +Option C is used when Option A doesn't work due to package Name length restrictions. +Currently WARddlm is the only instance using Option C. + +## 2.4. Decision 4: Version Encoding + +What data's encoded in the MSIX Version, and how? + +The following notation is used to describe the possible options + +* X = Major version +* N = Minor version +* P = Patch (per SemVer definition i.e. the 3rd field in a version) +* Y = Year +* M = Month +* D = Day +* E = Elapsed days since an epoch e.g. if Epoch=2021/01/01 then 2021/6/4=154 +* B = Build number (reset to zero when Major or Minor changes) +* 0 = Zero + +Single character indicates variable-length without leading zeros. +Multiple characters indicates fixed-length with leading zeroes if necessary. For example, Y=1 vs YY=01. + +NOTE: MSIX version's 4th field (Revision) is reserved for security updates. + +Examples are provided for the following theoretical versions... +* Windows App SDK 0.8.1, date=2021/6/4, build=123, elapsed=154 +* Windows App SDK 1.2.3, date=2021/12/31, build=123, elapsed=364 +* Windows App SDK 17.14.3, date=2031/10/20, build=123, elapsed=3944 + +|Option|Syntax|Example|Information|Comments| +| --- | :--- | :---: | :---: | :---: | +|A|X.N.P.0|0.8.1.0
1.2.3.0
17.14.3.0|Major Minor Patch|| +|B|X.NYYMM.DDPPP.0|0.82106.04001.0
1.22112.31003
--error--|Major Minor Patch Date|Minor max is 6
Patch max is 999
WinUI 2.x used this encoding
Windows App SDK 0.5 used this encoding| +|C|XNN.PYYMM.DDBBB.0|8.12106.04123.0
102.32112.31123.0
1714.33110.20123.0|Major Minor Patch Date Build|Minor max is 99
Patch max is 6
Build max is 999| +|D|NPPP.E.B.0|8001.154.123
2003.364.123
17014.3944.123.0|Minor Patch Elapsed Build|Minor max is 64
Patch max is 999
Build max is 65535| +|E|NPP.E.B.0|801.154.123
203.364.123
1714.3944.123.0|Minor Patch Elapsed Build|Minor max is 99
Patch max is 99
Build max is 65535| + +***Recommendation:*** Option D with Epoch=January 1, 2021. + +Option A works for a simple release strategy but doesn't work when there's regular +(e.g. daily) builds. + +Option B worked for WinUI 2.x and Windows App SDK 0.5 but is too limiting given it can't support +Minor versions beyond 6. It's also a complicated encoding scheme with date injected between Minor +and Patch (not readily legible). + +Option C is too limiting given it can't support Patch versions beyond 6. + +Option D relies on the package Name including Major version. This leaves sufficient space in the +version to encode up to 99 Minor and 99 Patch versions. Date encoding as an Epoch reduces the size +while supporting 20+ years with only 4 digits. + +Option E is a variant of Option D except Patch version is restricted to 2 digits, but it's an +unnecessary simplification. + +### 2.4.1. Windows App SDK 0.5 Notation + +Windows App SDK 0.5 encodes MSIX versions as `M.NYYMM.DDPPP.0` + +* M = Major version +* N = Minor version +* YY = Year +* MM = Month +* DD = Day +* PPP = Patch + +All fields are fixed-size with leading zeroes as needed. For example, Windows App SDK 0.5.0's MSIX package has a version of `0.52103.25000.0` + +* Major = 0 +* Minor = 5 +* Year = 21 (aka 2021) +* Month = 03 +* Day = 25 +* Patch = 000 (if we have a 0.5.1 release this would be `001`) + +This doesn't scale going forward e.g. MSIX version is a DotQuadNumber aka `uint16[4]`. If 0.8 was +released on May'31, 2021 MSIX version would be `0.82105.31000.0` + +### 2.4.2. WinUI 2.x Notation + +WinUI 2.x encodes MSIX versions as `M.NYYMM.DDPPP.0` (same as Windows App SDK 0.5). This runs into +issues starting with WinUI 2.7, as identified by [WinUI version schema sometime can't applied to +MinVersion +#4008](https://github.com/microsoft/microsoft-ui-xaml/issues/4008#issuecomment-765633788). + +## 2.5. Decision 5: Package Names + +Windows App SDK 0.8+ has 3 MSIX packages. We have choices for package Name patterns for 0.8 and 1.x. + +Assuming Breaking Change Boundary for v0.x and v1+'s decision are `Major.Minor` version we have the +following naming patterns release 0.x... + +* WARfwk: `Microsoft.WindowsAppRuntime..[-tag]` +* WARmain: `Microsoft.WindowsAppRuntime.Main..[-tag]` +* WARddlm: `Microsoft.WindowsAppRuntime.DDLM....-[-shorttag]` + +and release 1.x... + +* WARfwk: `Microsoft.WindowsAppRuntime..[-tag]` +* WARmain: `MicrosoftCorporationII.WinAppRuntime.Main..[-shorttag]` +* WARsingleton: `MicrosoftCorporationII.WinAppRuntime.Singleton[-shorttag]` +* WARddlm: `Microsoft.WinAppRuntime.DDLM....-[-shorttag]` + +where + +* rmajor = Major version number of the project release, base-10, no leading zeros (e.g. "1" for WindowsAppSDK 1.2) +* rminor = Minor version number of the project release, base-10, no leading zeros (e.g. "2" for WindowsAppSDK 1.2) +* major = Major version number of the release, base-10, no leading zeros +* minor = Minor version number of the release, base-10, no leading zeros +* build = Build version number, base-10, no leading zeros +* revision = Revision version number, base-10, no leading zeros +* architecture = Allowed values: "x86", "x64", "arm64" +* shortarchitecture = Allowed values: "x8", "x6", "a6" +* tag = Allowed values: "", "preview[#]", "experimental[#]" +* shorttag = Allowed values: "", "p[#]", "e[#]" + +**NOTE:** rmajor/rminor are the release version, major/minor/build/revision are the MSIX package +version (Microsoft.ProjectReunion.0.8-preview had a release version of 0.8 +but an MSIX package version of 8000.146.628.0). + +Version's fields have values 0-65535. + +WARddlm requires architecture in its package Name to support concurrent use of different +architectures of a framework. See the [Dynamic Dependencies spec](https://github.com/microsoft/WindowsAppSDK/blob/main/specs/dynamicdependencies/DynamicDependencies.md) +for more details. + +This leads to package Name length issues even for common cases: + +|Package|Average|AverageLength| +| --- | :--- | :---: | +|WARfwk |Microsoft.WindowsAppRuntime.1.15-preview1|41| +|WARmain|Microsoft.WindowsAppRuntime.Main.1.15-preview1|46| +|WARsingleton|Microsoft.WindowsAppRuntime.Singleton-preview1|46| +|WARddlm|Microsoft.WinAppRuntime.DDLM.1.15.12345.24680-arm64-preview1|**64**| + +|Package|Min|MinLength| +| --- | :--- | :---: | +|WARfwk |Microsoft.WindowsAppRuntime.1.0-preview1|40| +|WARmain|Microsoft.WindowsAppRuntime.Main.1.0-preview1|45| +|WARsingleton|Microsoft.WindowsAppRuntime.Singleton-preview1|46| +|WARddlm|Microsoft.WinAppRuntime.DDLM.1.0.0.0-arm64-preview1|**52**| + +|Package|Max|MaxLength| +| --- | :--- | :---: | +|WARfwk |Microsoft.WindowsAppRuntime.65535.65535-preview1|48| +|WARmain|Microsoft.WindowsAppRuntime.Main.65535.65535-preview1|53| +|WARsingleton|Microsoft.WindowsAppRuntime.Singleton-preview1|46| +|WARddlm|Microsoft.WinAppRuntime.DDLM.65535.65535.65535.65535-arm64-preview1|**71**| + +Possible options we can use to shorten package Name: + +* Change the Name constant/prefix to a shorter string e.g. change "Microsoft.WindowsAppRuntime.Main" to "Microsoft.WinAppRuntime.Main", etc +* Dictate max values e.g. Major=0-99 +* Encode values as base-16 +* Replace -channel with a shorter string e.g. replace "-preview" with "-pre", "-p", "p" +* Encode the channel name in the delimiter between name+version e.g. Microsoft.WinAppRuntime.DDLM.preview1.1.0.0.0-arm64 +* Encode tag in the delimiter between version+architecture e.g. Microsoft.WinAppRuntime.DDLM.1.0.0.0p1arm64 using P1 for Preview1, E1=Experimental1, ... +* Name WARddlm differently from WARfwk and WARmain e.g. use "-p1" for WARddlm regardless if WARfwk and WARmain use "-preview1" +* ??? + +WARddlm is needed until Dynamic Dependencies is 100% based on OS DynDep. + +Best case (!) WARddlm exists until the minimum supported Windows release is Cobalt. + +***Recommendation:*** The general package naming syntax is +`Microsoft.ProjectReunion[.SubName]-.[-tag]`. WARddlm and WARsingleton are +exceptions to the rule (see below). + +Windows App SDK 0.8 will use package Names of... + +* WARfwk: `Microsoft.WindowsAppRuntime..[-tag]` +* WARmain: `Microsoft.WindowsAppRuntime.Main..[-tag]` +* WARsingleton: `Microsoft.WindowsAppRuntime.Singleton[-tag]` +* WARddlm: `Microsoft.WinAppRuntime.DDLM....-[-shorttag]` + +Using Decision 5: Version Encoding = Option D (NPPP.E.B.0) WARddlm's maximum package Name length is +`Microsoft.WinAppRuntime.DDLM.1714.3944.123.24680-arm64-p3` = 58 characters. This can be reduced +with the following rules: + +* Major version <= 99 +* Minor version <= 999 +* Build number <= 9999 +* Revision (security update) <= 99 +* Architecture = 2 characters (x8=x86, x6=x64, a6=arm64) + +This produces a worst case for WARddlm in Windows App SDK 99.888.7777.66 ARM64 Preview 3 to the following identifiers: + +* Package Name = `Microsoft.WinAppRuntime.DDLM.99.888.7777.66-a6-p3` = 49 characters +* PackageFullName = `"Microsoft.WinAppRuntime.DDLM.99.888.7777.66-a6-p3_99.888.7777.66_arm64__8wekyb3d8bbwe"` +* PackageFamilyName = `"Microsoft.WinAppRuntime.DDLM.99.888.7777.66-a6-p3_8wekyb3d8bbwe"` +* PACKAGE_VERSION struct = `99.888.7777.66` +* PACKAGE_VERSION uint64 = `0x006303781E610042` + +# 3. Conclusions + +**Decision 1:** Windows App SDK version 0.* encodes `Major.Minor` into MSIX package Names starting with version 0.8.0.0. + +**Decision 2:** Windows App SDK version 1.* encodes `Major.Minor` into MSIX package Names. + +**Decision 3:** Windows App SDK supports an optional 'tag' to indicate a non-Stable channel. +A 'tag' comes in long and short (1-2 character) forms e.g. `-preview` and `-p`, +or `-preview1` and `-p1` (the digit suffix is optional). + +**Decision 4:** Windows App SDK encodes version as `...` +i.e. format encoding `NPPP.E.B.0`. See +[2.4. Decision 4: Version Encoding](#24-decision-4-version-encoding) for more details. + +**Decision 5:** MSIX package Names use the format +`Microsoft.WindowsAppRuntime[.SubName]-.[-tag]`. WARddlm is an exception due to Name +length constraints. The specific packages Names in Windows App SDK 1.0: + +* WARfwk: `Microsoft.WindowsAppRuntime..[-tag]` +* WARmain: `MicrosoftCorporationII.WinAppRuntime.Main..[-shorttag]` +* WARsingleton: `MicrosoftCorporationII.WinAppRuntime.Singleton[-shorttag]` +* WARddlm: `Microsoft.WinAppRuntime.DDLM....-[-shorttag]` + +See [2.5. Decision 5: Package Names](#25-decision-5-package-names) for more details. \ No newline at end of file diff --git a/specs/Deployment/deprecated/MSIXPackages.md b/specs/Deployment/deprecated/MSIXPackages.md new file mode 100644 index 0000000000..e32105097c --- /dev/null +++ b/specs/Deployment/deprecated/MSIXPackages.md @@ -0,0 +1,231 @@ +- [1. Background](#1-background) +- [2. MSIX Packages](#2-msix-packages) + - [2.1. Roles](#21-roles) + - [2.1.1. Role - Framework](#211-role---framework) + - [2.1.2. Role - Main](#212-role---main) + - [2.1.3. Role - Singleton](#213-role---singleton) + - [2.1.4. Dynamic Dependency Lifetime Manager (DDLM)](#214-dynamic-dependency-lifetime-manager-ddlm) +- [3. Package Naming](#3-package-naming) + - [3.1. Package Naming - SubName](#31-package-naming---subname) + - [3.2. Package Naming - Singleton](#32-package-naming---main) + - [3.3. Package Naming - Singleton](#33-package-naming---singleton) + - [3.4. Package Naming - DDLM](#34-package-naming---ddlm) +- [4. Package Versioning](#4-package-versioning) + +# 1. Background + +Windows App SDK supports deployment as a set of MSIX packages for use at runtime. +This document outlines the list of packages and their rules and roles. + +# 2. MSIX Packages + +Windows App SDK is distributed as multiple MSIX packages: + +1. Framework +2. Main +3. Singleton +4. Dynamic Dependency Lifetime Manager (DDLM) + +## 2.1. Roles + +### 2.1.1. Role - Framework + +The Framework package is the API delivery vehicle for Windows App SDK. The vast majority of code in +the project is found here. + +Framework packages support concurrent behavior. A user may have multiple versions of a framework +package in use across processes (process1 using 1.0.1.0, process2 using 1.0.2.0, ...). Updates can +be registered for a user without disrupting running apps. Windows points running apps to updated +Framework packages non-disruptively (e.g. when an app's not running), colaescing apps to newer +versions over time (not necessarily instaneously). This provides for a very flexible servicing +model. + +### 2.1.2. Role - Main + +The Main package supplements the Framework package, for when functionality is needed but can't be +delivered via the Framework package. Mechanisms include [Packaged COM](https://blogs.windows.com/windowsdeveloper/2017/04/13/com-server-ole-document-support-desktop-bridge/), +[app services](https://docs.microsoft.com/windows/uwp/launch-resume/how-to-create-and-consume-an-app-service), +[app extensions](https://docs.microsoft.com/uwp/api/Windows.ApplicationModel.AppExtensions.AppExtension), +[background tasks](https://docs.microsoft.com/windows/uwp/launch-resume/create-and-register-a-background-task), +[startup tasks](https://docs.microsoft.com/uwp/api/Windows.ApplicationModel.StartupTask) executing +on user login, [ApplicationData](https://docs.microsoft.com/uwp/api/Windows.Storage.ApplicationData) +for data storage scoped to Windows App SDK (not any particular app using Windows App SDK), and +more. + +The primary scenarios include: + +* Brokered Access -- processes running in an [AppContainer](https://docs.microsoft.com/windows/win32/secauthz/appcontainer-isolation) + requiring access to resources that cannot be access from within the + AppContainer can use a 'helper process' running at MediumIL and doing work on + the API's behalf. cannot do for itself (i.e. brokered access to a resource). +* Long-Running Process (aka user service) -- functionality requiring a long-running process + (especially if its lifetime isn't directly coupled to + an app's lifetime). + +Main packages don't support side-by-side behavior for a user. A user can only have 1 (or 0) Main +packages in a package family registered at a time. Thus if a user has v1.0.0.0 registered when +1.0.0.1 is registered it's an *update*, ending with the user having v1.0.0.1 registered instead of +v1.0.0.0. This poses servicing challenges, as updating the Main package requires any running +processes from the existing Main package to be terminated. + +For these reasons Windows App SDK developers are strongly encouraged to only rely on the Main package when +necessary. + +If a process from the Main package is necessary, it should be short-lived or support a save/restore +execution model. The former shrinks the possibility a running process when a servicing event +occurs. The latter ensures if Main package processes are running when a servicing event occurs, the +running processes can be terminated (e.g. via [DeploymentOptions.ForceTargetApplicationShutdown](https://docs.microsoft.com/uwp/api/windows.management.deployment.deploymentoptions)) +to allow the servicing event to occur and restarted upon its completion, with only a transient (and +possibly unnoticed) interruption of service. + +Further, if/when the Main package is necessary, Windows App SDK developers are encouraged to put as +little as practical in the Main package and use the Framework package as much as possible. For +example, if a StartupTask is needed you can declare the StartupTask in the Main package's +`appxmanifest.xml` and provide an executable with a trivial 1% implementation e.g. + +```c +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) +{ + return MyFeatureWinMain(hInstance, hPrevInstance, pCmdLine, nCmdShow); +} +``` + +and export `MyFeatureWinMain` from a DLL in the Framework package to get the implementation's +other 99%. + +### 2.1.3. Role - Singleton + +The Singleton package supplements the Main package, for when functionality is needed by a single +process spanning all versions of Windows App SDK. + +The Singleton package is a main package so the same guidance applies to the Singleton as to the Main +package -- Windows App SDK developers are strongly encouraged to only rely on the Singleton package +when necessary. See (2.1.2. Role- Main) for more details. + +The Singleton package's content is used by ALL versions of Windows App SDK registered to the user so +additional caution is advised. + +Only the highest version of the Singleton package will be installed for a user, e.g. if Windows App +SDK 1.0, 1.1 and 2.0 (Stable) are installed on an x86 system, the user will have registered... + +* Microsoft.WindowsAppRuntime.1.0 +* Microsoft.WindowsAppRuntime.1.1 +* Microsoft.WindowsAppRuntime.2.0 +* MicrosoftCorporationII.WinAppRuntime.Main.1.0 +* MicrosoftCorporationII.WinAppRuntime.Main.1.1 +* MicrosoftCorporationII.WinAppRuntime.Main.2.0 +* MicrosoftCorporationII.WinAppRuntime.Singleton (version 2.0) +* Microsoft.WinAppRuntime.DDLM.0.146.711.0-x8 +* Microsoft.WinAppRuntime.DDLM.1000.328.1510.0-x8 +* Microsoft.WinAppRuntime.DDLM.0.510.333.0-x8 + +Singleton package content MUST be backwards compatible across all releases due to the Singleton +package's singular nature + +### 2.1.4. Dynamic Dependency Lifetime Manager (DDLM) + +The [Dynamic Dependency API](https://github.com/microsoft/WindowsAppSDK/blob/main/specs/dynamicdependencies/DynamicDependencies.md) +resolves a package dependency to a specific framework package and make it available for a process, +but Windows doesn't know the package is in use by this process. Lacking this "package in use" +knowledge, Windows could service the package (remove, remediate, repair, ...) in negatively +impactful ways. To prevent this (without servicing Windows) we need... + +1. ...a running process running with package identity... +2. ...with an `appxmanifest.xml` declaring a `` on the framework package... +3. ...running for as long as the framework package is used by the app. + +This is accomplished for the Microsoft.WindowsAppRuntime framework package via a Packaged COM +out-of-process (OOP) server in a DDLM package, selected and managed via the Bootstrap API. See the +[Dynamic Dependency spec](https://github.com/microsoft/WindowsAppSDK/blob/main/specs/dynamicdependencies/DynamicDependencies.md) +for more details. + +# 3. Package Naming + +Windows App SDK's MSIX packages use the following naming rules for package identity: + +* Name = Microsoft.WindowsAppRuntime[.SubName].\.\[-VersionTag] +* Publisher = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" + +where + +* SubName -- optional package sub-name. Use to distinguish amongst the different packages +* Major -- major version of the release, e.g. "1" for Windows App SDK 1.0 +* Minor -- minor version of the release, e.g. "0" for Windows App SDK 1.0 +* VersionTag -- optional version tag to distinguish amongst channels and releases of a channel, e.g. "-preview2" for Windows App SDK 1.0 Preview 2 + +## 3.1. Package Naming - SubName + +The following SubName values are used: + +| SubName | Package | Example | +|-|-|-| +| | Framework | Microsoft.WindowsAppRuntime.1.0-experimental1 | +| Main | Main | MicrosoftCorporationII.WinAppRuntime.Main.1.0-e1 | +| Singleton | Singleton | MicrosoftCorporationII.WinAppRuntime.Singleton-e1 | +| DDLM | Dynamic Dependency Lifetime Manager (DDLM) | Microsoft.WinAppRuntime.DDLM.0.146.711.0-x6-e1 | + +## 3.2. Package Naming - Main + +The Main package follows a different naming scheme + +* Name = MicrosoftCcorporationII.WinAppRuntime.Main.\[-ShortVersionTag] + +where + +* ReleaseMajor = project release major version number. See the [MSIX Package Versioning](https://github.com/microsoft/WindowsAppSDK/blob/main/specs/deployment/MSIXPackageVersioning.md) for more details. +* ShortVersionTag = short form of the VersionTag + +ShortVersionTag is derived from a VersionTag by combining the 1st letter and the last digit (if any) for non-Stable channels (ShortVeresionTag is blank for the Stable channel, just like VersionTag). + +## 3.3. Package Naming - Singleton + +The Singleton package follows a naming scheme similar to the Main package: + +* Name = MicrosoftCorporationII.WinAppRuntime.Singleton[-ShortVersionTag] + +The package family is the same across all versions of Windows App SDK. As a main package, only one +Singleton package can be registered at a time for a user and by its nature it's meant to be used +with all versions of Windows App SDK registered for a user. Thus its package Name is rather simple +compared to other package Names, lacking any version information. + +See [2.1.3. Role - Singleton](#213-role---singleton) for more information. + +## 3.4. Package Naming - DDLM + +DDLM packages follow a different naming scheme + +* Name = Microsoft.WinAppRuntime.DDLM.\-\[-ShortVersionTag] + +where + +* Version = MSIX version number (not the project release version). See the [MSIX Package Versioning](https://github.com/microsoft/WindowsAppSDK/blob/main/specs/deployment/MSIXPackageVersioning.md) for more details. +* ShortArchitecture = short form of the Architecture (x6=x64, x8=x86, a6=arm64) +* ShortVersionTag = short form of the VersionTag + +ShortVersionTag is derived from a VersionTag by combining the 1st letter and the last digit (if any) for non-Stable channels (ShortVeresionTag is blank for the Stable channel, just like VersionTag). + +```C# +string ToShortVersionTag(string versionTag) +{ + if (String.IsNullOrEmpty(versionTag)) + { + return versionTag; + } + string prefix = versionTag.substr(0, 1); + if (versionTag.length > 1) + { + char lastChar = versionTag.substr(versionTag.length - 1, 1); + if (('0' <= lastChar) && (lastChar <= '9')) + { + suffix = lastChar.ToString(); + return prefix + suffix; + } + } + return prefix; +} +``` + +# 4. Package Versioning + +See the [MSIX Package Versioning](https://github.com/microsoft/WindowsAppSDK/blob/main/specs/Deployment/MSIXPackageVersioning.md) +decision document for more details.