|
|
|
|
@@ -13,9 +13,36 @@ Param(
|
|
|
|
|
|
|
|
|
|
# Root folder Path for processing
|
|
|
|
|
[Parameter(Mandatory=$False,Position=4)]
|
|
|
|
|
[string]$sourceLink = "https://microsoft.pkgs.visualstudio.com/ProjectReunion/_packaging/Project.Reunion.nuget.internal/nuget/v3/index.json"
|
|
|
|
|
[string]$sourceLink = "https://microsoft.pkgs.visualstudio.com/ProjectReunion/_packaging/Project.Reunion.nuget.internal/nuget/v3/index.json",
|
|
|
|
|
|
|
|
|
|
# Use Azure Pipeline artifact as source for metapackage
|
|
|
|
|
[Parameter(Mandatory=$False,Position=5)]
|
|
|
|
|
[boolean]$useArtifactSource = $False,
|
|
|
|
|
|
|
|
|
|
# Azure DevOps organization URL
|
|
|
|
|
[Parameter(Mandatory=$False,Position=6)]
|
|
|
|
|
[string]$azureDevOpsOrg = "https://dev.azure.com/microsoft",
|
|
|
|
|
|
|
|
|
|
# Azure DevOps project name
|
|
|
|
|
[Parameter(Mandatory=$False,Position=7)]
|
|
|
|
|
[string]$azureDevOpsProject = "ProjectReunion",
|
|
|
|
|
|
|
|
|
|
# Pipeline build ID (or "latest" for latest build)
|
|
|
|
|
[Parameter(Mandatory=$False,Position=8)]
|
|
|
|
|
[string]$buildId = "",
|
|
|
|
|
|
|
|
|
|
# Artifact name containing the NuGet packages
|
|
|
|
|
[Parameter(Mandatory=$False,Position=9)]
|
|
|
|
|
[string]$artifactName = "WindowsAppSDK_Nuget_And_MSIX",
|
|
|
|
|
|
|
|
|
|
# Metapackage name to look for in artifact
|
|
|
|
|
[Parameter(Mandatory=$False,Position=10)]
|
|
|
|
|
[string]$metaPackageName = "Microsoft.WindowsAppSDK"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Script-level constants
|
|
|
|
|
$script:PackageVersionRegex = '^(.+?)\.(\d+\..*)$'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function Read-FileWithEncoding {
|
|
|
|
|
@@ -57,7 +84,7 @@ function Add-NuGetSourceAndMapping {
|
|
|
|
|
|
|
|
|
|
# Ensure packageSources exists
|
|
|
|
|
if (-not $Xml.configuration.packageSources) {
|
|
|
|
|
$Xml.configuration.AppendChild($Xml.CreateElement("packageSources")) | Out-Null
|
|
|
|
|
$null = $Xml.configuration.AppendChild($Xml.CreateElement("packageSources"))
|
|
|
|
|
}
|
|
|
|
|
$sources = $Xml.configuration.packageSources
|
|
|
|
|
|
|
|
|
|
@@ -66,13 +93,13 @@ function Add-NuGetSourceAndMapping {
|
|
|
|
|
if (-not $sourceNode) {
|
|
|
|
|
$sourceNode = $Xml.CreateElement("add")
|
|
|
|
|
$sourceNode.SetAttribute("key", $Key)
|
|
|
|
|
$sources.AppendChild($sourceNode) | Out-Null
|
|
|
|
|
$null = $sources.AppendChild($sourceNode)
|
|
|
|
|
}
|
|
|
|
|
$sourceNode.SetAttribute("value", $Value)
|
|
|
|
|
|
|
|
|
|
# Ensure packageSourceMapping exists
|
|
|
|
|
if (-not $Xml.configuration.packageSourceMapping) {
|
|
|
|
|
$Xml.configuration.AppendChild($Xml.CreateElement("packageSourceMapping")) | Out-Null
|
|
|
|
|
$null = $Xml.configuration.AppendChild($Xml.CreateElement("packageSourceMapping"))
|
|
|
|
|
}
|
|
|
|
|
$mapping = $Xml.configuration.packageSourceMapping
|
|
|
|
|
|
|
|
|
|
@@ -80,7 +107,7 @@ function Add-NuGetSourceAndMapping {
|
|
|
|
|
$invalidNodes = $mapping.SelectNodes("packageSource[not(@key) or @key='']")
|
|
|
|
|
if ($invalidNodes) {
|
|
|
|
|
foreach ($node in $invalidNodes) {
|
|
|
|
|
$mapping.RemoveChild($node) | Out-Null
|
|
|
|
|
$null = $mapping.RemoveChild($node)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -91,9 +118,9 @@ function Add-NuGetSourceAndMapping {
|
|
|
|
|
$mappingSource.SetAttribute("key", $Key)
|
|
|
|
|
# Insert at top for priority
|
|
|
|
|
if ($mapping.HasChildNodes) {
|
|
|
|
|
$mapping.InsertBefore($mappingSource, $mapping.FirstChild) | Out-Null
|
|
|
|
|
$null = $mapping.InsertBefore($mappingSource, $mapping.FirstChild)
|
|
|
|
|
} else {
|
|
|
|
|
$mapping.AppendChild($mappingSource) | Out-Null
|
|
|
|
|
$null = $mapping.AppendChild($mappingSource)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -110,14 +137,273 @@ function Add-NuGetSourceAndMapping {
|
|
|
|
|
foreach ($pattern in $Patterns) {
|
|
|
|
|
$pkg = $Xml.CreateElement("package")
|
|
|
|
|
$pkg.SetAttribute("pattern", $pattern)
|
|
|
|
|
$mappingSource.AppendChild($pkg) | Out-Null
|
|
|
|
|
$null = $mappingSource.AppendChild($pkg)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Download-ArtifactFromPipeline {
|
|
|
|
|
param (
|
|
|
|
|
[string]$Organization,
|
|
|
|
|
[string]$Project,
|
|
|
|
|
[string]$BuildId,
|
|
|
|
|
[string]$ArtifactName,
|
|
|
|
|
[string]$OutputDir
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
Write-Host "Downloading artifact '$ArtifactName' from build $BuildId..."
|
|
|
|
|
$null = New-Item -ItemType Directory -Path $OutputDir -Force
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
# Authenticate with Azure DevOps using System Access Token (if available)
|
|
|
|
|
if ($env:SYSTEM_ACCESSTOKEN) {
|
|
|
|
|
Write-Host "Authenticating with Azure DevOps using System Access Token..."
|
|
|
|
|
$env:AZURE_DEVOPS_EXT_PAT = $env:SYSTEM_ACCESSTOKEN
|
|
|
|
|
} else {
|
|
|
|
|
Write-Host "No SYSTEM_ACCESSTOKEN found, assuming az CLI is already authenticated..."
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Use az CLI to download artifact
|
|
|
|
|
& az pipelines runs artifact download `
|
|
|
|
|
--organization $Organization `
|
|
|
|
|
--project $Project `
|
|
|
|
|
--run-id $BuildId `
|
|
|
|
|
--artifact-name $ArtifactName `
|
|
|
|
|
--path $OutputDir
|
|
|
|
|
|
|
|
|
|
if ($LASTEXITCODE -eq 0) {
|
|
|
|
|
Write-Host "Successfully downloaded artifact to $OutputDir"
|
|
|
|
|
return $true
|
|
|
|
|
} else {
|
|
|
|
|
Write-Warning "Failed to download artifact. Exit code: $LASTEXITCODE"
|
|
|
|
|
return $false
|
|
|
|
|
}
|
|
|
|
|
} catch {
|
|
|
|
|
Write-Warning "Error downloading artifact: $_"
|
|
|
|
|
return $false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Get-NuspecDependencies {
|
|
|
|
|
param (
|
|
|
|
|
[string]$NupkgPath,
|
|
|
|
|
[string]$TargetFramework = ""
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
$tempDir = Join-Path $env:TEMP "nuspec_parse_$(Get-Random)"
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
# Extract .nupkg (it's a zip file)
|
|
|
|
|
# Workaround: Expand-Archive may not recognize .nupkg extension, so copy to .zip first
|
|
|
|
|
$tempZip = Join-Path $env:TEMP "temp_$(Get-Random).zip"
|
|
|
|
|
Copy-Item $NupkgPath -Destination $tempZip -Force
|
|
|
|
|
Expand-Archive -Path $tempZip -DestinationPath $tempDir -Force
|
|
|
|
|
Remove-Item $tempZip -Force -ErrorAction SilentlyContinue
|
|
|
|
|
|
|
|
|
|
# Find .nuspec file
|
|
|
|
|
$nuspecFile = Get-ChildItem -Path $tempDir -Filter "*.nuspec" -Recurse | Select-Object -First 1
|
|
|
|
|
|
|
|
|
|
if (-not $nuspecFile) {
|
|
|
|
|
Write-Warning "No .nuspec file found in $NupkgPath"
|
|
|
|
|
return @{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[xml]$nuspec = Get-Content $nuspecFile.FullName
|
|
|
|
|
|
|
|
|
|
# Extract package info
|
|
|
|
|
$packageId = $nuspec.package.metadata.id
|
|
|
|
|
$version = $nuspec.package.metadata.version
|
|
|
|
|
Write-Host "Parsing $packageId version $version"
|
|
|
|
|
|
|
|
|
|
# Parse dependencies
|
|
|
|
|
$dependencies = @{}
|
|
|
|
|
$depGroups = $nuspec.package.metadata.dependencies.group
|
|
|
|
|
|
|
|
|
|
if ($depGroups) {
|
|
|
|
|
# Dependencies are grouped by target framework
|
|
|
|
|
foreach ($group in $depGroups) {
|
|
|
|
|
$fx = $group.targetFramework
|
|
|
|
|
Write-Host " Target Framework: $fx"
|
|
|
|
|
|
|
|
|
|
foreach ($dep in $group.dependency) {
|
|
|
|
|
$depId = $dep.id
|
|
|
|
|
$depVer = $dep.version
|
|
|
|
|
# Remove version range brackets if present (e.g., "[2.0.0]" -> "2.0.0")
|
|
|
|
|
$depVer = $depVer -replace '[\[\]]', ''
|
|
|
|
|
$dependencies[$depId] = $depVer
|
|
|
|
|
Write-Host " - ${depId} : ${depVer}"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
# No grouping, direct dependencies
|
|
|
|
|
$deps = $nuspec.package.metadata.dependencies.dependency
|
|
|
|
|
if ($deps) {
|
|
|
|
|
foreach ($dep in $deps) {
|
|
|
|
|
$depId = $dep.id
|
|
|
|
|
$depVer = $dep.version
|
|
|
|
|
$depVer = $depVer -replace '[\[\]]', ''
|
|
|
|
|
$dependencies[$depId] = $depVer
|
|
|
|
|
Write-Host " - ${depId} : ${depVer}"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $dependencies
|
|
|
|
|
}
|
|
|
|
|
catch {
|
|
|
|
|
Write-Warning "Failed to parse nuspec: $_"
|
|
|
|
|
return @{}
|
|
|
|
|
}
|
|
|
|
|
finally {
|
|
|
|
|
Remove-Item $tempDir -Recurse -Force -ErrorAction SilentlyContinue
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Resolve-ArtifactBasedDependencies {
|
|
|
|
|
param (
|
|
|
|
|
[string]$ArtifactDir,
|
|
|
|
|
[string]$MetaPackageName,
|
|
|
|
|
[string]$SourceUrl,
|
|
|
|
|
[string]$OutputDir
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
Write-Host "Resolving dependencies from artifact-based metapackage..."
|
|
|
|
|
$null = New-Item -ItemType Directory -Path $OutputDir -Force
|
|
|
|
|
|
|
|
|
|
# Find the metapackage in artifact
|
|
|
|
|
$metaNupkg = Get-ChildItem -Path $ArtifactDir -Recurse -Filter "$MetaPackageName.*.nupkg" |
|
|
|
|
|
Where-Object { $_.Name -notmatch "Runtime" } |
|
|
|
|
|
Select-Object -First 1
|
|
|
|
|
|
|
|
|
|
if (-not $metaNupkg) {
|
|
|
|
|
Write-Warning "Metapackage $MetaPackageName not found in artifact"
|
|
|
|
|
return @{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Extract version from filename
|
|
|
|
|
if ($metaNupkg.Name -match "$MetaPackageName\.(.+)\.nupkg") {
|
|
|
|
|
$metaVersion = $Matches[1]
|
|
|
|
|
Write-Host "Found metapackage: $MetaPackageName version $metaVersion"
|
|
|
|
|
} else {
|
|
|
|
|
Write-Warning "Could not extract version from $($metaNupkg.Name)"
|
|
|
|
|
return @{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Parse dependencies from metapackage
|
|
|
|
|
$dependencies = Get-NuspecDependencies -NupkgPath $metaNupkg.FullName
|
|
|
|
|
|
|
|
|
|
# Copy metapackage to output directory
|
|
|
|
|
Copy-Item $metaNupkg.FullName -Destination $OutputDir -Force
|
|
|
|
|
Write-Host "Copied metapackage to $OutputDir"
|
|
|
|
|
|
|
|
|
|
# Prepare package versions hashtable - initialize with metapackage version
|
|
|
|
|
$packageVersions = @{ $MetaPackageName = $metaVersion }
|
|
|
|
|
|
|
|
|
|
# Copy Runtime package from artifact (it's not in feed) and extract its version
|
|
|
|
|
$runtimeNupkg = Get-ChildItem -Path $ArtifactDir -Recurse -Filter "$MetaPackageName.Runtime.*.nupkg" | Select-Object -First 1
|
|
|
|
|
if ($runtimeNupkg) {
|
|
|
|
|
Copy-Item $runtimeNupkg.FullName -Destination $OutputDir -Force
|
|
|
|
|
Write-Host "Copied Runtime package to $OutputDir"
|
|
|
|
|
|
|
|
|
|
# Extract version from Runtime package filename
|
|
|
|
|
if ($runtimeNupkg.Name -match "$MetaPackageName\.Runtime\.(.+)\.nupkg") {
|
|
|
|
|
$runtimeVersion = $Matches[1]
|
|
|
|
|
$packageVersions["$MetaPackageName.Runtime"] = $runtimeVersion
|
|
|
|
|
Write-Host "Extracted Runtime package version: $runtimeVersion"
|
|
|
|
|
} else {
|
|
|
|
|
Write-Warning "Could not extract version from Runtime package: $($runtimeNupkg.Name)"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Download other dependencies from feed (excluding Runtime as it's already copied)
|
|
|
|
|
# Create temp nuget.config that includes both local packages and remote feed
|
|
|
|
|
# This allows NuGet to find packages already copied from artifact
|
|
|
|
|
$tempConfig = Join-Path $env:TEMP "nuget_artifact_$(Get-Random).config"
|
|
|
|
|
$tempConfigContent = @"
|
|
|
|
|
<?xml version='1.0' encoding='utf-8'?>
|
|
|
|
|
<configuration>
|
|
|
|
|
<packageSources>
|
|
|
|
|
<clear />
|
|
|
|
|
<add key='LocalPackages' value='$OutputDir' />
|
|
|
|
|
<add key='RemoteFeed' value='$SourceUrl' />
|
|
|
|
|
</packageSources>
|
|
|
|
|
</configuration>
|
|
|
|
|
"@
|
|
|
|
|
Set-Content -Path $tempConfig -Value $tempConfigContent
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
foreach ($depId in $dependencies.Keys) {
|
|
|
|
|
# Skip Runtime as it's already copied from artifact
|
|
|
|
|
if ($depId -like "*Runtime*") {
|
|
|
|
|
# Don't overwrite the version we extracted from the Runtime package filename
|
|
|
|
|
if (-not $packageVersions.ContainsKey($depId)) {
|
|
|
|
|
$packageVersions[$depId] = $dependencies[$depId]
|
|
|
|
|
}
|
|
|
|
|
Write-Host "Skipping $depId (already in artifact)"
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$depVersion = $dependencies[$depId]
|
|
|
|
|
Write-Host "Downloading dependency: $depId version $depVersion from feed..."
|
|
|
|
|
|
|
|
|
|
& nuget install $depId `
|
|
|
|
|
-Version $depVersion `
|
|
|
|
|
-ConfigFile $tempConfig `
|
|
|
|
|
-OutputDirectory $OutputDir `
|
|
|
|
|
-NonInteractive `
|
|
|
|
|
-NoCache `
|
|
|
|
|
| Out-Null
|
|
|
|
|
|
|
|
|
|
if ($LASTEXITCODE -eq 0) {
|
|
|
|
|
$packageVersions[$depId] = $depVersion
|
|
|
|
|
Write-Host " Successfully downloaded $depId"
|
|
|
|
|
} else {
|
|
|
|
|
Write-Warning " Failed to download $depId version $depVersion"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
finally {
|
|
|
|
|
Remove-Item $tempConfig -Force -ErrorAction SilentlyContinue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Parse all downloaded packages to get actual versions
|
|
|
|
|
$directories = Get-ChildItem -Path $OutputDir -Directory
|
|
|
|
|
$allLocalPackages = @()
|
|
|
|
|
|
|
|
|
|
# Add metapackage and runtime to the list (they are .nupkg files, not directories)
|
|
|
|
|
$allLocalPackages += $MetaPackageName
|
|
|
|
|
if ($packageVersions.ContainsKey("$MetaPackageName.Runtime")) {
|
|
|
|
|
$allLocalPackages += "$MetaPackageName.Runtime"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach ($dir in $directories) {
|
|
|
|
|
if ($dir.Name -match $script:PackageVersionRegex) {
|
|
|
|
|
$pkgId = $Matches[1]
|
|
|
|
|
$pkgVer = $Matches[2]
|
|
|
|
|
$allLocalPackages += $pkgId
|
|
|
|
|
if (-not $packageVersions.ContainsKey($pkgId)) {
|
|
|
|
|
$packageVersions[$pkgId] = $pkgVer
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Update nuget.config dynamically during pipeline execution
|
|
|
|
|
# This modification is temporary and won't be committed back to the repo
|
|
|
|
|
$nugetConfig = Join-Path $rootPath "nuget.config"
|
|
|
|
|
$configData = Read-FileWithEncoding -Path $nugetConfig
|
|
|
|
|
[xml]$xml = $configData.Content
|
|
|
|
|
|
|
|
|
|
Add-NuGetSourceAndMapping -Xml $xml -Key "localpackages" -Value $OutputDir -Patterns $allLocalPackages
|
|
|
|
|
|
|
|
|
|
$xml.Save($nugetConfig)
|
|
|
|
|
Write-Host "Updated nuget.config with localpackages mapping (temporary, for pipeline execution only)."
|
|
|
|
|
|
|
|
|
|
return ,$packageVersions
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Resolve-WinAppSdkSplitDependencies {
|
|
|
|
|
Write-Host "Version $WinAppSDKVersion detected. Resolving split dependencies..."
|
|
|
|
|
$installDir = Join-Path $rootPath "localpackages\output"
|
|
|
|
|
New-Item -ItemType Directory -Path $installDir -Force | Out-Null
|
|
|
|
|
$null = New-Item -ItemType Directory -Path $installDir -Force
|
|
|
|
|
|
|
|
|
|
# Create a temporary nuget.config to avoid interference from the repo's config
|
|
|
|
|
$tempConfig = Join-Path $env:TEMP "nuget_$(Get-Random).config"
|
|
|
|
|
@@ -131,14 +417,24 @@ function Resolve-WinAppSdkSplitDependencies {
|
|
|
|
|
if ($propsContent -match '<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="([^"]+)"') {
|
|
|
|
|
$buildToolsVersion = $Matches[1]
|
|
|
|
|
Write-Host "Downloading Microsoft.Windows.SDK.BuildTools version $buildToolsVersion..."
|
|
|
|
|
$nugetArgsBuildTools = "install Microsoft.Windows.SDK.BuildTools -Version $buildToolsVersion -ConfigFile $tempConfig -OutputDirectory $installDir -NonInteractive -NoCache"
|
|
|
|
|
Invoke-Expression "nuget $nugetArgsBuildTools" | Out-Null
|
|
|
|
|
& nuget install Microsoft.Windows.SDK.BuildTools `
|
|
|
|
|
-Version $buildToolsVersion `
|
|
|
|
|
-ConfigFile $tempConfig `
|
|
|
|
|
-OutputDirectory $installDir `
|
|
|
|
|
-NonInteractive `
|
|
|
|
|
-NoCache `
|
|
|
|
|
| Out-Null
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Download package to inspect nuspec and keep it for the build
|
|
|
|
|
$nugetArgs = "install Microsoft.WindowsAppSDK -Version $WinAppSDKVersion -ConfigFile $tempConfig -OutputDirectory $installDir -NonInteractive -NoCache"
|
|
|
|
|
Invoke-Expression "nuget $nugetArgs" | Out-Null
|
|
|
|
|
& nuget install Microsoft.WindowsAppSDK `
|
|
|
|
|
-Version $WinAppSDKVersion `
|
|
|
|
|
-ConfigFile $tempConfig `
|
|
|
|
|
-OutputDirectory $installDir `
|
|
|
|
|
-NonInteractive `
|
|
|
|
|
-NoCache `
|
|
|
|
|
| Out-Null
|
|
|
|
|
|
|
|
|
|
# Parse dependencies from the installed folders
|
|
|
|
|
# Folder structure is typically {PackageId}.{Version}
|
|
|
|
|
@@ -172,52 +468,101 @@ function Resolve-WinAppSdkSplitDependencies {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Execute nuget list and capture the output
|
|
|
|
|
if ($useExperimentalVersion) {
|
|
|
|
|
# The nuget list for experimental versions will cost more time
|
|
|
|
|
# So, we will not use -AllVersions to wast time
|
|
|
|
|
# But it can only get the latest experimental version
|
|
|
|
|
Write-Host "Fetching WindowsAppSDK with experimental versions"
|
|
|
|
|
$nugetOutput = nuget list Microsoft.WindowsAppSDK `
|
|
|
|
|
-Source $sourceLink `
|
|
|
|
|
-Prerelease
|
|
|
|
|
# Filter versions based on the specified version prefix
|
|
|
|
|
$escapedVersionNumber = [regex]::Escape($winAppSdkVersionNumber)
|
|
|
|
|
$filteredVersions = $nugetOutput | Where-Object { $_ -match "Microsoft.WindowsAppSDK $escapedVersionNumber\." }
|
|
|
|
|
$latestVersions = $filteredVersions
|
|
|
|
|
} else {
|
|
|
|
|
Write-Host "Fetching stable WindowsAppSDK versions for $winAppSdkVersionNumber"
|
|
|
|
|
$nugetOutput = nuget list Microsoft.WindowsAppSDK `
|
|
|
|
|
-Source $sourceLink `
|
|
|
|
|
-AllVersions
|
|
|
|
|
# Filter versions based on the specified version prefix
|
|
|
|
|
$escapedVersionNumber = [regex]::Escape($winAppSdkVersionNumber)
|
|
|
|
|
$filteredVersions = $nugetOutput | Where-Object { $_ -match "Microsoft.WindowsAppSDK $escapedVersionNumber\." }
|
|
|
|
|
$latestVersions = $filteredVersions | Sort-Object { [version]($_ -split ' ')[1] } -Descending | Select-Object -First 1
|
|
|
|
|
}
|
|
|
|
|
# Main logic: choose between artifact-based or feed-based approach
|
|
|
|
|
if ($useArtifactSource) {
|
|
|
|
|
Write-Host "=== Using Artifact-Based Source ===" -ForegroundColor Cyan
|
|
|
|
|
Write-Host "Organization: $azureDevOpsOrg"
|
|
|
|
|
Write-Host "Project: $azureDevOpsProject"
|
|
|
|
|
Write-Host "Build ID: $buildId"
|
|
|
|
|
Write-Host "Artifact: $artifactName"
|
|
|
|
|
|
|
|
|
|
Write-Host "Latest versions found: $latestVersions"
|
|
|
|
|
# Extract the latest version number from the output
|
|
|
|
|
$latestVersion = $latestVersions -split "`n" | `
|
|
|
|
|
Select-String -Pattern 'Microsoft.WindowsAppSDK\s*([0-9]+\.[0-9]+\.[0-9]+-*[a-zA-Z0-9]*)' | `
|
|
|
|
|
ForEach-Object { $_.Matches[0].Groups[1].Value } | `
|
|
|
|
|
Sort-Object -Descending | `
|
|
|
|
|
Select-Object -First 1
|
|
|
|
|
if ([string]::IsNullOrEmpty($buildId) -or $buildId -eq 'N/A') {
|
|
|
|
|
Write-Error "buildId parameter is required when using artifact source. Please provide a valid Windows App SDK Build ID."
|
|
|
|
|
Write-Host "Tip: You can find the build ID from the Windows App SDK pipeline run in Azure DevOps."
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($latestVersion) {
|
|
|
|
|
$WinAppSDKVersion = $latestVersion
|
|
|
|
|
Write-Host "Extracted version: $WinAppSDKVersion"
|
|
|
|
|
# Download artifact
|
|
|
|
|
$artifactDir = Join-Path $rootPath "localpackages\artifact"
|
|
|
|
|
$downloadSuccess = Download-ArtifactFromPipeline `
|
|
|
|
|
-Organization $azureDevOpsOrg `
|
|
|
|
|
-Project $azureDevOpsProject `
|
|
|
|
|
-BuildId $buildId `
|
|
|
|
|
-ArtifactName $artifactName `
|
|
|
|
|
-OutputDir $artifactDir
|
|
|
|
|
|
|
|
|
|
if (-not $downloadSuccess) {
|
|
|
|
|
Write-Host "Failed to download artifact"
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Resolve dependencies from artifact
|
|
|
|
|
$installDir = Join-Path $rootPath "localpackages\output"
|
|
|
|
|
$packageVersions = Resolve-ArtifactBasedDependencies `
|
|
|
|
|
-ArtifactDir $artifactDir `
|
|
|
|
|
-MetaPackageName $metaPackageName `
|
|
|
|
|
-SourceUrl $sourceLink `
|
|
|
|
|
-OutputDir $installDir
|
|
|
|
|
|
|
|
|
|
if ($packageVersions.Count -eq 0) {
|
|
|
|
|
Write-Error "Failed to resolve dependencies from artifact"
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$WinAppSDKVersion = $packageVersions[$metaPackageName]
|
|
|
|
|
Write-Host "WinAppSDK Version: $WinAppSDKVersion"
|
|
|
|
|
Write-Host "##vso[task.setvariable variable=WinAppSDKVersion]$WinAppSDKVersion"
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
Write-Host "Failed to extract version number from nuget list output"
|
|
|
|
|
exit 1
|
|
|
|
|
Write-Host "=== Using Feed-Based Source ===" -ForegroundColor Cyan
|
|
|
|
|
|
|
|
|
|
# Execute nuget list and capture the output
|
|
|
|
|
if ($useExperimentalVersion) {
|
|
|
|
|
# The nuget list for experimental versions will cost more time
|
|
|
|
|
# So, we will not use -AllVersions to wast time
|
|
|
|
|
# But it can only get the latest experimental version
|
|
|
|
|
Write-Host "Fetching WindowsAppSDK with experimental versions"
|
|
|
|
|
$nugetOutput = nuget list Microsoft.WindowsAppSDK `
|
|
|
|
|
-Source $sourceLink `
|
|
|
|
|
-Prerelease
|
|
|
|
|
# Filter versions based on the specified version prefix
|
|
|
|
|
$escapedVersionNumber = [regex]::Escape($winAppSdkVersionNumber)
|
|
|
|
|
$filteredVersions = $nugetOutput | Where-Object { $_ -match "Microsoft.WindowsAppSDK $escapedVersionNumber\." }
|
|
|
|
|
$latestVersions = $filteredVersions
|
|
|
|
|
} else {
|
|
|
|
|
Write-Host "Fetching stable WindowsAppSDK versions for $winAppSdkVersionNumber"
|
|
|
|
|
$nugetOutput = nuget list Microsoft.WindowsAppSDK `
|
|
|
|
|
-Source $sourceLink `
|
|
|
|
|
-AllVersions
|
|
|
|
|
# Filter versions based on the specified version prefix
|
|
|
|
|
$escapedVersionNumber = [regex]::Escape($winAppSdkVersionNumber)
|
|
|
|
|
$filteredVersions = $nugetOutput | Where-Object { $_ -match "Microsoft.WindowsAppSDK $escapedVersionNumber\." }
|
|
|
|
|
$latestVersions = $filteredVersions | Sort-Object { [version]($_ -split ' ')[1] } -Descending | Select-Object -First 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Write-Host "Latest versions found: $latestVersions"
|
|
|
|
|
# Extract the latest version number from the output
|
|
|
|
|
$latestVersion = $latestVersions -split "`n" | `
|
|
|
|
|
Select-String -Pattern 'Microsoft.WindowsAppSDK\s*([0-9]+\.[0-9]+\.[0-9]+-*[a-zA-Z0-9]*)' | `
|
|
|
|
|
ForEach-Object { $_.Matches[0].Groups[1].Value } | `
|
|
|
|
|
Sort-Object -Descending | `
|
|
|
|
|
Select-Object -First 1
|
|
|
|
|
|
|
|
|
|
if ($latestVersion) {
|
|
|
|
|
$WinAppSDKVersion = $latestVersion
|
|
|
|
|
Write-Host "Extracted version: $WinAppSDKVersion"
|
|
|
|
|
Write-Host "##vso[task.setvariable variable=WinAppSDKVersion]$WinAppSDKVersion"
|
|
|
|
|
} else {
|
|
|
|
|
Write-Host "Failed to extract version number from nuget list output"
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Resolve dependencies for 1.8+
|
|
|
|
|
$packageVersions = @{ "Microsoft.WindowsAppSDK" = $WinAppSDKVersion }
|
|
|
|
|
|
|
|
|
|
Resolve-WinAppSdkSplitDependencies
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Resolve dependencies for 1.8+
|
|
|
|
|
$packageVersions = @{ "Microsoft.WindowsAppSDK" = $WinAppSDKVersion }
|
|
|
|
|
|
|
|
|
|
Resolve-WinAppSdkSplitDependencies
|
|
|
|
|
|
|
|
|
|
# Update Directory.Packages.props file
|
|
|
|
|
Get-ChildItem -Path $rootPath -Recurse "Directory.Packages.props" | ForEach-Object {
|
|
|
|
|
$file = Read-FileWithEncoding -Path $_.FullName
|
|
|
|
|
@@ -226,9 +571,16 @@ Get-ChildItem -Path $rootPath -Recurse "Directory.Packages.props" | ForEach-Obje
|
|
|
|
|
|
|
|
|
|
foreach ($pkgId in $packageVersions.Keys) {
|
|
|
|
|
$ver = $packageVersions[$pkgId]
|
|
|
|
|
|
|
|
|
|
# Skip packages with empty versions to prevent corruption
|
|
|
|
|
if ([string]::IsNullOrWhiteSpace($ver)) {
|
|
|
|
|
Write-Warning "Skipping ${pkgId}: version is empty"
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Escape dots in package ID for regex
|
|
|
|
|
$pkgIdRegex = $pkgId -replace '\.', '\.'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$newVersionString = "<PackageVersion Include=""$pkgId"" Version=""$ver"" />"
|
|
|
|
|
$oldVersionString = "<PackageVersion Include=""$pkgIdRegex"" Version=""[-.0-9a-zA-Z]*"" />"
|
|
|
|
|
|
|
|
|
|
|