From 957d015caf6c4efc0f0e5f8bf807b4f6c660250b Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Thu, 19 Mar 2026 21:00:27 -0700 Subject: [PATCH 1/3] Update Bootstrapper for WinAppSDK 2.x/SemVer (#6180) * Update Bootstrapper for WinAppSDK 2.x/SemVer * Drop Compatibility.v1.x as it's a big cost to day-to-day for low gain (poor ROI). Better handled at the higher level testing actual product instead of testing via a UT * Drop Compatibility.v1.x * Fix a bad sprintf edit * More test fixes * More test fixes * Fix VersionShortTag and Installer output * SemVer now only uses Major, and has a different possible Tag * Remove an extra '\' * Allow old or new in the Installer match * Missed the framework Regex --------- Co-authored-by: Chris Wall (WIN SDE) Co-authored-by: Dreynor87 --- build/scripts/ExtractMSIXFromNuget.ps1 | 8 +- dev/Common/AppModel.Identity.h | 55 +++- .../MddBootstrap.cpp | 266 +++++++++++++----- .../MddBootstrap.h | 9 +- installer/dev/console.cpp | 8 + .../AppNotifications-AppxManifest.xml | 2 +- .../BackgroundTaskBuilder-AppxManifest.xml | 2 +- .../BadgeNotifications-AppxManifest.xml | 4 +- .../CameraCaptureUI-AppxManifest.xml | 2 +- ...loyment-RealNameFramework-AppxManifest.xml | 2 +- .../Test_Win32/TestPackages.h | 8 +- .../Test_WinRT/TestPackages.h | 8 +- .../appxmanifest.xml | 8 +- .../appxmanifest-arm64.xml | 6 +- .../appxmanifest-x64.xml | 6 +- .../appxmanifest-x86.xml | 6 +- .../appxmanifest-arm64.xml | 4 +- .../appxmanifest-x64.xml | 4 +- .../appxmanifest-x86.xml | 4 +- .../appxmanifest-arm64.xml | 4 +- .../appxmanifest-x64.xml | 4 +- .../appxmanifest-x86.xml | 4 +- .../appxmanifest.xml | 4 +- .../appxmanifest.xml | 2 +- .../AppxManifest.pkg.xml | 2 +- .../CentennialAppxManifest.pkg.xml | 2 +- .../PowerNotifications-AppxManifest.xml | 2 +- .../PushNotifications-AppxManifest.xml | 2 +- .../Package.appxmanifest | 2 +- .../Package.appxmanifest | 2 +- .../OAuthTestAppPackage/Package.appxmanifest | 2 +- .../Package.appxmanifest | 2 +- .../Package.appxmanifest | 2 +- .../ToastNotificationsDemoApp/main.cpp | 4 +- .../Package.appxmanifest | 2 +- .../Package.appxmanifest | 2 +- .../Package.appxmanifest | 2 +- test/inc/WindowsAppRuntime.Test.Bootstrap.h | 10 +- test/inc/WindowsAppRuntime.Test.Metadata.h | 4 +- test/inc/WindowsAppRuntime.Test.Package.h | 19 +- 40 files changed, 336 insertions(+), 155 deletions(-) diff --git a/build/scripts/ExtractMSIXFromNuget.ps1 b/build/scripts/ExtractMSIXFromNuget.ps1 index f4cdf881c6..274bb02c75 100644 --- a/build/scripts/ExtractMSIXFromNuget.ps1 +++ b/build/scripts/ExtractMSIXFromNuget.ps1 @@ -61,25 +61,25 @@ function Extract-MSIXFromNuget ($NugetPath) # * .msix = MSIX packages are always named *.msix # Find the base Frameworks - if ($filename -match '^.*(x86|x64|arm64)\\Microsoft\.WindowsAppRuntime[-.](\d+\.\d+)(-[a-z]+[0-9]*)?(\.appx|\.msix)$') + if ($filename -match '^.*(x86|x64|arm64)\\Microsoft\.WindowsAppRuntime[-.](\d+)(.\d+)?(-[A-Za-z.0-9]+)?(\.appx|\.msix)$') { $DestFilename = 'framework_' + $Matches[1] + '.msix' } # Find Main - if ($filename -match '^.*(x86|x64|arm64)\\Microsoft\.WindowsAppRuntime\.Main([-.](\d+\.\d+))?(-[a-z]+[0-9]*)?(\.appx|\.msix)$') + if ($filename -match '^.*(x86|x64|arm64)\\Microsoft\.WindowsAppRuntime\.Main([-.](\d+)(.\d+)?)?(-[A-Za-z.0-9]+)?(\.appx|\.msix)$') { $DestFilename = 'main_' + $Matches[1] + '.msix' } # Find Singleton - if ($filename -match '^.*(x86|x64|arm64)\\Microsoft\.WindowsAppRuntime\.Singleton([-.](\d+\.\d+))(-[a-z]+[0-9]*)?(\.appx|\.msix)$') + if ($filename -match '^.*(x86|x64|arm64)\\Microsoft\.WindowsAppRuntime\.Singleton([-.](\d+)(.\d+)?)(-[A-Za-z.0-9]+)?(\.appx|\.msix)$') { $DestFilename = 'singleton_' + $Matches[1] + '.msix' } # Find DDLM - if ($filename -match '^.*(x86|x64|arm64)\\Microsoft\.WindowsAppRuntime\.DDLM([-.](\d+\.\d+))?(-[a-z]+[0-9]*)?(\.appx|\.msix)$') + if ($filename -match '^.*(x86|x64|arm64)\\Microsoft\.WindowsAppRuntime\.DDLM([-.](\d+)(.\d+)?)?(-[A-Za-z.0-9]+)?(\.appx|\.msix)$') { $DestFilename = 'ddlm_' + $Matches[1] + '.msix' } diff --git a/dev/Common/AppModel.Identity.h b/dev/Common/AppModel.Identity.h index 5ba93d56bd..890865a2f1 100644 --- a/dev/Common/AppModel.Identity.h +++ b/dev/Common/AppModel.Identity.h @@ -268,13 +268,15 @@ inline bool operator>=(const PackageVersion& packageVersion1, const PackageVersi inline bool IsValidVersionShortTag( const std::wstring& versionShortTag) { - // VersionShortTag must be "" or 1 ASCII letter optionally followed by 1 ASCII digit + // VersionShortTag must be "" or 1 ASCII letter optionally followed by 1-2 base-36 characters (0-9, A-Z) + // v1.x format: letter [+ digit] e.g. "p", "p2" + // v2.x format: letter + base36(revision) e.g. "c0", "c1M", "pZ" if (versionShortTag.empty()) { return true; } - const size_t c_maxVersionShortTagLength{ 2 }; + const size_t c_maxVersionShortTagLength{ 3 }; const auto versionShortTagLength{ versionShortTag.length() }; if (versionShortTagLength > c_maxVersionShortTagLength) { @@ -287,11 +289,12 @@ inline bool IsValidVersionShortTag( { return false; } - if (versionShortTagLength > 1) + for (size_t i = 1; i < versionShortTagLength; ++i) { - const auto tagSuffix{ versionShortTag[1] }; - const auto isTagSuffixADigit{ ('0' <= tagSuffix) && (tagSuffix <= '9') }; - if (!isTagSuffixADigit) + const auto ch{ versionShortTag[i] }; + const auto isBase36Char{ (('0' <= ch) && (ch <= '9')) || + (('A' <= ch) && (ch <= 'Z')) }; + if (!isBase36Char) { return false; } @@ -300,6 +303,7 @@ inline bool IsValidVersionShortTag( } /// VersionShortTag = VersionTag[0] [+ VersionTag[last] if 0-9] +/// Use this for v1.x compatibility. inline std::wstring GetVersionShortTagFromVersionTag( PCWSTR versionTag) { @@ -321,6 +325,45 @@ inline std::wstring GetVersionShortTagFromVersionTag( return versionShortTag; } +/// VersionShortTag for v2.x+ = VersionTag[0] + ChannelBuildString +/// where ChannelBuildString is extracted from the end of the versionTag. +/// The Tag portion uses only lowercase letters and dots [a-z.], while the +/// ChannelBuildString (base-36 encoded) uses only digits and uppercase [0-9A-Z]. +/// These disjoint character sets allow deterministic extraction. +inline std::wstring GetVersionShortTagFromVersionTagV2( + PCWSTR versionTag) +{ + std::wstring versionShortTag; + if (versionTag && (versionTag[0] != L'\0')) + { + versionShortTag = versionTag[0]; + + // Extract the ChannelBuildString from the end of versionTag. + // Scan backwards: [0-9A-Z] chars are from the ChannelBuildString (max 2 chars). + const auto versionTagLength{ wcslen(versionTag) }; + size_t cbsStart{ versionTagLength }; + while (cbsStart > 0 && (versionTagLength - cbsStart) < 2) + { + const auto ch{ versionTag[cbsStart - 1] }; + if ((L'0' <= ch && ch <= L'9') || (L'A' <= ch && ch <= L'Z')) + { + --cbsStart; + } + else + { + break; + } + } + if (cbsStart < versionTagLength) + { + versionShortTag.append(versionTag + cbsStart, versionTagLength - cbsStart); + } + + THROW_HR_IF_MSG(E_INVALIDARG, !IsValidVersionShortTag(versionShortTag.c_str()), "VersionTag=%ls", versionTag); + } + return versionShortTag; +} + /// Package Identity class PackageIdentity { diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp index d9e186cdd3..1bc1a48409 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp @@ -169,10 +169,20 @@ STDAPI MddBootstrapInitialize2( if (WI_IsFlagSet(options, MddBootstrapInitializeOptions_OnError_FailFast) || IsOptionEnabled(L"MICROSOFT_WINDOWSAPPRUNTIME_BOOTSTRAP_INITIALIZE_FAILFAST")) { - FAIL_FAST_HR_MSG(hr, - "Bootstrap initialize(0x%08X, '%ls', %hu.%hu.%hu.%hu)", - majorMinorVersion, (!versionTag ? L"" : versionTag), - minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision); + if (majorMinorVersion >= 0x00020000) + { + FAIL_FAST_HR_MSG(hr, + "Bootstrap initialize(0x%04Xxxxx, '%ls', %hu.%hu.%hu.%hu)", + ((majorMinorVersion >> 16) & 0x0000FFFFu), (!versionTag ? L"" : versionTag), + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision); + } + else + { + FAIL_FAST_HR_MSG(hr, + "Bootstrap initialize(0x%08X, '%ls', %hu.%hu.%hu.%hu)", + majorMinorVersion, (!versionTag ? L"" : versionTag), + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision); + } } activityContext.StopActivityForWilReturnHR(true); RETURN_HR(hr); @@ -332,30 +342,60 @@ void VerifyInitializationIsCompatible( GetFrameworkPackageFamilyName(majorMinorVersion, versionTag); // Is the initialization request compatible with the current initialization state? - THROW_HR_IF_MSG(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, - majorMinorVersion != g_initializationMajorMinorVersion, - "MddBootstrapInitialize(***0x%08X***, '%ls', %hu.%hu.%hu.%hu) not compatible with current initialization state (0x%X, '%ls', %hu.%hu.%hu.%hu)", - majorMinorVersion, (!versionTag ? L"" : versionTag), - minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision, - g_initializationMajorMinorVersion, g_initializationVersionTag.c_str(), - g_initializationFrameworkPackageVersion.Major, g_initializationFrameworkPackageVersion.Minor, - g_initializationFrameworkPackageVersion.Build, g_initializationFrameworkPackageVersion.Revision); - THROW_HR_IF_MSG(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, - CompareStringOrdinal((!versionTag ? L"" : versionTag), -1, g_initializationVersionTag.c_str(), -1, TRUE) != CSTR_EQUAL, - "MddBootstrapInitialize(0x%08X, ***'%ls'***, %hu.%hu.%hu.%hu) not compatible with current initialization state (0x%X, '%ls', %hu.%hu.%hu.%hu)", - majorMinorVersion, (!versionTag ? L"" : versionTag), - minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision, - g_initializationMajorMinorVersion, g_initializationVersionTag.c_str(), - g_initializationFrameworkPackageVersion.Major, g_initializationFrameworkPackageVersion.Minor, - g_initializationFrameworkPackageVersion.Build, g_initializationFrameworkPackageVersion.Revision); - THROW_HR_IF_MSG(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, - minVersion.Version > g_initializationFrameworkPackageVersion.Version, - "MddBootstrapInitialize(0x%08X, '%ls', ***%hu.%hu.%hu.%hu***) not compatible with current initialization state (0x%X, '%ls', %hu.%hu.%hu.%hu)", - majorMinorVersion, (!versionTag ? L"" : versionTag), - minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision, - g_initializationMajorMinorVersion, g_initializationVersionTag.c_str(), - g_initializationFrameworkPackageVersion.Major, g_initializationFrameworkPackageVersion.Minor, - g_initializationFrameworkPackageVersion.Build, g_initializationFrameworkPackageVersion.Revision); + if (majorMinorVersion >= 0x00020000) + { + THROW_HR_IF_MSG(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, + majorMinorVersion != g_initializationMajorMinorVersion, + "MddBootstrapInitialize(***0x%04Xxxxx***, '%ls', %hu.%hu.%hu.%hu) not compatible with current initialization state (0x%X, '%ls', %hu.%hu.%hu.%hu)", + ((majorMinorVersion >> 16) & 0x0000FFFFu), (!versionTag ? L"" : versionTag), + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision, + g_initializationMajorMinorVersion, g_initializationVersionTag.c_str(), + g_initializationFrameworkPackageVersion.Major, g_initializationFrameworkPackageVersion.Minor, + g_initializationFrameworkPackageVersion.Build, g_initializationFrameworkPackageVersion.Revision); + THROW_HR_IF_MSG(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, + CompareStringOrdinal((!versionTag ? L"" : versionTag), -1, g_initializationVersionTag.c_str(), -1, TRUE) != CSTR_EQUAL, + "MddBootstrapInitialize(0x%04Xxxxx, ***'%ls'***, %hu.%hu.%hu.%hu) not compatible with current initialization state (0x%X, '%ls', %hu.%hu.%hu.%hu)", + ((majorMinorVersion >> 16) & 0x0000FFFFu), (!versionTag ? L"" : versionTag), + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision, + g_initializationMajorMinorVersion, g_initializationVersionTag.c_str(), + g_initializationFrameworkPackageVersion.Major, g_initializationFrameworkPackageVersion.Minor, + g_initializationFrameworkPackageVersion.Build, g_initializationFrameworkPackageVersion.Revision); + THROW_HR_IF_MSG(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, + minVersion.Version > g_initializationFrameworkPackageVersion.Version, + "MddBootstrapInitialize(0x%04Xxxxx, '%ls', ***%hu.%hu.%hu.%hu***) not compatible with current initialization state (0x%X, '%ls', %hu.%hu.%hu.%hu)", + ((majorMinorVersion >> 16) & 0x0000FFFFu), (!versionTag ? L"" : versionTag), + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision, + g_initializationMajorMinorVersion, g_initializationVersionTag.c_str(), + g_initializationFrameworkPackageVersion.Major, g_initializationFrameworkPackageVersion.Minor, + g_initializationFrameworkPackageVersion.Build, g_initializationFrameworkPackageVersion.Revision); + } + else + { + THROW_HR_IF_MSG(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, + majorMinorVersion != g_initializationMajorMinorVersion, + "MddBootstrapInitialize(***0x%08X***, '%ls', %hu.%hu.%hu.%hu) not compatible with current initialization state (0x%X, '%ls', %hu.%hu.%hu.%hu)", + majorMinorVersion, (!versionTag ? L"" : versionTag), + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision, + g_initializationMajorMinorVersion, g_initializationVersionTag.c_str(), + g_initializationFrameworkPackageVersion.Major, g_initializationFrameworkPackageVersion.Minor, + g_initializationFrameworkPackageVersion.Build, g_initializationFrameworkPackageVersion.Revision); + THROW_HR_IF_MSG(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, + CompareStringOrdinal((!versionTag ? L"" : versionTag), -1, g_initializationVersionTag.c_str(), -1, TRUE) != CSTR_EQUAL, + "MddBootstrapInitialize(0x%08X, ***'%ls'***, %hu.%hu.%hu.%hu) not compatible with current initialization state (0x%X, '%ls', %hu.%hu.%hu.%hu)", + majorMinorVersion, (!versionTag ? L"" : versionTag), + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision, + g_initializationMajorMinorVersion, g_initializationVersionTag.c_str(), + g_initializationFrameworkPackageVersion.Major, g_initializationFrameworkPackageVersion.Minor, + g_initializationFrameworkPackageVersion.Build, g_initializationFrameworkPackageVersion.Revision); + THROW_HR_IF_MSG(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, + minVersion.Version > g_initializationFrameworkPackageVersion.Version, + "MddBootstrapInitialize(0x%08X, '%ls', ***%hu.%hu.%hu.%hu***) not compatible with current initialization state (0x%X, '%ls', %hu.%hu.%hu.%hu)", + majorMinorVersion, (!versionTag ? L"" : versionTag), + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision, + g_initializationMajorMinorVersion, g_initializationVersionTag.c_str(), + g_initializationFrameworkPackageVersion.Major, g_initializationFrameworkPackageVersion.Minor, + g_initializationFrameworkPackageVersion.Build, g_initializationFrameworkPackageVersion.Revision); + } } void FirstTimeInitialization( @@ -463,16 +503,31 @@ void FirstTimeInitialization( uint16_t minorVersion{ static_cast(majorMinorVersion) }; PCWSTR packagVersionTagDelimiter{ packageVersionTag.empty() ? L"" : L"-" }; - const std::wstring frameworkPackageFamilyName{ std::format(L"{}.{}.{}{}{}_8wekyb3d8bbwe", - g_test_frameworkPackageNamePrefix, - majorVersion, minorVersion, - packagVersionTagDelimiter, packageVersionTag) }; + std::wstring frameworkPackageFamilyName; + std::wstring mainPackageFamilyName; + if (majorMinorVersion >= 0x00020000) + { + frameworkPackageFamilyName = std::format(L"{}.{}{}{}_8wekyb3d8bbwe", + g_test_frameworkPackageNamePrefix, + majorVersion, + packagVersionTagDelimiter, packageVersionTag); + mainPackageFamilyName = std::format(L"{}.{}{}{}_8wekyb3d8bbwe", + g_test_mainPackageNamePrefix, + majorVersion, + packagVersionTagDelimiter, packageVersionTag); + } + else + { + frameworkPackageFamilyName = std::format(L"{}.{}.{}{}{}_8wekyb3d8bbwe", + g_test_frameworkPackageNamePrefix, + majorVersion, minorVersion, + packagVersionTagDelimiter, packageVersionTag); + mainPackageFamilyName = std::format(L"{}.{}.{}{}{}_8wekyb3d8bbwe", + g_test_mainPackageNamePrefix, + majorVersion, minorVersion, + packagVersionTagDelimiter, packageVersionTag); + } FAIL_FAST_HR_IF_MSG(E_UNEXPECTED, frameworkPackageFamilyName.length() > PACKAGE_FAMILY_NAME_MAX_LENGTH, "%ls", frameworkPackageFamilyName.c_str()); - - const std::wstring mainPackageFamilyName{ std::format(L"{}.{}.{}{}{}_8wekyb3d8bbwe", - g_test_mainPackageNamePrefix, - majorVersion, minorVersion, - packagVersionTagDelimiter, packageVersionTag) }; FAIL_FAST_HR_IF_MSG(E_UNEXPECTED, mainPackageFamilyName.length() > PACKAGE_FAMILY_NAME_MAX_LENGTH, "%ls", mainPackageFamilyName.c_str()); ::WindowsAppRuntime::VersionInfo::TestInitialize(frameworkPackageFamilyName.c_str(), mainPackageFamilyName.c_str()); @@ -508,12 +563,24 @@ std::wstring GetFrameworkPackageFamilyName( PCWSTR packageVersionTag{ !versionTag ? L"" : versionTag }; PCWSTR packageVersionTagDelimiter{ (packageVersionTag[0] == L'\0') ? L"" : L"-"}; - const std::wstring packageFamilyName{ std::format(L"{}.{}.{}{}{}_8wekyb3d8bbwe", - namePrefix, majorVersion, minorVersion, - packageVersionTagDelimiter, packageVersionTag) }; - THROW_HR_IF_MSG(E_INVALIDARG, packageFamilyName.length() > PACKAGE_FAMILY_NAME_MAX_LENGTH, "%ls", packageFamilyName.c_str()); + if (majorMinorVersion >= 0x00020000) + { + const std::wstring packageFamilyName{ std::format(L"{}.{}{}{}_8wekyb3d8bbwe", + namePrefix, majorVersion, + packageVersionTagDelimiter, packageVersionTag) }; + THROW_HR_IF_MSG(E_INVALIDARG, packageFamilyName.length() > PACKAGE_FAMILY_NAME_MAX_LENGTH, "%ls", packageFamilyName.c_str()); + + return packageFamilyName; + } + else + { + const std::wstring packageFamilyName{ std::format(L"{}.{}.{}{}{}_8wekyb3d8bbwe", + namePrefix, majorVersion, minorVersion, + packageVersionTagDelimiter, packageVersionTag) }; + THROW_HR_IF_MSG(E_INVALIDARG, packageFamilyName.length() > PACKAGE_FAMILY_NAME_MAX_LENGTH, "%ls", packageFamilyName.c_str()); - return packageFamilyName; + return packageFamilyName; + } } /// Determine the path for the Windows App Runtime Framework package @@ -768,20 +835,38 @@ CLSID FindDDLMViaAppExtension( std::wstring appExtensionName; const UINT16 majorVersion{ HIWORD(majorMinorVersion) }; const UINT16 minorVersion{ LOWORD(majorMinorVersion) }; - const auto versionShortTag{ AppModel::Identity::GetVersionShortTagFromVersionTag(versionTag) }; - if (!versionShortTag.empty()) + if (majorMinorVersion >= 0x00020000) { - appExtensionName = std::format(L"microsoft.winappruntime.ddlm-{}.{}-{}-{}", - majorVersion, minorVersion, AppModel::Identity::GetCurrentArchitectureAsShortString(), versionShortTag); - THROW_HR_IF_MSG(E_INVALIDARG, appExtensionName.length() > PACKAGE_NAME_MAX_LENGTH, "%ls", appExtensionName.c_str()); + const auto versionShortTag{ AppModel::Identity::GetVersionShortTagFromVersionTagV2(versionTag) }; + if (!versionShortTag.empty()) + { + appExtensionName = std::format(L"microsoft.winappruntime.ddlm-{}-{}-{}", + majorVersion, AppModel::Identity::GetCurrentArchitectureAsShortString(), versionShortTag); + THROW_HR_IF_MSG(E_INVALIDARG, appExtensionName.length() > PACKAGE_NAME_MAX_LENGTH, "%ls", appExtensionName.c_str()); + } + else + { + appExtensionName = std::format(L"microsoft.winappruntime.ddlm-{}-{}", + majorVersion, AppModel::Identity::GetCurrentArchitectureAsShortString()); + THROW_HR_IF_MSG(E_INVALIDARG, appExtensionName.length() > PACKAGE_NAME_MAX_LENGTH, "%ls", appExtensionName.c_str()); + } } else { - appExtensionName = std::format(L"microsoft.winappruntime.ddlm-{}.{}-{}", - majorVersion, minorVersion, AppModel::Identity::GetCurrentArchitectureAsShortString()); - THROW_HR_IF_MSG(E_INVALIDARG, appExtensionName.length() > PACKAGE_NAME_MAX_LENGTH, "%ls", appExtensionName.c_str()); + const auto versionShortTag{ AppModel::Identity::GetVersionShortTagFromVersionTag(versionTag) }; + if (!versionShortTag.empty()) + { + appExtensionName = std::format(L"microsoft.winappruntime.ddlm-{}.{}-{}-{}", + majorVersion, minorVersion, AppModel::Identity::GetCurrentArchitectureAsShortString(), versionShortTag); + THROW_HR_IF_MSG(E_INVALIDARG, appExtensionName.length() > PACKAGE_NAME_MAX_LENGTH, "%ls", appExtensionName.c_str()); + } + else + { + appExtensionName = std::format(L"microsoft.winappruntime.ddlm-{}.{}-{}", + majorVersion, minorVersion, AppModel::Identity::GetCurrentArchitectureAsShortString()); + THROW_HR_IF_MSG(E_INVALIDARG, appExtensionName.length() > PACKAGE_NAME_MAX_LENGTH, "%ls", appExtensionName.c_str()); + } } - auto catalog{ winrt::Windows::ApplicationModel::AppExtensions::AppExtensionCatalog::Open(appExtensionName) }; auto appExtensions{ catalog.FindAllAsync().get() }; for (auto appExtension : appExtensions) @@ -880,7 +965,9 @@ void FindDDLMViaEnumeration( WCHAR packageNameSuffix[10]{}; size_t packageNameSuffixLength{}; - const auto versionShortTag{ AppModel::Identity::GetVersionShortTagFromVersionTag(versionTag) }; + const auto versionShortTag{ (majorMinorVersion >= 0x00020000) + ? AppModel::Identity::GetVersionShortTagFromVersionTagV2(versionTag) + : AppModel::Identity::GetVersionShortTagFromVersionTag(versionTag) }; if (!versionShortTag.empty()) { packageNameSuffix[0] = L'-'; @@ -978,9 +1065,9 @@ void FindDDLMViaEnumeration( (void)LOG_LAST_ERROR_MSG("Enumeration: FindFirst(%ls) found %ls", fileSpec.c_str(), findFileData.cFileName); continue; } - if ((releaseMajorVersion != majorVersion) || (releaseMinorVersion != minorVersion)) + if ((releaseMajorVersion != majorVersion) || ((majorVersion < 0x0002) && (releaseMinorVersion != minorVersion))) { - // The package's major or minor release version doesn't match the expected value. Skip it + // The package's major or (if 1.x) minor release version doesn't match the expected value. Skip it continue; } @@ -1045,10 +1132,20 @@ void FindDDLMViaEnumeration( } } - THROW_HR_IF_MSG(STATEREPOSITORY_E_DEPENDENCY_NOT_RESOLVED, bestFitVersion.Version == 0, - "Major.Minor=%hu.%hu, Tag=%ls, MinVersion=%hu.%hu.%hu.%hu", - majorVersion, minorVersion, (!versionTag ? L"" : versionTag), - minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision); + if (majorVersion >= 0x0002) + { + THROW_HR_IF_MSG(STATEREPOSITORY_E_DEPENDENCY_NOT_RESOLVED, bestFitVersion.Version == 0, + "Major=%hu, Tag=%ls, MinVersion=%hu.%hu.%hu.%hu", + majorVersion, (!versionTag ? L"" : versionTag), + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision); + } + else + { + THROW_HR_IF_MSG(STATEREPOSITORY_E_DEPENDENCY_NOT_RESOLVED, bestFitVersion.Version == 0, + "Major.Minor=%hu.%hu, Tag=%ls, MinVersion=%hu.%hu.%hu.%hu", + majorVersion, minorVersion, (!versionTag ? L"" : versionTag), + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision); + } // Success! TraceLoggingWrite( @@ -1124,7 +1221,9 @@ HRESULT MddBootstrapInitialize_Log( const DWORD c_eventId{ static_cast(hrInitialize) }; PCWSTR message1{ L"Windows App Runtime" }; WCHAR message2[1024]{}; - PCWSTR message2Format{ L"ERROR 0x%08X: Bootstrapper initialization failed while looking for version %hu.%hu%s (MSIX package version >= %hu.%hu.%hu.%hu)" }; + PCWSTR message2Format{ majorMinorVersion >= 0x00020000 ? + L"ERROR 0x%08X: Bootstrapper initialization failed while looking for version %hu.x%s (MSIX package version >= %hu.%hu.%hu.%hu)" : + L"ERROR 0x%08X: Bootstrapper initialization failed while looking for version %hu.%hu%s (MSIX package version >= %hu.%hu.%hu.%hu)" }; const UINT16 majorVersion{ HIWORD(majorMinorVersion) }; const UINT16 minorVersion{ LOWORD(majorMinorVersion) }; WCHAR formattedVersionTag[64]{}; @@ -1138,9 +1237,18 @@ HRESULT MddBootstrapInitialize_Log( } FAIL_FAST_IF_FAILED(StringCchPrintfW(formattedVersionTag, ARRAYSIZE(formattedVersionTag), L"-%s", versionTag)); } - FAIL_FAST_IF_FAILED(StringCchPrintfW(message2, ARRAYSIZE(message2), message2Format, - hrInitialize, majorVersion, minorVersion, formattedVersionTag, - minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision)); + if (majorMinorVersion >= 0x00020000) + { + FAIL_FAST_IF_FAILED(StringCchPrintfW(message2, ARRAYSIZE(message2), message2Format, + hrInitialize, majorVersion, formattedVersionTag, + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision)); + } + else + { + FAIL_FAST_IF_FAILED(StringCchPrintfW(message2, ARRAYSIZE(message2), message2Format, + hrInitialize, majorVersion, minorVersion, formattedVersionTag, + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision)); + } PCWSTR strings[2]{ message1, message2 }; LOG_IF_WIN32_BOOL_FALSE(ReportEventW(hEventLog, EVENTLOG_ERROR_TYPE, 0, c_eventId, nullptr, ARRAYSIZE(strings), 0, strings, nullptr)); @@ -1193,12 +1301,19 @@ HRESULT MddBootstrapInitialize_ShowUI_OnNoMatch( // Get the message body WCHAR text[1024]{}; - PCWSTR textFormat{ L"Required components of the Windows App Runtime are missing\n" - L" Version %hu.%hu%s\n" - L" (MSIX package version >= %hu.%hu.%hu.%hu)\n" - L"\n" - L"Do you want to install a compatible Windows App Runtime now?" - }; + PCWSTR textFormat_2x{ L"Required components of the Windows App Runtime are missing\n" + L" Version %hu.x%s\n" + L" (MSIX package version >= %hu.%hu.%hu.%hu)\n" + L"\n" + L"Do you want to install a compatible Windows App Runtime now?" + }; + PCWSTR textFormat_1x{ L"Required components of the Windows App Runtime are missing\n" + L" Version %hu.%hu%s\n" + L" (MSIX package version >= %hu.%hu.%hu.%hu)\n" + L"\n" + L"Do you want to install a compatible Windows App Runtime now?" + }; + PCWSTR textFormat{ majorMinorVersion >= 0x00020000 ? textFormat_2x : textFormat_1x }; const UINT16 majorVersion{ HIWORD(majorMinorVersion) }; const UINT16 minorVersion{ LOWORD(majorMinorVersion) }; WCHAR formattedVersionTag[64]{}; @@ -1206,9 +1321,18 @@ HRESULT MddBootstrapInitialize_ShowUI_OnNoMatch( { FAIL_FAST_IF_FAILED(StringCchPrintfW(formattedVersionTag, ARRAYSIZE(formattedVersionTag), L"-%s", versionTag)); } - FAIL_FAST_IF_FAILED(StringCchPrintfW(text, ARRAYSIZE(text), textFormat, - majorVersion, minorVersion, formattedVersionTag, - minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision)); + if (majorMinorVersion >= 0x00020000) + { + FAIL_FAST_IF_FAILED(StringCchPrintfW(text, ARRAYSIZE(text), textFormat, + majorVersion, formattedVersionTag, + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision)); + } + else + { + FAIL_FAST_IF_FAILED(StringCchPrintfW(text, ARRAYSIZE(text), textFormat, + majorVersion, minorVersion, formattedVersionTag, + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision)); + } // Show the prompt const auto yesno{ MessageBoxW(nullptr, text, caption, MB_YESNO | MB_ICONERROR) }; diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h index 9d416edd77..ea9cfd5bee 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h @@ -48,7 +48,8 @@ DEFINE_ENUM_FLAG_OPERATORS(MddBootstrapInitializeOptions) /// If the request is not compatible with the framework package currently in use /// the API fails and an error is returned. /// -/// @param majorMinorVersion the major and minor version to use, e..g 0x00010002 for Major.Minor=1.2 +/// @param majorMinorVersion the major and minor version to use. The minor version is ignored for release 2.0+; +/// minor is only used for release 1.x, e.g. 0x00010002 is Major.Minor=1.2 whereas 0x0002xxxx is Major=2. /// @param versionTag the version pre-release identifier, or NULL if none. /// @param minVersion the minimum version to use STDAPI MddBootstrapInitialize( @@ -67,7 +68,8 @@ STDAPI MddBootstrapInitialize( /// If the request is not compatible with the framework package currently in use /// the API fails and an error is returned. /// -/// @param majorMinorVersion the major and minor version to use, e..g 0x00010002 for Major.Minor=1.2 +/// @param majorMinorVersion the major and minor version to use. The minor version is ignored for release 2.0+; +/// minor is only used for release 1.x, e.g. 0x00010002 is Major.Minor=1.2 whereas 0x0002xxxx is Major=2. /// @param versionTag the version pre-release identifier, or NULL if none. /// @param minVersion the minimum version to use STDAPI MddBootstrapInitialize2( @@ -190,6 +192,7 @@ namespace DynamicDependency::Bootstrap /// candidate is selected. /// /// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002). + /// The minor version is ignored for release 2.0+; minor is only used for release 1.x, e.g. 0x00010002 is Major.Minor=1.2 whereas 0x0002xxxx is Major=2. /// @param versionTag version tag (if any), e.g. "preview1". /// @param minVersion the minimum version to use /// @param options optional behavior @@ -238,6 +241,7 @@ namespace DynamicDependency::Bootstrap /// candidate is selected. /// /// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002). + /// The minor version is ignored for release 2.0+; minor is only used for release 1.x, e.g. 0x00010002 is Major.Minor=1.2 whereas 0x0002xxxx is Major=2. /// @param versionTag version tag (if any), e.g. "preview1". /// @param minVersion the minimum version to use /// @param options optional behavior @@ -293,6 +297,7 @@ namespace DynamicDependency::Bootstrap /// candidate is selected. /// /// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002). + /// The minor version is ignored for release 2.0+; minor is only used for release 1.x, e.g. 0x00010002 is Major.Minor=1.2 whereas 0x0002xxxx is Major=2. /// @param versionTag version tag (if any), e.g. "preview1". /// @param minVersion the minimum version to use /// @param options optional behavior diff --git a/installer/dev/console.cpp b/installer/dev/console.cpp index d90b6a8f37..896e6a8ad3 100644 --- a/installer/dev/console.cpp +++ b/installer/dev/console.cpp @@ -69,6 +69,12 @@ void WindowsAppRuntimeInstaller::Console::DisplayError(const HRESULT hr) std::wcout << message.get(); } + // On non-English systems, FormatMessage may return localized text containing characters + // that cannot be converted by std::wcout in narrow text mode (e.g. when stdout is a pipe). + // This sets the stream's badbit, silently dropping ALL subsequent output. + // Clear the stream state to ensure subsequent output is not lost. + std::wcout.clear(); + // Don't log redundant Hr information if (FAILED(installActivityContext.GetDeploymentErrorExtendedHResult()) && (installActivityContext.GetDeploymentErrorExtendedHResult() != hResult) && @@ -82,6 +88,7 @@ void WindowsAppRuntimeInstaller::Console::DisplayError(const HRESULT hr) nullptr, installActivityContext.GetDeploymentErrorExtendedHResult(), 0, reinterpret_cast(&message), 0, nullptr) != 0) { std::wcout << message.get(); + std::wcout.clear(); } } @@ -91,5 +98,6 @@ void WindowsAppRuntimeInstaller::Console::DisplayError(const HRESULT hr) installActivityContext.GetInstallStage() == InstallStage::RegisterPackage)) { std::wcout << "ErrorMessage: " << installActivityContext.GetDeploymentErrorText(); + std::wcout.clear(); } } diff --git a/test/AppNotificationTests/AppNotifications-AppxManifest.xml b/test/AppNotificationTests/AppNotifications-AppxManifest.xml index 90304589ca..fc9a5f1e78 100644 --- a/test/AppNotificationTests/AppNotifications-AppxManifest.xml +++ b/test/AppNotificationTests/AppNotifications-AppxManifest.xml @@ -24,7 +24,7 @@ - + diff --git a/test/BackgroundTaskTests/BackgroundTaskBuilder-AppxManifest.xml b/test/BackgroundTaskTests/BackgroundTaskBuilder-AppxManifest.xml index db76e25ecf..09e4e8941d 100644 --- a/test/BackgroundTaskTests/BackgroundTaskBuilder-AppxManifest.xml +++ b/test/BackgroundTaskTests/BackgroundTaskBuilder-AppxManifest.xml @@ -21,7 +21,7 @@ - + diff --git a/test/BadgeNotificationTest/BadgeNotifications-AppxManifest.xml b/test/BadgeNotificationTest/BadgeNotifications-AppxManifest.xml index caac8b8fc8..3bfee28456 100644 --- a/test/BadgeNotificationTest/BadgeNotifications-AppxManifest.xml +++ b/test/BadgeNotificationTest/BadgeNotifications-AppxManifest.xml @@ -21,10 +21,10 @@ Windows APP SDK taef.png - + - + diff --git a/test/CameraCaptureUITests/CameraCaptureUI-AppxManifest.xml b/test/CameraCaptureUITests/CameraCaptureUI-AppxManifest.xml index a37be81c8a..313e562286 100644 --- a/test/CameraCaptureUITests/CameraCaptureUI-AppxManifest.xml +++ b/test/CameraCaptureUITests/CameraCaptureUI-AppxManifest.xml @@ -21,7 +21,7 @@ - + diff --git a/test/Deployment/API/Deployment-RealNameFramework-AppxManifest.xml b/test/Deployment/API/Deployment-RealNameFramework-AppxManifest.xml index cd9c483c4e..bfb1c22363 100644 --- a/test/Deployment/API/Deployment-RealNameFramework-AppxManifest.xml +++ b/test/Deployment/API/Deployment-RealNameFramework-AppxManifest.xml @@ -21,7 +21,7 @@ - + diff --git a/test/DynamicDependency/Test_Win32/TestPackages.h b/test/DynamicDependency/Test_Win32/TestPackages.h index e68d036e8a..5d61b4f19c 100644 --- a/test/DynamicDependency/Test_Win32/TestPackages.h +++ b/test/DynamicDependency/Test_Win32/TestPackages.h @@ -129,8 +129,8 @@ namespace WindowsAppRuntimeFramework { constexpr PCWSTR c_PackageDirName = L"Microsoft.WindowsAppRuntime.Framework"; constexpr PCWSTR c_PackageNamePrefix = L"Microsoft.WindowsAppRuntime"; - constexpr PCWSTR c_PackageFamilyName = L"Microsoft.WindowsAppRuntime.4.1_8wekyb3d8bbwe"; - constexpr PCWSTR c_PackageFullName = L"Microsoft.WindowsAppRuntime.4.1_4.1.1967.333_neutral__8wekyb3d8bbwe"; + constexpr PCWSTR c_PackageFamilyName = L"Microsoft.WindowsAppRuntime.4_8wekyb3d8bbwe"; + constexpr PCWSTR c_PackageFullName = L"Microsoft.WindowsAppRuntime.4_4.1.1967.333_neutral__8wekyb3d8bbwe"; constexpr const PACKAGE_VERSION GetPackageVersion() { PACKAGE_VERSION version{}; @@ -153,8 +153,8 @@ namespace DynamicDependencyDataStore { constexpr PCWSTR c_PackageDirName = L"DynamicDependency.DataStore"; constexpr PCWSTR c_PackageNamePrefix = L"WindowsAppRuntime.Test.DynDep.DataStore"; - constexpr PCWSTR c_PackageFamilyName = L"WindowsAppRuntime.Test.DynDep.DataStore.4.1_8wekyb3d8bbwe"; - constexpr PCWSTR c_PackageFullName = L"WindowsAppRuntime.Test.DynDep.DataStore.4.1_4.1.1967.333_neutral__8wekyb3d8bbwe"; + constexpr PCWSTR c_PackageFamilyName = L"WindowsAppRuntime.Test.DynDep.DataStore.4_8wekyb3d8bbwe"; + constexpr PCWSTR c_PackageFullName = L"WindowsAppRuntime.Test.DynDep.DataStore.4_4.1.1967.333_neutral__8wekyb3d8bbwe"; } namespace WindowsAppRuntimeMain = DynamicDependencyDataStore; diff --git a/test/DynamicDependency/Test_WinRT/TestPackages.h b/test/DynamicDependency/Test_WinRT/TestPackages.h index 9b892b3677..a652cf22ad 100644 --- a/test/DynamicDependency/Test_WinRT/TestPackages.h +++ b/test/DynamicDependency/Test_WinRT/TestPackages.h @@ -129,8 +129,8 @@ namespace WindowsAppRuntimeFramework { constexpr PCWSTR c_PackageDirName = L"Microsoft.WindowsAppRuntime.Framework"; constexpr PCWSTR c_PackageNamePrefix = L"Microsoft.WindowsAppRuntime"; - constexpr PCWSTR c_PackageFamilyName = L"Microsoft.WindowsAppRuntime.4.1_8wekyb3d8bbwe"; - constexpr PCWSTR c_PackageFullName = L"Microsoft.WindowsAppRuntime.4.1_4.1.1967.333_neutral__8wekyb3d8bbwe"; + constexpr PCWSTR c_PackageFamilyName = L"Microsoft.WindowsAppRuntime.4_8wekyb3d8bbwe"; + constexpr PCWSTR c_PackageFullName = L"Microsoft.WindowsAppRuntime.4_4.1.1967.333_neutral__8wekyb3d8bbwe"; constexpr const PACKAGE_VERSION GetPackageVersion() { PACKAGE_VERSION version{}; @@ -153,8 +153,8 @@ namespace DynamicDependencyDataStore { constexpr PCWSTR c_PackageDirName = L"DynamicDependency.DataStore"; constexpr PCWSTR c_PackageNamePrefix = L"WindowsAppRuntime.Test.DynDep.DataStore"; - constexpr PCWSTR c_PackageFamilyName = L"WindowsAppRuntime.Test.DynDep.DataStore.4.1_8wekyb3d8bbwe"; - constexpr PCWSTR c_PackageFullName = L"WindowsAppRuntime.Test.DynDep.DataStore.4.1_4.1.1967.333_neutral__8wekyb3d8bbwe"; + constexpr PCWSTR c_PackageFamilyName = L"WindowsAppRuntime.Test.DynDep.DataStore.4_8wekyb3d8bbwe"; + constexpr PCWSTR c_PackageFullName = L"WindowsAppRuntime.Test.DynDep.DataStore.4_4.1.1967.333_neutral__8wekyb3d8bbwe"; } namespace WindowsAppRuntimeMain = DynamicDependencyDataStore; diff --git a/test/DynamicDependency/data/DynamicDependency.DataStore.Msix/appxmanifest.xml b/test/DynamicDependency/data/DynamicDependency.DataStore.Msix/appxmanifest.xml index 8b2fd7fef0..413253b595 100644 --- a/test/DynamicDependency/data/DynamicDependency.DataStore.Msix/appxmanifest.xml +++ b/test/DynamicDependency/data/DynamicDependency.DataStore.Msix/appxmanifest.xml @@ -10,19 +10,19 @@ IgnorableNamespaces="uap uap3 uap5 com rescap"> - WindowsAppRuntime.Test.DynDep.DataStore v4.1 (aka MicrosoftCorporationII.WinAppRuntime.Main) fake for tests + WindowsAppRuntime.Test.DynDep.DataStore v4.* (aka MicrosoftCorporationII.WinAppRuntime.Main) fake for tests Microsoft Corporation Assets\logo.png - + @@ -34,7 +34,7 @@ Executable="DynamicDependency.DataStore.exe" EntryPoint="Windows.FullTrustApplication"> - + @@ -46,10 +46,10 @@ - + DisplayName="Windows App Runtime DynamicDependency LifetimeManager Extension (4.* arm64)"> 32E7CF70-038C-429a-BD49-88850F1B4A11 diff --git a/test/DynamicDependency/data/DynamicDependencyLifetimeManager.Msix/appxmanifest-x64.xml b/test/DynamicDependency/data/DynamicDependencyLifetimeManager.Msix/appxmanifest-x64.xml index bb441777cc..fc5bc31dd4 100644 --- a/test/DynamicDependency/data/DynamicDependencyLifetimeManager.Msix/appxmanifest-x64.xml +++ b/test/DynamicDependency/data/DynamicDependencyLifetimeManager.Msix/appxmanifest-x64.xml @@ -23,7 +23,7 @@ - + @@ -46,10 +46,10 @@ - + DisplayName="Windows App Runtime DynamicDependency LifetimeManager Extension (4.* x64)"> 32E7CF70-038C-429a-BD49-88850F1B4A11 diff --git a/test/DynamicDependency/data/DynamicDependencyLifetimeManager.Msix/appxmanifest-x86.xml b/test/DynamicDependency/data/DynamicDependencyLifetimeManager.Msix/appxmanifest-x86.xml index 59f6341d8b..e6f18abc7b 100644 --- a/test/DynamicDependency/data/DynamicDependencyLifetimeManager.Msix/appxmanifest-x86.xml +++ b/test/DynamicDependency/data/DynamicDependencyLifetimeManager.Msix/appxmanifest-x86.xml @@ -23,7 +23,7 @@ - + @@ -46,10 +46,10 @@ - + DisplayName="Windows App Runtime DynamicDependency LifetimeManager Extension (4.* x86)"> 32E7CF70-038C-429a-BD49-88850F1B4A11 diff --git a/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1000.Msix/appxmanifest-arm64.xml b/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1000.Msix/appxmanifest-arm64.xml index d631917fd5..eff8c74a33 100644 --- a/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1000.Msix/appxmanifest-arm64.xml +++ b/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1000.Msix/appxmanifest-arm64.xml @@ -23,7 +23,7 @@ - + @@ -45,7 +45,7 @@ - diff --git a/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1000.Msix/appxmanifest-x64.xml b/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1000.Msix/appxmanifest-x64.xml index 4be667749b..2743b7cbd0 100644 --- a/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1000.Msix/appxmanifest-x64.xml +++ b/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1000.Msix/appxmanifest-x64.xml @@ -23,7 +23,7 @@ - + @@ -45,7 +45,7 @@ - diff --git a/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1000.Msix/appxmanifest-x86.xml b/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1000.Msix/appxmanifest-x86.xml index 5521c26e01..5eb94b8712 100644 --- a/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1000.Msix/appxmanifest-x86.xml +++ b/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1000.Msix/appxmanifest-x86.xml @@ -23,7 +23,7 @@ - + @@ -45,7 +45,7 @@ - diff --git a/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1010.Msix/appxmanifest-arm64.xml b/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1010.Msix/appxmanifest-arm64.xml index b928157cbd..6d026408bc 100644 --- a/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1010.Msix/appxmanifest-arm64.xml +++ b/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1010.Msix/appxmanifest-arm64.xml @@ -23,7 +23,7 @@ - + @@ -45,7 +45,7 @@ - diff --git a/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1010.Msix/appxmanifest-x64.xml b/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1010.Msix/appxmanifest-x64.xml index 1dd12c1073..528ad7f37c 100644 --- a/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1010.Msix/appxmanifest-x64.xml +++ b/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1010.Msix/appxmanifest-x64.xml @@ -23,7 +23,7 @@ - + @@ -45,7 +45,7 @@ - diff --git a/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1010.Msix/appxmanifest-x86.xml b/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1010.Msix/appxmanifest-x86.xml index 32634d5fe2..d7aeb30864 100644 --- a/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1010.Msix/appxmanifest-x86.xml +++ b/test/DynamicDependency/data/DynamicDependencyLifetimeManagerGC1010.Msix/appxmanifest-x86.xml @@ -23,7 +23,7 @@ - + @@ -45,7 +45,7 @@ - diff --git a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml index b94b09a1b3..4da765d04d 100644 --- a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml +++ b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml @@ -6,12 +6,12 @@ IgnorableNamespaces="uap"> - Microsoft.WindowsAppRuntime.Framework 4.1 fake for tests + Microsoft.WindowsAppRuntime.Framework 4.* fake for tests Windows App Runtime logo.png true diff --git a/test/DynamicDependency/data/WindowsAppRuntime.Test.Singleton.Msix/appxmanifest.xml b/test/DynamicDependency/data/WindowsAppRuntime.Test.Singleton.Msix/appxmanifest.xml index 85b46a7087..51e8881044 100644 --- a/test/DynamicDependency/data/WindowsAppRuntime.Test.Singleton.Msix/appxmanifest.xml +++ b/test/DynamicDependency/data/WindowsAppRuntime.Test.Singleton.Msix/appxmanifest.xml @@ -22,7 +22,7 @@ - + diff --git a/test/EnvironmentManagerTests/AppxManifest.pkg.xml b/test/EnvironmentManagerTests/AppxManifest.pkg.xml index 6fa75394d1..838be4242f 100644 --- a/test/EnvironmentManagerTests/AppxManifest.pkg.xml +++ b/test/EnvironmentManagerTests/AppxManifest.pkg.xml @@ -15,7 +15,7 @@ - + diff --git a/test/EnvironmentManagerTests/CentennialAppxManifest.pkg.xml b/test/EnvironmentManagerTests/CentennialAppxManifest.pkg.xml index b1c309bbc6..ee58bba3dc 100644 --- a/test/EnvironmentManagerTests/CentennialAppxManifest.pkg.xml +++ b/test/EnvironmentManagerTests/CentennialAppxManifest.pkg.xml @@ -17,7 +17,7 @@ - + diff --git a/test/PowerNotifications/PowerNotifications-AppxManifest.xml b/test/PowerNotifications/PowerNotifications-AppxManifest.xml index c81ca09511..d0925c645b 100644 --- a/test/PowerNotifications/PowerNotifications-AppxManifest.xml +++ b/test/PowerNotifications/PowerNotifications-AppxManifest.xml @@ -21,7 +21,7 @@ - + diff --git a/test/PushNotificationTests/PushNotifications-AppxManifest.xml b/test/PushNotificationTests/PushNotifications-AppxManifest.xml index 1bdac462b2..6c75d1fdef 100644 --- a/test/PushNotificationTests/PushNotifications-AppxManifest.xml +++ b/test/PushNotificationTests/PushNotifications-AppxManifest.xml @@ -23,7 +23,7 @@ - + diff --git a/test/TestApps/AccessControlTestAppPackage/Package.appxmanifest b/test/TestApps/AccessControlTestAppPackage/Package.appxmanifest index c05de3bfda..4c23e67616 100644 --- a/test/TestApps/AccessControlTestAppPackage/Package.appxmanifest +++ b/test/TestApps/AccessControlTestAppPackage/Package.appxmanifest @@ -21,7 +21,7 @@ - + diff --git a/test/TestApps/AppLifecycleTestPackage/Package.appxmanifest b/test/TestApps/AppLifecycleTestPackage/Package.appxmanifest index 159050fedd..bde83b73be 100644 --- a/test/TestApps/AppLifecycleTestPackage/Package.appxmanifest +++ b/test/TestApps/AppLifecycleTestPackage/Package.appxmanifest @@ -20,7 +20,7 @@ - + diff --git a/test/TestApps/OAuthTestAppPackage/Package.appxmanifest b/test/TestApps/OAuthTestAppPackage/Package.appxmanifest index ef3a268bcb..4e5ded1b8c 100644 --- a/test/TestApps/OAuthTestAppPackage/Package.appxmanifest +++ b/test/TestApps/OAuthTestAppPackage/Package.appxmanifest @@ -21,7 +21,7 @@ - + diff --git a/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest b/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest index 25b4b44fc0..59f7171d14 100644 --- a/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest +++ b/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest @@ -22,7 +22,7 @@ - + diff --git a/test/TestApps/PushNotificationsTestAppPackage/Package.appxmanifest b/test/TestApps/PushNotificationsTestAppPackage/Package.appxmanifest index 7167f44b82..1208963375 100644 --- a/test/TestApps/PushNotificationsTestAppPackage/Package.appxmanifest +++ b/test/TestApps/PushNotificationsTestAppPackage/Package.appxmanifest @@ -21,7 +21,7 @@ - + diff --git a/test/TestApps/ToastNotificationsDemoApp/main.cpp b/test/TestApps/ToastNotificationsDemoApp/main.cpp index 4845002082..cae59511e8 100644 --- a/test/TestApps/ToastNotificationsDemoApp/main.cpp +++ b/test/TestApps/ToastNotificationsDemoApp/main.cpp @@ -145,8 +145,8 @@ int main() { constexpr PCWSTR c_PackageNamePrefix{ L"WindowsAppRuntime.Test.DDLM" }; constexpr PCWSTR c_PackagePublisherId{ L"8wekyb3d8bbwe" }; - constexpr PCWSTR c_FrameworkPackageFamilyName = L"Microsoft.WindowsAppRuntime.4.1_8wekyb3d8bbwe"; - constexpr PCWSTR c_MainPackageFamilyName = L"WindowsAppRuntime.Test.DynDep.DataStore.4.1_8wekyb3d8bbwe"; + constexpr PCWSTR c_FrameworkPackageFamilyName = L"Microsoft.WindowsAppRuntime.4_8wekyb3d8bbwe"; + constexpr PCWSTR c_MainPackageFamilyName = L"WindowsAppRuntime.Test.DynDep.DataStore.4_8wekyb3d8bbwe"; RETURN_IF_FAILED(MddBootstrapTestInitialize(c_PackageNamePrefix, c_PackagePublisherId, c_FrameworkPackageFamilyName, c_MainPackageFamilyName)); // Major.Minor version, MinVersion=0 to find any framework package for this major.minor version diff --git a/test/TestApps/ToastNotificationsDemoAppPackage/Package.appxmanifest b/test/TestApps/ToastNotificationsDemoAppPackage/Package.appxmanifest index 54f309d5d2..e4018401ab 100644 --- a/test/TestApps/ToastNotificationsDemoAppPackage/Package.appxmanifest +++ b/test/TestApps/ToastNotificationsDemoAppPackage/Package.appxmanifest @@ -22,7 +22,7 @@ - + diff --git a/test/TestApps/ToastNotificationsDemoPackage/Package.appxmanifest b/test/TestApps/ToastNotificationsDemoPackage/Package.appxmanifest index def1c78ea7..a2acfdf562 100644 --- a/test/TestApps/ToastNotificationsDemoPackage/Package.appxmanifest +++ b/test/TestApps/ToastNotificationsDemoPackage/Package.appxmanifest @@ -22,7 +22,7 @@ - + diff --git a/test/TestApps/ToastNotificationsTestAppPackage/Package.appxmanifest b/test/TestApps/ToastNotificationsTestAppPackage/Package.appxmanifest index 4bcdfd942f..998b2dc893 100644 --- a/test/TestApps/ToastNotificationsTestAppPackage/Package.appxmanifest +++ b/test/TestApps/ToastNotificationsTestAppPackage/Package.appxmanifest @@ -21,7 +21,7 @@ - + diff --git a/test/inc/WindowsAppRuntime.Test.Bootstrap.h b/test/inc/WindowsAppRuntime.Test.Bootstrap.h index a831f77aa0..a94dac4f07 100644 --- a/test/inc/WindowsAppRuntime.Test.Bootstrap.h +++ b/test/inc/WindowsAppRuntime.Test.Bootstrap.h @@ -16,11 +16,11 @@ namespace Test::Bootstrap { enum class Packages { - None = 0, - Framework = 0x0001, - Main = 0x0002, - DDLM = 0x0004, - Singleton = 0x0008, + None = 0, + Framework = 0x0001, + Main = 0x0002, + DDLM = 0x0004, + Singleton = 0x0008, Default = Framework | Main | DDLM | Singleton, }; diff --git a/test/inc/WindowsAppRuntime.Test.Metadata.h b/test/inc/WindowsAppRuntime.Test.Metadata.h index e39fdd828f..7460abf09a 100644 --- a/test/inc/WindowsAppRuntime.Test.Metadata.h +++ b/test/inc/WindowsAppRuntime.Test.Metadata.h @@ -13,9 +13,9 @@ #define WINDOWSAPPRUNTIME_TEST_MSIX_PUBLISHERID L"8wekyb3d8bbwe" -#define WINDOWSAPPRUNTIME_TEST_MSIX_FRAMEWORK_PACKAGE_NAME L"Microsoft.WindowsAppRuntime.4.1" +#define WINDOWSAPPRUNTIME_TEST_MSIX_FRAMEWORK_PACKAGE_NAME L"Microsoft.WindowsAppRuntime.4" #define WINDOWSAPPRUNTIME_TEST_MSIX_DDLM_PACKAGE_NAME L"WindowsAppRuntime.Test.DDLM" -#define WINDOWSAPPRUNTIME_TEST_MSIX_MAIN_PACKAGE_NAME L"WindowsAppRuntime.Test.DynDep.DataStore.4.1" +#define WINDOWSAPPRUNTIME_TEST_MSIX_MAIN_PACKAGE_NAME L"WindowsAppRuntime.Test.DynDep.DataStore.4" #define WINDOWSAPPRUNTIME_TEST_MSIX_SINGLETON_PACKAGE_NAME L"WindowsAppRuntime.Test.Singleton" #define WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_NAMEPREFIX L"WindowsAppRuntime.Test.DDLM" diff --git a/test/inc/WindowsAppRuntime.Test.Package.h b/test/inc/WindowsAppRuntime.Test.Package.h index 5c1bb8de6b..38defe0671 100644 --- a/test/inc/WindowsAppRuntime.Test.Package.h +++ b/test/inc/WindowsAppRuntime.Test.Package.h @@ -17,22 +17,19 @@ #define WINDOWSAPPRUNTIME_TEST_METADATA_VERSION_BUILD 1967 #define WINDOWSAPPRUNTIME_TEST_METADATA_VERSION_REVISION 333 #define WINDOWSAPPRUNTIME_TEST_METADATA_VERSION_STRING L"4.1.1967.333" -#define WINDOWSAPPRUNTIME_TEST_METADATA_RELEASE_STRING L"4.1" +#define WINDOWSAPPRUNTIME_TEST_METADATA_RELEASE_STRING L"4" #define WINDOWSAPPRUNTIME_TEST_MSIX_PUBLISHERID L"8wekyb3d8bbwe" -#define WINDOWSAPPRUNTIME_TEST_MSIX_FRAMEWORK_PACKAGE_NAME L"Microsoft.WindowsAppRuntime.4.1" -#define WINDOWSAPPRUNTIME_TEST_MSIX_DDLM_PACKAGE_NAME L"WindowsAppRuntime.Test.DDLM" -#define WINDOWSAPPRUNTIME_TEST_MSIX_MAIN_PACKAGE_NAME L"WindowsAppRuntime.Test.DynDep.DataStore.4.1" -#define WINDOWSAPPRUNTIME_TEST_MSIX_SINGLETON_PACKAGE_NAME L"WindowsAppRuntime.Test.Singleton" +#define WINDOWSAPPRUNTIME_TEST_MSIX_FRAMEWORK_PACKAGE_NAME L"Microsoft.WindowsAppRuntime.4" +#define WINDOWSAPPRUNTIME_TEST_MSIX_DDLM_PACKAGE_NAME L"WindowsAppRuntime.Test.DDLM" +#define WINDOWSAPPRUNTIME_TEST_MSIX_MAIN_PACKAGE_NAME L"WindowsAppRuntime.Test.DynDep.DataStore.4" +#define WINDOWSAPPRUNTIME_TEST_MSIX_SINGLETON_PACKAGE_NAME L"WindowsAppRuntime.Test.Singleton" #define WINDOWSAPPRUNTIME_TEST_MSIX_DEPLOYMENT_FRAMEWORK_PACKAGE_NAME L"Microsoft.WindowsAppRuntime.1.0-Test" #define WINDOWSAPPRUNTIME_TEST_MSIX_DEPLOYMENT_MAIN_PACKAGE_NAME L"MicrosoftCorporationII.WinAppRuntime.Main.1.0-T" #define WINDOWSAPPRUNTIME_TEST_MSIX_DEPLOYMENT_SINGLETON_PACKAGE_NAME L"MicrosoftCorporationII.WinAppRuntime.Singleton-T" -#define WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_NAMEPREFIX L"WindowsAppRuntime.Test.DDLM" -#define WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_VERSION WINDOWSAPPRUNTIME_TEST_METADATA_VERSION -#define WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_VERSION_STRING WINDOWSAPPRUNTIME_TEST_METADATA_VERSION_STRING #define MSIX_PACKAGE_ARCHITECTURE_ARM L"arm" #define MSIX_PACKAGE_ARCHITECTURE_ARM64 L"arm64" #define MSIX_PACKAGE_ARCHITECTURE_NEUTRAL L"neutral" @@ -49,6 +46,10 @@ #else # error "Unknown processor architecture" #endif + +#define WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_NAMEPREFIX L"WindowsAppRuntime.Test.DDLM" +#define WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_VERSION WINDOWSAPPRUNTIME_TEST_METADATA_VERSION +#define WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_VERSION_STRING WINDOWSAPPRUNTIME_TEST_METADATA_VERSION_STRING #define WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_NAME WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_NAMEPREFIX L"." WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_VERSION_STRING L"-" WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_ARCHITECTURE #define WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_PUBLISHERID WINDOWSAPPRUNTIME_TEST_MSIX_PUBLISHERID #define WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_FAMILYNAME WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_NAME L"_" WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_PUBLISHERID @@ -95,7 +96,7 @@ namespace DynamicDependencyDataStore constexpr PCWSTR c_PackageDirName = L"DynamicDependency.DataStore"; constexpr PCWSTR c_PackageNamePrefix = L"WindowsAppRuntime.Test.DynDep.DataStore"; constexpr PCWSTR c_PackageFamilyName = L"WindowsAppRuntime.Test.DynDep.DataStore." WINDOWSAPPRUNTIME_TEST_METADATA_RELEASE_STRING "_" WINDOWSAPPRUNTIME_TEST_MSIX_PUBLISHERID; - constexpr PCWSTR c_PackageFullName = L"WindowsAppRuntime.Test.DynDep.DataStore." WINDOWSAPPRUNTIME_TEST_METADATA_RELEASE_STRING "_" WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_VERSION_STRING L"_neutral__" WINDOWSAPPRUNTIME_TEST_MSIX_PUBLISHERID; + constexpr PCWSTR c_PackageFullName = L"WindowsAppRuntime.Test.DynDep.DataStore." WINDOWSAPPRUNTIME_TEST_METADATA_RELEASE_STRING "_" WINDOWSAPPRUNTIME_TEST_METADATA_VERSION_STRING L"_neutral__" WINDOWSAPPRUNTIME_TEST_MSIX_PUBLISHERID; } namespace WindowsAppRuntimeMain = DynamicDependencyDataStore; From 890a5f12c84f01ac21d3757a0d032eb8e45f455d Mon Sep 17 00:00:00 2001 From: Dreynor87 Date: Thu, 14 May 2026 14:03:29 -0600 Subject: [PATCH 2/3] Automate Patch and Revision versions using Azure DevOps Variable Library (#6462) * Automate Patch and Revision versions using Azure DevOps Variable Library Add version automation to the Open (Foundation) repo, mirroring the pattern from the Aggregator repo. Uses a separate '{MajorVersion}-Foundation-Versions' Library to track PatchVersion and Revision across builds. - Add WindowsAppSDK-VersionVariables.yml to load version vars from Library - Add WindowsAppSDK-UpdateLibrary-Job.yml to bump versions after official builds - Update Official/PR/Nightly pipelines to include version templates - Update PackTransportPackage to use Library-based versioning for official builds - Patch only bumps on official builds (not PR or Nightly) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove the system.debug, since parameters.debug is empty * Change name of pipeline run * Respond to Agne 1 * Revert the change to depending on Publish --------- Co-authored-by: Chris Wall (WIN SDE) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ...ndowsAppSDK-PackTransportPackage-Stage.yml | 68 ++++++-- .../WindowsAppSDK-UpdateLibrary-Job.yml | 157 ++++++++++++++++++ .../WindowsAppSDK-VersionVariables.yml | 52 ++++++ build/WindowsAppSDK-CommonVariables.yml | 13 +- build/WindowsAppSDK-Foundation-DevTest.yml | 9 +- build/WindowsAppSDK-Foundation-Nightly.yml | 9 +- build/WindowsAppSDK-Foundation-Official.yml | 25 ++- build/WindowsAppSDK-Foundation-PR.yml | 9 +- 8 files changed, 320 insertions(+), 22 deletions(-) create mode 100644 build/AzurePipelinesTemplates/WindowsAppSDK-UpdateLibrary-Job.yml create mode 100644 build/AzurePipelinesTemplates/WindowsAppSDK-VersionVariables.yml diff --git a/build/AzurePipelinesTemplates/WindowsAppSDK-PackTransportPackage-Stage.yml b/build/AzurePipelinesTemplates/WindowsAppSDK-PackTransportPackage-Stage.yml index d282709c2f..d65a8b99f2 100644 --- a/build/AzurePipelinesTemplates/WindowsAppSDK-PackTransportPackage-Stage.yml +++ b/build/AzurePipelinesTemplates/WindowsAppSDK-PackTransportPackage-Stage.yml @@ -14,6 +14,18 @@ parameters: - name: "BuildMockWindowsAppSDK" type: boolean default: true +- name: PrOrNightly + displayName: "PR or Nightly" + type: string + default: '' +- name: BuildType + displayName: "Build Type" + type: string + default: 'experimental' +- name: RunUpdateLibraryJob + displayName: "Run the Update Library Variable Group Job" + type: boolean + default: false stages: - stage: Pack @@ -168,18 +180,9 @@ stages: targetType: 'inline' script: | $buildType = '$(channel)' - $majorMinorPatchRev = '$(MajorVersion).$(MinorVersion).21' - - if ($env:ComponentType) - { - Write-Host "componentType " $env:ComponentType - $majorMinorPatchRev = $majorMinorPatchRev + $env:ComponentType - } - - $version = $majorMinorPatchRev + '-' + $buildType - # If using release versioning, drop the version suffix, which includes a tag & build stamp. - # This should only be done when prepping final release packages. + # All builds (PR, Nightly, Official) use Library-based versioning + $majorMinorPatch = '$(MajorVersion).$(FoundationMinorVersionResolved).$(FoundationPatchVersionResolved)' if ('${{ parameters.IsOfficial }}' -eq 'true') { @@ -203,8 +206,37 @@ stages: { $formattedTag = '-' + $versionTag } + + # For stable official builds with no tag: Major.Minor.Patch + # For non-stable official builds: Major.Minor.Patch-tag{Revision} + $revision = '$(Revision)' + if ($buildType -eq "stable" -and [String]::IsNullOrEmpty($formattedTag)) + { + $version = $majorMinorPatch + } + elseif (-not [String]::IsNullOrEmpty($revision)) + { + $version = $majorMinorPatch + $formattedTag + $revision + } + else + { + $version = $majorMinorPatch + $formattedTag + } + Write-Host "Using Release Versioning" - $version = $majorMinorPatchRev + $formattedTag + } + else + { + # PR/Nightly: Major.Minor.Patch-{NugetBuildTypePrefix}{buildType}{Revision} + # Uses Library version but does NOT update it. Distinguished by prefix + revision. + $versionTag = '$(NugetBuildTypePrefix)' + $buildType + $version = $majorMinorPatch + '-' + $versionTag + '$(Revision)' + } + + if ($env:ComponentType) + { + Write-Host "componentType " $env:ComponentType + $version = $version + $env:ComponentType } Write-Host 'Component Package Version: ' $version @@ -261,4 +293,14 @@ stages: verbosityPush: 'Detailed' nuGetFeedType: 'internal' #Note: The project qualifier is always required when using a feed name. Also, do not use organization scoped feeds. - publishVstsFeed: 'ProjectReunion/Project.Reunion.nuget.internal' \ No newline at end of file + publishVstsFeed: 'ProjectReunion/Project.Reunion.nuget.internal' + +- stage: UpdateFoundationLibrary + dependsOn: Pack + condition: and(succeeded('Pack'), eq(${{ parameters.RunUpdateLibraryJob }}, true)) + jobs: + - template: WindowsAppSDK-UpdateLibrary-Job.yml + parameters: + jobName: 'UpdateFoundationLibraryJob' + BuildType: ${{ parameters.BuildType }} + PrOrNightly: ${{ parameters.PrOrNightly }} diff --git a/build/AzurePipelinesTemplates/WindowsAppSDK-UpdateLibrary-Job.yml b/build/AzurePipelinesTemplates/WindowsAppSDK-UpdateLibrary-Job.yml new file mode 100644 index 0000000000..b1c637304a --- /dev/null +++ b/build/AzurePipelinesTemplates/WindowsAppSDK-UpdateLibrary-Job.yml @@ -0,0 +1,157 @@ +# This template updates the Azure DevOps Variable Group (Library) for the Open (Foundation) repo +# after a successful official build. It bumps PatchVersion and Revision variables. +# This job should only run on official builds (not PR or Nightly). + +parameters: +- name: jobName + displayName: "Job Name" + type: string + default: 'UpdateFoundationLibraryJob' +- name: BuildType + displayName: "Build Type" + type: string + default: 'stable' +- name: PrOrNightly + displayName: "PR or Nightly" + type: string + default: '' + +jobs: +- job: ${{ parameters.jobName }} + variables: + ob_outputDirectory: '$(REPOROOT)\out' + ob_artifactBaseName: '${{parameters.jobName}}' + pool: + type: windows + displayName: "Update Foundation Variable Group" + steps: + - script: | + echo MajorVersion : $(MajorVersion) + echo MinorVersion : $(MinorVersion) + echo Revision : $(Revision) + echo FoundationMinorVersionResolved : $(FoundationMinorVersionResolved) + echo FoundationPatchVersionResolved : $(FoundationPatchVersionResolved) + echo FoundationLibraryName : $(FoundationLibraryName) + echo NugetBuildTypePrefix : $(NugetBuildTypePrefix) + displayName: 'Variables' + + # Create the next Variable Group if it does not already exist so that when we change the Major version, + # the next build will already have the variable group available. + - task: PowerShell@2 + displayName: Create Next Variable Group if Necessary + env: + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + inputs: + targetType: 'inline' + script: | + $NextMajorVersion = [int]$(MajorVersion) + 1 + $NextLibraryName = "$NextMajorVersion-Foundation-Versions" + + echo "Next Major Version will be $NextMajorVersion, so next Variable Group will be $NextLibraryName" + echo "Checking to see if the next Variable Group exists" + $groupExists = az pipelines variable-group list --query "[?name=='$NextLibraryName']" | ConvertFrom-Json + if ($groupExists.Count -eq 0) + { + echo "Creating Variable Group $NextLibraryName" + az pipelines variable-group create --name "$NextLibraryName" --description "Variable group for Windows App SDK Foundation Major Version $NextMajorVersion" --authorize --variables FoundationMinorVersion=0 FoundationPatchVersion=0 FoundationPreviewRevision=0 FoundationExperimentalRevision=0 + } + else + { + echo "Variable Group $NextLibraryName already exists" + } + + - task: PowerShell@2 + condition: and(ne(variables.FoundationMinorVersionResolved, variables.MinorVersion), eq('${{ parameters.PrOrNightly }}', '')) + displayName: Update FoundationMinorVersion in Variable Group + env: + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + inputs: + targetType: 'inline' + script: | + echo "Updating Foundation Minor Version variable in Variable Group" + $group_id = $(az pipelines variable-group list -p $(System.TeamProject) --group-name $(FoundationLibraryName) --query '[0].id' -o json) + az pipelines variable-group variable update --group-id $group_id --name FoundationMinorVersion --value $(MinorVersion) + + - task: PowerShell@2 + condition: eq('${{ parameters.PrOrNightly }}', '') + displayName: Update PreviewRevision in Variable Group + env: + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + inputs: + targetType: 'inline' + script: | + echo "Determining if we need to update FoundationPreviewRevision variable in Variable Group" + $NextPreviewRevision = [int]$(FoundationPreviewRevisionResolved) + if ("${{ parameters.BuildType }}" -eq 'preview') + { + $NextPreviewRevision = $NextPreviewRevision + 1 + } + + if ($NextPreviewRevision -ne '$(FoundationPreviewRevision)') + { + echo "Updating FoundationPreviewRevision variable in Variable Group to $NextPreviewRevision" + $group_id = $(az pipelines variable-group list -p $(System.TeamProject) --group-name $(FoundationLibraryName) --query '[0].id' -o json) + az pipelines variable-group variable update --group-id $group_id --name FoundationPreviewRevision --value $NextPreviewRevision + } + else + { + echo "No update needed for FoundationPreviewRevision variable in Variable Group" + } + + - task: PowerShell@2 + condition: eq('${{ parameters.PrOrNightly }}', '') + displayName: Update ExperimentalRevision in Variable Group + env: + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + inputs: + targetType: 'inline' + script: | + echo "Determining if we need to update FoundationExperimentalRevision variable in Variable Group" + $NextExperimentalRevision = [int]$(FoundationExperimentalRevisionResolved) + if ("${{ parameters.BuildType }}" -eq "experimental") + { + $NextExperimentalRevision = $NextExperimentalRevision + 1 + } + + if ($NextExperimentalRevision -ne '$(FoundationExperimentalRevision)') + { + echo "Updating FoundationExperimentalRevision variable in Variable Group to $NextExperimentalRevision" + $group_id = $(az pipelines variable-group list -p $(System.TeamProject) --group-name $(FoundationLibraryName) --query '[0].id' -o json) + az pipelines variable-group variable update --group-id $group_id --name FoundationExperimentalRevision --value $NextExperimentalRevision + } + else + { + echo "No update needed for FoundationExperimentalRevision variable in Variable Group" + } + + - task: PowerShell@2 + condition: eq('${{ parameters.PrOrNightly }}', '') + displayName: Update FoundationPatchVersion in Variable Group + env: + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + inputs: + targetType: 'inline' + script: | + echo "Determining if we need to update FoundationPatchVersion variable in Variable Group" + $NextPatchVersion = "$(FoundationPatchVersionResolved)" + + # Bump patch on stable official builds (when NugetBuildTypePrefix is empty, meaning not PR/Nightly) + if (("${{ parameters.BuildType }}" -eq "stable") -And ('$(NugetBuildTypePrefix)' -eq '')) + { + $NextPatchVersion = [int]$NextPatchVersion + 1 + } + elseif ((($(FoundationMinorVersionResolved) -ne 0) -Or ($(FoundationPatchVersionResolved) -ne 0)) -And ('$(NugetBuildTypePrefix)' -eq '')) + { + $NextPatchVersion = [int]$NextPatchVersion + 1 + } + + if ($NextPatchVersion -ne '$(FoundationPatchVersion)') + { + echo "Updating FoundationPatchVersion variable in Variable Group to $NextPatchVersion" + $group_id = $(az pipelines variable-group list -p $(System.TeamProject) --group-name $(FoundationLibraryName) --query '[0].id' -o json) + az pipelines variable-group variable update --group-id $group_id --name FoundationPatchVersion --value $NextPatchVersion + } + else + { + echo "No update needed for FoundationPatchVersion variable in Variable Group" + } diff --git a/build/AzurePipelinesTemplates/WindowsAppSDK-VersionVariables.yml b/build/AzurePipelinesTemplates/WindowsAppSDK-VersionVariables.yml new file mode 100644 index 0000000000..2f911a5a60 --- /dev/null +++ b/build/AzurePipelinesTemplates/WindowsAppSDK-VersionVariables.yml @@ -0,0 +1,52 @@ +# This template loads version variables from a per-major-version Azure DevOps Library +# for the Open (Foundation) repo. It mirrors the pattern from the Aggregator repo's +# WindowsAppSDK-VersionVariables.yml but uses a separate "Foundation-Versions" library. +# +# Variables loaded from the library: +# - FoundationMinorVersion: The minor version for Foundation, tracked independently +# - FoundationPatchVersion: The patch version, incremented on each official build +# - FoundationPreviewRevision: The revision for preview official builds +# - FoundationExperimentalRevision: The revision for experimental official builds +# +# All builds (PR, Nightly, Official) use the Library-based version. Only official builds +# update the Library values. PR/Nightly are distinguished by NugetBuildTypePrefix + Revision. + +parameters: +- name: PrOrNightly + displayName: "PR or Nightly Identifier" + type: string + default: '' +- name: BuildType + displayName: "Build Type" + type: string + default: 'experimental' + +variables: + - template: AzurePipelinesTemplates\WindowsAppSDK-Versions.yml@WindowsAppSDKVersionConfig + - name: FoundationLibraryName + value: ${{ format('{0}-Foundation-Versions', variables.MajorVersion)}} + - group: ${{ variables.FoundationLibraryName }} + - name: FoundationMinorVersionResolved + value: $[coalesce(variables['FoundationMinorVersion'], 0)] + - name: FoundationPatchVersionResolved + value: $[coalesce(variables['FoundationPatchVersion'], 0)] + - name: PRNightlyRevision + value: $[counter(format('{0}-{1}-{2}-{3}', variables.MajorVersion, variables.FoundationMinorVersionResolved, variables.FoundationPatchVersionResolved, variables.NugetBuildTypePrefix), 1)] + - name: FoundationPreviewRevisionResolved + value: $[coalesce(variables['FoundationPreviewRevision'], 0)] + - name: FoundationExperimentalRevisionResolved + value: $[coalesce(variables['FoundationExperimentalRevision'], 0)] + - ${{ if ne(parameters.PrOrNightly, '') }}: + - name: Revision + value: $[variables['PRNightlyRevision']] + - ${{ else }}: + - ${{ if eq(parameters.BuildType, 'experimental') }}: + - name: Revision + value: $[variables['FoundationExperimentalRevisionResolved']] + - ${{ else }}: + - ${{ if eq(parameters.BuildType, 'preview') }}: + - name: Revision + value: $[variables['FoundationPreviewRevisionResolved']] + - ${{ else }}: + - name: Revision + value: "" diff --git a/build/WindowsAppSDK-CommonVariables.yml b/build/WindowsAppSDK-CommonVariables.yml index b89b31240c..3dc8e82eee 100644 --- a/build/WindowsAppSDK-CommonVariables.yml +++ b/build/WindowsAppSDK-CommonVariables.yml @@ -1,3 +1,9 @@ +parameters: +- name: PrOrNightly + displayName: "PR or Nightly Identifier" + type: string + default: '' + variables: _useBuildOutputFromPipeline: $[coalesce(variables.useBuildOutputFromPipeline, variables['System.DefinitionId'] )] _useBuildOutputFromBuildId: $[coalesce(variables.useBuildOutputFromBuildId, variables['Build.BuildId'] )] @@ -9,10 +15,15 @@ variables: versionCounter: $[counter(variables['versionDate'], 0)] version: $[format('{0}.{1}.{2}-{3}.{4}', variables['MajorVersion'], variables['MinorVersion'], variables['PatchVersion'], variables['versionDate'], variables['versionCounter'])] SamplesBranch: "release/2.0-stable" # Used in the Samples Build Compat Test + + # Extra nuget version variables for version automation + ${{ if ne(parameters.PrOrNightly, '') }}: + NugetBuildTypePrefix: ${{ format('{0}.', parameters.PrOrNightly) }} + ${{ else }}: + NugetBuildTypePrefix: '' #OneBranch Variables CDP_DEFINITION_BUILD_COUNT: $[counter('', 0)] # needed for onebranch.pipeline.version task https://aka.ms/obpipelines/versioning - system.debug: ${{ parameters.debug }} ENABLE_PRS_DELAYSIGN: 1 ROOT: $(Build.SourcesDirectory) REPOROOT: $(Build.SourcesDirectory) diff --git a/build/WindowsAppSDK-Foundation-DevTest.yml b/build/WindowsAppSDK-Foundation-DevTest.yml index afcd8fdef1..7c47ba6908 100644 --- a/build/WindowsAppSDK-Foundation-DevTest.yml +++ b/build/WindowsAppSDK-Foundation-DevTest.yml @@ -14,8 +14,6 @@ # # ##################################################################################################################################### -name: $(version) - # https://aka.ms/obpipelines/triggers trigger: none @@ -51,11 +49,18 @@ variables: - template: WindowsAppSDK-Foundation-TestConfig.yml@WindowsAppSDKConfig - template: AzurePipelinesTemplates\WindowsAppSDK-Versions.yml@WindowsAppSDKVersionConfig - template: WindowsAppSDK-CommonVariables.yml + parameters: + PrOrNightly: 'devtest' +- template: AzurePipelinesTemplates\WindowsAppSDK-VersionVariables.yml + parameters: + PrOrNightly: 'devtest' - name: maxParallelForBuildSamplesCompatJob_x64 value: 20 - name: maxParallelForBuildSamplesCompatJob_arm64 value: 20 +name: $(MajorVersion).$(FoundationMinorVersionResolved).$(FoundationPatchVersionResolved)-$(NugetBuildTypePrefix)$(channel)$(Revision) + resources: repositories: - repository: templates diff --git a/build/WindowsAppSDK-Foundation-Nightly.yml b/build/WindowsAppSDK-Foundation-Nightly.yml index 40725ec12b..5724fbfaba 100644 --- a/build/WindowsAppSDK-Foundation-Nightly.yml +++ b/build/WindowsAppSDK-Foundation-Nightly.yml @@ -14,8 +14,6 @@ # # ##################################################################################################################################### -name: $(version) - # https://aka.ms/obpipelines/triggers trigger: none @@ -58,11 +56,18 @@ variables: - template: WindowsAppSDK-Foundation-TestConfig.yml@WindowsAppSDKConfig - template: AzurePipelinesTemplates\WindowsAppSDK-Versions.yml@WindowsAppSDKVersionConfig - template: WindowsAppSDK-CommonVariables.yml + parameters: + PrOrNightly: 'dev' +- template: AzurePipelinesTemplates\WindowsAppSDK-VersionVariables.yml + parameters: + PrOrNightly: 'dev' - name: maxParallelForBuildSamplesCompatJob_x64 value: 20 - name: maxParallelForBuildSamplesCompatJob_arm64 value: 20 +name: $(MajorVersion).$(FoundationMinorVersionResolved).$(FoundationPatchVersionResolved)-$(NugetBuildTypePrefix)$(channel)$(Revision) + resources: repositories: - repository: templates diff --git a/build/WindowsAppSDK-Foundation-Official.yml b/build/WindowsAppSDK-Foundation-Official.yml index 3c61c3bb40..fe3b349e14 100644 --- a/build/WindowsAppSDK-Foundation-Official.yml +++ b/build/WindowsAppSDK-Foundation-Official.yml @@ -14,8 +14,6 @@ # # ##################################################################################################################################### -name: $(version) - # https://aka.ms/obpipelines/triggers trigger: none @@ -57,16 +55,36 @@ parameters: displayName: "Run WindowsAppSDK-CheckApiChanges stage" type: boolean default: true +- name: BuildType + displayName: "Build Type" + type: string + default: 'experimental' + values: + - 'stable' + - 'experimental' + - 'preview' +- name: RunUpdateLibraryJob + displayName: "Run the Update Library Variable Group Job" + type: boolean + default: true variables: - template: WindowsAppSDK-Foundation-TestConfig.yml@WindowsAppSDKConfig - template: AzurePipelinesTemplates\WindowsAppSDK-Versions.yml@WindowsAppSDKVersionConfig - template: WindowsAppSDK-CommonVariables.yml + parameters: + PrOrNightly: '' +- template: AzurePipelinesTemplates\WindowsAppSDK-VersionVariables.yml + parameters: + PrOrNightly: '' + BuildType: ${{ parameters.BuildType }} - name: maxParallelForBuildSamplesCompatJob_x64 value: 20 - name: maxParallelForBuildSamplesCompatJob_arm64 value: 20 +name: $(MajorVersion).$(FoundationMinorVersionResolved).$(FoundationPatchVersionResolved)-$(NugetBuildTypePrefix)$(channel)$(Revision) + resources: repositories: - repository: templates @@ -177,6 +195,9 @@ extends: SignOutput: ${{ parameters.SignOutput }} PublishPackage: true IsOfficial: true + PrOrNightly: '' + BuildType: ${{ parameters.BuildType }} + RunUpdateLibraryJob: ${{ parameters.RunUpdateLibraryJob }} - ${{ if eq( parameters.CheckApiChanges, true ) }}: - template: AzurePipelinesTemplates\WindowsAppSDK-CheckApiChanges-Stage.yml@self diff --git a/build/WindowsAppSDK-Foundation-PR.yml b/build/WindowsAppSDK-Foundation-PR.yml index 9533faf781..528a35f51b 100644 --- a/build/WindowsAppSDK-Foundation-PR.yml +++ b/build/WindowsAppSDK-Foundation-PR.yml @@ -14,8 +14,6 @@ # # ##################################################################################################################################### -name: $(version) - # https://aka.ms/obpipelines/triggers trigger: none @@ -41,11 +39,18 @@ variables: - template: WindowsAppSDK-Foundation-TestConfig.yml@WindowsAppSDKConfig - template: AzurePipelinesTemplates\WindowsAppSDK-Versions.yml@WindowsAppSDKVersionConfig - template: WindowsAppSDK-CommonVariables.yml + parameters: + PrOrNightly: 'ci' +- template: AzurePipelinesTemplates\WindowsAppSDK-VersionVariables.yml + parameters: + PrOrNightly: 'ci' - name: maxParallelForBuildSamplesCompatJob_x64 value: 20 - name: maxParallelForBuildSamplesCompatJob_arm64 value: 20 +name: $(MajorVersion).$(FoundationMinorVersionResolved).$(FoundationPatchVersionResolved)-$(NugetBuildTypePrefix)$(channel)$(Revision) + resources: repositories: - repository: templates From 0f8859d351382d0504488c4f543242989615ed89 Mon Sep 17 00:00:00 2001 From: "Chris Wall (WIN SDE)" Date: Thu, 14 May 2026 14:20:05 -0600 Subject: [PATCH 3/3] Since this is the Stable branch, set the Official Pipeline's default BuildType to stable --- build/WindowsAppSDK-Foundation-Official.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/WindowsAppSDK-Foundation-Official.yml b/build/WindowsAppSDK-Foundation-Official.yml index fe3b349e14..5923e606e4 100644 --- a/build/WindowsAppSDK-Foundation-Official.yml +++ b/build/WindowsAppSDK-Foundation-Official.yml @@ -58,7 +58,7 @@ parameters: - name: BuildType displayName: "Build Type" type: string - default: 'experimental' + default: 'stable' values: - 'stable' - 'experimental'