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 ', ')"
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 +104 to +109
Copy link

Copilot AI Mar 19, 2026

Choose a reason for hiding this comment

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

makeappx bundle is invoked via the call operator, which won’t fail the step on a non-zero native exit code by default. Please ensure the pipeline fails when bundling fails (e.g., check $LASTEXITCODE after the call and throw, or use the repo’s native-execution helper) so we don’t publish missing/invalid bundles.

This issue also appears on line 116 of the same file.

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"
}

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 @@ -224,6 +253,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
Write-Host "##vso[task.setvariable variable=LTS]$($IsLTS.ToString().ToLower())"
Write-Host "##vso[task.setvariable variable=STABLE]$($IsStable.ToString().ToLower())"
Expand All @@ -244,7 +296,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 @@ -256,7 +308,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 @@ -136,12 +136,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 @@ -175,6 +177,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 @@ -4274,18 +4274,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 @@ -4301,6 +4291,13 @@ function New-MSIXPackage
Write-Verbose -Verbose "ProductName: $productName"
Write-Verbose -Verbose "DisplayName: $displayName"

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

# Appends Architecture to the package name
if ($ProductNameSuffix) {
$packageName += "-$ProductNameSuffix"
}

$ProductVersion = Get-WindowsVersion -PackageName $packageName

# Any app that is submitted to the Store must have a PhoneIdentity in its appxmanifest.
Expand Down
Loading