Skip to content
Open
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
15 changes: 11 additions & 4 deletions tools/ci_build/github/azure-pipelines/dml-nuget-packaging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,13 @@ extends:
DoNugetPack: 'true'
DoEsrp: ${{ parameters.DoEsrp }}
NuPackScript: |
python -m pip install setuptools
msbuild $(Build.SourcesDirectory)\csharp\OnnxRuntime.CSharp.proj /p:Configuration=RelWithDebInfo /t:CreatePackage /p:OrtPackageId=Microsoft.ML.OnnxRuntime.DirectML /p:IsReleaseBuild=${{ parameters.IsReleaseBuild }} /p:CurrentData=$(BuildDate) /p:CurrentTime=$(BuildTime)
if errorlevel 1 exit /b 1
copy $(Build.SourcesDirectory)\csharp\src\Microsoft.ML.OnnxRuntime\bin\RelWithDebInfo\*.nupkg $(Build.ArtifactStagingDirectory)
copy $(Build.BinariesDirectory)\RelWithDebInfo\RelWithDebInfo\*.nupkg $(Build.ArtifactStagingDirectory)
if errorlevel 1 exit /b 1
powershell -ExecutionPolicy Bypass -File $(Build.SourcesDirectory)\tools\ci_build\github\windows\select_dml_package.ps1 -SourceDir "$(Build.BinariesDirectory)\RelWithDebInfo\RelWithDebInfo" -IsReleaseBuild "${{ parameters.IsReleaseBuild }}" -Action copy -DestinationDir "$(Build.ArtifactStagingDirectory)"
if errorlevel 1 exit /b 1
mkdir $(Build.ArtifactStagingDirectory)\testdata
copy $(Build.BinariesDirectory)\RelWithDebInfo\RelWithDebInfo\custom_op_library.* $(Build.ArtifactStagingDirectory)\testdata

Expand All @@ -94,13 +98,16 @@ extends:
DoEsrp: ${{ parameters.DoEsrp }}
RunTests: 'false'
NuPackScript: |
python -m pip install setuptools
msbuild $(Build.SourcesDirectory)\csharp\OnnxRuntime.CSharp.proj /p:Configuration=RelWithDebInfo /p:TargetArchitecture=arm64 /t:CreatePackage /p:OrtPackageId=Microsoft.ML.OnnxRuntime.DirectML /p:IsReleaseBuild=${{ parameters.IsReleaseBuild }}
cd $(Build.BinariesDirectory)\RelWithDebInfo\RelWithDebInfo\
ren Microsoft.ML.OnnxRuntime.DirectML.* win-dml-arm64.zip
if errorlevel 1 exit /b 1
powershell -ExecutionPolicy Bypass -File $(Build.SourcesDirectory)\tools\ci_build\github\windows\select_dml_package.ps1 -SourceDir "$(Build.BinariesDirectory)\RelWithDebInfo\RelWithDebInfo" -IsReleaseBuild "${{ parameters.IsReleaseBuild }}" -Action rename -NewName "win-dml-arm64.zip"
if errorlevel 1 exit /b 1
copy $(Build.BinariesDirectory)\RelWithDebInfo\RelWithDebInfo\win-dml-arm64.zip $(Build.ArtifactStagingDirectory)
if errorlevel 1 exit /b 1
mkdir $(Build.ArtifactStagingDirectory)\testdata
copy $(Build.BinariesDirectory)\RelWithDebInfo\RelWithDebInfo\custom_op_library.* $(Build.ArtifactStagingDirectory)\testdata

- template: stages/nuget_dml_packaging_stage.yml
parameters:
DoEsrp: ${{ parameters.DoEsrp }}
DoEsrp: ${{ parameters.DoEsrp }}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ parameters:
PackageType: ''
PackageName: ''
PackagePath: ''
IsReleaseBuild: false
ScriptPath: '$(Build.SourcesDirectory)/tools/nuget/validate_package.py'
workingDirectory: "$(Build.BinariesDirectory)"

Expand All @@ -17,5 +18,5 @@ steps:
displayName: 'Validate Package'
inputs:
scriptPath: '${{parameters.ScriptPath}}'
arguments: '--package_type ${{parameters.PackageType}} --package_name ${{parameters.PackageName}} --package_path ${{parameters.PackagePath}} --platforms_supported ${{parameters.PlatformsSupported}} --verify_nuget_signing ${{parameters.VerifyNugetSigning}}'
arguments: '--package_type ${{parameters.PackageType}} --package_name ${{parameters.PackageName}} --package_path ${{parameters.PackagePath}} --platforms_supported ${{parameters.PlatformsSupported}} --verify_nuget_signing ${{parameters.VerifyNugetSigning}} --is_release_build ${{parameters.IsReleaseBuild}}'
workingDirectory: ${{parameters.workingDirectory}}
57 changes: 48 additions & 9 deletions tools/ci_build/github/windows/bundle_dml_package.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,27 @@ $arm64ExtractPath = "win-dml-arm64-unzipped"
Write-Host "Extracting $arm64ZipFile to $arm64ExtractPath..."
& $sevenZipPath x $arm64ZipFile -o"$arm64ExtractPath" -y

# Debug: List contents of extracted arm64 zip
Write-Host "Contents of $arm64ExtractPath (recursive):"
Get-ChildItem -Path $arm64ExtractPath -Recurse | ForEach-Object { Write-Host " - $($_.FullName)" }

# 2. Find the target NuGet package.
# It finds all .nupkg files that do not contain "Managed" in their name.
$nupkgFiles = Get-ChildItem -Path . -Recurse -Filter *.nupkg | Where-Object { $_.Name -notlike "*Managed*" }
$nupkgFiles = Get-ChildItem -Path . -Filter *.nupkg | Where-Object { ($_.Name -notlike "*Managed*") -and ($_.Name -notlike "*.symbols.nupkg") }

Write-Host "Found $($nupkgFiles.Count) candidate nupkg file(s) for bundling:"
$nupkgFiles | ForEach-Object { Write-Host " - $($_.FullName)" }

# 3. Validate that exactly one package was found.
if ($nupkgFiles.Count -ne 1) {
Write-Error "Error: Expected to find exactly one non-managed NuGet package, but found $($nupkgFiles.Count)."
# 3. Select the best package (shortest name prefers Release over Dev, and Main over Symbols)
if ($nupkgFiles.Count -eq 0) {
Write-Error "Error: No matching NuGet packages found to bundle into."
exit 1
}
$nupkg = $nupkgFiles[0]
Write-Host "Found package to process: $($nupkg.Name)"
if ($nupkgFiles.Count -gt 1) {
Write-Warning "Found multiple packages. Selecting the one with the shortest filename as the target for bundling."
}
$nupkg = $nupkgFiles | Sort-Object {$_.Name.Length} | Select-Object -First 1
Write-Host "Selected target package: $($nupkg.Name)"

# 4. Validate the package name matches the expected format.
if ($nupkg.Name -notlike "Microsoft.ML.OnnxRuntime.DirectML*.nupkg") {
Expand All @@ -61,14 +71,36 @@ New-Item -ItemType Directory -Path $tempDir | Out-Null
Write-Host "Extracting $($nupkg.Name) to $tempDir..."
& $sevenZipPath x $nupkg.FullName -o"$tempDir" -y

# Debug: Print the .nuspec content
$nuspecFile = Get-ChildItem -Path $tempDir -Filter *.nuspec | Select-Object -First 1
if ($nuspecFile) {
Write-Host "Found manifest: $($nuspecFile.FullName)"
Write-Host "--- Manifest Content ---"
Get-Content $nuspecFile.FullName | ForEach-Object { Write-Host $_ }
Write-Host "------------------------"
}

# Debug: List contents of extracted target nupkg
Write-Host "Contents of $tempDir (recursive):"
Get-ChildItem -Path $tempDir -Recurse | ForEach-Object { Write-Host " - $($_.FullName)" }

# Step B: Create the new runtime directory structure.
$newRuntimePath = Join-Path $tempDir "runtimes\win-arm64\native"
Write-Host "Ensuring destination path exists: $newRuntimePath"
New-Item -ItemType Directory -Path $newRuntimePath -Force | Out-Null

# Step C: Copy the ARM64 binaries into the new structure.
$arm64SourcePath = Join-Path . "$arm64ExtractPath\runtimes\win-arm64\native"
Write-Host "Copying ARM64 binaries from $arm64SourcePath to $newRuntimePath..."
Copy-Item -Path "$arm64SourcePath\*" -Destination $newRuntimePath -Recurse -Force
if (Test-Path $arm64SourcePath) {
Write-Host "Copying ARM64 binaries from $arm64SourcePath to $newRuntimePath..."
$filesToCopy = Get-ChildItem -Path "$arm64SourcePath\*"
Write-Host "Files found in source: $($filesToCopy.Count)"
$filesToCopy | ForEach-Object { Write-Host " -> $($_.Name)" }
Copy-Item -Path "$arm64SourcePath\*" -Destination $newRuntimePath -Recurse -Force
} else {
Write-Error "Error: ARM64 source path not found: $arm64SourcePath. Bailing out to avoid creating a broken package."
exit 1
}

# Step D: Delete the original nupkg file.
Remove-Item -Path $nupkg.FullName -Force
Expand All @@ -79,6 +111,13 @@ Push-Location $tempDir
& $sevenZipPath a -tzip "$($nupkg.FullName)" ".\" -r
Pop-Location

# Debug: Check final nupkg existence
if (Test-Path $nupkg.FullName) {
Write-Host "Final package created successfully: $($nupkg.FullName)"
$finalSize = (Get-Item $nupkg.FullName).Length
Write-Host "Final package size: $finalSize bytes"
}

# --- Cleanup and Final Steps ---
Write-Host "Cleaning up temporary directory $tempDir..."
Remove-Item -Recurse -Force $tempDir
Expand All @@ -91,4 +130,4 @@ Write-Host "Copying final artifact to $ArtifactStagingDirectory..."
Copy-Item -Path ".\Microsoft.ML.OnnxRuntime.DirectML*.nupkg" -Destination $ArtifactStagingDirectory -Force

Write-Host "---"
Write-Host "Script completed successfully."
Write-Host "Script completed successfully."
86 changes: 86 additions & 0 deletions tools/ci_build/github/windows/select_dml_package.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# select_dml_package.ps1
# Helper script to select the correct DML NuGet package based on build type
# Usage: select_dml_package.ps1 -SourceDir <path> -IsReleaseBuild <true|false> -Action <copy|rename> [-DestinationDir <path>] [-NewName <name>]

param(
[Parameter(Mandatory=$true)]
[string]$SourceDir,

[Parameter(Mandatory=$true)]
[string]$IsReleaseBuild,

[Parameter(Mandatory=$true)]
[ValidateSet("copy", "rename")]
[string]$Action,

[Parameter(Mandatory=$false)]
[string]$DestinationDir,

[Parameter(Mandatory=$false)]
[string]$NewName
)

$ErrorActionPreference = "Stop"

Write-Host "Searching for packages in: $SourceDir"
Write-Host "IsReleaseBuild: $IsReleaseBuild"
Write-Host "Action: $Action"

# Convert string to boolean
$isRelease = [System.Convert]::ToBoolean($IsReleaseBuild)

# Find all matching packages
$allPackages = Get-ChildItem -Path $SourceDir -Filter "Microsoft.ML.OnnxRuntime.DirectML.*.nupkg"
Write-Host "Found $($allPackages.Count) total package(s):"
$allPackages | ForEach-Object { Write-Host " - $($_.Name)" }

# Filter packages based on build type
$filteredPackages = $allPackages | Where-Object {
$name = $_.Name
$isSymbols = $name -like "*symbols*"
$isDev = $name -like "*-dev*"

if ($isSymbols) {
return $false
}

if ($isRelease) {
return -not $isDev
} else {
return $isDev
}
}

Write-Host "After filtering (isRelease=$isRelease), found $($filteredPackages.Count) matching package(s):"
$filteredPackages | ForEach-Object { Write-Host " - $($_.Name)" }

if ($filteredPackages.Count -eq 0) {
Write-Error "No matching package found!"
exit 1
}

# Select the first matching package (sorted by name length for consistency)
$selectedPackage = $filteredPackages | Sort-Object { $_.Name.Length } | Select-Object -First 1
Write-Host "Selected package: $($selectedPackage.FullName)"

# Perform the action
if ($Action -eq "copy") {
if (-not $DestinationDir) {
Write-Error "DestinationDir is required for copy action"
exit 1
}
Write-Host "Copying to: $DestinationDir"
Copy-Item -Path $selectedPackage.FullName -Destination $DestinationDir -Force
Write-Host "Copy successful."
}
elseif ($Action -eq "rename") {
if (-not $NewName) {
Write-Error "NewName is required for rename action"
exit 1
}
Write-Host "Renaming to: $NewName"
Rename-Item -Path $selectedPackage.FullName -NewName $NewName -Force
Write-Host "Rename successful."
}

exit 0
13 changes: 12 additions & 1 deletion tools/nuget/validate_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ def parse_arguments():
"--verify_nuget_signing",
help="Flag indicating if Nuget package signing is to be verified. Only accepts 'true' or 'false'",
)
parser.add_argument(
"--is_release_build",
help="Flag indicating if validating a release build or dev build. Only accepts 'true' or 'false'",
)

return parser.parse_args()

Expand Down Expand Up @@ -285,7 +289,14 @@ def validate_zip(args):

def validate_nuget(args):
files = glob.glob(os.path.join(args.package_path, args.package_name))
nuget_packages_found_in_path = [i for i in files if i.endswith(".nupkg") and "Managed" not in i]
is_release_build = args.is_release_build and args.is_release_build.lower() == "true"
nuget_packages_found_in_path = [
i
for i in files
if i.endswith(".nupkg")
and "Managed" not in i
and ((is_release_build and "-dev" not in i) or (not is_release_build and "-dev" in i))
]
if len(nuget_packages_found_in_path) != 1:
print("Nuget packages found in path: ")
print(nuget_packages_found_in_path)
Expand Down
Loading