mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 11:17:53 +01: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 Background: The current PowerToys installer is built using Wix3, which has now been deprecated. To improve security, service quality, and community support, we’re upgrading the installer to Wix5. Implementation: Created Wix5-based projects(PowerToysSetupVext and PowerToysSetupCustomActionsVNext) within the installer while retaining the existing Wix3 project. Both versions are built to generate separate installation packages. The Wix3-related code will be removed after successful release testing confirms no issues. Special case: Wix5 has removed the property for 'ShowFilesInUse'. Now, whenever a file is in use during installation, a FilesInUse pop-upwill automatically appear asking for the next step. To ensure this doesn't interfere with scenarios that require silent installation (e.g. Winget method), we’ve handled it using the bafunction approach. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [ ] Closes: #xxx - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **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 --------- Co-authored-by: Jerry Xu <n.xu@outlook.com> Co-authored-by: Kai Tao <69313318+vanzue@users.noreply.github.com> Co-authored-by: leileizhang <leilzh@microsoft.com> Co-authored-by: Kai Tao (from Dev Box) <kaitao@microsoft.com> Co-authored-by: vanzue <vanzue@outlook.com>
209 lines
9.4 KiB
YAML
209 lines
9.4 KiB
YAML
parameters:
|
|
- name: versionNumber
|
|
type: string
|
|
default: "0.0.1"
|
|
- name: buildUserInstaller
|
|
type: boolean
|
|
default: false
|
|
- name: codeSign
|
|
type: boolean
|
|
default: false
|
|
- name: signingIdentity
|
|
type: object
|
|
default: {}
|
|
- name: additionalBuildOptions
|
|
type: string
|
|
default: ''
|
|
- name: installerSuffix
|
|
type: string
|
|
default: "wix5"
|
|
|
|
steps:
|
|
# Install WiX 5.0.2 tools needed for VNext installer (matching project SDK)
|
|
- task: DotNetCoreCLI@2
|
|
displayName: Install WiX 5.0.2 tools
|
|
inputs:
|
|
command: 'custom'
|
|
custom: 'tool'
|
|
arguments: 'install --global wix --version 5.0.2'
|
|
|
|
- pwsh: |-
|
|
& git clean -xfd -e *exe -- .\installer\
|
|
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Clean installer to reduce cross-contamination
|
|
|
|
- pwsh: |-
|
|
# Determine whether this is a per-user build
|
|
$IsPerUser = $${{ parameters.buildUserInstaller }}
|
|
|
|
# Build slug used to locate the artifacts
|
|
$InstallerBuildSlug = if ($IsPerUser) { 'UserSetup' } else { 'MachineSetup' }
|
|
|
|
# VNext bundle folder; base name intentionally omits the VNext suffix
|
|
$InstallerFolder = 'PowerToysSetupVNext'
|
|
if ($IsPerUser) {
|
|
$InstallerBasename = "PowerToysUserSetup-${{ parameters.versionNumber }}-${{ parameters.installerSuffix }}-$(BuildPlatform)"
|
|
}
|
|
else {
|
|
$InstallerBasename = "PowerToysSetup-${{ parameters.versionNumber }}-${{ parameters.installerSuffix }}-$(BuildPlatform)"
|
|
}
|
|
|
|
# Export variables for downstream steps
|
|
Write-Host "##vso[task.setvariable variable=InstallerBuildSlug]$InstallerBuildSlug"
|
|
Write-Host "##vso[task.setvariable variable=InstallerRelativePath]$(BuildPlatform)\$(BuildConfiguration)\$InstallerBuildSlug"
|
|
Write-Host "##vso[task.setvariable variable=InstallerBasename]$InstallerBasename"
|
|
Write-Host "##vso[task.setvariable variable=InstallerFolder]$InstallerFolder"
|
|
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Prepare Installer variables
|
|
|
|
# This dll needs to be built and signed before building the MSI.
|
|
- task: VSBuild@1
|
|
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Build PowerToysSetupCustomActionsVNext
|
|
inputs:
|
|
solution: "**/installer/PowerToysSetup.sln"
|
|
vsVersion: 17.0
|
|
msbuildArgs: >-
|
|
/t:PowerToysSetupCustomActionsVNext
|
|
/p:RunBuildEvents=true;PerUser=${{parameters.buildUserInstaller}};RestorePackagesConfig=true;CIBuild=true
|
|
/p:InstallerSuffix=${{ parameters.installerSuffix }}
|
|
-restore -graph
|
|
/bl:$(LogOutputDirectory)\installer-$(InstallerBuildSlug)-actions.binlog
|
|
${{ parameters.additionalBuildOptions }}
|
|
platform: $(BuildPlatform)
|
|
configuration: $(BuildConfiguration)
|
|
clean: true
|
|
msbuildArchitecture: x64
|
|
maximumCpuCount: true
|
|
|
|
- ${{ if eq(parameters.codeSign, true) }}:
|
|
- template: steps-esrp-signing.yml
|
|
parameters:
|
|
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Sign PowerToysSetupCustomActionsVNext
|
|
signingIdentity: ${{ parameters.signingIdentity }}
|
|
inputs:
|
|
FolderPath: 'installer/PowerToysSetupCustomActionsVNext/$(InstallerRelativePath)'
|
|
signType: batchSigning
|
|
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_installer.json'
|
|
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
|
|
|
|
## INSTALLER START
|
|
#### MSI BUILDING AND SIGNING
|
|
- task: VSBuild@1
|
|
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Build VNext MSI
|
|
inputs:
|
|
solution: "**/installer/PowerToysSetup.sln"
|
|
vsVersion: 17.0
|
|
msbuildArgs: >-
|
|
-restore
|
|
/t:PowerToysInstallerVNext
|
|
/p:RunBuildEvents=false;PerUser=${{parameters.buildUserInstaller}};BuildProjectReferences=false;CIBuild=true
|
|
/p:InstallerSuffix=${{ parameters.installerSuffix }}
|
|
/bl:$(LogOutputDirectory)\installer-$(InstallerBuildSlug)-msi.binlog
|
|
${{ parameters.additionalBuildOptions }}
|
|
platform: $(BuildPlatform)
|
|
configuration: $(BuildConfiguration)
|
|
clean: false # don't undo our hard work above by deleting the CustomActions dll
|
|
msbuildArchitecture: x64
|
|
maximumCpuCount: true
|
|
|
|
- script: |-
|
|
wix msi decompile installer\$(InstallerFolder)\$(InstallerRelativePath)\$(InstallerBasename).msi -x $(build.sourcesdirectory)\extractedMsi
|
|
dir $(build.sourcesdirectory)\extractedMsi
|
|
displayName: "${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} WiX5: Extract and verify MSI"
|
|
|
|
# Check if deps.json files don't reference different dll versions.
|
|
- pwsh: |-
|
|
& '.pipelines/verifyDepsJsonLibraryVersions.ps1' -targetDir '$(build.sourcesdirectory)\extractedMsi\File'
|
|
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Audit deps.json in MSI extracted files
|
|
|
|
- ${{ if eq(parameters.codeSign, true) }}:
|
|
- pwsh: |-
|
|
& .pipelines/versionAndSignCheck.ps1 -targetDir '$(build.sourcesdirectory)\extractedMsi\File'
|
|
& .pipelines/versionAndSignCheck.ps1 -targetDir '$(build.sourcesdirectory)\extractedMsi\Binary'
|
|
git clean -xfd ./extractedMsi
|
|
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Verify all binaries are signed and versioned
|
|
|
|
- template: steps-esrp-signing.yml
|
|
parameters:
|
|
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Sign VNext MSI
|
|
signingIdentity: ${{ parameters.signingIdentity }}
|
|
inputs:
|
|
FolderPath: 'installer/$(InstallerFolder)/$(InstallerRelativePath)'
|
|
signType: batchSigning
|
|
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_installer.json'
|
|
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
|
|
|
|
#### END MSI
|
|
#### BOOTSTRAP BUILDING AND SIGNING
|
|
- task: VSBuild@1
|
|
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Build VNext Bootstrapper
|
|
inputs:
|
|
solution: "**/installer/PowerToysSetup.sln"
|
|
vsVersion: 17.0
|
|
msbuildArgs: >-
|
|
-restore
|
|
/t:PowerToysBootstrapperVNext
|
|
/p:PerUser=${{parameters.buildUserInstaller}};CIBuild=true
|
|
/p:InstallerSuffix=${{ parameters.installerSuffix }}
|
|
/bl:$(LogOutputDirectory)\installer-$(InstallerBuildSlug)-bootstrapper.binlog
|
|
-restore -graph
|
|
${{ parameters.additionalBuildOptions }}
|
|
platform: $(BuildPlatform)
|
|
configuration: $(BuildConfiguration)
|
|
clean: false # don't undo our hard work above by deleting the MSI
|
|
msbuildArchitecture: x64
|
|
maximumCpuCount: true
|
|
|
|
# The entirety of bundle unpacking/re-packing is unnecessary if we are not code signing it.
|
|
- ${{ if eq(parameters.codeSign, true) }}:
|
|
- script: |-
|
|
wix burn detach installer\$(InstallerFolder)\$(InstallerRelativePath)\$(InstallerBasename).exe -engine installer\engine.exe
|
|
displayName: "${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} WiX5: Extract Engine from Bundle"
|
|
|
|
- template: steps-esrp-signing.yml
|
|
parameters:
|
|
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Sign WiX Engine
|
|
signingIdentity: ${{ parameters.signingIdentity }}
|
|
inputs:
|
|
FolderPath: "installer"
|
|
Pattern: engine.exe
|
|
signConfigType: inlineSignParams
|
|
inlineOperation: |
|
|
[
|
|
{
|
|
"KeyCode": "CP-230012",
|
|
"OperationCode": "SigntoolSign",
|
|
"Parameters": {
|
|
"OpusName": "Microsoft",
|
|
"OpusInfo": "http://www.microsoft.com",
|
|
"FileDigest": "/fd \"SHA256\"",
|
|
"PageHash": "/NPH",
|
|
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
|
},
|
|
"ToolName": "sign",
|
|
"ToolVersion": "1.0"
|
|
},
|
|
{
|
|
"KeyCode": "CP-230012",
|
|
"OperationCode": "SigntoolVerify",
|
|
"Parameters": {},
|
|
"ToolName": "sign",
|
|
"ToolVersion": "1.0"
|
|
}
|
|
]
|
|
|
|
- script: |-
|
|
wix burn reattach installer\$(InstallerFolder)\$(InstallerRelativePath)\$(InstallerBasename).exe -engine installer\engine.exe -o installer\$(InstallerFolder)\$(InstallerRelativePath)\$(InstallerBasename).exe
|
|
displayName: "${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} WiX5: Reattach Engine to Bundle"
|
|
|
|
- template: steps-esrp-signing.yml
|
|
parameters:
|
|
displayName: ${{replace(replace(parameters.buildUserInstaller,'True','👤'),'False','💻')}} Sign Final Bootstrapper
|
|
signingIdentity: ${{ parameters.signingIdentity }}
|
|
inputs:
|
|
FolderPath: 'installer/$(InstallerFolder)/$(InstallerRelativePath)'
|
|
signType: batchSigning
|
|
batchSignPolicyFile: '$(build.sourcesdirectory)\.pipelines\ESRPSigning_installer.json'
|
|
ciPolicyFile: '$(build.sourcesdirectory)\.pipelines\CIPolicy.xml'
|
|
|
|
#### END BOOTSTRAP
|
|
## END INSTALLER
|