Commit Graph

3 Commits

Author SHA1 Message Date
Boliang Zhang
e753ec51fb feat(release): automate draft preview release preparation (#49797)
## Summary of the Pull Request

Adds a `Prepare Preview Release` custom agent that autonomously turns a
successful PowerToys Azure DevOps release-candidate build into a
complete GitHub draft prerelease for final human review.

The implementation extends the existing `release-note-generation` skill
instead of duplicating it. It adds exact-build metadata resolution,
published-release baseline selection, semantic PR deltas across `main`
and `stable`, release asset validation, idempotent draft-only release
updates, and final draft verification.

## PR Checklist

- [x] **Communication:** The autonomous preview-release design was
reviewed and approved before implementation
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** N/A; no end-user-facing strings were added
- [x] **Dev docs:** Added preview scenario, delta, draft safety, and
reporting references

## Detailed Description of the Pull Request / Additional comments

- Adds `.github/agents/prepare-preview-release.agent.md` with a
no-mid-run-decision workflow and a strict prohibition on publishing
releases.
- Extends `.github/skills/release-note-generation/SKILL.md` with
stable/preview scenario routing while preserving the existing
stable-release workflow.
- Adds canonical scripts under
`.github/skills/release-note-generation/scripts/` to:
  - Resolve and validate ADO build metadata.
- Select the latest published stable or preview baseline before build
queue time.
- Calculate same-lineage or branch-transition PR deltas using PR
numbers, cherry-pick provenance, and patch-ID equivalence.
  - Collect normalized PR metadata and create `release-manifest.json`.
- Download and validate installers, symbols, and GPO assets, including
hashes, signatures, and ZIP contents.
- Create or update draft prereleases while preserving human text outside
managed markers.
- Verify draft flags, immutable target commit, body markers, and
uploaded assets.
- Updates `.pipelines/resolveBuildMetadata.ps1` and
`.pipelines/v2/release.yml` with explicit `auto`, `preview-release`, and
`stable-release` intent handling so preview candidates can be built from
either `main` or `stable`.
- Adds `.pipelines/writeReleaseMetadata.ps1` so each signed build
artifact records its resolved version, channel, intent, source branch,
and immutable source commit.
- Keeps release publication outside the agent: the automation can only
create or update a draft prerelease.

## Validation Steps Performed

- `Invoke-Pester` for:
  - `.pipelines/tests/resolveBuildMetadata.Tests.ps1`
  - `.pipelines/tests/writeReleaseMetadata.Tests.ps1`
-
`.github/skills/release-note-generation/tests/preview-release.Tests.ps1`
- 37 tests passed, covering stable-branch preview intent, metadata
contracts, baseline selection, same-lineage and branch-transition
deltas, patch-ID equivalence, managed-body preservation, and
published-release refusal.
- Parsed all added or modified PowerShell scripts with the PowerShell
AST parser.
- Parsed the modified pipeline YAML files with `ConvertFrom-Yaml`.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8e04a72e-3b0f-4ac4-8156-d04ea9b8bb85
Copilot-Session: e9f79ac2-9a7b-4083-834c-0d87e8c83bfd
Copilot-Session: 1ecea747-b313-49a1-9969-543c01ba1be8
2026-08-17 14:47:18 +08:00
Boliang Zhang
bb12277d8d fix(ci): support automatic versions and counter-exhaustion recovery (#49745)
## Summary of the Pull Request

Follow-up to #49414 that fixes two release-pipeline recovery issues:

- Azure DevOps treats an empty runtime string parameter as required, so
`.pipelines/v2/release.yml` now uses `auto` as the default version
override.
- Explicit `main` and `stable` version overrides are resolved before
automatic `YDDDB` generation, allowing a manually versioned build to
proceed after the daily sequence exceeds 9.

## PR Checklist

- [x] **Communication:** This is a follow-up to the reviewed
preview-release versioning design in #49414
- [x] **Tests:** Added/updated and all pass

## Detailed Description of the Pull Request / Additional comments

`auto` is normalized to an empty override in
`.pipelines/resolveBuildMetadata.ps1`, preserving automatic
release-train version generation without requiring input in the Run
Pipeline dialog.

Override parsing is now separated from automatic version generation.
Full explicit versions bypass daily-sequence and generated-date
validation, while automatic versions continue to require a sequence from
1 through 9 and fail closed outside that range.

`.pipelines/tests/resolveBuildMetadata.Tests.ps1` covers scheduled
`main` with the `auto` default, automatic `stable` generation, and
explicit preview/stable recovery when the daily counter has reached 10.

## Validation Steps Performed

- `Invoke-Pester .pipelines\tests\resolveBuildMetadata.Tests.ps1
-EnableExit` — 22 passed
- Confirmed `auto` resolves a first August 7 stable build to
`0.100.2191.0`
- Confirmed explicit `0.101.0` resolves to `0.101.0.0` with daily
sequence 10

Copilot-Session: 8e04a72e-3b0f-4ac4-8156-d04ea9b8bb85
2026-08-07 15:34:29 +08:00
Boliang Zhang
558e633c59 Add preview release versioning and update channel support (#49414)
## 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.

![PowerToys Settings with preview updates disabled by
policy](https://raw.githubusercontent.com/LegendaryBlair/PowerToys/df808630b04e65ba437081aff9401c4efd58e67f/.github/pr-assets/49414/gpo-policy-enforced.png)

### 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.

![PowerToys Settings with the preview-update preference
restored](https://raw.githubusercontent.com/LegendaryBlair/PowerToys/df808630b04e65ba437081aff9401c4efd58e67f/.github/pr-assets/49414/gpo-preference-restored.png)

### 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.

![Disable preview build updates in Local Group Policy
Editor](https://raw.githubusercontent.com/LegendaryBlair/PowerToys/e9e5c12f4480ef895d263460a59982246b7654dc/.github/pr-assets/49414/group-policy-editor-policy-dialog.png)

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ad8b7909-0472-4464-bdee-deaeca726f94
Copilot-Session: 8e04a72e-3b0f-4ac4-8156-d04ea9b8bb85
2026-08-06 23:45:11 +08:00