terminal
terminal copied to clipboard
confusing, conflicting version indication
I'm finding the version indication confusing. My use case is simple:
- I want to see what version.
- I have and compare that to the version currently released.
- I want to check the changelog to see what has changed and see if I want to upgrade.
That seems to be a reasonable sequence of events for any software for a power user. But with Windows Terminal, this is what happens:
- I look to see what file I installed Windows Terminal with. It looks like it was
Microsoft.WindowsTerminal_Win10_1.14.1962.0_8wekyb3d8bbwe.msixbundle, because that's the last installer I have saved. - But going to
Aboutin Windows Terminal shows v1.15.2712.0. Did it auto-update at some point? Maybe; I don't remember. But no problem, I can just check the changelog, right? - I go to the releases page and search for
1.15.2712.0. It isn't found. - In addition, the latest v1.15 release is v1.15.252! In most version schemes I'm used to, "2712" is eons greater than "252". How did I get something much more recent?
- I see that v1.15.252 is tagged with
v1.15.2524.0. Oh, so maybe they are chopping off digits in the official version number? Is GitHub doing this? - Regardless of what is making the tags and version number and labels inconsistent, where is the changelog entry for 1.15.2712.0, and why is it so much later than what is shown as the latest on GitHub?
I'm a little confused here.
Similar issue. Application stopped launching today so I installed the latest release version and received the following:
"Windows cannot install package Microsoft.WindowsTerminal_1.15.2524.0_x64__8wekyb3d8bbwe because it has version 1.15.2524.0. A higher version 1.15.2712.0 of this package is already installed."
I do not have the exact version that was originally installed, but it was installed in Nov 2021, so needless to say it wasn't 2524 or 2712. Was an update pushed too early? Also confused....
Thanks for bringing this up! It's definitely an issue, but more one of poor communication than anything else.
Every build of Terminal that we publish to the store is actually two packages, targeting different versions of Windows. For various reasons, those packages cannot have the same version number; they are, however, built from the same code. For various other reasons, the final version component must be 0.
Because of that, building Terminal will produce two packages versioned 1.0.101.0 and 1.0.102.0. You're right about the chopping: those two packages are considered part of the 1.0.10 release cycle (stripping the final digit that indicates which one built first).
I've therefore been releasing them both under the "1.0.10" banner, but I've been tagging the release to match the first-produced package (in this case, v1.0.101.0)
The feedback here indicates that I should change:
- Tag the commit with the "pretty" release cycle version (
v1.0.10) - In the About dialog, strip off the
1.0or2.0(or really, the ones place from the revision and the vestigial.0)
The last bit is that I did not publish the changelog for the 1.15.271 release cycle. Sorry about that. ☹️
… two packages versioned
1.0.101.0and1.0.102.0. You're right about the chopping: those two packages are considered part of the1.0.10release cycle …
This is completely nonstandard and in conflict with Semantic Versioning comparison rules. It will break any automated admin tools that makes decisions about upgrading, not to mention causing humans the type of confusion that happened here. Pretending that 101 is really 10 is wrong on so many levels. The reasons versions have dots to begin with is to serve as delimiters so that we don't have to guess where an arbitrary convention is dividing the version number.
Please consider changing to a conventional approach. Semantic versioning has "metadata" for exactly this kind of situation. If Windows can't handle semantic versioning, well, that's another story. But arbitrarily placing invisible delimiters within the version string is not a good workaround.
The feedback here indicates that I should change:
Sorry if I jumped the gun and commented before I saw the rest of your reply.
As for what you should do, above all you should be following Semantic Versioning. This would mean:
- If you want to use
100and101somewhere to mean10"under the covers" so to speak, fine, as long as the "never see the light of day". There should only be one version number, and they should be in sequence sorted by each component. (See semantic version comparison rules.) - If this is a
1.0.10release cycle, then yes, the Git commit should be tagged with something likev1.0.10. - Anywhere that you want the version to show up (e.g. the about box), the main part of the version should show exactly
1.0.10. - If you want to distinguish between the two packages, you can add them as semantic version metadata, e.g.
1.0.10+0/1.0.10+1or1.0.10+a/1.0.10+bor1.0.10+win.10/1.0.10+win.11. (The latter is probably closer to what you want.). There is lots of leeway for the metadata, because the semver spec makes it clear that it does not affect the version comparison.
Oh, I see now that the 1.0 and 2.0 are actually a separate versioning scheme you've appended to the main "release cycle" version number. So another easy approach for you would be to simply insert a + before the 1.0/2.0, producing 1.0.10+1.0/1.0.10+2.0. This meets your needs, removes all confuses, brings semver compatibility, and (hopefully) can be done with the most trivial of code changes.
Oh, it's so much worse than all that. We were never intentionally trying to follow SemVer (though I do hold it in high regard, and wish I could stay within its light), but until recently we somewhat were.
NOTE: This ended up longer than I was intending. Please feel free to ignore it or skim it.
The real issue here is the Windows Store. In an ideal world, Terminal would just follow semantic versioning and call it a day. Unfortunately, we're regretfully hampered by a couple limitations.
- Application (and OS!) versions comprise four components,
maj.min.rev.build- Each component is roughly 14 bits wide (limitation 1)
- On upload to the store, the final component (
build) must be0(limitation 2)
- The store doesn't support semver (!) with all of its high-fidelity metadata
- (Limitation 4 to be called out later)
Under the hood, we actually use a date-based versioning scheme. It's "okay" for most purposes and always monotonically increasing. That is, maj.min.YYMM.DDBBB where BBB is the build number from that day (just to deduplicate multiple builds produced on the same day.) That results in this mouthful (for executable files packaged with Terminal):
Now, for limitation 4: we want to follow this versioning scheme because that's the one used by all internally-produced Windows applications that build outside the operating system. I know, it's not a great reason. It could even be called an artificial limitation.
Anyway, due to limitation 2 above, we get to compress the available version space into three components for the final package file that gets uploaded to the store. Thanks to limitation 1, we can't exactly store YYMMDDBBB (or even YYMMDDB) in 14 bits. There's probably a way for us to do it that would break around the decade rollover, but... I digress.
The internally-popular versioning implementation has an answer to this, though! Epoch and day count. maj.min.EDDDB.0. E is the number of years since maj.min was minted, DDD is the 3-digit day-of-year, and B is of course the same deduplicating build number. Leading zeroes are dropped.
If taken as a historical relic that we shouldn't talk about, all of this would be fine...
...until I had to produce two nearly identical versions of the application during the same build. The format doesn't leave us a lot of fields to work with, so we opted to increment the B portion of the version number. That's where the 1.0 and 2.0 are coming from: 1 is the first build of the day, and 2 is its fraternal twin counterpart. It's kinda like we stuck the 1.0 and 2.0 on afterwards, but they were derived from the above calculation.
Anyway, all this so that now I'm looking for options that reduce the cognitive dissonance.
as long as the "never see the light of day"
The store APIs (and those for package servicing) will expose any version number we encode in our package, even if it's for mechanical/deployment purposes only. I don't think I could ever get rid of it from the public eye entirely.
+
I wish! I think the store just compares the version as a 64-bit number.
Thoughts
I'd love to switch over to semver, and I think Azure DevOps supports storing an ever-incrementing variable across runs that we could key on the maj.min version number pair; that could be an easy way to fix this issue... for future releases. Admittedly, that would mean the builds that never see the light of day take up version number slots. I don't know if I care about that.
Citing sources
The part of the code that increments B for the twin package
https://github.com/microsoft/terminal/blob/21a9c557529212c08db8fadecd0f6135c48a9f2b/custom.props#L5-L15
The commit whose body describes (in brief) how all this versioning works for our different product outputs
https://github.com/microsoft/terminal/commit/e22487d10b583053515a8f5afff27b64e86fd77e
I wish GitHub had 😱 as a reaction to posts, that was literally me when reading this explanation.
I wish GitHub had 😱 as a reaction to posts, that was literally me when reading this explanation.
Don't forget this one: 🤦♂️
Looping back on this - I'm yanking triage and converting this to track specifically:
The feedback here indicates that I should change:
- Tag the commit with the "pretty" release cycle version (
v1.0.10)- In the About dialog, strip off the
1.0or2.0(or really, the ones place from the revision and the vestigial.0)
FWIW I think this might do the second bit, ~but I'm not quite sure how to fake this. Might need to trick VS into building and signing a straight up appx...~
diff --git a/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp b/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp
index c9aa9ff8e..3c6378c66 100644
--- a/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp
+++ b/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp
@@ -1015,7 +1015,7 @@ winrt::hstring CascadiaSettings::ApplicationVersion()
{
const auto package{ winrt::Windows::ApplicationModel::Package::Current() };
const auto version{ package.Id().Version() };
- winrt::hstring formatted{ wil::str_printf<std::wstring>(L"%u.%u.%u.%u", version.Major, version.Minor, version.Build, version.Revision) };
+ winrt::hstring formatted{ wil::str_printf<std::wstring>(L"%u.%u.%u", version.Major, version.Minor, version.Build / 10) };
return formatted;
}
CATCH_LOG();

The first bit is just paperwork.
:tada:This issue was addressed in #14660, which has now been successfully released as Windows Terminal Preview v1.17.1023.:tada:
Handy links: