mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-08-29 10:09:43 +02:00
## 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
219 lines
10 KiB
YAML
219 lines
10 KiB
YAML
trigger: none
|
|
pr: none
|
|
|
|
resources:
|
|
repositories:
|
|
- repository: 1ESPipelineTemplates
|
|
type: git
|
|
name: 1ESPipelineTemplates/1ESPipelineTemplates
|
|
ref: refs/tags/release
|
|
|
|
# Expose all of these parameters for user configuration.
|
|
parameters:
|
|
- name: publishSymbolsToPublic
|
|
displayName: "Publish Symbols to **PUBLIC** (use only for Final Builds)"
|
|
type: boolean
|
|
default: false
|
|
|
|
- name: versionNumber
|
|
displayName: "Version Override ('auto' generates a release-train version)"
|
|
type: string
|
|
default: 'auto'
|
|
|
|
- name: releaseIntent
|
|
displayName: "Release Intent"
|
|
type: string
|
|
default: auto
|
|
values:
|
|
- auto
|
|
- preview-release
|
|
- stable-release
|
|
|
|
- name: buildConfigurations
|
|
displayName: "Build Configurations"
|
|
type: object
|
|
default:
|
|
- Release
|
|
|
|
- name: buildPlatforms
|
|
displayName: "Build Platforms"
|
|
type: object
|
|
default:
|
|
- x64
|
|
- arm64
|
|
|
|
- name: useVSPreview
|
|
type: boolean
|
|
displayName: "Build Using Visual Studio Preview"
|
|
default: false
|
|
|
|
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
|
|
|
|
variables:
|
|
- template: templates/variables-nuget-package-version.yml
|
|
- name: versionDate
|
|
value: $[format('{0:yyyyMMdd}', pipeline.startTime)]
|
|
- ${{ if or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/stable')) }}:
|
|
- name: dailyVersionSequence
|
|
value: $[counter(format('release-{0:yyyyMMdd}', pipeline.startTime), 1)]
|
|
- ${{ else }}:
|
|
- name: dailyVersionSequence
|
|
value: 0
|
|
|
|
extends:
|
|
template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates
|
|
parameters:
|
|
customBuildTags:
|
|
- 1ES.PT.ViaStartRight
|
|
pool:
|
|
name: SHINE-INT-S
|
|
${{ if eq(parameters.useVSPreview, true) }}:
|
|
demands: ImageOverride -equals SHINE-VS18-Preview
|
|
${{ else }}:
|
|
demands: ImageOverride -equals SHINE-VS18-Latest
|
|
os: windows
|
|
sdl:
|
|
tsa:
|
|
enabled: true
|
|
configFile: '$(Build.SourcesDirectory)\.pipelines\tsa.json'
|
|
binskim:
|
|
enabled: true
|
|
# Exclude every dll/exe in tests/*, as well as all msdia*, covrun* and vcruntime*
|
|
analyzeTargetGlob: +:file|$(Build.ArtifactStagingDirectory)/**/*.dll;+:file|$(Build.ArtifactStagingDirectory)/**/*.exe;-:file:regex|tests.*\.(dll|exe)$;-:file:regex|(covrun.*)\.dll$;-:file:regex|(msdia.*)\.dll$;-:file:regex|(vcruntime.*)\.dll$
|
|
|
|
stages:
|
|
- stage: Build
|
|
displayName: Build
|
|
dependsOn: []
|
|
jobs:
|
|
- template: .pipelines/v2/templates/job-build-project.yml@self
|
|
parameters:
|
|
pool:
|
|
name: SHINE-INT-L
|
|
demands:
|
|
# Our INT agents have a large disk mounted at P:\
|
|
- ${{ if eq(parameters.useVSPreview, true) }}:
|
|
- ImageOverride -equals SHINE-VS18-Latest-Preview
|
|
- ${{ else }}:
|
|
- ImageOverride -equals SHINE-VS18-Latest
|
|
os: windows
|
|
variables:
|
|
IsPipeline: 1 # The installer uses this to detect whether it should pick up localizations
|
|
SkipCppCodeAnalysis: 1 # Skip the code analysis to speed up release CI. It runs on PR CI, anyway
|
|
# IsExperimentationLive: 1 # The build and installer use this to turn on experimentation
|
|
buildPlatforms: ${{ parameters.buildPlatforms }}
|
|
buildConfigurations: ${{ parameters.buildConfigurations }}
|
|
versionNumber: ${{ parameters.versionNumber }}
|
|
publishArtifacts: false # 1ES PT handles publication for us.
|
|
official: true
|
|
codeSign: true
|
|
runTests: false
|
|
buildTests: false
|
|
signingIdentity:
|
|
serviceName: $(SigningServiceName)
|
|
appId: $(SigningAppId)
|
|
tenantId: $(SigningTenantId)
|
|
akvName: $(SigningAKVName)
|
|
authCertName: $(SigningAuthCertName)
|
|
signCertName: $(SigningSignCertName)
|
|
useManagedIdentity: $(SigningUseManagedIdentity)
|
|
clientId: $(SigningOriginalClientId)
|
|
# Have msbuild use the release nuget config profile
|
|
additionalBuildOptions: /p:RestoreConfigFile="$(Build.SourcesDirectory)\.pipelines\release-nuget.config" /p:EnableCmdPalAOT=true /p:PhiSilicaLafToken=$(PhiSilicaLafToken) /p:PhiSilicaLafAttestation="$(PhiSilicaLafAttestation)"
|
|
beforeBuildSteps:
|
|
# Install the Terrapin retrieval tool, which replaces vcpkg's download handler
|
|
# to redirect it to a safe Microsoft-controlled location
|
|
- template: .pipelines/v2/templates/steps-install-terrapin.yml@self
|
|
|
|
# Sets versions for all PowerToy created DLLs
|
|
- pwsh: |-
|
|
$metadata = .pipelines/resolveBuildMetadata.ps1 `
|
|
-VersionOverride '${{ parameters.versionNumber }}' `
|
|
-ReleaseIntent '${{ parameters.releaseIntent }}' `
|
|
-BuildDate '$(versionDate)' `
|
|
-DailyVersionSequence '$(dailyVersionSequence)'
|
|
$publishSymbolsToPublic = $${{ parameters.publishSymbolsToPublic }}
|
|
if ($publishSymbolsToPublic -and -not $metadata.AllowPublicSymbols) {
|
|
throw "Public symbols are only supported for manually queued stable-branch releases"
|
|
}
|
|
|
|
.pipelines/versionSetting.ps1 -versionNumber $metadata.Version -DevEnvironment '' -Channel $metadata.Channel
|
|
[xml]$versionProps = Get-Content 'src\Version.props'
|
|
$resolvedVersion = [string]$versionProps.Project.PropertyGroup.Version
|
|
Write-Host "Resolved PowerToys version: $resolvedVersion"
|
|
Write-Host "##vso[task.setvariable variable=ResolvedVersionNumber]$resolvedVersion"
|
|
Write-Host "##vso[task.setvariable variable=EffectiveVersionNumber]$resolvedVersion"
|
|
Write-Host "##vso[task.setvariable variable=ResolvedReleaseChannel]$($metadata.Channel)"
|
|
Write-Host "##vso[task.setvariable variable=ResolvedBuildIntent]$($metadata.Intent)"
|
|
Write-Host "##vso[task.setvariable variable=ShouldPublishPreview]$($metadata.ShouldPublishPreview)"
|
|
displayName: Prepare versioning
|
|
|
|
- pwsh: |-
|
|
$path = Join-Path '$(Build.ArtifactStagingDirectory)' 'release-metadata.json'
|
|
.pipelines/writeReleaseMetadata.ps1 `
|
|
-DefinitionId '$(System.DefinitionId)' `
|
|
-BuildId '$(Build.BuildId)' `
|
|
-BuildNumber '$(Build.BuildNumber)' `
|
|
-Version '$(ResolvedVersionNumber)' `
|
|
-Channel '$(ResolvedReleaseChannel)' `
|
|
-Intent '$(ResolvedBuildIntent)' `
|
|
-SourceBranch '$(Build.SourceBranch)' `
|
|
-SourceCommit '$(Build.SourceVersion)' `
|
|
-BuildReason '$(Build.Reason)' `
|
|
-ShouldPublishPreview '$(ShouldPublishPreview)' `
|
|
-QueuedAt '$(Build.QueuedTime)' `
|
|
-StartedAt '$(System.PipelineStartTime)' `
|
|
-OutputPath $path | Out-Null
|
|
Write-Host "Staged release metadata: $path"
|
|
displayName: Stage release metadata
|
|
|
|
# Prepare the localizations and telemetry config before the release build
|
|
- template: .pipelines/v2/templates/steps-fetch-and-prepare-localizations.yml@self
|
|
|
|
- pwsh: |-
|
|
$ErrorActionPreference = 'Stop'
|
|
$PSNativeCommandUseErrorActionPreference = $true
|
|
& nuget.exe restore -configFile .pipelines/release-nuget.config -PackagesDirectory . .pipelines/packages.config
|
|
Move-Item -Force -Verbose "Microsoft.PowerToys.Telemetry.*\build\include\TraceLoggingDefines.h" "src\common\Telemetry\TraceLoggingDefines.h"
|
|
Move-Item -Force -Verbose "Microsoft.PowerToys.Telemetry.*\build\include\TelemetryBase.cs" "src\common\Telemetry\TelemetryBase.cs"
|
|
displayName: Emplace telemetry files
|
|
|
|
- stage: Build_SDK
|
|
displayName: Build SDK
|
|
dependsOn: []
|
|
jobs:
|
|
- template: .pipelines/v2/templates/job-build-sdk.yml@self
|
|
parameters:
|
|
pool:
|
|
name: SHINE-INT-L
|
|
os: windows
|
|
official: true
|
|
codeSign: true
|
|
signingIdentity:
|
|
serviceName: $(SigningServiceName)
|
|
appId: $(SigningAppId)
|
|
tenantId: $(SigningTenantId)
|
|
akvName: $(SigningAKVName)
|
|
authCertName: $(SigningAuthCertName)
|
|
signCertName: $(SigningSignCertName)
|
|
useManagedIdentity: $(SigningUseManagedIdentity)
|
|
clientId: $(SigningOriginalClientId)
|
|
beforeBuildSteps:
|
|
# Install the Terrapin retrieval tool, which replaces vcpkg's download handler
|
|
# to redirect it to a safe Microsoft-controlled location
|
|
- template: .pipelines/v2/templates/steps-install-terrapin.yml@self
|
|
|
|
- stage: Publish
|
|
displayName: Publish
|
|
dependsOn: [Build]
|
|
jobs:
|
|
- template: .pipelines/v2/templates/job-publish-symbols-using-symbolrequestprod-api.yml@self
|
|
parameters:
|
|
versionNumber: ${{ parameters.versionNumber }}
|
|
releaseIntent: ${{ parameters.releaseIntent }}
|
|
includePublicSymbolServer: ${{ parameters.publishSymbolsToPublic }}
|
|
${{ if ne(parameters.publishSymbolsToPublic, true) }}:
|
|
symbolExpiryTime: 10 # For private builds, expire symbols within 10 days. The default is 100 years.
|
|
subscription: $(SymbolPublishingServiceConnection)
|
|
symbolProject: $(SymbolPublishingProject)
|