Updates to package and release pipelines (#23800)

This commit is contained in:
Aditya Patwardhan
2024-05-15 16:35:46 -07:00
committed by GitHub
parent fc68b61d2f
commit 53df284437
19 changed files with 1944 additions and 11 deletions
@@ -93,7 +93,7 @@ extends:
cg:
enabled: true
ignoreDirectories: '.devcontainer,demos,docker,docs,src,test,tools/packaging'
asyncSdl: # https://aka.ms/obpipelines/asyncsdl
asyncSdl:
enabled: true
forStages: [prep, macos, linux, windows, SignFiles, test_and_release_artifacts]
credscan:
+6 -6
View File
@@ -1,4 +1,4 @@
trigger: none # https://aka.ms/obpipelines/triggers
trigger: none
parameters: # parameters are shown up in ADO UI in a build queue time
- name: 'debug'
@@ -20,7 +20,7 @@ parameters: # parameters are shown up in ADO UI in a build queue time
variables:
- name: CDP_DEFINITION_BUILD_COUNT
value: $[counter('', 0)] # needed for onebranch.pipeline.version task https://aka.ms/obpipelines/versioning
value: $[counter('', 0)] # needed for onebranch.pipeline.version task
- name: system.debug
value: ${{ parameters.debug }}
- name: ENABLE_PRS_DELAYSIGN
@@ -40,7 +40,7 @@ variables:
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: WindowsContainerImage
value: 'onebranch.azurecr.io/windows/ltsc2019/vse2022:latest' # Docker image which is used to build the project https://aka.ms/obpipelines/containers
value: 'onebranch.azurecr.io/windows/ltsc2019/vse2022:latest' # Docker image which is used to build the project
- name: LinuxContainerImage
value: mcr.microsoft.com/onebranch/cbl-mariner/build:2.0
- group: mscodehub-feed-read-akv
@@ -66,9 +66,9 @@ resources:
ref: refs/heads/main
extends:
template: v2/OneBranch.Official.CrossPlat.yml@templates # https://aka.ms/obpipelines/templates
template: v2/OneBranch.Official.CrossPlat.yml@templates
parameters:
cloudvault: # https://aka.ms/obpipelines/cloudvault
cloudvault:
enabled: false
featureFlags:
linuxEsrpSigning: true
@@ -88,7 +88,7 @@ extends:
cg:
enabled: true
ignoreDirectories: '.devcontainer,demos,docker,docs,src,test,tools/packaging'
asyncSdl: # https://aka.ms/obpipelines/asyncsdl
asyncSdl:
enabled: true
forStages: ['build']
credscan:
+409
View File
@@ -0,0 +1,409 @@
trigger: none
parameters: # parameters are shown up in ADO UI in a build queue time
- name: 'debug'
displayName: 'Enable debug output'
type: boolean
default: false
- name: InternalSDKBlobURL
displayName: URL to the blob having internal .NET SDK
type: string
default: ' '
- name: ReleaseTagVar
displayName: Release Tag
type: string
default: 'fromBranch'
- name: SKIP_SIGNING
displayName: Skip Signing
type: string
default: 'NO'
variables:
- name: CDP_DEFINITION_BUILD_COUNT
value: $[counter('', 0)]
- name: system.debug
value: ${{ parameters.debug }}
- name: ENABLE_PRS_DELAYSIGN
value: 1
- name: ROOT
value: $(Build.SourcesDirectory)
- name: REPOROOT
value: $(Build.SourcesDirectory)
- name: OUTPUTROOT
value: $(REPOROOT)\out
- name: NUGET_XMLDOC_MODE
value: none
- name: nugetMultiFeedWarnLevel
value: none
- name: NugetSecurityAnalysisWarningLevel
value: none
- name: skipNugetSecurityAnalysis
value: true
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: WindowsContainerImage
value: 'onebranch.azurecr.io/windows/ltsc2019/vse2022:latest'
- name: LinuxContainerImage
value: mcr.microsoft.com/onebranch/cbl-mariner/build:2.0
- name: ReleaseTagVar
value: ${{ parameters.ReleaseTagVar }}
resources:
repositories:
- repository: templates
type: git
name: OneBranch.Pipelines/GovernedTemplates
ref: refs/heads/main
pipelines:
- pipeline: CoOrdinatedBuildPipeline
source: 'PowerShell-Coordinated Packages-Official'
- pipeline: PSPackagesOfficial
source: 'PowerShell-Packages-Official'
trigger:
branches:
include:
- master
- releases/*
extends:
template: v2/OneBranch.Official.CrossPlat.yml@templates
parameters:
cloudvault:
enabled: false
globalSdl:
disableLegacyManifest: true
# disabled Armory as we dont have any ARM templates to scan. It fails on some sample ARM templates.
armory:
enabled: false
asyncSdl:
enabled: true
tsaOptionsFile: .config/tsaoptions.json
tsa:
enabled: true
credscan:
enabled: true
scanFolder: $(Build.SourcesDirectory)
suppressionsFile: $(Build.SourcesDirectory)\.config\suppress.json
binskim:
break: false # always break the build on binskim issues in addition to TSA upload
policheck:
break: true # always break the build on policheck issues. You can disable it by setting to 'false'
# suppression:
# suppressionFile: $(Build.SourcesDirectory)\.gdn\global.gdnsuppress
tsaOptionsFile: .config\tsaoptions.json
stages:
- stage: msixbundle
displayName: 'Create MSIX Bundle'
jobs:
- template: /.pipelines/templates/release-create-msix.yml@self
- stage: validateSdk
displayName: 'Validate SDK'
jobs:
- template: /.pipelines/templates/release-validate-sdk.yml@self
parameters:
jobName: "windowsSDK"
displayName: "Windows SDK Validation"
jobtype: windows
- template: /.pipelines/templates/release-validate-sdk.yml@self
parameters:
jobName: "MacOSSDK"
displayName: "MacOS SDK Validation"
jobtype: macos
- template: /.pipelines/templates/release-validate-sdk.yml@self
parameters:
jobName: "LinuxSDK"
displayName: "Linux SDK Validation"
jobtype: linux
- stage: gbltool
displayName: 'Validate Global tools'
jobs:
- template: /.pipelines/templates/release-validate-globaltools.yml@self
parameters:
jobName: "WindowsGlobalTools"
displayName: "Windows Global Tools Validation"
jobtype: windows
- template: /.pipelines/templates/release-validate-globaltools.yml@self
parameters:
jobName: "LinuxGlobalTools"
displayName: "Linux Global Tools Validation"
jobtype: linux
globalToolExeName: 'pwsh'
globalToolPackageName: 'PowerShell.Linux.x64'
- stage: fxdpackages
displayName: 'Validate FXD Packages'
jobs:
- template: /.pipelines/templates/release-validate-fxdpackages.yml@self
parameters:
jobName: 'winfxd'
displayName: 'Validate Win Fxd Packages'
jobtype: 'windows'
artifactName: 'drop_windows_package_package_win_fxdependent'
packageNamePattern: '**/*win-fxdependent.zip'
- template: /.pipelines/templates/release-validate-fxdpackages.yml@self
parameters:
jobName: 'winfxdDesktop'
displayName: 'Validate WinDesktop Fxd Packages'
jobtype: 'windows'
artifactName: 'drop_windows_package_package_win_fxdependentWinDesktop'
packageNamePattern: '**/*win-fxdependentwinDesktop.zip'
- template: /.pipelines/templates/release-validate-fxdpackages.yml@self
parameters:
jobName: 'linuxfxd'
displayName: 'Validate Linux Fxd Packages'
jobtype: 'linux'
artifactName: 'drop_linux_package_fxdependent'
packageNamePattern: '**/*linux-x64-fxdependent.tar.gz'
- template: /.pipelines/templates/release-validate-fxdpackages.yml@self
parameters:
jobName: 'linuxArm64fxd'
displayName: 'Validate Linux ARM64 Fxd Packages'
jobtype: 'linux'
artifactName: 'drop_linux_package_fxdependent'
packageNamePattern: '**/*linux-x64-fxdependent.tar.gz'
arm64: 'yes'
- stage: validatePackages
displayName: 'Validate Packages'
jobs:
- template: /.pipelines/templates/release-validate-packagenames.yml@self
- stage: ManualValidation
dependsOn: []
displayName: Manual Validation
jobs:
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Validate Windows Packages
jobName: ValidateWinPkg
instructions: |
Validate zip package on windows
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Validate OSX Packages
jobName: ValidateOsxPkg
instructions: |
Validate tar.gz package on osx-arm64
- stage: ReleaseAutomation
dependsOn: []
displayName: 'Release Automation'
jobs:
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Start Release Automation
jobName: StartRA
instructions: |
Kick off Release automation build at: https://dev.azure.com/powershell-rel/Release-Automation/_build?definitionId=10&_a=summary
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Triage results
jobName: TriageRA
dependsOnJob: StartRA
instructions: |
Triage ReleaseAutomation results
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Signoff Tests
dependsOnJob: TriageRA
jobName: SignoffTests
instructions: |
Signoff ReleaseAutomation results
- stage: UpdateChangeLog
displayName: Update the changelog
dependsOn:
- ManualValidation
- ReleaseAutomation
- validatePackages
- fxdpackages
- gbltool
- validateSdk
- msixbundle
jobs:
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Make sure the changelog is updated
jobName: MergeChangeLog
instructions: |
Update and merge the changelog for the release.
This step is required for creating GitHub draft release.
- stage: BlobPublic
displayName: Make Blob Public
dependsOn: UpdateChangeLog
jobs:
- template: /.pipelines/templates/release-MakeBlobPublic.yml@self
- stage: PublishGitHubRelease
displayName: Publish GitHub Release
dependsOn: BlobPublic
jobs:
- template: /.pipelines/templates/release-githubtasks.yml@self
- stage: PublishNuGet
displayName: Publish NuGet
dependsOn: PublishGitHubRelease
jobs:
- template: /.pipelines/templates/release-publish-nuget.yml@self
parameters:
skipPublish: true
- stage: PublishPMC
displayName: Publish PMC
dependsOn: PublishGitHubRelease
jobs:
- template: /.pipelines/templates/release-publish-pmc.yml@self
parameters:
skipPublish: true
- stage: ReleaseDocker
dependsOn: PublishGitHubRelease
displayName: 'Docker Release'
jobs:
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Start Docker Build
jobName: StartDockerBuild
instructions: |
Kick off Docker build
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Start Docker Release
dependsOnJob: StartDockerBuild
jobName: StartDockerRelease
instructions: |
Kickoff docker release
- stage: UpdateDotnetDocker
dependsOn: PublishGitHubRelease
displayName: Update DotNet SDK Docker images
jobs:
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Update .NET SDK docker images
jobName: DotnetDocker
instructions: |
Create PR for updating dotnet-docker images to use latest PowerShell version.
1. Fork and clone https://github.com/dotnet/dotnet-docker.git
2. git checkout upstream/nightly -b updatePS
3. dotnet run --project .\eng\update-dependencies\ -- <dotnetversion> --product-version powershell=<powershellversion> --compute-shas
4. create PR targeting nightly branch
- stage: UpdateWinGet
dependsOn: PublishGitHubRelease
displayName: Add manifest entry to winget
jobs:
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Add manifest entry to winget
jobName: UpdateWinGet
instructions: |
This is typically done by the community 1-2 days after the release.
- stage: PublishMsix
dependsOn: PublishGitHubRelease
displayName: Publish MSIX to store
jobs:
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Publish the MSIX Bundle package to store
jobName: PublishMsix
instructions: |
Ask Steve to release MSIX bundle package to Store
- stage: PublishVPack
dependsOn: PublishGitHubRelease
displayName: Release vPack
jobs:
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Start vPack Release pipeline
jobName: PublishVPack
instructions: |
Kick off vPack release pipeline
# Need to verify if the Az PS / CLI team still uses this. Skippinng for this release.
# - stage: ReleaseDeps
# dependsOn: GitHubTasks
# displayName: Update pwsh.deps.json links
# jobs:
# - template: templates/release-UpdateDepsJson.yml
- stage: UploadBuildInfoJson
dependsOn: PublishGitHubRelease
displayName: Upload BuildInfo.json
jobs:
- template: /.pipelines/templates/release-upload-buildinfo.yml@self
- stage: ReleaseSymbols
dependsOn: PublishGitHubRelease
displayName: Release Symbols
jobs:
- template: /.pipelines/templates/release-symbols.yml@self
- stage: ChangesToMaster
displayName: Ensure changes are in GH master
dependsOn: ['PublishNuGet', 'PublishPMC']
jobs:
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Make sure changes are in master
jobName: MergeToMaster
instructions: |
Make sure that changes README.md and metadata.json are merged into master on GitHub.
- stage: ReleaseSnap
displayName: Release Snap
dependsOn: 'ChangesToMaster'
jobs:
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Publish Snap
jobName: PublishSnapJob
instructions: |
Publish Snap
- stage: ReleaseToMU
displayName: Release to MU
dependsOn: ['PublishNuGet', 'PublishPMC', 'ChangesToMaster']
jobs:
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Release to MU
instructions: |
Notify the PM team to start the process of releasing to MU.
- stage: ReleaseClose
displayName: Finish Release
dependsOn: ['ReleaseToMU', 'ReleaseSymbols', 'ReleaseSnap']
jobs:
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Retain Build
jobName: RetainBuild
instructions: |
Retain the build
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Delete release branch
jobName: DeleteBranch
instructions: |
Delete release
+36
View File
@@ -0,0 +1,36 @@
parameters:
- name: displayName
type: string
- name: instructions
type: string
- name: jobName
type: string
default: approval
- name: timeoutInMinutes
type: number
# 2 days
default: 2880
- name: onTimeout
type: string
default: 'reject'
values:
- resume
- reject
- name: dependsOnJob
type: string
default: ''
jobs:
- job: ${{ parameters.jobName }}
dependsOn: ${{ parameters.dependsOnJob }}
displayName: ${{ parameters.displayName }}
pool:
type: agentless
timeoutInMinutes: 4320 # job times out in 3 days
steps:
- task: ManualValidation@0
displayName: ${{ parameters.displayName }}
timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
inputs:
instructions: ${{ parameters.instructions }}
onTimeout: ${{ parameters.onTimeout }}
@@ -0,0 +1,170 @@
jobs:
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Approve Blob Public
jobName: ApproveBlobPublic
instructions: |
Are you sure you want to make the blob public?
- job: blobPublic
displayName: Make Azure Blob Public
dependsOn: ApproveBlobPublic
condition: succeeded()
pool:
type: windows
variables:
- name: runCodesignValidationInjection
value: false
- name: NugetSecurityAnalysisWarningLevel
value: none
- name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
value: 1
- group: 'Azure Blob variable group'
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: ob_sdl_codeSignValidation_enabled
value: false
- name: ob_sdl_binskim_enabled
value: false
- name: ob_sdl_tsa_configFile
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
- name: ob_sdl_credscan_suppressionsFile
value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
- ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/master') }}:
- name: ob_sdl_codeql_compiled_enabled
value: true
steps:
- checkout: self
clean: true
env:
ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase
- template: /.pipelines/templates/SetVersionVariables.yml@self
parameters:
ReleaseTagVar: $(ReleaseTagVar)
CreateJson: yes
UseJson: no
- template: /.pipelines/templates/cloneToOfficialPath.yml@self
- pwsh: |
Get-ChildItem Env:
displayName: 'Capture Environment Variables'
- pwsh: |
$azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose
if ($azureRmModule) {
Write-Host 'AzureRM module exists. Removing it'
Uninstall-AzureRm
Write-Host 'AzureRM module removed'
}
Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose
displayName: Remove AzRM modules
- task: AzurePowerShell@5
displayName: Set blob permissions
inputs:
azureSubscription: az-blob-cicd-infra
scriptType: inlineScript
azurePowerShellVersion: LatestVersion
pwsh: true
inline: |
$storageAccount = "$(StorageAccount)"
$containerName = "$(azureVersion)"
$publicAccess = "blob"
Set-AzStorageContainerAcl `
-Context (New-AzStorageContext -StorageAccountName $storageAccount) `
-Container $containerName `
-PublicAccess $publicAccess
Set-AzStorageContainerAcl `
-Context (New-AzStorageContext -StorageAccountName $storageAccount) `
-Container "$containerName-gc" `
-PublicAccess $publicAccess
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Approve Copy Global tool packages to PSInfra storage
jobName: CopyBlobApproval
dependsOnJob: blobPublic
instructions: |
Approval for Copy global tool packages to PSInfra storage
- job: PSInfraBlobPublic
displayName: Copy global tools to PSInfra storage
dependsOn: CopyBlobApproval
pool:
type: windows
variables:
- group: 'PSInfraStorage'
- group: 'Azure Blob variable group'
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
steps:
- checkout: self
clean: true
env:
ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase
- template: /.pipelines/templates/SetVersionVariables.yml@self
parameters:
ReleaseTagVar: $(ReleaseTagVar)
CreateJson: yes
UseJson: no
- template: /.pipelines/templates/cloneToOfficialPath.yml@self
- pwsh: |
Get-ChildItem Env:
displayName: 'Capture Environment Variables'
- pwsh: |
$azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose
if ($azureRmModule) {
Write-Host 'AzureRM module exists. Removing it'
Uninstall-AzureRm
Write-Host 'AzureRM module removed'
}
Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose
displayName: Remove AzRM modules
- task: AzurePowerShell@5
displayName: Copy blobs to PSInfra storage
inputs:
azureSubscription: az-blob-cicd-infra
scriptType: inlineScript
azurePowerShellVersion: LatestVersion
pwsh: true
inline: |
$sourceStorageAccountName = '$(StorageAccount)'
$sourceContainerName = '$(AzureVersion)'
$destinationStorageAccountName = '$(PSInfraStorageAccount)'
$destinationContainerName = "tool/$(Version)"
$sourceContext = New-AzStorageContext -StorageAccountName $sourceStorageAccountName
$destinationContext = New-AzStorageContext -StorageAccountName $destinationStorageAccountName
$blobs = Get-AzStorageBlob -Context $sourceContext -Container $sourceContainerName
foreach ($blob in $blobs) {
$sourceBlobName = $blob.Name
$destinationBlobName = $sourceBlobName
$destinationBlob = Start-AzStorageBlobCopy -Context $destinationContext -SrcContainer $sourceContainerName -SrcBlob $sourceBlobName -DestContainer $destinationContainerName -DestBlob $destinationBlobName
# Wait for the copy operation to complete
$destinationBlob | Wait-AzStorageBlobCopy
if ($destinationBlob.CopyStatus -eq "Success") {
Write-Host "Blob copy completed successfully for $sourceBlobName."
} else {
Write-Host "Blob copy failed for $sourceBlobName."
}
}
@@ -0,0 +1,26 @@
steps:
- pwsh: |
$variable = 'releaseTag'
$branch = $ENV:BUILD_SOURCEBRANCH
if($branch -notmatch '^.*((release/|rebuild/.*rebuild))')
{
throw "Branch name is not in release format: '$branch'"
}
$releaseTag = $Branch -replace '^.*((release|rebuild)/)'
$vstsCommandString = "vso[task.setvariable variable=$Variable]$releaseTag"
Write-Verbose -Message "setting $Variable to $releaseTag" -Verbose
Write-Host -Object "##$vstsCommandString"
displayName: Set Release Tag
- pwsh: |
$azureVersion = '$(ReleaseTag)'.ToLowerInvariant() -replace '\.', '-'
$vstsCommandString = "vso[task.setvariable variable=AzureVersion]$azureVersion"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
$version = '$(ReleaseTag)'.ToLowerInvariant().Substring(1)
$vstsCommandString = "vso[task.setvariable variable=Version]$version"
Write-Host ("sending " + $vstsCommandString)
Write-Host "##$vstsCommandString"
displayName: Set container name
@@ -0,0 +1,100 @@
jobs:
- job: CreateMSIXBundle
displayName: Create .msixbundle file
pool:
type: windows
variables:
- group: msixTools
- group: 'Azure Blob variable group'
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
steps:
- template: release-SetReleaseTagandContainerName.yml@self
- download: PSPackagesOfficial
artifact: drop_windows_package_package_win_arm64
displayName: Download arm64 msix
patterns: '**/*.msix'
- download: PSPackagesOfficial
artifact: drop_windows_package_package_win_x64
displayName: Download x64 msix
patterns: '**/*.msix'
- download: PSPackagesOfficial
artifact: drop_windows_package_package_win_x86
displayName: Download x86 msix
patterns: '**/*.msix'
- pwsh: |
$cmd = Get-Command makeappx.exe -ErrorAction Ignore
if ($cmd) {
Write-Verbose -Verbose 'makeappx available in PATH'
$exePath = $cmd.Source
} else {
$toolsDir = '$(Pipeline.Workspace)\releasePipeline\tools'
New-Item $toolsDir -Type Directory -Force > $null
Invoke-RestMethod -Uri '$(makeappUrl)' -OutFile "$toolsDir\makeappx.zip"
Expand-Archive "$toolsDir\makeappx.zip" -DestinationPath "$toolsDir\makeappx" -Force
$exePath = "$toolsDir\makeappx\makeappx.exe"
Write-Verbose -Verbose 'makeappx was installed:'
Get-ChildItem -Path $toolsDir -Recurse
}
$vstsCommandString = "vso[task.setvariable variable=MakeAppxPath]$exePath"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
displayName: Install makeappx tool
retryCountOnTaskFailure: 1
- pwsh: |
$sourceDir = '$(Pipeline.Workspace)\releasePipeline\msix'
$null = New-Item -Path $sourceDir -ItemType Directory -Force
$msixFiles = Get-ChildItem -Path "$(Pipeline.Workspace)/PSPackagesOfficial/*.msix" -Recurse
foreach ($msixFile in $msixFiles) {
$null = Copy-Item -Path $msixFile.FullName -Destination $sourceDir -Force -Verbose
}
$file = Get-ChildItem $sourceDir | Select-Object -First 1
$prefix = ($file.BaseName -split "-win")[0]
$pkgName = "$prefix.msixbundle"
Write-Verbose -Verbose "Creating $pkgName"
$makeappx = '$(MakeAppxPath)'
$outputDir = "$sourceDir\output"
New-Item $outputDir -Type Directory -Force > $null
& $makeappx bundle /d $sourceDir /p "$outputDir\$pkgName"
Get-ChildItem -Path $sourceDir -Recurse
$vstsCommandString = "vso[task.setvariable variable=BundleDir]$outputDir"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
displayName: Create MsixBundle
retryCountOnTaskFailure: 1
- task: AzurePowerShell@5
displayName: Upload msix to blob
inputs:
azureSubscription: az-blob-cicd-infra
scriptType: inlineScript
azurePowerShellVersion: LatestVersion
pwsh: true
inline: |
$containerName = '$(AzureVersion)-private'
$storageAccount = '$(StorageAccount)'
$storageContext = New-AzStorageContext -StorageAccountName $storageAccount -UseConnectedAccount
if ($env:BundleDir) {
$bundleFile = "$env:BundleDir\*.msixbundle"
$blobName = Get-Item $bundleFile | Split-Path -Leaf
Write-Verbose -Verbose "Uploading $bundleFile to $containerName/$blobName"
Set-AzStorageBlobContent -File $jsonFile -Container $containerName -Blob $blobName -Context $storageContext
}
else{
throw "BundleDir not found"
}
@@ -0,0 +1,160 @@
jobs:
- job: GithubReleaseDraft
displayName: Create GitHub Release Draft
condition: succeeded()
pool:
type: windows
variables:
- name: runCodesignValidationInjection
value: false
- name: NugetSecurityAnalysisWarningLevel
value: none
- name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
value: 1
- group: 'mscodehub-code-read-akv'
- group: 'Azure Blob variable group'
- group: 'GitHubTokens'
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: ob_sdl_codeSignValidation_enabled
value: false
- name: ob_sdl_binskim_enabled
value: false
- name: ob_sdl_tsa_configFile
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
- name: ob_sdl_credscan_suppressionsFile
value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
steps:
- checkout: self
clean: true
env:
ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase
- template: release-SetReleaseTagAndContainerName.yml
- pwsh: |
Get-ChildItem Env:
displayName: 'Capture Environment Variables'
- pwsh: |
# Uninstall Azure RM modules
$azRmModules = Get-Module -Name AzureRM* -ListAvailable
if ($azRmModules) {
$azRmModules | Remove-Module -Force
}
# Install Az.Storage module if not already installed
if (-not (Get-Module -Name Az.Storage -ListAvailable)) {
Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose
}
displayName: Install Az.Storage module
- task: AzurePowerShell@5
displayName: Download packages from Azure Storage
inputs:
azureSubscription: az-blob-cicd-infra
scriptType: inlineScript
azurePowerShellVersion: LatestVersion
pwsh: true
inline: |
$storageAccount = "$(StorageAccount)"
$containerName = "$(AzureVersion)"
$destinationPath = "$(System.ArtifactsDirectory)"
# Get storage account context
$storageContext = New-AzStorageContext -StorageAccountName $storageAccount
$blobList = Get-AzStorageBlob -Container $containerName -Context $storageContext
foreach ($blob in $blobList) {
$blobName = $blob.Name
$destinationFile = Join-Path -Path $destinationPath -ChildPath $blobName
Get-AzStorageBlobContent -Container $containerName -Blob $blobName -Destination $destinationFile -Context $storageContext -Force
Write-Output "Downloaded $blobName to $destinationFile"
}
- pwsh: |
Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty FullName
displayName: Capture downloaded artifacts
- pwsh: |
git clone https://$(mscodehubCodeReadPat)@mscodehub.visualstudio.com/PowerShellCore/_git/Internal-PowerShellTeam-Tools '$(Pipeline.Workspace)/tools'
displayName: Clone Internal-Tools repository
- pwsh: |
$Path = "$(System.ArtifactsDirectory)"
$OutputPath = Join-Path $Path 'hashes.sha256'
$srcPaths = @($Path)
$packages = Get-ChildItem -Path $srcPaths -Include * -Recurse -File
$checksums = $packages |
ForEach-Object {
Write-Verbose -Verbose "Generating checksum file for $($_.FullName)"
$packageName = $_.Name
$hash = (Get-FileHash -Path $_.FullName -Algorithm SHA256).Hash.ToLower()
# the '*' before the packagename signifies it is a binary
"$hash *$packageName"
}
$checksums | Out-File -FilePath $OutputPath -Force
$fileContent = Get-Content -Path $OutputPath -Raw | Out-String
Write-Verbose -Verbose -Message $fileContent
displayName: Add sha256 hashes
- pwsh: |
$releaseVersion = '$(ReleaseTag)' -replace '^v',''
$vstsCommandString = "vso[task.setvariable variable=ReleaseVersion]$releaseVersion"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
displayName: 'Set release version'
- pwsh: |
Import-module '$(Pipeline.Workspace)/tools/Scripts/GitHubRelease.psm1'
$releaseVersion = '$(ReleaseTag)' -replace '^v',''
$semanticVersion = [System.Management.Automation.SemanticVersion]$releaseVersion
$isPreview = $semanticVersion.PreReleaseLabel -ne $null
$fileName = if ($isPreview) {
"preview.md"
}
else {
$semanticVersion.Major.ToString() + "." + $semanticVersion.Minor.ToString() + ".md"
}
$filePath = "$env:BUILD_SOURCESDIRECTORY/PowerShell/CHANGELOG/$fileName"
Write-Verbose -Verbose "Selected Log file: $filePath"
if (-not (Test-Path $filePath)) {
throw "$filePath not found"
}
$changelog = Get-Content -Path $filePath
$startPattern = "^## \[" + ([regex]::Escape($releaseVersion)) + "\]"
$endPattern = "^## \[{0}\.{1}\.{2}*" -f $semanticVersion.Major, $semanticVersion.Minor, $semanticVersion.Patch
$clContent = $changelog | ForEach-Object {
if ($_ -match $startPattern) { $outputLine = $true }
elseif ($_ -match $endPattern) { $outputLine = $false }
if ($outputLine) { $_}
} | Out-String
Write-Verbose -Verbose "Selected content: `n$clContent"
Publish-ReleaseDraft -Tag '$(ReleaseTag)' -Name '$(ReleaseTag) Release of PowerShell' -Description $clContent -User PowerShell -Repository PowerShell -PackageFolder $(PackagesRoot) -Token $(GitHubReleasePat)
displayName: Publish Release Draft
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Push Git Tag
jobName: PushGitTag
dependsOnJob: GithubReleaseDraft
instructions: |
Push the git tag to upstream
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Make Draft Public
jobName: DraftPublic
dependsOnJob: PushGitTag
instructions: |
Make the GitHub Release Draft Public
@@ -0,0 +1,71 @@
parameters:
- name: skipPublish
default: false
type: boolean
jobs:
- job: NuGetPublish
displayName: Publish to NuGet
condition: succeeded()
pool:
type: windows
variables:
- name: runCodesignValidationInjection
value: false
- name: NugetSecurityAnalysisWarningLevel
value: none
- name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
value: 1
- group: 'mscodehub-code-read-akv'
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: ob_sdl_codeSignValidation_enabled
value: false
- name: ob_sdl_binskim_enabled
value: false
- name: ob_sdl_tsa_configFile
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
- name: ob_sdl_credscan_suppressionsFile
value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
steps:
- checkout: self
clean: true
env:
ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase
- template: release-SetReleaseTagAndContainerName.yml
- pwsh: |
Get-ChildItem Env:
displayName: 'Capture Environment Variables'
- download: PSPackagesOfficial
artifact: drop_nupkg_build_nupkg
displayName: Download nuget packages
- pwsh: |
#Exclude all global tool packages. Their names start with 'PowerShell.'
$null = New-Item -ItemType Directory -Path "$(Pipeline.Workspace)/release"
Copy-Item "$ENV:PIPELINE_WORKSPACE/PSPackagesOfficial/*.nupkg" -Destination "$(Pipeline.Workspace)/release" -Exclude "PowerShell.*.nupkg" -Force -Verbose
$releaseVersion = '$(VERSION)'
$globalToolPath = "$ENV:PIPELINE_WORKSPACE/PSPackagesOfficial/PowerShell.$releaseVersion.nupkg"
if ($releaseVersion -notlike '*-*') {
# Copy the global tool package for stable releases
Copy-Item $globalToolPath -Destination "$(Pipeline.Workspace)/release"
}
Get-ChildItem "$(Pipeline.Workspace)/release" -recurse
displayName: Download and capture nupkgs
condition: and(eq('${{ parameters.skipPublish }}', 'false'), succeeded())
- task: NuGetCommand@2
displayName: 'NuGet push'
condition: and(eq('${{ parameters.skipPublish }}', 'false'), succeeded())
inputs:
command: push
packagesToPush: '$(Pipeline.Workspace)/release/*.nupkg'
nuGetFeedType: external
publishFeedCredentials: PowerShellNuGetOrgPush
@@ -0,0 +1,83 @@
parameters:
- name: skipPublish
default: false
type: boolean
jobs:
- job: PMCPublish
displayName: Publish to PMC
condition: succeeded()
pool:
type: linux
variables:
- name: runCodesignValidationInjection
value: false
- name: NugetSecurityAnalysisWarningLevel
value: none
- name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
value: 1
- group: 'mscodehub-code-read-akv'
- group: 'packages.microsoft.com'
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: ob_sdl_codeSignValidation_enabled
value: false
- name: ob_sdl_binskim_enabled
value: false
- name: ob_sdl_tsa_configFile
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
- name: ob_sdl_credscan_suppressionsFile
value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
steps:
- template: release-SetReleaseTagAndContainerName.yml
- pwsh: |
$packageVersion = '$(ReleaseTag)'.ToLowerInvariant() -replace '^v',''
$vstsCommandString = "vso[task.setvariable variable=packageVersion]$packageVersion"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
displayName: Set Package version
- pwsh: |
$branch = 'main-mirror'
$gitArgs = "clone",
"--verbose",
"--branch",
"$branch",
"https://$(mscodehubCodeReadPat)@mscodehub.visualstudio.com/PowerShellCore/_git/Internal-PowerShellTeam-Tools",
'$(Pipeline.Workspace)/tools'
$gitArgs | Write-Verbose -Verbose
git $gitArgs
displayName: Clone Internal-PowerShellTeam-Tools from MSCodeHub
- task: PipAuthenticate@1
inputs:
artifactFeeds: 'pmc'
pythonDownloadServiceConnections: pmcDownload
- pwsh: |
pip install pmc-cli
$newPath = (resolve-path '~/.local/bin').providerpath
$vstsCommandString = "vso[task.setvariable variable=PATH]${env:PATH}:$newPath"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
displayName: Install pmc cli
- pwsh: |
$metadata = Get-Content -Path "$(Build.SourcesDirectory)/tools/metadata.json" -Raw | ConvertFrom-Json
$params = @{
ReleaseTag = "$(ReleaseTag)"
AadClientId = "$(PmcCliClientID)"
BlobFolderName = "$(AzureVersion)"
LTS = $metadata.LTSRelease.Latest
ForProduction = $true
SkipPublish = $${{ parameters.skipPublish }}
MappingFilePath = '$(System.DefaultWorkingDirectory)/tools/packages.microsoft.com/mapping.json'
}
$params | Out-String -width 9999 -Stream | write-Verbose -Verbose
& '$(Pipeline.Workspace)/tools/packages.microsoft.com-v4/releaseLinuxPackages.ps1' @params
displayName: Run release script
+85
View File
@@ -0,0 +1,85 @@
parameters:
- name: skipPublish
default: false
type: boolean
jobs:
- job: PublishSymbols
displayName: Publish Symbols
condition: succeeded()
pool:
type: windows
variables:
- name: runCodesignValidationInjection
value: false
- name: NugetSecurityAnalysisWarningLevel
value: none
- name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
value: 1
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: ob_sdl_codeSignValidation_enabled
value: false
- name: ob_sdl_binskim_enabled
value: false
- name: ob_sdl_tsa_configFile
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
- name: ob_sdl_credscan_suppressionsFile
value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
steps:
- template: release-SetReleaseTagAndContainerName.yml
- pwsh: |
Get-ChildItem Env:
displayName: 'Capture Environment Variables'
- download: CoOrdinatedBuildPipeline
artifact: drop_windows_build_windows_x64_release
patterns: 'symbols.zip'
displayName: Download winx64
- download: CoOrdinatedBuildPipeline
artifact: drop_windows_build_windows_x86_release
patterns: 'symbols.zip'
displayName: Download winx86
- download: CoOrdinatedBuildPipeline
artifact: drop_windows_build_windows_arm64_release
patterns: 'symbols.zip'
displayName: Download winx64
- pwsh: |
Write-Verbose -Verbose "Enumerating $(Pipeline.Workspace)\CoOrdinatedBuildPipeline"
$downloadedArtifacts = Get-ChildItem -Recurse "$(Pipeline.Workspace)\CoOrdinatedBuildPipeline" -Recurse -Filter 'symbols.zip'
$downloadedArtifacts
$expandedRoot = New-Item -Path "$(Pipeline.Workspace)/expanded" -ItemType Directory -Verbose
$symbolsRoot = New-Item -Path "$(Pipeline.Workspace)/symbols" -ItemType Directory -Verbose
$downloadedArtifacts | ForEach-Object {
$folderName = (Get-Item (Split-Path $_.FullName)).Name
$destFolder = New-Item -Path "$expandedRoot/$folderName/$($_.BaseName)/" -ItemType Directory -Verbose
Expand-Archive -Path $_.FullName -DestinationPath $destFolder -Force
$symbolsToPublish = New-Item -Path "$symbolsRoot/$($_.BaseName)" -ItemType Directory -Verbose
Get-ChildItem -Path $destFolder -Recurse -Filter '*.pdb' | ForEach-Object {
Copy-Item -Path $_.FullName -Destination $symbolsToPublish -Verbose
}
}
Write-Verbose -Verbose "Enumerating $symbolsRoot"
Get-ChildItem -Path $symbolsRoot -Recurse
$vstsCommandString = "vso[task.setvariable variable=SymbolsPath]$symbolsRoot"
Write-Verbose -Message "$vstsCommandString" -Verbose
Write-Host -Object "##$vstsCommandString"
displayName: Expand and capture symbols folders
- task: PublishSymbols@2
inputs:
symbolsFolder: '$(SymbolsPath)'
searchPattern: '**/*.pdb'
indexSources: false
publishSymbols: true
symbolServerType: teamServices
detailedLog: true
@@ -0,0 +1,129 @@
parameters:
- name: skipPublish
default: false
type: boolean
jobs:
- job: PMCPublish
displayName: Publish to PMC
condition: succeeded()
pool:
type: windows
variables:
- name: runCodesignValidationInjection
value: false
- name: NugetSecurityAnalysisWarningLevel
value: none
- name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
value: 1
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: ob_sdl_codeSignValidation_enabled
value: false
- name: ob_sdl_binskim_enabled
value: false
- name: ob_sdl_tsa_configFile
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
- name: ob_sdl_credscan_suppressionsFile
value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
steps:
- template: release-SetReleaseTagAndContainerName.yml
- pwsh: |
Get-ChildItem Env:
displayName: 'Capture Environment Variables'
- download: PSPackagesOfficial
artifact: BuildInfoJson
displayName: Download build info artifact
- pwsh: |
Import-Module '$(Build.SourcesDirectory)/tools/ci.psm1'
$jsonFile = Get-Item "$ENV:PIPELINE_WORKSPACE/PSPackagesOfficial/BuildInfoJson/*.json"
$fileName = Split-Path $jsonFile -Leaf
$dateTime = [datetime]::UtcNow
$dateTime = [datetime]::new($dateTime.Ticks - ($dateTime.Ticks % [timespan]::TicksPerSecond), $dateTime.Kind)
$metadata = Get-Content ./tools/metadata.json | ConvertFrom-Json
$stableRelease = $metadata.StableRelease.Latest
$ltsRelease = $metadata.LTSRelease.Latest
Write-Verbose -Verbose "Writing $jsonFile contents:"
$buildInfoJsonContent = Get-Content $jsonFile -Encoding UTF8NoBom -Raw
Write-Verbose -Verbose $buildInfoJsonContent
$buildInfo = $buildInfoJsonContent | ConvertFrom-Json
$buildInfo.ReleaseDate = $dateTime
$targetFile = "$ENV:PIPELINE_WORKSPACE/$fileName"
ConvertTo-Json -InputObject $buildInfo | Out-File $targetFile -Encoding ascii
if ($stableRelease -or $fileName -eq "preview.json") {
Set-BuildVariable -Name CopyMainBuildInfo -Value YES
} else {
Set-BuildVariable -Name CopyMainBuildInfo -Value NO
}
Set-BuildVariable -Name BuildInfoJsonFile -Value $targetFile
## Create 'lts.json' if it's the latest stable and also a LTS release.
if ($fileName -eq "stable.json") {
if ($ltsRelease) {
$ltsFile = "$ENV:PIPELINE_WORKSPACE/lts.json"
Copy-Item -Path $targetFile -Destination $ltsFile -Force
Set-BuildVariable -Name LtsBuildInfoJsonFile -Value $ltsFile
Set-BuildVariable -Name CopyLTSBuildInfo -Value YES
} else {
Set-BuildVariable -Name CopyLTSBuildInfo -Value NO
}
$releaseTag = $buildInfo.ReleaseTag
$version = $releaseTag -replace '^v'
$semVersion = [System.Management.Automation.SemanticVersion] $version
$versionFile = "$ENV:PIPELINE_WORKSPACE/$($semVersion.Major)-$($semVersion.Minor).json"
Copy-Item -Path $targetFile -Destination $versionFile -Force
Set-BuildVariable -Name VersionBuildInfoJsonFile -Value $versionFile
Set-BuildVariable -Name CopyVersionBuildInfo -Value YES
} else {
Set-BuildVariable -Name CopyVersionBuildInfo -Value NO
}
displayName: Create json files
- task: AzurePowerShell@5
displayName: Upload buildjson to blob
inputs:
azureSubscription: az-blob-cicd-infra
scriptType: inlineScript
azurePowerShellVersion: LatestVersion
pwsh: true
inline: |
$containerName = "BuildInfo"
$storageAccount = '$(StorageAccount)'
$storageContext = New-AzStorageContext -StorageAccountName $storageAccount -UseConnectedAccount
if ($env:CopyMainBuildInfo -eq 'YES') {
$jsonFile = "$env:BuildInfoJsonFile"
$blobName = Get-Item $jsonFile | Split-Path -Leaf
Write-Verbose -Verbose "Uploading $jsonFile to $containerName/$blobName"
Set-AzStorageBlobContent -File $jsonFile -Container $containerName -Blob $blobName -Context $storageContext
}
if ($env:CopyLTSBuildInfo -eq 'YES') {
$jsonFile = "$env:LtsBuildInfoJsonFile"
$blobName = Get-Item $jsonFile | Split-Path -Leaf
Write-Verbose -Verbose "Uploading $jsonFile to $containerName/$blobName"
Set-AzStorageBlobContent -File $jsonFile -Container $containerName -Blob $blobName -Context $storageContext
}
if ($env:CopyVersionBuildInfo -eq 'YES') {
$jsonFile = "$env:VersionBuildInfoJsonFile"
$blobName = Get-Item $jsonFile | Split-Path -Leaf
Write-Verbose -Verbose "Uploading $jsonFile to $containerName/$blobName"
Set-AzStorageBlobContent -File $jsonFile -Container $containerName -Blob $blobName -Context $storageContext
}
condition: and(succeeded(), eq(variables['CopyMainBuildInfo'], 'YES'))
@@ -0,0 +1,132 @@
parameters:
jobName: ""
displayName: ""
jobtype: ""
artifactName: ""
packageNamePattern: ""
arm64: "no"
jobs:
- job: ${{ parameters.jobName }}
displayName: ${{ parameters.displayName }}
variables:
- group: DotNetPrivateBuildAccess
- name: artifactName
value: ${{ parameters.artifactName }}
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: ob_sdl_credscan_suppressionsFile
value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
- name: ob_sdl_tsa_configFile
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
pool:
type: ${{ parameters.jobtype }}
${{ if eq(parameters.arm64, 'yes') }}:
hostArchitecture: arm64
steps:
- checkout: self
clean: true
- template: release-SetReleaseTagandContainerName.yml@self
- download: PSPackagesOfficial
artifact: "${{ parameters.artifactName }}"
displayName: Download fxd artifact
- pwsh: |
Get-ChildItem -Path env:
displayName: Capture environment
- pwsh: |
$artifactName = '$(artifactName)'
Get-ChildItem "$(Pipeline.Workspace)/PSPackagesOfficial/$artifactName" -Recurse
displayName: 'Capture Downloaded Artifacts'
- pwsh: |
$repoRoot = "$(Build.SourcesDirectory)/PowerShell"
$dotnetMetadataPath = "$repoRoot/DotnetRuntimeMetadata.json"
$dotnetMetadataJson = Get-Content $dotnetMetadataPath -Raw | ConvertFrom-Json
# Channel is like: $Channel = "5.0.1xx-preview2"
$Channel = $dotnetMetadataJson.sdk.channel
$sdkVersion = (Get-Content "$repoRoot/global.json" -Raw | ConvertFrom-Json).sdk.version
Import-Module "$repoRoot/build.psm1" -Force
Find-Dotnet
if(-not (Get-PackageSource -Name 'dotnet' -ErrorAction SilentlyContinue))
{
$nugetFeed = ([xml](Get-Content $repoRoot/nuget.config -Raw)).Configuration.packagesources.add | Where-Object { $_.Key -eq 'dotnet' } | Select-Object -ExpandProperty Value
if ($nugetFeed) {
Register-PackageSource -Name 'dotnet' -Location $nugetFeed -ProviderName NuGet
Write-Verbose -Message "Register new package source 'dotnet'" -verbose
}
}
## Install latest version from the channel
#Install-Dotnet -Channel "$Channel" -Version $sdkVersion
Start-PSBootstrap
Write-Verbose -Message "Installing .NET SDK completed." -Verbose
displayName: Install .NET
env:
__DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
- pwsh: |
$artifactName = '$(artifactName)'
$rootPath = "$(Pipeline.Workspace)/PSPackagesOfficial/$artifactName"
$destPath = New-Item "$rootPath/fxd" -ItemType Directory
$packageNameFilter = '${{ parameters.packageNamePattern }}'
if ($packageNameFilter.EndsWith('tar.gz')) {
$package = @(Get-ChildItem -Path "$rootPath/*.tar.gz")
Write-Verbose -Verbose "Package: $package"
if ($package.Count -ne 1) {
throw 'Only 1 package was expected.'
}
tar -xvf $package.FullName -C $destPath
}
else {
$package = @(Get-ChildItem -Path "$rootPath/*.zip")
Write-Verbose -Verbose "Package: $package"
if ($package.Count -ne 1) {
throw 'Only 1 package was expected.'
}
Expand-Archive -Path $package.FullName -Destination "$destPath" -Verbose
}
displayName: Expand fxd package
- pwsh: |
$repoRoot = "$(Build.SourcesDirectory)/PowerShell"
$artifactName = '$(artifactName)'
$rootPath = "$(Pipeline.Workspace)/PSPackagesOfficial/$artifactName"
$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
Import-Module "$repoRoot/build.psm1" -Force
Find-Dotnet -SetDotnetRoot
Write-Verbose -Verbose "DOTNET_ROOT: $env:DOTNET_ROOT"
Write-Verbose -Verbose "Check dotnet install"
dotnet --info
Write-Verbose -Verbose "Start test"
$packageNameFilter = '${{ parameters.packageNamePattern }}'
$pwshExeName = if ($packageNameFilter.EndsWith('tar.gz')) { 'pwsh' } else { 'pwsh.exe' }
$pwshPath = Join-Path "$rootPath/fxd" $pwshExeName
if ($IsLinux) {
chmod u+x $pwshPath
}
$pwshDllPath = Join-Path "$rootPath/fxd" 'pwsh.dll'
$actualOutput = & dotnet $pwshDllPath -c 'Start-ThreadJob -ScriptBlock { "1" } | Wait-Job | Receive-Job'
Write-Verbose -Verbose "Actual output: $actualOutput"
if ($actualOutput -ne 1) {
throw "Actual output is not as expected"
}
displayName: Test package
@@ -0,0 +1,157 @@
parameters:
jobName: ""
displayName: ""
jobtype: "windows"
globalToolExeName: 'pwsh.exe'
globalToolPackageName: 'PowerShell.Windows.x64'
jobs:
- job: ${{ parameters.jobName }}
displayName: ${{ parameters.displayName }}
pool:
type: ${{ parameters.jobtype }}
variables:
- group: DotNetPrivateBuildAccess
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: ob_sdl_credscan_suppressionsFile
value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
- name: ob_sdl_tsa_configFile
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
steps:
- checkout: self
clean: true
- template: release-SetReleaseTagandContainerName.yml@self
- download: PSPackagesOfficial
artifact: drop_nupkg_build_nupkg
displayName: Download nupkgs
- pwsh: |
Get-ChildItem -Path env:
displayName: Capture environment
- pwsh: |
Get-ChildItem "$(Pipeline.Workspace)/PSPackagesOfficial/drop_nupkg_build_nupkg" -Recurse
displayName: 'Capture Downloaded Artifacts'
- pwsh: |
$repoRoot = "$(Build.SourcesDirectory)/PowerShell"
$dotnetMetadataPath = "$repoRoot/DotnetRuntimeMetadata.json"
$dotnetMetadataJson = Get-Content $dotnetMetadataPath -Raw | ConvertFrom-Json
# Channel is like: $Channel = "5.0.1xx-preview2"
$Channel = $dotnetMetadataJson.sdk.channel
$sdkVersion = (Get-Content "$repoRoot/global.json" -Raw | ConvertFrom-Json).sdk.version
Import-Module "$repoRoot/build.psm1" -Force
Find-Dotnet
if(-not (Get-PackageSource -Name 'dotnet' -ErrorAction SilentlyContinue))
{
$nugetFeed = ([xml](Get-Content $repoRoot/nuget.config -Raw)).Configuration.packagesources.add | Where-Object { $_.Key -eq 'dotnet' } | Select-Object -ExpandProperty Value
if ($nugetFeed) {
Register-PackageSource -Name 'dotnet' -Location $nugetFeed -ProviderName NuGet
Write-Verbose -Message "Register new package source 'dotnet'" -verbose
}
}
## Install latest version from the channel
#Install-Dotnet -Channel "$Channel" -Version $sdkVersion
Start-PSBootstrap
Write-Verbose -Message "Installing .NET SDK completed." -Verbose
displayName: Install .NET
env:
__DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
- pwsh: |
$repoRoot = "$(Build.SourcesDirectory)/PowerShell"
$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
Import-Module "$repoRoot/build.psm1" -Force
Start-PSBootstrap
$toolPath = New-Item -ItemType Directory "$(System.DefaultWorkingDirectory)/toolPath" | Select-Object -ExpandProperty FullName
Write-Verbose -Verbose "dotnet tool list -g"
dotnet tool list -g
$packageName = '${{ parameters.globalToolPackageName }}'
Write-Verbose -Verbose "Installing $packageName"
dotnet tool install --add-source "$ENV:PIPELINE_WORKSPACE/PSPackagesOfficial/drop_nupkg_build_nupkg" --tool-path $toolPath --version '$(Version)' $packageName
Get-ChildItem -Path $toolPath
displayName: Install global tool
env:
__DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
- pwsh: |
$toolPath = "$(System.DefaultWorkingDirectory)/toolPath/${{ parameters.globalToolExeName }}"
if (-not (Test-Path $toolPath))
{
throw "Tool is not installed at $toolPath"
}
else
{
Write-Verbose -Verbose "Tool found at: $toolPath"
}
displayName: Validate tool is installed
- pwsh: |
$repoRoot = "$(Build.SourcesDirectory)/PowerShell"
Import-Module "$repoRoot/build.psm1" -Force
Start-PSBootstrap
$exeName = if ($IsWindows) { "pwsh.exe" } else { "pwsh" }
$toolPath = "$(System.DefaultWorkingDirectory)/toolPath/${{ parameters.globalToolExeName }}"
$source = (get-command -Type Application -Name dotnet | Select-Object -First 1 -ExpandProperty source)
$target = (Get-ChildItem $source).target
# If we find a symbolic link for dotnet, then we need to split the filename off the target.
if ($target) {
Write-Verbose -Verbose "Splitting target: $target"
$target = Split-Path $target
}
Write-Verbose -Verbose "target is set as $target"
$env:DOTNET_ROOT = (resolve-path -Path (Join-Path (split-path $source) $target)).ProviderPath
Write-Verbose -Verbose "DOTNET_ROOT: $env:DOTNET_ROOT"
Get-ChildItem $env:DOTNET_ROOT
$versionFound = & $toolPath -c '$PSVersionTable.PSVersion.ToString()'
if ( '$(Version)' -ne $versionFound)
{
throw "Expected version of global tool not found. Installed version is $versionFound"
}
else
{
write-verbose -verbose "Found expected version: $versionFound"
}
$dateYear = & $toolPath -c '(Get-Date).Year'
if ( $dateYear -ne [DateTime]::Now.Year)
{
throw "Get-Date returned incorrect year: $dateYear"
}
else
{
write-verbose -verbose "Got expected year: $dateYear"
}
displayName: Basic validation
env:
__DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
@@ -0,0 +1,193 @@
jobs:
- job: validatePackageNames
displayName: Validate Package Names
pool:
type: windows
variables:
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: ob_sdl_credscan_suppressionsFile
value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
- name: ob_sdl_tsa_configFile
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
- group: 'Azure Blob variable group'
steps:
- pwsh: |
Get-ChildItem ENV:
displayName: Capture environment
- template: release-SetReleaseTagAndContainerName.yml
- pwsh: |
$name = "{0}_{1:x}" -f '$(releaseTag)', (Get-Date).Ticks
Write-Host $name
Write-Host "##vso[build.updatebuildnumber]$name"
displayName: Set Release Name
- pwsh: |
$azureRmModule = Get-InstalledModule AzureRM -ErrorAction SilentlyContinue -Verbose
if ($azureRmModule) {
Write-Host 'AzureRM module exists. Removing it'
Uninstall-AzureRm
Write-Host 'AzureRM module removed'
}
Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose
displayName: Remove AzRM modules and install Az.Storage
- task: AzurePowerShell@5
displayName: Upload packages to blob
inputs:
azureSubscription: az-blob-cicd-infra
scriptType: inlineScript
azurePowerShellVersion: LatestVersion
pwsh: true
inline: |
$storageAccount = Get-AzStorageAccount -ResourceGroupName '$(StorageResourceGroup)' -Name '$(StorageAccount)'
$ctx = $storageAccount.Context
$container = '$(AzureVersion)'
$destinationPath = '$(System.ArtifactsDirectory)'
$blobList = Get-AzStorageBlob -Container $container -Context $ctx
foreach ($blob in $blobList) {
$blobName = $blob.Name
$destinationFile = Join-Path -Path $destinationPath -ChildPath $blobName
Get-AzStorageBlobContent -Container $container -Blob $blobName -Destination $destinationFile -Context $ctx -Force
Write-Output "Downloaded $blobName to $destinationFile"
}
- pwsh: |
Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty Name
displayName: Capture Artifact Listing
- pwsh: |
$message = @()
Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -filter *.rpm | ForEach-Object {
if($_.Name -notmatch 'powershell\-(preview-|lts-)?\d+\.\d+\.\d+(_[a-z]*\.\d+)?-1.(rh|cm).(x86_64|aarch64)\.rpm')
{
$messageInstance = "$($_.Name) is not a valid package name"
$message += $messageInstance
Write-Warning $messageInstance
}
}
if($message.count -gt 0){throw ($message | out-string)}
displayName: Validate RPM package names
- pwsh: |
$message = @()
Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -filter *.tar.gz | ForEach-Object {
if($_.Name -notmatch 'powershell-(lts-)?\d+\.\d+\.\d+\-([a-z]*.\d+\-)?(linux|osx|linux-musl)+\-(x64\-fxdependent|x64|arm32|arm64|x64\-musl-noopt\-fxdependent)\.(tar\.gz)')
{
$messageInstance = "$($_.Name) is not a valid package name"
$message += $messageInstance
Write-Warning $messageInstance
}
}
if($message.count -gt 0){throw ($message | out-string)}
displayName: Validate Tar.Gz Package Names
- pwsh: |
$message = @()
Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -filter *.pkg | ForEach-Object {
if($_.Name -notmatch 'powershell-(lts-)?\d+\.\d+\.\d+\-([a-z]*.\d+\-)?osx(\.10\.12)?\-(x64|arm64)\.pkg')
{
$messageInstance = "$($_.Name) is not a valid package name"
$message += $messageInstance
Write-Warning $messageInstance
}
}
if($message.count -gt 0){throw ($message | out-string)}
displayName: Validate PKG Package Names
- pwsh: |
$message = @()
Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -include *.zip, *.msi | ForEach-Object {
if($_.Name -notmatch 'PowerShell-\d+\.\d+\.\d+\-([a-z]*.\d+\-)?win\-(fxdependent|x64|arm64|x86|fxdependentWinDesktop)\.(msi|zip){1}')
{
$messageInstance = "$($_.Name) is not a valid package name"
$message += $messageInstance
Write-Warning $messageInstance
}
}
if($message.count -gt 0){throw ($message | out-string)}
displayName: Validate Zip and MSI Package Names
- pwsh: |
$message = @()
Get-ChildItem $(System.ArtifactsDirectory)\* -recurse -filter *.deb | ForEach-Object {
if($_.Name -notmatch 'powershell(-preview|-lts)?_\d+\.\d+\.\d+([\-~][a-z]*.\d+)?-\d\.deb_amd64\.deb')
{
$messageInstance = "$($_.Name) is not a valid package name"
$message += $messageInstance
Write-Warning $messageInstance
}
}
if($message.count -gt 0){throw ($message | out-string)}
displayName: Validate Deb Package Names
# Move to 1ES SBOM validation tool
# - job: validateBOM
# displayName: Validate Package Names
# pool:
# type: windows
# variables:
# - name: ob_outputDirectory
# value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
# - name: ob_sdl_credscan_suppressionsFile
# value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
# - name: ob_sdl_tsa_configFile
# value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
# - group: 'Azure Blob variable group'
# steps:
# - checkout: self
# clean: true
# - pwsh: |
# Get-ChildItem ENV:
# displayName: Capture environment
# - template: release-SetReleaseTagAndContainerName.yml
# - pwsh: |
# $name = "{0}_{1:x}" -f '$(releaseTag)', (Get-Date).Ticks
# Write-Host $name
# Write-Host "##vso[build.updatebuildnumber]$name"
# displayName: Set Release Name
# - task: DownloadPipelineArtifact@2
# inputs:
# source: specific
# project: PowerShellCore
# pipeline: '696'
# preferTriggeringPipeline: true
# runVersion: latestFromBranch
# runBranch: '$(Build.SourceBranch)'
# artifact: finalResults
# path: $(System.ArtifactsDirectory)
# - pwsh: |
# Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty Name
# displayName: Capture Artifact Listing
# - pwsh: |
# Install-module Pester -Scope CurrentUser -Force -MaximumVersion 4.99
# displayName: Install Pester
# condition: succeededOrFailed()
# - pwsh: |
# Import-module './build.psm1'
# Import-module './tools/packaging'
# $env:PACKAGE_FOLDER = '$(System.ArtifactsDirectory)'
# $path = Join-Path -Path $pwd -ChildPath './packageReleaseTests.xml'
# $results = invoke-pester -Script './tools/packaging/releaseTests' -OutputFile $path -OutputFormat NUnitXml -PassThru
# Write-Host "##vso[results.publish type=NUnit;mergeResults=true;runTitle=Package Release Tests;publishRunAttachments=true;resultFiles=$path;]"
# if($results.TotalCount -eq 0 -or $results.FailedCount -gt 0)
# {
# throw "Package Release Tests failed"
# }
# displayName: Run packaging release tests
@@ -0,0 +1,127 @@
parameters:
jobName: ""
displayName: ""
jobtype: "windows"
jobs:
- job: ${{ parameters.jobName }}
displayName: ${{ parameters.displayName }}
pool:
${{ if eq(parameters.jobtype, 'macos') }}:
type: linux
isCustom: true
name: Azure Pipelines
vmImage: 'macOS-latest'
${{ else }}:
type: ${{ parameters.jobtype }}
variables:
- group: AzDevOpsArtifacts
- group: DotNetPrivateBuildAccess
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: ob_sdl_credscan_suppressionsFile
value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
- name: ob_sdl_tsa_configFile
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
steps:
- checkout: self
clean: true
- template: release-SetReleaseTagandContainerName.yml@self
- download: PSPackagesOfficial
artifact: drop_nupkg_build_nupkg
displayName: Download nupkgs
- pwsh: |
Get-ChildItem -Path env:
displayName: Capture environment
- pwsh: |
Get-ChildItem "$(Pipeline.Workspace)/PSPackagesOfficial/drop_nupkg_build_nupkg" -Recurse
displayName: 'Capture Downloaded Artifacts'
- pwsh: |
$repoRoot = $isMacOS ? "$(Build.SourcesDirectory)" : "$(Build.SourcesDirectory)/PowerShell"
$dotnetMetadataPath = "$repoRoot/DotnetRuntimeMetadata.json"
$dotnetMetadataJson = Get-Content $dotnetMetadataPath -Raw | ConvertFrom-Json
# Channel is like: $Channel = "5.0.1xx-preview2"
$Channel = $dotnetMetadataJson.sdk.channel
$sdkVersion = (Get-Content "$repoRoot/global.json" -Raw | ConvertFrom-Json).sdk.version
Import-Module "$repoRoot/build.psm1" -Force
Find-Dotnet
if(-not (Get-PackageSource -Name 'dotnet' -ErrorAction SilentlyContinue))
{
$nugetFeed = ([xml](Get-Content $repoRoot/nuget.config -Raw)).Configuration.packagesources.add | Where-Object { $_.Key -eq 'dotnet' } | Select-Object -ExpandProperty Value
if ($nugetFeed) {
Register-PackageSource -Name 'dotnet' -Location $nugetFeed -ProviderName NuGet
Write-Verbose -Message "Register new package source 'dotnet'" -verbose
}
}
## Install latest version from the channel
#Install-Dotnet -Channel "$Channel" -Version $sdkVersion
Start-PSBootstrap
Write-Verbose -Message "Installing .NET SDK completed." -Verbose
displayName: Install .NET
env:
__DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
- pwsh: |
$repoRoot = $isMacOS ? "$(Build.SourcesDirectory)" : "$(Build.SourcesDirectory)/PowerShell"
$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
Import-Module "$repoRoot/build.psm1" -Force
Start-PSBootstrap
$localLocation = "$(Pipeline.Workspace)/PSPackagesOfficial/drop_nupkg_build_nupkg"
$xmlElement = @"
<add key=`"local`" value=`"$localLocation`" />
<add key="dotnet" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9/nuget/v2" />
</packageSources>
"@
$releaseVersion = '$(Version)'
Write-Verbose -Message "Release Version: $releaseVersion" -Verbose
Set-Location -Path $repoRoot/test/hosting
Get-ChildItem
## register the packages download directory in the nuget file
$nugetConfigContent = Get-Content ./NuGet.Config -Raw
$updateNugetContent = $nugetConfigContent.Replace("</packageSources>", $xmlElement)
$updateNugetContent | Out-File ./NuGet.Config -Encoding ascii
Get-Content ./NuGet.Config
# Add workaround to unblock xUnit testing see issue: https://github.com/dotnet/sdk/issues/26462
$dotnetPath = if ($IsWindows) { "$env:LocalAppData\Microsoft\dotnet" } else { "$env:HOME/.dotnet" }
$env:DOTNET_ROOT = $dotnetPath
dotnet --info
dotnet restore
dotnet test /property:RELEASE_VERSION=$releaseVersion --test-adapter-path:. "--logger:xunit;LogFilePath=$(System.DefaultWorkingDirectory)/test-hosting.xml"
displayName: Restore and execute tests
env:
__DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
- task: PublishTestResults@2
displayName: 'Publish Test Results **\test-hosting.xml'
inputs:
testResultsFormat: XUnit
testResultsFiles: '**\test-hosting.xml'
@@ -106,6 +106,8 @@ jobs:
$pdbs | ForEach-Object {
Write-Verbose -Verbose "Pdb: $($_.FullName)"
}
$pdbs | Compress-Archive -DestinationPath "$(ob_outputDirectory)/symbols.zip" -Update
}
if ($runtime -eq 'fxdependent')
+1 -1
View File
@@ -2297,7 +2297,7 @@ function Start-PSBootstrap {
}
if ($Package) {
Import-Module "$PSScriptRoot\tools\wix\wix.psm1"
$isArm64 = '$(Runtime)' -eq 'arm64'
$isArm64 = "$env:RUNTIME" -eq 'arm64'
Install-Wix -arm64:$isArm64
}
}
+56 -3
View File
@@ -1,6 +1,27 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
Import-Module "$PSScriptRoot\dockerInstall.psm1"
function Append-Path
{
param
(
$path
)
$machinePathString = [System.Environment]::GetEnvironmentVariable('path',[System.EnvironmentVariableTarget]::Machine)
$machinePath = $machinePathString -split ';'
if($machinePath -inotcontains $path)
{
$newPath = "$machinePathString;$path"
Write-Verbose "Adding $path to path..." -Verbose
[System.Environment]::SetEnvironmentVariable('path',$newPath,[System.EnvironmentVariableTarget]::Machine)
Write-Verbose "Added $path to path." -Verbose
}
else
{
Write-Verbose "$path already in path." -Verbose
}
}
# Install using Wix Zip because the MSI requires an older version of dotnet
# which was large and unstable in docker
@@ -14,16 +35,48 @@ function Install-Wix
Remove-Item $targetRoot -Recurse -Force
}
$binPath = Join-Path -Path $targetRoot -ChildPath 'bin'
Register-PSRepository -Name 'dotnet-eng' -SourceLocation "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json"
# keep version in sync with Microsoft.PowerShell.Packaging.csproj
Save-Module -name Microsoft.Signed.Wix -RequiredVersion '3.14.1-8722.20240403.1' -path "$binPath/"
$docExpandPath = Join-Path -Path $binPath -ChildPath 'doc'
$sdkExpandPath = Join-Path -Path $binPath -ChildPath 'sdk'
$docTargetPath = Join-Path -Path $targetRoot -ChildPath 'doc'
if (-not (Test-Path $docTargetPath)) {
$null = New-Item -ItemType Directory -Path $docTargetPath
Write-Verbose -Verbose "Created doc directory for WIX at $docTargetPath"
}
$sdkTargetPath = Join-Path -Path $targetRoot -ChildPath 'sdk'
if (-not (Test-Path $sdkTargetPath)) {
$null = New-Item -ItemType Directory -Path $sdkTargetPath
Write-Verbose -Verbose "Created sdk directory for WIX at $sdkTargetPath"
}
$binTargetPath = Join-Path -Path $targetRoot -ChildPath 'bin'
if (-not (Test-Path $binTargetPath)) {
$null = New-Item -ItemType Directory -Path $binTargetPath
Write-Verbose -Verbose "Created bin directory for WIX at $binTargetPath"
}
$x86TargetPath = Join-Path -Path $binPath -ChildPath 'x86'
if (-not (Test-Path $x86TargetPath)) {
$null = New-Item -ItemType Directory -Path $x86TargetPath
Write-Verbose -Verbose "Created x86 directory for WIX at $x86TargetPath"
}
Write-Verbose "Fixing folder structure ..." -Verbose
Move-Item -Path $docExpandPath -Destination $docTargetPath
Move-Item -Path $sdkExpandPath -Destination $sdkTargetPath
Copy-Item -Path $docExpandPath -Destination $docTargetPath -Force
Copy-Item -Path $sdkExpandPath -Destination $sdkTargetPath -Force
Copy-Item -Path "$binPath\wix\3.14.1\tools\*" -Destination $binTargetPath -Force
Copy-Item -Path $x86ExpandPath -Destination $x86TargetPath -Force -Recurse -Verbose
Copy-Item -Path "$x86ExpandPath\burn.exe" -Destination "$x86TargetPath\burn.exe" -Force -Verbose
Append-Path -path $binPath
Write-Verbose "Done installing WIX!"
}