mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-10 21:41:51 +02:00
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request This pull request introduces an "artifact-based" mode for consuming the Windows App SDK in CI pipelines, allowing builds to use NuGet packages directly from Azure DevOps pipeline artifacts instead of public/internal feeds. This is achieved by adding new parameters and logic to pipeline YAML and PowerShell scripts, supporting scenarios where packages are not yet published to a feed. The changes also improve robustness when updating package versions and add documentation for authentication requirements. These changes make the pipeline more flexible and robust, enabling builds to consume unreleased or pre-release packages directly from CI artifacts, which is especially useful for testing and validation scenarios. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [ ] Closes: #xxx <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [x] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed
661 lines
26 KiB
YAML
661 lines
26 KiB
YAML
parameters:
|
|
- name: additionalBuildOptions
|
|
type: string
|
|
default: ''
|
|
- name: buildConfigurations
|
|
type: object
|
|
default:
|
|
- Release
|
|
- name: buildPlatforms
|
|
type: object
|
|
default:
|
|
- x64
|
|
- arm64
|
|
- name: official
|
|
type: boolean
|
|
default: false
|
|
- name: codeSign
|
|
type: boolean
|
|
default: false
|
|
- name: artifactStem
|
|
type: string
|
|
default: ''
|
|
- name: jobName
|
|
type: string
|
|
default: 'Build'
|
|
- name: condition
|
|
type: string
|
|
default: ''
|
|
- name: dependsOn
|
|
type: object
|
|
default: []
|
|
- name: pool
|
|
type: object
|
|
default: []
|
|
- name: beforeBuildSteps
|
|
type: stepList
|
|
default: []
|
|
- name: variables
|
|
type: object
|
|
default: {}
|
|
- name: publishArtifacts
|
|
type: boolean
|
|
default: true
|
|
- name: signingIdentity
|
|
type: object
|
|
default: {}
|
|
- name: enablePackageCaching
|
|
type: boolean
|
|
default: false
|
|
- name: enableMsBuildCaching
|
|
type: boolean
|
|
default: false
|
|
- name: msBuildCacheIsReadOnly
|
|
type: boolean
|
|
default: true
|
|
- name: runTests
|
|
type: boolean
|
|
default: true
|
|
- name: buildTests
|
|
type: boolean
|
|
default: true
|
|
- name: useVSPreview
|
|
type: boolean
|
|
default: false
|
|
- name: versionNumber
|
|
type: string
|
|
default: '0.0.1'
|
|
- name: useLatestWinAppSDK
|
|
type: boolean
|
|
default: false
|
|
- name: winAppSDKVersionNumber
|
|
type: string
|
|
default: 1.6
|
|
- name: useExperimentalVersion
|
|
type: boolean
|
|
default: false
|
|
# Artifact mode parameters
|
|
- name: useArtifactSource
|
|
type: boolean
|
|
default: false
|
|
- name: azureDevOpsOrg
|
|
type: string
|
|
default: 'https://dev.azure.com/microsoft'
|
|
- name: azureDevOpsProject
|
|
type: string
|
|
default: 'ProjectReunion'
|
|
- name: buildId
|
|
type: string
|
|
default: ''
|
|
- name: artifactName
|
|
type: string
|
|
default: 'WindowsAppSDK_Nuget_And_MSIX'
|
|
- name: metaPackageName
|
|
type: string
|
|
default: 'Microsoft.WindowsAppSDK'
|
|
- name: csProjectsToPublish
|
|
type: object
|
|
default:
|
|
- 'src/settings-ui/Settings.UI/PowerToys.Settings.csproj'
|
|
- 'src/modules/launcher/PowerLauncher/PowerLauncher.csproj'
|
|
- 'src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandler.csproj'
|
|
- 'src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.csproj'
|
|
- 'src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj'
|
|
- 'src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.csproj'
|
|
- 'src/modules/FileLocksmith/FileLocksmithUI/FileLocksmithUI.csproj'
|
|
- name: timeoutInMinutes
|
|
type: number
|
|
default: 240
|
|
- name: cancelTimeoutInMinutes
|
|
type: number
|
|
default: 1
|
|
|
|
jobs:
|
|
- job: ${{ parameters.jobName }}
|
|
${{ if ne(length(parameters.pool), 0) }}:
|
|
pool: ${{ parameters.pool }}
|
|
dependsOn: ${{ parameters.dependsOn }}
|
|
condition: ${{ parameters.condition }}
|
|
strategy:
|
|
matrix:
|
|
${{ each config in parameters.buildConfigurations }}:
|
|
${{ each platform in parameters.buildPlatforms }}:
|
|
${{ config }}_${{ platform }}:
|
|
BuildConfiguration: ${{ config }}
|
|
BuildPlatform: ${{ platform }}
|
|
${{ if eq(platform, 'x86') }}:
|
|
OutputBuildPlatform: Win32
|
|
${{ elseif eq(platform, 'Any CPU') }}:
|
|
OutputBuildPlatform: AnyCPU
|
|
${{ else }}:
|
|
OutputBuildPlatform: ${{ platform }}
|
|
variables:
|
|
NUGET_PACKAGES: 'C:\NuGetPackages' # Some of our build steps cache these here... and it was apparently part of the global environment
|
|
MakeAppxPath: 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x86\MakeAppx.exe'
|
|
# Azure DevOps abhors a vacuum
|
|
# If these are blank, expansion will fail later on... which will result in direct substitution of the variable *names*
|
|
# later on. We'll just... set them to a single space and if we need to, check IsNullOrWhiteSpace.
|
|
# Yup.
|
|
MSBuildCacheParameters: ' '
|
|
JobOutputDirectory: $(Build.ArtifactStagingDirectory)
|
|
LogOutputDirectory: $(Build.ArtifactStagingDirectory)\logs
|
|
JobOutputArtifactName: build-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}
|
|
NUGET_RESTORE_MSBUILD_ARGS: /p:Platform=$(BuildPlatform) # Required for nuget to work due to self contained
|
|
NODE_OPTIONS: --max_old_space_size=16384
|
|
${{ if or(eq(parameters.runTests, true), eq(parameters.buildTests, true)) }}:
|
|
MSBuildMainBuildTargets: Build;Test
|
|
${{ else }}:
|
|
MSBuildMainBuildTargets: Build
|
|
${{ insert }}: ${{ parameters.variables }}
|
|
${{ if eq(parameters.useLatestWinAppSDK, true) }}:
|
|
RestoreAdditionalProjectSourcesArg: '/p:RestoreAdditionalProjectSources="$(Build.SourcesDirectory)\localpackages\NugetPackages" /p:IgnoreExperimentalWarnings=true'
|
|
${{ else }}:
|
|
RestoreAdditionalProjectSourcesArg: ''
|
|
displayName: Build
|
|
timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
|
|
cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }}
|
|
templateContext: # Required when this template is hosted in 1ES PT
|
|
outputs:
|
|
- output: pipelineArtifact
|
|
artifactName: $(JobOutputArtifactName)
|
|
targetPath: $(Build.ArtifactStagingDirectory)
|
|
- output: pipelineArtifact
|
|
artifactName: $(JobOutputArtifactName)-failure-$(System.JobAttempt)
|
|
targetPath: $(LogOutputDirectory)
|
|
condition: or(failed(), canceled())
|
|
steps:
|
|
- checkout: self
|
|
clean: true
|
|
submodules: true
|
|
persistCredentials: True
|
|
fetchTags: false
|
|
fetchDepth: 1
|
|
|
|
- ${{ if eq(parameters.enableMsBuildCaching, true) }}:
|
|
- pwsh: |-
|
|
$MSBuildCacheParameters = ""
|
|
$MSBuildCacheParameters += " -graph"
|
|
$MSBuildCacheParameters += " -reportfileaccesses"
|
|
$MSBuildCacheParameters += " -p:MSBuildCacheEnabled=true"
|
|
$MSBuildCacheParameters += " -p:MSBuildCacheLogDirectory=$(LogOutputDirectory)\MSBuildCacheLogs"
|
|
# Cache read-only policy controlled by parameter
|
|
$cacheIsReadOnly = "${{ parameters.msBuildCacheIsReadOnly }}"
|
|
if ($cacheIsReadOnly -eq "True") {
|
|
$MSBuildCacheParameters += " /p:MSBuildCacheRemoteCacheIsReadOnly=true"
|
|
}
|
|
Write-Host "MSBuildCacheParameters: $MSBuildCacheParameters"
|
|
Write-Host "##vso[task.setvariable variable=MSBuildCacheParameters]$MSBuildCacheParameters"
|
|
displayName: Prepare MSBuildCache variables
|
|
|
|
- template: steps-ensure-dotnet-version.yml
|
|
parameters:
|
|
sdk: true
|
|
version: '6.0' # .NET 6.0 is required in CI for ESRP code signing tasks. Please do not remove.
|
|
|
|
- template: steps-ensure-dotnet-version.yml
|
|
parameters:
|
|
sdk: true
|
|
version: '8.0'
|
|
|
|
- template: steps-ensure-dotnet-version.yml
|
|
parameters:
|
|
sdk: true
|
|
version: '9.0'
|
|
|
|
- ${{ if eq(parameters.runTests, true) }}:
|
|
- task: VisualStudioTestPlatformInstaller@1
|
|
displayName: Ensure VSTest Platform
|
|
|
|
- pwsh: |-
|
|
& '.pipelines/applyXamlStyling.ps1' -Passive
|
|
displayName: Verify XAML formatting
|
|
|
|
- pwsh: |-
|
|
& '.pipelines/verifyNugetPackages.ps1' -solution '$(build.sourcesdirectory)\PowerToys.slnx'
|
|
displayName: Verify Nuget package versions for PowerToys.slnx
|
|
|
|
- pwsh: |-
|
|
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\PowerToys.slnx'
|
|
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\tools\BugReportTool\BugReportTool.sln'
|
|
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\tools\StylesReportTool\StylesReportTool.sln'
|
|
& '.pipelines/verifyArm64Configuration.ps1' -solution '$(build.sourcesdirectory)\installer\PowerToysSetup.slnx'
|
|
displayName: Verify ARM64 configurations
|
|
|
|
- ${{ if eq(parameters.enablePackageCaching, true) }}:
|
|
- task: Cache@2
|
|
displayName: 'Cache nuget packages (PackageReference)'
|
|
inputs:
|
|
key: '"PackageReference" | "$(Agent.OS)" | Directory.Packages.props'
|
|
restoreKeys: |
|
|
"PackageReference" | "$(Agent.OS)"
|
|
"PackageReference"
|
|
path: $(NUGET_PACKAGES)
|
|
|
|
- task: Cache@2
|
|
displayName: 'Cache nuget packages (packages.config)'
|
|
inputs:
|
|
key: '"packages.config" | "$(Agent.OS)" | **/packages.config'
|
|
restoreKeys: |
|
|
"packages.config" | "$(Agent.OS)"
|
|
"packages.config"
|
|
path: packages
|
|
|
|
- ${{ if eq(parameters.useLatestWinAppSDK, true)}}:
|
|
- template: .\steps-update-winappsdk-and-restore-nuget.yml
|
|
parameters:
|
|
versionNumber: ${{ parameters.winAppSDKVersionNumber }}
|
|
useExperimentalVersion: ${{ parameters.useExperimentalVersion }}
|
|
useArtifactSource: ${{ parameters.useArtifactSource }}
|
|
azureDevOpsOrg: ${{ parameters.azureDevOpsOrg }}
|
|
azureDevOpsProject: ${{ parameters.azureDevOpsProject }}
|
|
buildId: ${{ parameters.buildId }}
|
|
artifactName: ${{ parameters.artifactName }}
|
|
metaPackageName: ${{ parameters.metaPackageName }}
|
|
|
|
- ${{ if eq(parameters.useLatestWinAppSDK, false)}}:
|
|
- template: .\steps-restore-nuget.yml
|
|
|
|
- pwsh: |-
|
|
& "$(build.sourcesdirectory)\.pipelines\verifyAndSetLatestVCToolsVersion.ps1"
|
|
displayName: Work around DD-1541167 (VCToolsVersion)
|
|
${{ if eq(parameters.useVSPreview, true) }}:
|
|
env:
|
|
VCWhereExtraVersionTarget: '-prerelease'
|
|
|
|
- ${{ if eq(parameters.official, true) }}:
|
|
- template: .\steps-setup-versioning.yml
|
|
parameters:
|
|
directory: $(build.sourcesdirectory)\src\modules\cmdpal
|
|
|
|
|
|
|
|
- ${{ parameters.beforeBuildSteps }}
|
|
|
|
- task: VSBuild@1
|
|
${{ if eq(parameters.runTests, true) }}:
|
|
displayName: Build and Test PowerToys main project
|
|
${{ else }}:
|
|
displayName: Build PowerToys main project
|
|
inputs:
|
|
solution: 'PowerToys.slnx'
|
|
vsVersion: 18.0
|
|
msbuildArgs: >-
|
|
-restore -graph
|
|
/p:RestorePackagesConfig=true
|
|
/p:CIBuild=true
|
|
/p:BuildTests=${{ parameters.buildTests }}
|
|
/bl:$(LogOutputDirectory)\build-0-main.binlog
|
|
${{ parameters.additionalBuildOptions }}
|
|
$(MSBuildCacheParameters)
|
|
/t:$(MSBuildMainBuildTargets)
|
|
$(RestoreAdditionalProjectSourcesArg)
|
|
platform: $(BuildPlatform)
|
|
configuration: $(BuildConfiguration)
|
|
msbuildArchitecture: x64
|
|
maximumCpuCount: true
|
|
${{ if eq(parameters.enableMsBuildCaching, true) }}:
|
|
env:
|
|
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
|
|
|
- task: VSBuild@1
|
|
displayName: Generate DSC artifacts for ARM64
|
|
condition: and(succeeded(), eq(variables['BuildPlatform'], 'arm64'))
|
|
inputs:
|
|
solution: PowerToys.slnx
|
|
vsVersion: 18.0
|
|
msbuildArgs: >-
|
|
-restore
|
|
/p:Configuration=$(BuildConfiguration)
|
|
/p:Platform=x64
|
|
/t:DSC\PowerToys_Settings_DSC_Schema_Generator
|
|
/bl:$(LogOutputDirectory)\build-dsc-generator.binlog
|
|
${{ parameters.additionalBuildOptions }}
|
|
$(MSBuildCacheParameters)
|
|
$(RestoreAdditionalProjectSourcesArg)
|
|
platform: x64
|
|
configuration: $(BuildConfiguration)
|
|
msbuildArchitecture: x64
|
|
maximumCpuCount: true
|
|
|
|
# Build PowerToys.DSC.exe for ARM64 (x64 uses existing binary from previous build)
|
|
- task: VSBuild@1
|
|
displayName: Build PowerToys.DSC.exe (x64 for generating manifests)
|
|
condition: and(succeeded(), ne(variables['BuildPlatform'], 'x64'))
|
|
inputs:
|
|
solution: src/dsc/v3/PowerToys.DSC/PowerToys.DSC.csproj
|
|
msbuildArgs: /t:Build /m /restore
|
|
platform: x64
|
|
configuration: $(BuildConfiguration)
|
|
msbuildArchitecture: x64
|
|
maximumCpuCount: true
|
|
|
|
# Generate DSC manifests using PowerToys.DSC.exe
|
|
- pwsh: |-
|
|
& '.pipelines/generateDscManifests.ps1' -BuildPlatform '$(BuildPlatform)' -BuildConfiguration '$(BuildConfiguration)' -RepoRoot '$(Build.SourcesDirectory)'
|
|
displayName: Generate DSC manifests
|
|
|
|
- task: CopyFiles@2
|
|
displayName: Stage SDK/build
|
|
inputs:
|
|
contents: |-
|
|
"**/cmdpal/extensionsdk/nuget/Microsoft.CommandPalette.Extensions.SDK.props"
|
|
"**/cmdpal/extensionsdk/nuget/Microsoft.CommandPalette.Extensions.SDK.targets"
|
|
flattenFolders: True
|
|
targetFolder: $(JobOutputDirectory)/sdk/build
|
|
|
|
- task: CopyFiles@2
|
|
displayName: Stage SDK/lib
|
|
inputs:
|
|
contents: |-
|
|
"**/Microsoft.CommandPalette.Extensions.Toolkit/$(BuildPlatform)/release/WinUI3Apps/CmdPal/Microsoft.CommandPalette.Extensions.Toolkit.dll"
|
|
"**/Microsoft.CommandPalette.Extensions.Toolkit/$(BuildPlatform)/release/WinUI3Apps/CmdPal/Microsoft.CommandPalette.Extensions.Toolkit.deps.json"
|
|
flattenFolders: True
|
|
targetFolder: $(JobOutputDirectory)/sdk/lib/net8.0-windows10.0.19041.0
|
|
|
|
- task: CopyFiles@2
|
|
displayName: Stage SDK/winmd
|
|
inputs:
|
|
contents: |-
|
|
"**/Microsoft.CommandPalette.Extensions/$(BuildPlatform)/release/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.winmd"
|
|
flattenFolders: True
|
|
targetFolder: $(JobOutputDirectory)/sdk/winmd
|
|
|
|
- task: VSBuild@1
|
|
displayName: Build BugReportTool
|
|
inputs:
|
|
solution: '**/tools/BugReportTool/BugReportTool.sln'
|
|
vsVersion: 18.0
|
|
msbuildArgs: >-
|
|
-restore -graph
|
|
/p:RestorePackagesConfig=true
|
|
/p:CIBuild=true
|
|
/bl:$(LogOutputDirectory)\build-bug-report.binlog
|
|
${{ parameters.additionalBuildOptions }}
|
|
$(MSBuildCacheParameters)
|
|
$(RestoreAdditionalProjectSourcesArg)
|
|
platform: $(BuildPlatform)
|
|
configuration: $(BuildConfiguration)
|
|
msbuildArchitecture: x64
|
|
maximumCpuCount: true
|
|
${{ if eq(parameters.enableMsBuildCaching, true) }}:
|
|
env:
|
|
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
|
|
|
- task: VSBuild@1
|
|
displayName: Build StylesReportTool
|
|
inputs:
|
|
solution: '**/tools/StylesReportTool/StylesReportTool.sln'
|
|
vsVersion: 18.0
|
|
msbuildArgs: >-
|
|
-restore -graph
|
|
/p:RestorePackagesConfig=true
|
|
/p:CIBuild=true
|
|
/bl:$(LogOutputDirectory)\build-styles-report.binlog
|
|
${{ parameters.additionalBuildOptions }}
|
|
$(MSBuildCacheParameters)
|
|
$(RestoreAdditionalProjectSourcesArg)
|
|
platform: $(BuildPlatform)
|
|
configuration: $(BuildConfiguration)
|
|
msbuildArchitecture: x64
|
|
maximumCpuCount: true
|
|
${{ if eq(parameters.enableMsBuildCaching, true) }}:
|
|
env:
|
|
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
|
|
|
- ${{ each project in parameters.csProjectsToPublish }}:
|
|
- task: VSBuild@1
|
|
displayName: Publish ${{ project }} for Packaging
|
|
inputs:
|
|
solution: ${{ project }}
|
|
vsVersion: 18.0
|
|
msbuildArgs: >-
|
|
/target:Publish
|
|
/graph
|
|
/p:Configuration=$(BuildConfiguration);Platform=$(BuildPlatform);AppxBundle=Never
|
|
/p:VCRTForwarders-IncludeDebugCRT=false
|
|
/p:PowerToysRoot=$(Build.SourcesDirectory)
|
|
/p:PublishProfile=InstallationPublishProfile.pubxml
|
|
/p:TargetFramework=net9.0-windows10.0.26100.0
|
|
/bl:$(LogOutputDirectory)\publish-${{ join('_',split(project, '/')) }}.binlog
|
|
$(RestoreAdditionalProjectSourcesArg)
|
|
platform: $(BuildPlatform)
|
|
configuration: $(BuildConfiguration)
|
|
msbuildArchitecture: x64
|
|
maximumCpuCount: true
|
|
|
|
### HACK: On ARM64 builds, building an app with Windows App SDK copies the x64 WebView2 dll instead of the ARM64 one. This task makes sure the right dll is used.
|
|
- task: CopyFiles@2
|
|
displayName: HACK Copy core WebView2 ARM64 dll to output directory
|
|
condition: and(succeeded(), eq(variables['BuildPlatform'], 'arm64'))
|
|
inputs:
|
|
contents: packages/Microsoft.Web.WebView2.1.0.2903.40/runtimes/win-ARM64/native_uap/Microsoft.Web.WebView2.Core.dll
|
|
targetFolder: $(Build.SourcesDirectory)/ARM64/Release/WinUI3Apps/
|
|
flattenFolders: True
|
|
OverWrite: True
|
|
|
|
# Check if all projects (located in src sub-folder) import common props
|
|
- pwsh: |-
|
|
& '.pipelines/verifyCommonProps.ps1' -sourceDir '$(build.sourcesdirectory)\src'
|
|
displayName: Audit shared common props for CSharp projects in src sub-folder
|
|
|
|
# Check if deps.json files don't reference different dll versions.
|
|
- pwsh: |-
|
|
& '.pipelines/verifyDepsJsonLibraryVersions.ps1' -targetDir '$(build.sourcesdirectory)\$(BuildPlatform)\$(BuildConfiguration)'
|
|
displayName: Audit deps.json files for all applications
|
|
|
|
# Check if asset files on the main application paths are playing nice and avoiding basic conflicts.
|
|
- pwsh: |-
|
|
& '.pipelines/verifyPossibleAssetConflicts.ps1' -targetDir '$(build.sourcesdirectory)\$(BuildPlatform)\$(BuildConfiguration)'
|
|
displayName: Audit base applications path asset conflicts
|
|
|
|
- pwsh: |-
|
|
& '.pipelines/verifyPossibleAssetConflicts.ps1' -targetDir '$(build.sourcesdirectory)\$(BuildPlatform)\$(BuildConfiguration)\WinUI3Apps'
|
|
displayName: Audit WinAppSDK applications path asset conflicts
|
|
|
|
# To streamline the pipeline and prevent errors, skip this step during compatibility tests with the latest WinAppSDK.
|
|
- ${{ if eq(parameters.useLatestWinAppSDK, false) }}:
|
|
- pwsh: |-
|
|
& '.pipelines/verifyNoticeMdAgainstNugetPackages.ps1' -path '$(build.sourcesdirectory)\'
|
|
displayName: Verify NOTICE.md and NuGet packages match
|
|
|
|
- ${{ if eq(parameters.runTests, true) }}:
|
|
# Publish test results which ran in MSBuild
|
|
- task: PublishTestResults@2
|
|
displayName: 'Publish Test Results'
|
|
inputs:
|
|
testResultsFormat: VSTest
|
|
testResultsFiles: '**/*.trx'
|
|
condition: and(succeeded(), ne(variables['BuildPlatform'], 'arm64'))
|
|
|
|
# Native dlls
|
|
- task: VSTest@2
|
|
condition: and(succeeded(), ne(variables['BuildPlatform'], 'arm64')) # No arm64 agents to run the tests.
|
|
displayName: 'Native Tests'
|
|
inputs:
|
|
platform: '$(BuildPlatform)'
|
|
configuration: '$(BuildConfiguration)'
|
|
testSelector: 'testAssemblies'
|
|
testAssemblyVer2: |
|
|
**\KeyboardManagerEngineTest.dll
|
|
**\KeyboardManagerEditorTest.dll
|
|
**\*UnitTest*.dll
|
|
!**\obj\**
|
|
|
|
- pwsh: |-
|
|
$Packages = Get-ChildItem -Recurse -Filter "Microsoft.CmdPal.UI_*.msix"
|
|
Write-Host "Found $($Packages.Count) CmdPal MSIX package(s):"
|
|
foreach ($pkg in $Packages) {
|
|
Write-Host " - $($pkg.FullName)"
|
|
}
|
|
|
|
if ($Packages.Count -gt 0) {
|
|
# Priority: Look for platform-specific MSIX (x64/arm64) first, then fall back to any
|
|
$PlatformPackage = $Packages | Where-Object { $_.Name -match "Microsoft\.CmdPal\.UI_.*_(x64|arm64)\.msix$" } | Select-Object -First 1
|
|
if ($PlatformPackage) {
|
|
$Package = $PlatformPackage
|
|
Write-Host "Using platform-specific package: $($Package.FullName)"
|
|
} else {
|
|
$Package = $Packages | Select-Object -First 1
|
|
Write-Host "Using first available package: $($Package.FullName)"
|
|
}
|
|
|
|
$PackageFilename = $Package.FullName
|
|
Write-Host "##vso[task.setvariable variable=CmdPalPackagePath]${PackageFilename}"
|
|
} else {
|
|
Write-Warning "No CmdPal MSIX packages found!"
|
|
}
|
|
displayName: Locate the CmdPal MSIX
|
|
|
|
- ${{ if eq(parameters.codeSign, true) }}:
|
|
- pwsh: |-
|
|
& "$(MakeAppxPath)" unpack /p "$(CmdPalPackagePath)" /d "$(JobOutputDirectory)/CmdPalPackageContents"
|
|
displayName: Unpack the MSIX for signing
|
|
|
|
- template: steps-esrp-signing.yml
|
|
parameters:
|
|
displayName: Sign CmdPal MSIX content
|
|
signingIdentity: ${{ parameters.signingIdentity }}
|
|
inputs:
|
|
FolderPath: '$(JobOutputDirectory)/CmdPalPackageContents'
|
|
signType: batchSigning
|
|
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_cmdpal_msix_content.json'
|
|
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
|
|
|
|
- pwsh: |-
|
|
$outDir = New-Item -Type Directory "$(JobOutputDirectory)/_appx" -ErrorAction:Ignore
|
|
$PackageFilename = Join-Path $outDir.FullName (Split-Path -Leaf "$(CmdPalPackagePath)")
|
|
& "$(MakeAppxPath)" pack /h SHA256 /o /p $PackageFilename /d "$(JobOutputDirectory)/CmdPalPackageContents"
|
|
Copy-Item -Force $PackageFilename "$(CmdPalPackagePath)"
|
|
Remove-Item -Force -Recurse "$(JobOutputDirectory)/CmdPalPackageContents" -ErrorAction:Ignore
|
|
Remove-Item -Force -Recurse "$(JobOutputDirectory)/_appx" -ErrorAction:Ignore
|
|
displayName: Re-pack the new CmdPal package after signing
|
|
|
|
- pwsh: |
|
|
$testsPath = "$(Build.SourcesDirectory)/$(BuildPlatform)/$(BuildConfiguration)/tests"
|
|
if (Test-Path $testsPath) {
|
|
Remove-Item -Path $testsPath -Recurse -Force
|
|
Write-Host "Removed tests folder to reduce signing workload: $testsPath"
|
|
}
|
|
displayName: Remove tests folder before signing
|
|
|
|
- template: steps-esrp-signing.yml
|
|
parameters:
|
|
displayName: Sign Core PowerToys
|
|
signingIdentity: ${{ parameters.signingIdentity }}
|
|
inputs:
|
|
FolderPath: '$(BuildPlatform)/$(BuildConfiguration)'
|
|
signType: batchSigning
|
|
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_core.json'
|
|
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
|
|
|
|
- template: steps-esrp-signing.yml
|
|
parameters:
|
|
displayName: Sign DSC files
|
|
signingIdentity: ${{ parameters.signingIdentity }}
|
|
inputs:
|
|
FolderPath: 'src/dsc/Microsoft.PowerToys.Configure'
|
|
signType: batchSigning
|
|
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_DSC.json'
|
|
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
|
|
|
|
- pwsh: |-
|
|
Copy-Item -Verbose -Force "$(CmdPalPackagePath)" "$(JobOutputDirectory)"
|
|
displayName: Stage the final CmdPal package
|
|
|
|
|
|
|
|
- template: steps-build-installer-vnext.yml
|
|
parameters:
|
|
codeSign: ${{ parameters.codeSign }}
|
|
signingIdentity: ${{ parameters.signingIdentity }}
|
|
versionNumber: ${{ parameters.versionNumber }}
|
|
additionalBuildOptions: ${{ parameters.additionalBuildOptions }}
|
|
|
|
# This saves ~1GiB per architecture. We won't need these later.
|
|
# Removes:
|
|
# - All .pdb files from any static libs .libs (which were only used during linking)
|
|
- pwsh: |-
|
|
$binDir = '$(Build.SourcesDirectory)'
|
|
$ImportLibs = Get-ChildItem $binDir -Recurse -File -Filter '*.exp' | ForEach-Object { $_.FullName -Replace "exp$","lib" }
|
|
$StaticLibs = Get-ChildItem $binDir -Recurse -File -Filter '*.lib' | Where-Object FullName -NotIn $ImportLibs
|
|
|
|
$Items = @()
|
|
$Items += Get-Item ($StaticLibs.FullName -Replace "lib$","pdb") -ErrorAction:Ignore
|
|
|
|
$Items | Remove-Item -Recurse -Force -Verbose -ErrorAction:Ignore
|
|
displayName: Clean up static libs PDBs
|
|
errorActionPreference: silentlyContinue # It's OK if this silently fails
|
|
|
|
- task: CopyFiles@2
|
|
displayName: Stage Installers
|
|
inputs:
|
|
contents: |-
|
|
**/PowerToys*Setup-*.exe
|
|
!**/PowerToysSetupVNext/obj/**
|
|
flattenFolders: True
|
|
targetFolder: $(JobOutputDirectory)
|
|
|
|
- pwsh: |-
|
|
$Symbols = Get-ChildItem "$(BuildPlatform)" -Recurse -Filter *.pdb -Exclude "vc143.pdb","*test*.pdb" |
|
|
Group-Object Name | ForEach-Object { $_.Group[0] }
|
|
$OutDir = "$(JobOutputDirectory)/symbols-$(BuildPlatform)"
|
|
New-Item -Type Directory $OutDir -EA:Ignore
|
|
Write-Host "Linking $($Symbols.Length) symbols into place at $OutDir"
|
|
ForEach($s in $Symbols) {
|
|
New-Item -Type HardLink -Target $s.FullName (Join-Path $OutDir $s.Name)
|
|
}
|
|
displayName: Stage Unique Symbols (as hard links)
|
|
|
|
- pwsh: |-
|
|
$p = "$(JobOutputDirectory)\"
|
|
|
|
# Calculate hashes for installers
|
|
$userSetupFiles = Get-ChildItem -Path $p -Filter "PowerToysUserSetup*.exe"
|
|
$machineSetupFiles = Get-ChildItem -Path $p -Filter "PowerToysSetup*.exe" | Where-Object { $_.Name -notmatch "PowerToysUserSetup" }
|
|
|
|
if ($userSetupFiles.Count -gt 0) {
|
|
$userHash = ($userSetupFiles[0] | Get-FileHash).Hash;
|
|
$userPlat = "hash_user_$(BuildPlatform).txt";
|
|
$combinedUserPath = $p + $userPlat;
|
|
echo "User: $userHash"
|
|
$userHash | out-file -filepath $combinedUserPath
|
|
}
|
|
|
|
if ($machineSetupFiles.Count -gt 0) {
|
|
$machineHash = ($machineSetupFiles[0] | Get-FileHash).Hash;
|
|
$machinePlat = "hash_machine_$(BuildPlatform).txt";
|
|
$combinedMachinePath = $p + $machinePlat;
|
|
echo "Machine: $machineHash"
|
|
$machineHash | out-file -filepath $combinedMachinePath
|
|
}
|
|
displayName: Calculate file hashes for all installers
|
|
|
|
# Publishing the GPO files
|
|
- pwsh: |-
|
|
$GpoArchive = "$(JobOutputDirectory)\GroupPolicyObjectFiles-${{ parameters.versionNumber }}.zip"
|
|
tar -c -v --format=zip -C .\src\gpo\assets -f $GpoArchive *
|
|
displayName: Stage GPO files
|
|
|
|
- ${{ if or(eq(parameters.runTests, true), eq(parameters.buildTests, true)) }}:
|
|
# Running the tests may result in future jobs consuming artifacts out of this build
|
|
# Instead of running an expensive file copy step, move everything over since the build is totally done.
|
|
- pwsh: |-
|
|
# It seems weird, but this is for compatibility. Our artifacts historically contained the folder x64/Release/x64/Release (for example).
|
|
$FinalOutputRoot = "$(JobOutputDirectory)\$(BuildPlatform)\$(BuildConfiguration)\$(BuildPlatform)"
|
|
$ProjectBuildRoot = "$(Build.SourcesDirectory)\$(BuildPlatform)"
|
|
$ProjectBuildDirectory = "$ProjectBuildRoot\$(BuildConfiguration)"
|
|
|
|
New-Item -Type Directory $FinalOutputRoot -EA:Ignore
|
|
Move-Item $ProjectBuildDirectory $FinalOutputRoot
|
|
displayName: Move entire output directory into artifacts
|
|
|
|
- ${{ if eq(parameters.publishArtifacts, true) }}:
|
|
- publish: $(JobOutputDirectory)
|
|
artifact: $(JobOutputArtifactName)
|
|
displayName: Publish all outputs
|
|
condition: succeeded()
|
|
|
|
- publish: $(JobOutputDirectory)
|
|
artifact: $(JobOutputArtifactName)-failure-$(System.JobAttempt)
|
|
displayName: Publish failure logs
|
|
condition: or(failed(), canceled()) |