Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .pipelines/PowerShell-Release-Official.yml
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ extends:
parameters:
jobName: "LinuxSDK"
displayName: "Linux SDK Validation"
imageName: PSMMSUbuntu20.04-Secure
imageName: PSMMSUbuntu22.04-Secure
poolName: $(ubuntuPool)

- stage: gbltool
Expand Down Expand Up @@ -358,7 +358,7 @@ extends:
This is typically done by the community 1-2 days after the release.

- stage: PublishMsix
dependsOn:
dependsOn:
- setReleaseTagAndChangelog
- PushGitTagAndMakeDraftPublic
displayName: Publish MSIX to store
Expand Down Expand Up @@ -440,4 +440,4 @@ extends:
displayName: Delete release branch
jobName: DeleteBranch
instructions: |
Delete release
Delete release
6 changes: 4 additions & 2 deletions .pipelines/store/SBConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"packageParameters": {
"PDPRootPath": "",
"Release": "",
"PDPInclude": [],
"PDPInclude": [
"PDP.xml"
],
"PDPExclude": [],
"LanguageExclude": [
"default",
Expand All @@ -21,7 +23,7 @@
},
"appSubmission": {
"productId": "",
"targetPublishMode": "NotSet",
"targetPublishMode": "Immediate",
"targetPublishDate": null,
"visibility": "NotSet",
"pricing": {
Expand Down
66 changes: 24 additions & 42 deletions .pipelines/templates/package-create-msix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ jobs:
- group: msixTools
- group: 'Azure Blob variable group'
- group: 'Store Publish Variables'
- name: ob_sdl_credscan_suppressionsFile
value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
- name: ob_sdl_tsa_configFile
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'

Expand Down Expand Up @@ -145,16 +149,19 @@ jobs:
'LTS' = @{
AppStoreName = 'PowerShell-LTS'
ProductId = '$(productId-LTS)'
AppId = '$(AppID-LTS)'
ServiceEndpoint = "StoreAppPublish-Stable"
}
'Stable' = @{
AppStoreName = 'PowerShell'
ProductId = '$(productId-Stable)'
AppId = '$(AppID-Stable)'
ServiceEndpoint = "StoreAppPublish-Stable"
}
'Preview' = @{
AppStoreName = 'PowerShell (Preview)'
ProductId = '$(productId-Preview)'
AppId = '$(AppID-Preview)'
ServiceEndpoint = "StoreAppPublish-Preview"
}
}
Expand All @@ -179,16 +186,21 @@ jobs:

[xml]$pdpXml = Get-Content $pdpPath -Raw

$appStoreNameElement = $pdpXml.SelectSingleNode("//AppStoreName[@_locID]")
# Create namespace manager for XML with default namespace
$nsManager = New-Object System.Xml.XmlNamespaceManager($pdpXml.NameTable)
$nsManager.AddNamespace("pd", "http://schemas.microsoft.com/appx/2012/ProductDescription")

$appStoreNameElement = $pdpXml.SelectSingleNode("//pd:AppStoreName", $nsManager)
if ($appStoreNameElement) {
$appStoreNameElement.InnerText = $config.AppStoreName
Write-Verbose -Verbose "Updated AppStoreName to: $($config.AppStoreName)"
$appStoreNameElement.SetAttribute("_locID", $config.AppStoreName)
Write-Verbose -Verbose "Updated AppStoreName _locID to: $($config.AppStoreName)"
Comment on lines +189 to +196
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PDP update logic now sets the AppStoreName element’s _locID attribute to values like PowerShell / PowerShell-LTS, but it does not set the element text. In the checked-in PDP.xml, <AppStoreName _locID="PowerShell-Private"> currently has no inner text, so this change likely won’t update the Store name as intended. If the goal is to update the Store display name, set the element content (or clarify/update both _locID and the text consistently with how StoreBroker expects this value).

Copilot uses AI. Check for mistakes.
} else {
Write-Warning "AppStoreName element not found in PDP file"
}

$pdpXml.Save($pdpPath)
Write-Verbose -Verbose "PDP file updated successfully"
Get-Content -Path $pdpPath | Write-Verbose -Verbose
} else {
Write-Error "PDP file not found: $pdpPath"
exit 1
Expand All @@ -206,62 +218,32 @@ jobs:

$sbConfigJson | ConvertTo-Json -Depth 100 | Set-Content $sbConfigPath -Encoding UTF8
Write-Verbose -Verbose "SBConfig file updated successfully"
Get-Content -Path $sbConfigPath | Write-Verbose -Verbose
} else {
Write-Error "SBConfig file not found: $sbConfigPath"
exit 1
}

Write-Host "##vso[task.setvariable variable=ServiceConnection]$($config.ServiceEndpoint)"
Write-Host "##vso[task.setvariable variable=SBConfigPath]$($sbConfigPath)"
Comment on lines 227 to 228
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ServiceConnection is being set from $config.ServiceEndpoint, but it isn't referenced anywhere else in this template (the StoreBroker tasks now use hard-coded StoreAppPublish-Private). Consider removing this variable assignment (and the unused per-channel ServiceEndpoint config values) to avoid confusion about which endpoint is actually used.

Copilot uses AI. Check for mistakes.

# These variables are used in the next tasks to determine which ServiceEndpoint to use
$ltsValue = $IsLTS.ToString().ToLower()
$stableValue = $IsStable.ToString().ToLower()
$previewValue = $IsPreview.ToString().ToLower()

Write-Verbose -Verbose "About to set variables:"
Write-Verbose -Verbose " LTS=$ltsValue"
Write-Verbose -Verbose " STABLE=$stableValue"
Write-Verbose -Verbose " PREVIEW=$previewValue"

Write-Host "##vso[task.setvariable variable=LTS]$ltsValue"
Write-Host "##vso[task.setvariable variable=STABLE]$stableValue"
Write-Host "##vso[task.setvariable variable=PREVIEW]$previewValue"

Write-Verbose -Verbose "Variables set successfully"
name: UpdateConfigs
displayName: Update PDPs and SBConfig.json

- pwsh: |
Write-Verbose -Verbose "Checking variables after UpdateConfigs:"
Write-Verbose -Verbose "LTS=$(LTS)"
Write-Verbose -Verbose "STABLE=$(STABLE)"
Write-Verbose -Verbose "PREVIEW=$(PREVIEW)"
displayName: Debug - Check Variables

- task: MS-RDX-MRO.windows-store-publish.package-task.store-package@3
displayName: 'Create StoreBroker Package (Preview)'
condition: eq(variables['PREVIEW'], 'true')
displayName: 'Create StoreBroker Package'
inputs:
serviceEndpoint: 'StoreAppPublish-Preview'
serviceEndpoint: 'StoreAppPublish-Private'
sbConfigPath: '$(SBConfigPath)'
Comment on lines 232 to 236
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file contains an unresolved merge-conflict marker (>>>>>>> ...) and also has duplicate inputs: keys under the same task. Either of these will break YAML parsing / task configuration; please resolve the conflict and ensure the task has a single inputs: mapping.

Copilot uses AI. Check for mistakes.
sourceFolder: '$(BundleDir)'
contents: '*.msixBundle'
outSBName: 'PowerShellStorePackage'
pdpPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP'
pdpMediaPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP-Media'

- task: MS-RDX-MRO.windows-store-publish.package-task.store-package@3
displayName: 'Create StoreBroker Package (Stable/LTS)'
condition: or(eq(variables['STABLE'], 'true'), eq(variables['LTS'], 'true'))
inputs:
serviceEndpoint: 'StoreAppPublish-Stable'
sbConfigPath: '$(SBConfigPath)'
sourceFolder: '$(BundleDir)'
contents: '*.msixBundle'
outSBName: 'PowerShellStorePackage'
pdpPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP'
pdpMediaPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP-Media'
- pwsh: |
Get-Item -Path "$(System.DefaultWorkingDirectory)/SBLog.txt" -ErrorAction SilentlyContinue |
Copy-Item -Destination "$(ob_outputDirectory)" -Verbose
displayName: Upload Store Failure Log
condition: failed()

- pwsh: |
$submissionPackageDir = "$(System.DefaultWorkingDirectory)/SBOutDir"
Expand All @@ -279,4 +261,4 @@ jobs:
else {
Write-Error "Required files not found in $submissionPackageDir"
}
displayName: 'Upload StoreBroker Package'
displayName: 'Upload StoreBroker Package'
95 changes: 43 additions & 52 deletions .pipelines/templates/release-MSIX-Publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ jobs:
artifactName: drop_msixbundle_CreateMSIXBundle
variables:
- group: 'Store Publish Variables'
- name: LTS
value: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsLTS'] ]
- name: STABLE
value: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsStable'] ]
- name: PREVIEW
value: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsPreview'] ]
- template: ./variable/release-shared.yml@self
parameters:
RELEASETAG: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['OutputReleaseTag.releaseTag'] ]
LTS: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsLTS'] ]
STABLE: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsStable'] ]
PREVIEW: $[ stageDependencies.setReleaseTagAndChangelog.setTagAndChangelog.outputs['ChannelSelection.IsPreview'] ]
steps:
- task: PowerShell@2
inputs:
Expand All @@ -40,15 +43,14 @@ jobs:
}
$middleURL = ''
$tagString = "$(ReleaseTag)"
if ($tagString -match '-') {
if ($tagString -match '-preview') {
$middleURL = "preview"
}
elseif ($tagString -match '(\d+\.\d+)') {
$middleURL = $matches[1]
}


$endURL = $tagString -replace '^v','' -replace '\.',''
$endURL = $tagString -replace '^v|\.', ''
$message = "Changelog: https://github.com/PowerShell/PowerShell/blob/master/CHANGELOG/$middleURL.md#$endURL"
Write-Verbose -Verbose "Release Notes for the Store:"
Write-Verbose -Verbose "$message"
Expand All @@ -64,61 +66,32 @@ jobs:
inputs:
targetType: inline
script: |
Write-Verbose -Verbose "Channel Selection - LTS: $(LTS), Stable: $(Stable), Preview: $(Preview)"
# Convert ADO variables to PowerShell boolean variables
$IsLTS = '$(LTS)' -eq 'true'
$IsStable = '$(STABLE)' -eq 'true'
$IsPreview = '$(PREVIEW)' -eq 'true'

# Define app configurations for each channel using secret variables
$channelConfigs = @{
'LTS' = @{
AppId = '$(AppID-LTS)'
ServiceEndpoint = 'StoreAppPublish-Stable'
}
'Stable' = @{
AppId = '$(AppID-Stable)'
ServiceEndpoint = 'StoreAppPublish-Stable'
}
'Preview' = @{
AppId = '$(AppID-Preview)'
ServiceEndpoint = 'StoreAppPublish-Preview'
}
}
Write-Verbose -Verbose "Channel Selection - LTS: $(LTS), Stable: $(STABLE), Preview: $(PREVIEW)"

# Determine the current channel for logging purposes
$currentChannel = if ($IsLTS) { 'LTS' }
elseif ($IsStable) { 'Stable' }
elseif ($IsPreview) { 'Preview' }
else {
Write-Error "No valid channel detected"
exit 1
}

# Assign AppID for Store-Publish Task
$appID = $null
if ($IsLTS) {
$appID = '$(AppID-LTS)'
}
elseif ($IsStable) {
$appID = '$(AppID-Stable)'
}
else {
$appID = '$(AppID-Preview)'
}

Write-Host "##vso[task.setvariable variable=AppID]$appID"

Write-Verbose -Verbose "Selected channel: $currentChannel"
Write-Verbose -Verbose "App ID: $($config.AppId)"
Write-Verbose -Verbose "Service Endpoint: $($config.ServiceEndpoint)"

# Set pipeline variables for use in the store-publish task
Write-Host "##vso[task.setvariable variable=SelectedAppId]$($config.AppId)"
Write-Host "##vso[task.setvariable variable=SelectedServiceEndpoint]$($config.ServiceEndpoint)"
Write-Host "##vso[task.setvariable variable=SelectedChannel]$currentChannel"
displayName: 'Set StoreBroker Configurations'
Write-Verbose -Verbose "Conditional tasks will handle the publishing based on channel variables"
displayName: 'Validate Channel Selection'

- task: MS-RDX-MRO.windows-store-publish.publish-task.store-publish@3
displayName: 'Publish StoreBroker Package (Stable/LTS)'
condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), or(eq('$(STABLE)', 'true'), eq('$(LTS)', 'true')))
displayName: 'Publish LTS StoreBroker Package'
condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), eq(variables['LTS'], 'true'))
inputs:
serviceEndpoint: 'StoreAppPublish-Stable'
appId: '$(AppID)'
serviceEndpoint: 'StoreAppPublish-Private'
appId: '$(AppID-LTS)'
inputMethod: JsonAndZip
jsonPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.json'
zipPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.zip'
Expand All @@ -127,14 +100,32 @@ jobs:
targetPublishMode: 'Immediate'

- task: MS-RDX-MRO.windows-store-publish.publish-task.store-publish@3
displayName: 'Publish StoreBroker Package (Preview)'
condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), eq('$(PREVIEW)', 'true'))
displayName: 'Publish Stable StoreBroker Package'
condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), eq(variables['STABLE'], 'true'))
inputs:
serviceEndpoint: 'StoreAppPublish-Preview'
appId: '$(AppID)'
serviceEndpoint: 'StoreAppPublish-Private'
appId: '$(AppID-Stable)'
inputMethod: JsonAndZip
jsonPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.json'
zipPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.zip'
numberOfPackagesToKeep: 2
jsonZipUpdateMetadata: true
targetPublishMode: 'Immediate'

- task: MS-RDX-MRO.windows-store-publish.publish-task.store-publish@3
displayName: 'Publish Preview StoreBroker Package'
condition: and(ne('${{ parameters.skipMSIXPublish }}', 'true'), eq(variables['PREVIEW'], 'true'))
inputs:
serviceEndpoint: 'StoreAppPublish-Private'
appId: '$(AppID-Preview)'
inputMethod: JsonAndZip
jsonPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.json'
zipPath: '$(Pipeline.Workspace)\SBOutDir\PowerShellStorePackage.zip'
numberOfPackagesToKeep: 2
jsonZipUpdateMetadata: true
targetPublishMode: 'Immediate'

- pwsh: |
Get-Content -Path "$(System.DefaultWorkingDirectory)/SBLog.txt" -ErrorAction SilentlyContinue
displayName: Upload Store Failure Log
condition: failed()
Comment on lines +128 to +131
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This step is labeled "Upload Store Failure Log", but it only prints the contents of SBLog.txt and doesn't publish it as an artifact or attach it anywhere. Either rename the step to reflect its behavior (e.g., "Print Store Failure Log") or add an explicit artifact upload/publish step if the intent is to persist the log.

Copilot uses AI. Check for mistakes.
4 changes: 2 additions & 2 deletions .pipelines/templates/release-githubNuget.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@ jobs:
$middleURL = ''
$tagString = "$(ReleaseTag)"
Write-Verbose -Verbose "Use the following command to push the tag:"
if ($tagString -match '-') {
if ($tagString -match '-preview') {
$middleURL = "preview"
}
elseif ($tagString -match '(\d+\.\d+)') {
$middleURL = $matches[1]
}
$endURL = $tagString -replace '[v\.]',''
$endURL = $tagString -replace '^v|\.', ''
$message = "https://github.com/PowerShell/PowerShell/blob/master/CHANGELOG/$middleURL.md#$endURL"
Write-Verbose -Verbose "git tag -a $(ReleaseTag) $env:BUILD_SOURCEVERSION -m $message"
displayName: Git Push Tag Command
Expand Down
6 changes: 6 additions & 0 deletions .pipelines/templates/release-validate-globaltools.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ jobs:
- pwsh: |
$repoRoot = "$(Build.SourcesDirectory)/PowerShell"

Import-Module "$repoRoot/build.psm1" -Force -Verbose
Start-PSBootstrap -Scenario Dotnet

$toolPath = New-Item -ItemType Directory "$(System.DefaultWorkingDirectory)/toolPath" | Select-Object -ExpandProperty FullName

Write-Verbose -Verbose "dotnet tool list -g"
Expand Down Expand Up @@ -75,6 +78,9 @@ jobs:
- pwsh: |
$repoRoot = "$(Build.SourcesDirectory)/PowerShell"

Import-Module "$repoRoot/build.psm1" -Force -Verbose
Start-PSBootstrap -Scenario Dotnet

$exeName = if ($IsWindows) { "pwsh.exe" } else { "pwsh" }

$toolPath = "$(System.DefaultWorkingDirectory)/toolPath/${{ parameters.globalToolExeName }}"
Expand Down
5 changes: 4 additions & 1 deletion .pipelines/templates/release-validate-sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ jobs:
- pwsh: |
$repoRoot = "$(Build.SourcesDirectory)"

$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
Import-Module "$repoRoot/build.psm1" -Force -Verbose
Start-PSBootstrap -Scenario Dotnet
Comment on lines 51 to +55
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$repoRoot is set to $(Build.SourcesDirectory), but other release templates in this repo consistently reference the repo content under $(Build.SourcesDirectory)/PowerShell (for example, release-SetTagAndChangelog.yml and release-validate-globaltools.yml). With the current value, Import-Module "$repoRoot/build.psm1" and Set-Location $repoRoot/test/hosting are likely to point at the wrong path in the release pipeline layout. Update $repoRoot (and the insert-nuget-config repoRoot parameter if needed) to the same .../PowerShell root used elsewhere.

Copilot uses AI. Check for mistakes.

$env:DOTNET_NOLOGO=1

Comment on lines +54 to 58
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file contains an unresolved merge-conflict marker (>>>>>>> ...). YAML parsing will fail and the pipeline template won't run until this marker is removed and the conflict is properly resolved.

Copilot uses AI. Check for mistakes.
$localLocation = "$(Pipeline.Workspace)/PSPackagesOfficial/drop_nupkg_build_nupkg"
$xmlElement = @"
Expand Down
2 changes: 1 addition & 1 deletion .pipelines/templates/windows-hosted-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ jobs:
'Microsoft.PowerShell.PSResourceGet'
'Microsoft.PowerShell.Archive'
'PSReadLine'
'ThreadJob'
'Microsoft.PowerShell.ThreadJob'
)

$sourceModulePath = Join-Path '$(GlobalToolArtifactPath)' 'publish' 'PowerShell.Windows.x64' 'release' 'Modules'
Expand Down
Loading