Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions specs/Deployment/MSIXPackageVersioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -520,3 +520,30 @@ length constraints. The specific packages Names in Windows App SDK 1.0:
* WARddlm: `Microsoft.WinAppRuntime.DDLM.<major>.<minor>.<build>.<revision>-<shortarchitecture>[-shorttag]`

See [2.5. Decision 5: Package Names](#25-decision-5-package-names) for more details.


## Version Starting 2.0
In 2.0, the family name of the MSIX package changes. The new style will be:
* WARfwk: `Microsoft.WindowsAppRuntime.<rmajor>[-tag]`
Copy link
Collaborator

Choose a reason for hiding this comment

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

tag

Is a nightly or pr build called out in the tag (or in some other way) to avoid conflicting with official builds? The old versioning scheme made it easier to avoid version issues since both official and night/pr builds used the same counters with the Elapsed/Build parts of the MSIX versioning making it easier to have a newer version. If nightly/pr now run with their own 'patch' counter, how do those avoid conflicts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

-ni and -pr are the tags for nightly and pr builds.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Are these written down somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the Aggregator Repo PR:

Each Repo can decide what to do for their <-label?> section, though there should be a label for non-release
builds. For the Aggregator Repo, the label would contain the following:
<pr/ni?><experimental?>
If a build was triggered for nightly or pull request, then the pr/ni would be part of the label.
If a build was triggered for experimental, then the experimental would be part of the label.
Since a Nightly build can still also be experimental, both can happen, at which point a "."
would be put between the 2, for easier reading.

I did not show this here. I can add it.

Copy link
Member

Choose a reason for hiding this comment

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

SemVer processing (and thus Nuget, and anything else SemVer-compliant) sorts "prerelease" alphabetically

This means if you have a multiple versions the sorted order (oldest to newest/latest) is

  • 1.2.3-experimental
  • 1.2.3-preview
  • 1.2.3

But now add -ni and it's

  • 1.2.3-experimental
  • 1.2.3-nightly
  • 1.2.3-preview
  • 1.2.3

This is notable because things like VS using nuget does so per SemVer, so it's biased towards "latest".

  • 1.2.3 < 1.2.4 < 1.3.0 < 2.0.0
    and
  • 1.2.3-ci < 1.2.3-dev < 1.2.3-experimental < 1.2.3-nightly < 1.2.3-preview < 1.2.3

We chose Experimental and Preview as channel names and used them in Nuget package versions in part because they respect SemVer version sorting rules.

That's also why -nightly is weird, as saying it's newer/later/better than -experimental but not new/recent/good as -preview isn't always true.

Think carefully about other naming for other -prerelease tags. Ideally think about the evolutionary timeline of software/builds and pick names that fit that flow.

* WARmain: `MicrosoftCorporationII.WinAppRuntime.Main.<rmajor>[-shorttag]`
* WARsingleton: `MicrosoftCorporationII.WinAppRuntime.Singleton[-shorttag]`
* WARddlm: `Microsoft.WinAppRuntime.DDLM.<major>.<minor>.<Patch>.<BuildNumber>-<shortarchitecture>[-shorttag]`

The version will also change:
<Major>.<Minor>.<Patch>.<BuildNumber>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Given "MSIX version's 4th field (Revision) is reserved for security updates", I think we could just list this as "0".

Copy link
Member

Choose a reason for hiding this comment

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

Only way you could list this as "0" is if the DDLM will never (and can never) need an update leveraging this.

If you engrave that in stone then Revision needs to support a non-zero value, even if rarely (hopefully never?) used.

Even if you declare "Revision can only be 1 digit (0-9) the DDLM package Name's max length is still too big with just this restriction. See the math above for more details

The exception to this version change is WARSingleton. This package is still the same family, so
the version needs to continue to increase. In this case, the Major version is Major+8000 (which forces the Major
version in the Singleton package to be higher than it was at the time of the switch).

The Major, Minor, and Patch will all match the Nuget versions from building the Aggregator Repo.
The BuildNumber is which build for that day. We have the following restrictions on the versions:
Copy link
Collaborator

Choose a reason for hiding this comment

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

BuildNumber

What value does BuildNumber bring? "Patch" will be incremented with each build, making BuildNumber unnecessary, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree it should not ever get above 0, since each full build will give a new Patch. I am including that here in case that ever were to change to have some way of doing security update changes without updating the patch.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did just think of one place we might actually want to use this number...

We don't want every PR build to bump the patch, or we might actually reach the max for the patch. We could have a counter for PR (and nightly if we only want official to bump the patch) that will use the same Patch version until the next bump from an official build, and the "security update" field could distinguish 2 pr builds from each other.

Copy link
Member

Choose a reason for hiding this comment

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

Have you considered using different channel for PR builds?

Could use '-dev' for PR/CI builds, and perhaps -dev# so it doesn't affect the patch value

We've named SemVer -prerelease per our channels (-experimental, -preview). PR/CI could use its own -VersionTag that alphabetically sorts before -e[xperimental].

We've considered -d[ev] for if/when we do (public) dev/nightly builds as -d[ev] < -e[xperimental]

If we wanted to preserve -d[ev] for potential future public use something -a, -b or -c would work (-a[lpha] ?)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree PR builds should not update the Patch for official builds. I think it would be fine they use their own counter with an appropriate tag/whatever to put them in separate package families.

I similarly hope Nightly builds don't update the Patch for official builds. The Patch for official builds should only be for runs of the Official pipeline (which might still have multiple runs before we've selected the next build to release).


Major <= 99
Minor <= 999
Patch <= 9999
BuildNumber <= 99
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why these limits? I'm guessing they are from the comment from @DrusTheAxe. I'm wonderinf if those are just examples, since it seems like Major/Minor/Patch will each be limited to 65535 (minus 8000 for Major, given singleton).

(Also note these lines all show up as one line when viewing the formatted md.)

Copy link
Member

Choose a reason for hiding this comment

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

It's a DotQuadNumber ie UINT64 expressed as UINT16[4] -- major=array[0], minor=array[1], patch=array[2], build=array[3]. Thus each part can be 0-65535

DDLM naming requires name prefix ("Microsoft.WindowsAppRuntime.DDLM." in 1.x) plus architecture (fixed 2chars in1.x e.g. "x6") plus version (a.b.c.d). That means the DDLM package Name length in 1.x could have ranged from

  • Min length = Microsoft.WindowsAppRuntime.DDLM.0.0.0.0-x6-e == 45 chars
  • Max length = Microsoft.WindowsAppRuntime.DDLM.65535.65535.65535.65535-x6-e == 62 chars

MSIX package Name maxlength=50

So those major/minor/patch/build max values restricted the max Name to

Microsoft.WindowsAppRuntime.DDLM.99.999.9999.99-x6-e = 52chars

but in practice we never expected to need such large minor and patch (e.g. 10.100.1000.10) for non-stable (experimental, preview, ...) as we expected to roll over to the next minor (resetting patch to 0) or major (resetting minor to 0) before needing >50 chars. Even with 3 builds a day you can go ~3yrs before needing a 4digit patch number (way more than we'd ever need). Stable's has no channel suffix (eg -e) so even worst case was always fine. To top if off, we expected 4 or maybe 3 releases a year so the caps were theoretical and way beyond anything we'd ever bump into.

For the new rules we don't necessarily need those caps, but we do need a design and associated rules, policies and expectations to guarantee we won't have a problem.

P.S. Increasing MSIX package Name maxlength could solve this (maybe, if the reasons we chose 50 were also addressed...). But changing MSIX identity rules is exceedingly high for new Windows releases, and downlevel makes that look trivial by comparison. TL;DR impractical, so we must work within the world that is.


As with the Aggregator Repo, if the Major updates, Minor resets to 0. Similarly if Minor updates, Patch
resets to 0. In the unlikely event that Minor or Patch reach these limits, then the Major (for the Minor)
or Minor (for the Patch) will bump in order to keep these restrictions. If\When we reach Major version 100, then
the Major version will be the Actual Major %100.
9 changes: 7 additions & 2 deletions specs/Deployment/MSIXPackages.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ where
* 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

## Change for 2.0

In 2.0 the MSIX package family changes to the format
* Name = Microsoft.WindowsAppRuntime[.SubName].\<Major\>[-VersionTag]
Copy link
Member

Choose a reason for hiding this comment

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

See previous comment

Copy link
Collaborator

Choose a reason for hiding this comment

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

VersionTag

What will the VersionTag be for experimental builds in 2.x? Do we continue with the "e1", "e2", etc. counter? That currently requires manual updates for each experimental, and if 2.x continues with regular monthly experimentals, that would mean more manual updates. Also, will there be any problems when we get to the tenth experimental and need another digit for "e10"?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Answering my last question, the removal of "." from the package family name will leave room for double-digit experimental numbers in the version tag.

Copy link
Member

@DrusTheAxe DrusTheAxe Nov 20, 2025

Choose a reason for hiding this comment

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

e.g. Microsoft.WindowsAppRuntime2-Experimental23 ?

"VersionTag" was spelled out e.g. Experimental2. "ShortVersionTag" ("VersionShortTag"?) was the 1letter + optional number, as DDLM's Name couldn't fit anything longer. Are we planning to change the tag to always use short form? Microsoft.WindowsAppRuntime2-e1 rather than Microsoft.WindowsAppRuntime2-experimental1 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We are removing the # from the tag (short and long). Updating in spec.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The # is required to prevent a newer experimental from overtaking a previous experimental instead of being side-by-side. (Same for previews.) We want to keep these side-by-side to ensure that an app which works on experimental1 isn't suddenly broken when experimental2 gets installed even though the app is still trying to use experimental1.

If the ever-increasing "patch" number were somehow incorporated instead (only for experimental and previous releases), that could be an alternative to the #.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We expect the number of experimentals in a given Major to be much more than we have had in the past(particularly when we only did a few before the next 1.X release). Having too many could lead to the Max Character issue getting hit by that, which means we would need a solution for when that rolls over. I did forsee that when you are using the experimental if the package updates, then you just get it/deal with it. Since this is developers, who actually would have had to request a newer experimental, I didn't think it would be a big deal.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I have many test apps for various versions sitting around on my machine. It is never fun when I go back to an old test app and find it no longer working for some reason.

How many characters do we have to work with? Do we have 2 characters, such that we can do [A-Z0-9] for each character, giving us 36*36 experimentals per Major version? If we release 12 experimentals per year, that gives us 108 years of experimentals, or nearly 25 years if we release an experimental every week.


## 3.1. Package Naming - SubName

The following SubName values are used:
Expand All @@ -168,11 +173,11 @@ The following SubName values are used:

The Main package follows a different naming scheme

* Name = MicrosoftCcorporationII.WinAppRuntime.Main.\<ReleaseMajorMinor\>[-ShortVersionTag]
* Name = MicrosoftCcorporationII.WinAppRuntime.Main.\<ReleaseMajor\>[-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).
Expand Down