mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-09-01 19:51:34 +02:00
## Summary - Publish scheduled `main` builds as GitHub prereleases while keeping manual `main` runs as preview validation builds. - Add an opt-in Settings switch for prerelease update checks; stable updates remain the default. - Use one MSI-safe version across bundles, MSI packages, binaries, symbols, and package manifests. - Prevent preview releases from triggering Microsoft Store, WinGet, or public-symbol publication. - Label preview builds explicitly in Settings, update notifications, and What's New. ## Build intent | Source | Trigger | Intent | | --- | --- | --- | | `main` | Scheduled | Publish a preview release | | `main` | Manual | Validate a preview build without publishing | | `stable` | Manual | Produce a stable release | | Other branches | Any supported trigger | Produce a private validation build | ## MSI-safe release versioning Windows Installer compares only `major.minor.build` and ignores the fourth version component. Preview and stable release builds therefore use: ```text major.minor.YDDDB.0 ``` - `Y`: zero-based number of calendar years since `ReleaseTrainEpoch`. - `DDD`: three-position calendar day of year. - `B`: daily release sequence `1-9`. - The fourth component is always `0`. With `ReleaseTrainVersion=0.100` and `ReleaseTrainEpoch=2026-01-01`: ```text 0.100.2111.0 = July 30, 2026, release build 1 0.100.3659.0 = December 31, 2026, release build 9 0.100.10011.0 = January 1, 2027, release build 1 ``` The allocator formats `DDD` as exactly three digits before converting the MSI component to its numeric representation. Leading zeros may not be displayed because Windows version components are numeric; decoding remains positional: ```text B = component % 10 DDD = (component / 10) % 1000 Y = component / 10000 ``` `ReleaseTrainVersion` and `ReleaseTrainEpoch` are checked in under `src/Version.props`. The epoch remains January 1 of the active epoch year and advances on the first release-train minor change in a new year. ## Daily release counter Azure DevOps persists the daily sequence server-side using a counter keyed as `release-YYYYMMDD`. - `main` and `stable` share the same daily counter. - Other branches do not evaluate or consume the release counter. - Failed or canceled `main`/`stable` runs may leave gaps. - The build fails when the daily sequence exceeds `9`. - The counter date and encoded `YDDD` date both use `pipeline.startTime`. Private branches retain independent `0.0.<extended-day><NN>.0` validation versions. ## Update behavior - Stable users continue to query GitHub's stable latest-release path. - Users who explicitly enable preview updates can select newer GitHub prereleases. - Preview releases and notifications are labeled as PowerToys Preview. - What's New separates preview entries from stable release history and hides previews by default. ## Validation - 17 Pester tests cover `main`, `stable`, private branches, year rollover, epoch reset, monotonicity, override validation, sequence limits, and date alignment. - Version propagation verified `0.100.2111.0` in `Version.props` and all affected AppX/MSIX manifests. - Azure DevOps pipeline dry-runs succeeded for both `refs/heads/main` and `refs/heads/stable`. - The affected native version project builds successfully. - PR CI is green for x64, ARM64, Command Palette SDK, dependency review, telemetry detection, and CLA. ## Remaining end-to-end checks - Install two locally or officially produced installers with consecutive MSI-visible `YDDDB` versions and verify the upgrade preserves binaries, package registrations, hardlinks, and shell integrations. - On the first natural post-merge `main` or `stable` run, verify the production counter value and resolved version in the release logs. ## Local GPO verification Validated locally with the signed `v0.100.2171` build from Azure DevOps build [153961073](https://microsoft.visualstudio.com/Dart/_build/results?buildId=153961073). These checks cover the administrative-template integration and Settings behavior. ### Policy enabled: preview updates are disabled With `PreviewUpdatesDisabled=1`, **Include prerelease updates** is forced off and locked, and Settings displays the managed-by-your-organization notice.  ### Policy removed: the user preference is preserved After removing `PreviewUpdatesDisabled` and restarting PowerToys, the previously selected preview-update preference is restored and editable. The policy suppresses the preference without overwriting it.  ### Group Policy Editor After importing the updated ADMX/ADML templates, **Disable preview build updates** appears under **Microsoft PowerToys > Installer and Updates**. The policy dialog documents that **Enabled** blocks preview updates, while **Disabled** or **Not Configured** leaves the choice available to the user.  --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ad8b7909-0472-4464-bdee-deaeca726f94 Copilot-Session: 8e04a72e-3b0f-4ac4-8156-d04ea9b8bb85
118 lines
4.6 KiB
C++
118 lines
4.6 KiB
C++
#include "pch.h"
|
|
#include "trace.h"
|
|
|
|
#include "general_settings.h"
|
|
|
|
#include <common/Telemetry/TraceBase.h>
|
|
|
|
TRACELOGGING_DEFINE_PROVIDER(
|
|
g_hProvider,
|
|
"Microsoft.PowerToys",
|
|
// {38e8889b-9731-53f5-e901-e8a7c1753074}
|
|
(0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74),
|
|
TraceLoggingOptionProjectTelemetry());
|
|
|
|
void Trace::EventLaunch(const std::wstring& versionNumber, bool isProcessElevated)
|
|
{
|
|
TraceLoggingWriteWrapper(
|
|
g_hProvider,
|
|
"Runner_Launch",
|
|
TraceLoggingWideString(versionNumber.c_str(), "Version"),
|
|
TraceLoggingBoolean(isProcessElevated, "Elevated"),
|
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
|
}
|
|
|
|
void Trace::SettingsChanged(const GeneralSettings& settings)
|
|
{
|
|
std::wstring enabledModules;
|
|
for (const auto& [name, isEnabled] : settings.isModulesEnabledMap)
|
|
{
|
|
if (isEnabled)
|
|
{
|
|
if (!enabledModules.empty())
|
|
{
|
|
enabledModules += L", ";
|
|
}
|
|
|
|
enabledModules += name;
|
|
}
|
|
}
|
|
|
|
TraceLoggingWriteWrapper(
|
|
g_hProvider,
|
|
"GeneralSettingsChanged",
|
|
TraceLoggingBoolean(settings.isStartupEnabled, "RunAtStartup"),
|
|
TraceLoggingBoolean(settings.enableWarningsElevatedApps, "EnableWarningsElevatedApps"),
|
|
TraceLoggingWideString(settings.startupDisabledReason.c_str(), "StartupDisabledReason"),
|
|
TraceLoggingWideString(enabledModules.c_str(), "ModulesEnabled"),
|
|
TraceLoggingBoolean(settings.isRunElevated, "AlwaysRunElevated"),
|
|
TraceLoggingBoolean(settings.downloadUpdatesAutomatically, "DownloadUpdatesAutomatically"),
|
|
TraceLoggingBoolean(settings.includePrereleaseUpdates, "IncludePrereleaseUpdates"),
|
|
TraceLoggingBoolean(settings.enableExperimentation, "EnableExperimentation"),
|
|
TraceLoggingWideString(settings.theme.c_str(), "Theme"),
|
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
|
}
|
|
|
|
void Trace::UpdateCheckCompleted(bool success, bool updateAvailable, const std::wstring& fromVersion, const std::wstring& toVersion)
|
|
{
|
|
TraceLoggingWriteWrapper(
|
|
g_hProvider,
|
|
"UpdateCheck_Completed",
|
|
TraceLoggingBoolean(success, "Success"),
|
|
TraceLoggingBoolean(updateAvailable, "UpdateAvailable"),
|
|
TraceLoggingWideString(fromVersion.c_str(), "FromVersion"),
|
|
TraceLoggingWideString(toVersion.c_str(), "ToVersion"),
|
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
|
}
|
|
|
|
void Trace::UpdateDownloadCompleted(bool success, const std::wstring& version)
|
|
{
|
|
TraceLoggingWriteWrapper(
|
|
g_hProvider,
|
|
"UpdateDownload_Completed",
|
|
TraceLoggingBoolean(success, "Success"),
|
|
TraceLoggingWideString(version.c_str(), "Version"),
|
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
|
}
|
|
|
|
void Trace::TrayIconLeftClick(bool quickAccessEnabled)
|
|
{
|
|
TraceLoggingWriteWrapper(
|
|
g_hProvider,
|
|
"TrayIcon_LeftClick",
|
|
TraceLoggingBoolean(quickAccessEnabled, "QuickAccessEnabled"),
|
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
|
}
|
|
|
|
void Trace::TrayIconDoubleClick(bool quickAccessEnabled)
|
|
{
|
|
TraceLoggingWriteWrapper(
|
|
g_hProvider,
|
|
"TrayIcon_DoubleClick",
|
|
TraceLoggingBoolean(quickAccessEnabled, "QuickAccessEnabled"),
|
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
|
}
|
|
|
|
void Trace::TrayIconRightClick(bool quickAccessEnabled)
|
|
{
|
|
TraceLoggingWriteWrapper(
|
|
g_hProvider,
|
|
"TrayIcon_RightClick",
|
|
TraceLoggingBoolean(quickAccessEnabled, "QuickAccessEnabled"),
|
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
|
}
|