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
78 changes: 65 additions & 13 deletions .pipelines/templates/package-create-msix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,44 @@ jobs:
$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
# Separate LTS and Stable/Preview MSIX files by filename convention
$ltsMsix = @(Get-ChildItem $sourceDir -Filter '*.msix' | Where-Object { $_.BaseName -match '-LTS-' })
$stableMsix = @(Get-ChildItem $sourceDir -Filter '*.msix' | Where-Object { $_.BaseName -notmatch '-LTS-' })

Write-Verbose -Verbose "Stable/Preview MSIX files: $($stableMsix.Name -join ', ')"
Comment on lines +92 to +96
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

This step adds more non-trivial PowerShell logic directly in YAML (file discovery + bundle creation). Consider moving this logic into a reusable PowerShell function (e.g., in tools/ci.psm1 / packaging module) and calling it from YAML to keep the pipeline template easier to maintain and test.

Copilot uses AI. Check for mistakes.
Write-Verbose -Verbose "LTS MSIX files: $($ltsMsix.Name -join ', ')"

# Create Stable/Preview bundle
if ($stableMsix.Count -gt 0) {
$stableDir = "$sourceDir\stable"
New-Item $stableDir -Type Directory -Force > $null
$stableMsix | Copy-Item -Destination $stableDir -Force
$file = $stableMsix | Select-Object -First 1
$prefix = ($file.BaseName -split "-win")[0]
$stableBundleName = "$prefix.msixbundle"
Write-Verbose -Verbose "Creating Stable/Preview bundle: $stableBundleName"
& $makeappx bundle /d $stableDir /p "$outputDir\$stableBundleName"
}
Comment on lines +105 to +109
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

makeappx bundle is executed via the call operator, which won’t fail the step on non-zero exit codes by default. Wrap this native call with Start-NativeExecution (or check $LASTEXITCODE and throw) so bundling failures reliably fail the pipeline with useful diagnostics.

Copilot uses AI. Check for mistakes.

# Create LTS bundle
if ($ltsMsix.Count -gt 0) {
$ltsDir = "$sourceDir\lts"
New-Item $ltsDir -Type Directory -Force > $null
$ltsMsix | Copy-Item -Destination $ltsDir -Force
$file = $ltsMsix | Select-Object -First 1
$prefix = ($file.BaseName -split "-win")[0]
$ltsBundleName = "$prefix.msixbundle"
Write-Verbose -Verbose "Creating LTS bundle: $ltsBundleName"
& $makeappx bundle /d $ltsDir /p "$outputDir\$ltsBundleName"
}
Comment on lines +117 to +121
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

Same as above: this makeappx bundle invocation should use Start-NativeExecution (or explicit exit-code handling) to ensure failures stop the job instead of silently continuing.

Copilot uses AI. Check for mistakes.

Write-Verbose -Verbose "Created bundles:"
Get-ChildItem -Path $outputDir -Recurse

$vstsCommandString = "vso[task.setvariable variable=BundleDir]$outputDir"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
Expand All @@ -112,16 +139,18 @@ jobs:
search_root: '$(BundleDir)'

- pwsh: |
$signedBundle = Get-ChildItem -Path $(BundleDir) -Filter "*.msixbundle" -File
Write-Verbose -Verbose "Signed bundle: $signedBundle"
$signedBundles = @(Get-ChildItem -Path $(BundleDir) -Filter "*.msixbundle" -File)
Write-Verbose -Verbose "Signed bundles: $($signedBundles.Name -join ', ')"

if (-not (Test-Path $(ob_outputDirectory))) {
New-Item -ItemType Directory -Path $(ob_outputDirectory) -Force
}

Copy-Item -Path $signedBundle.FullName -Destination "$(ob_outputDirectory)" -Verbose
foreach ($bundle in $signedBundles) {
Copy-Item -Path $bundle.FullName -Destination "$(ob_outputDirectory)" -Verbose
}

Write-Verbose -Verbose "Uploaded Bundle:"
Write-Verbose -Verbose "Uploaded Bundles:"
Get-ChildItem -Path $(ob_outputDirectory) | Write-Verbose -Verbose
displayName: Upload msixbundle to Artifacts

Expand Down Expand Up @@ -225,6 +254,29 @@ jobs:
Write-Host "##vso[task.setvariable variable=ServiceConnection]$($config.ServiceEndpoint)"
Write-Host "##vso[task.setvariable variable=SBConfigPath]$($sbConfigPath)"

# Select the correct bundle based on channel
$bundleFiles = @(Get-ChildItem -Path '$(BundleDir)' -Filter '*.msixbundle')
Write-Verbose -Verbose "Available bundles: $($bundleFiles.Name -join ', ')"

if ($IsLTS) {
$bundleFile = $bundleFiles | Where-Object { $_.Name -match '-LTS-' }
} else {
# Catches Stable or Preview
$bundleFile = $bundleFiles | Where-Object { $_.Name -notmatch '-LTS-' }
}

if (-not $bundleFile) {
Write-Error "No matching bundle found for channel '$currentChannel'. Available bundles: $($bundleFiles.Name -join ', ')"
exit 1
}

# Copy the selected bundle to a dedicated directory for store packaging
$storeBundleDir = '$(Pipeline.Workspace)\releasePipeline\msix\store-bundle'
New-Item $storeBundleDir -Type Directory -Force > $null
Copy-Item -Path $bundleFile.FullName -Destination $storeBundleDir -Force -Verbose
Write-Host "##vso[task.setvariable variable=StoreBundleDir]$storeBundleDir"
Write-Verbose -Verbose "Selected bundle for store packaging: $($bundleFile.Name)"

# These variables are used in the next tasks to determine which ServiceEndpoint to use
$ltsValue = $IsLTS.ToString().ToLower()
$stableValue = $IsStable.ToString().ToLower()
Expand Down Expand Up @@ -256,7 +308,7 @@ jobs:
inputs:
serviceEndpoint: 'StoreAppPublish-Preview'
sbConfigPath: '$(SBConfigPath)'
sourceFolder: '$(BundleDir)'
sourceFolder: '$(StoreBundleDir)'
contents: '*.msixBundle'
outSBName: 'PowerShellStorePackage'
pdpPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP'
Expand All @@ -268,7 +320,7 @@ jobs:
inputs:
serviceEndpoint: 'StoreAppPublish-Stable'
sbConfigPath: '$(SBConfigPath)'
sourceFolder: '$(BundleDir)'
sourceFolder: '$(StoreBundleDir)'
contents: '*.msixBundle'
outSBName: 'PowerShellStorePackage'
pdpPath: '$(System.DefaultWorkingDirectory)/PowerShell/.pipelines/store/PDP/PDP'
Expand Down
8 changes: 8 additions & 0 deletions .pipelines/templates/packaging/windows/package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,14 @@ jobs:

# Don't build LTS packages for rebuild branches
$LTS = $metadata.LTSRelease.Package -and -not $isRebuildBranch
$Stable = [bool]$metadata.StableRelease.Package

if ($isRebuildBranch) {
Write-Verbose -Message "Rebuild branch detected, skipping LTS package build" -Verbose
}

Write-Verbose -Verbose "LTS: $LTS"
Write-Verbose -Verbose "Stable: $Stable"

if ($LTS) {
Write-Verbose -Message "LTS Release: $LTS"
Expand Down Expand Up @@ -179,6 +181,12 @@ jobs:

Start-PSPackage -Type $packageTypes -SkipReleaseChecks -WindowsRuntime $WindowsRuntime -ReleaseTag $(ReleaseTagVar) -PackageBinPath $signedFilesPath -LTS:$LTS

# When both LTS and Stable are requested, also build the Stable MSIX
if ($packageTypes -contains 'msix' -and $LTS -and $Stable) {
Write-Verbose -Verbose "Both LTS and Stable packages requested. Building additional Stable MSIX."
Start-PSPackage -Type msix -SkipReleaseChecks -WindowsRuntime $WindowsRuntime -ReleaseTag $(ReleaseTagVar) -PackageBinPath $signedFilesPath
}

displayName: 'Build Packages (Unsigned)'
env:
__DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
Expand Down
19 changes: 8 additions & 11 deletions tools/packaging/packaging.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -4240,18 +4240,8 @@ function New-MSIXPackage

$makepri = Get-Item (Join-Path $makeappx.Directory "makepri.exe") -ErrorAction Stop

$displayName = $ProductName
$ProductSemanticVersion = Get-PackageSemanticVersion -Version $ProductVersion
$productSemanticVersionWithName = $ProductName + '-' + $ProductSemanticVersion
$packageName = $productSemanticVersionWithName
if ($Private) {
$ProductNameSuffix = 'Private'
}

if ($ProductNameSuffix) {
$packageName += "-$ProductNameSuffix"
}

$displayName = $productName

if ($Private) {
$ProductName = 'PowerShell-Private'
Expand All @@ -4267,6 +4257,13 @@ function New-MSIXPackage
Write-Verbose -Verbose "ProductName: $productName"
Write-Verbose -Verbose "DisplayName: $displayName"

$packageName = $ProductName + '-' + $ProductSemanticVersion

# Appends Architecture to the package name
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

The comment says the package name suffix appends architecture, but the code appends ProductNameSuffix (which may or may not be architecture). Consider updating the comment to reflect what’s actually appended (e.g., the RID/name suffix like win-x64).

Suggested change
# Appends Architecture to the package name
# Append the product name suffix (e.g., RID/architecture suffix like win-x64) to the package name

Copilot uses AI. Check for mistakes.
if ($ProductNameSuffix) {
$packageName += "-$ProductNameSuffix"
}

$ProductVersion = Get-WindowsVersion -PackageName $packageName

$isPreview = Test-IsPreview -Version $ProductSemanticVersion
Expand Down
Loading