From ef4b00c788afd6997f35ef8c0b8ae64aba64a249 Mon Sep 17 00:00:00 2001 From: gargsaumya Date: Tue, 8 Sep 2026 11:37:22 +0530 Subject: [PATCH 1/2] Accept mssql-python-rs wheel package --- eng/scripts/install-mssql-py-core.ps1 | 51 ++++++++++++++++++-------- eng/scripts/install-mssql-py-core.sh | 52 ++++++++++++++++++--------- eng/scripts/resolve_nuget_feed.py | 2 +- 3 files changed, 73 insertions(+), 32 deletions(-) diff --git a/eng/scripts/install-mssql-py-core.ps1 b/eng/scripts/install-mssql-py-core.ps1 index be63e94db..00c91b733 100644 --- a/eng/scripts/install-mssql-py-core.ps1 +++ b/eng/scripts/install-mssql-py-core.ps1 @@ -1,15 +1,15 @@ <# .SYNOPSIS - Downloads the mssql-py-core-wheels NuGet package from a public Azure Artifacts - feed and extracts the matching mssql_py_core binary into the repository root - so that 'import mssql_py_core' works when running from the source tree. + Downloads the mssql-python-rs-wheels NuGet package (or its legacy name) from + a public Azure Artifacts feed and extracts the matching mssql_py_core binary + into the repository root so that 'import mssql_py_core' works from source. .PARAMETER FeedUrl The NuGet v3 feed URL. This is a public feed — no authentication required. .PARAMETER OutputDir Temporary directory for downloaded artifacts. Cleaned up after extraction. - Defaults to $env:TEMP\mssql-py-core-wheels. + Defaults to $env:TEMP\mssql-python-rs-wheels. .PARAMETER TargetArch Target CPU architecture ('x64' or 'arm64') for cross-compilation builds. @@ -23,7 +23,7 @@ param( [string]$FeedUrl = "https://pkgs.dev.azure.com/sqlclientdrivers/public/_packaging/mssql-rs_Public/nuget/v3/index.json", - [string]$OutputDir = "$env:TEMP\mssql-py-core-wheels", + [string]$OutputDir = "$env:TEMP\mssql-python-rs-wheels", [string]$TargetArch = "" ) @@ -80,8 +80,11 @@ function Get-PlatformInfo { default { throw "Unsupported platform: $script:Platform" } } - $script:WheelPattern = "mssql_py_core-*-$script:PyVersion-$script:PyVersion-$script:WheelPlatform.whl" - Write-Host "Wheel pattern: $script:WheelPattern" + $script:WheelPatterns = @( + "mssql_python_rs-*-$script:PyVersion-$script:PyVersion-$script:WheelPlatform.whl" + "mssql_py_core-*-$script:PyVersion-$script:PyVersion-$script:WheelPlatform.whl" + ) + Write-Host "Wheel patterns: $($script:WheelPatterns -join ', ')" } function Get-NupkgFromFeed { @@ -97,14 +100,28 @@ function Get-NupkgFromFeed { $packageBaseUrl = ($feedIndex.resources | Where-Object { $_.'@type' -like 'PackageBaseAddress*' }).'@id' if (-not $packageBaseUrl) { throw "Could not resolve PackageBaseAddress from feed" } - $packageId = "mssql-py-core-wheels" $versionLower = $script:PackageVersion.ToLower() - # e.g. https://pkgs.dev.azure.com/.../nuget/v3/flat2/mssql-py-core-wheels/0.1.0-dev.20260222.140833/mssql-py-core-wheels.0.1.0-dev.20260222.140833.nupkg - $nupkgUrl = "${packageBaseUrl}${packageId}/${versionLower}/${packageId}.${versionLower}.nupkg" - $script:NupkgPath = Join-Path $OutputDir "${packageId}.${versionLower}.nupkg" + $packageIds = @("mssql-python-rs-wheels", "mssql-py-core-wheels") + $script:NupkgPath = $null + foreach ($packageId in $packageIds) { + $nupkgUrl = "${packageBaseUrl}${packageId}/${versionLower}/${packageId}.${versionLower}.nupkg" + $candidatePath = Join-Path $OutputDir "${packageId}.${versionLower}.nupkg" + Write-Host "Downloading: $nupkgUrl" + try { + Invoke-WebRequest -Uri $nupkgUrl -OutFile $candidatePath + $script:NupkgPath = $candidatePath + Write-Host "Using NuGet package: $packageId" + break + } + catch { + Remove-Item $candidatePath -Force -ErrorAction SilentlyContinue + Write-Host "Package not available: $packageId $script:PackageVersion" + } + } + if (-not $script:NupkgPath) { + throw "Package version $script:PackageVersion was not found under: $($packageIds -join ', ')" + } - Write-Host "Downloading: $nupkgUrl" - Invoke-WebRequest -Uri $nupkgUrl -OutFile $script:NupkgPath $sizeMB = [math]::Round((Get-Item $script:NupkgPath).Length / 1MB, 2) Write-Host "Downloaded: $script:NupkgPath ($sizeMB MB)" } @@ -124,11 +141,15 @@ function Find-MatchingWheel { throw "No 'wheels' directory found in NuGet package" } - $script:MatchingWheel = Get-ChildItem $wheelsDir -Filter $script:WheelPattern | Select-Object -First 1 + $script:MatchingWheel = $null + foreach ($wheelPattern in $script:WheelPatterns) { + $script:MatchingWheel = Get-ChildItem $wheelsDir -Filter $wheelPattern | Select-Object -First 1 + if ($script:MatchingWheel) { break } + } if (-not $script:MatchingWheel) { Write-Host "Available wheels:" Get-ChildItem $wheelsDir -Filter *.whl | ForEach-Object { Write-Host " $_" } - throw "No wheel found matching: $script:WheelPattern" + throw "No wheel found matching: $($script:WheelPatterns -join ', ')" } Write-Host "Found: $($script:MatchingWheel.Name)" diff --git a/eng/scripts/install-mssql-py-core.sh b/eng/scripts/install-mssql-py-core.sh index 6196fc9dd..7aa176527 100644 --- a/eng/scripts/install-mssql-py-core.sh +++ b/eng/scripts/install-mssql-py-core.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -# Downloads the mssql-py-core-wheels NuGet package from a public Azure Artifacts -# feed and extracts the matching mssql_py_core binary into the repository root -# so that 'import mssql_py_core' works when running from the source tree. +# Downloads the mssql-python-rs-wheels NuGet package (or its legacy name) from a +# public Azure Artifacts feed and extracts the matching mssql_py_core binary into +# the repository root so that 'import mssql_py_core' works from the source tree. # # The extracted files are placed at /mssql_py_core/ which contains: # - __init__.py @@ -74,8 +74,11 @@ print(f'cp{v.major}{v.minor} {platform.system().lower()} {platform.machine().low ;; esac - WHEEL_PATTERN="mssql_py_core-*-${PY_VERSION}-${PY_VERSION}-${WHEEL_PLATFORM}.whl" - echo "Wheel pattern: $WHEEL_PATTERN" + WHEEL_PATTERNS=( + "mssql_python_rs-*-${PY_VERSION}-${PY_VERSION}-${WHEEL_PLATFORM}.whl" + "mssql_py_core-*-${PY_VERSION}-${PY_VERSION}-${WHEEL_PLATFORM}.whl" + ) + echo "Wheel patterns: ${WHEEL_PATTERNS[*]}" } download_nupkg() { @@ -92,16 +95,26 @@ download_nupkg() { exit 1 fi - local package_id="mssql-py-core-wheels" local version_lower version_lower=$(echo "$PACKAGE_VERSION" | tr '[:upper:]' '[:lower:]') - - # e.g. https://pkgs.dev.azure.com/.../nuget/v3/flat2/mssql-py-core-wheels/0.1.0-dev.20260222.140833/mssql-py-core-wheels.0.1.0-dev.20260222.140833.nupkg - NUPKG_URL="${PACKAGE_BASE_URL}${package_id}/${version_lower}/${package_id}.${version_lower}.nupkg" - NUPKG_PATH="$output_dir/${package_id}.${version_lower}.nupkg" - - echo "Downloading: $NUPKG_URL" - curl -sSL -o "$NUPKG_PATH" "$NUPKG_URL" + local package_id + NUPKG_PATH="" + for package_id in "mssql-python-rs-wheels" "mssql-py-core-wheels"; do + NUPKG_URL="${PACKAGE_BASE_URL}${package_id}/${version_lower}/${package_id}.${version_lower}.nupkg" + local candidate_path="$output_dir/${package_id}.${version_lower}.nupkg" + echo "Downloading: $NUPKG_URL" + if curl -fsSL -o "$candidate_path" "$NUPKG_URL"; then + NUPKG_PATH="$candidate_path" + echo "Using NuGet package: $package_id" + break + fi + rm -f "$candidate_path" + echo "Package not available: $package_id $PACKAGE_VERSION" + done + if [ -z "$NUPKG_PATH" ]; then + echo "ERROR: Package version $PACKAGE_VERSION was not found under the new or legacy package ID" + exit 1 + fi local filesize filesize=$(wc -c < "$NUPKG_PATH") @@ -131,11 +144,18 @@ find_matching_wheel() { exit 1 fi - MATCHING_WHEEL=$(find "$wheels_dir" -name "$WHEEL_PATTERN" | head -1) + MATCHING_WHEEL="" + local wheel_pattern + for wheel_pattern in "${WHEEL_PATTERNS[@]}"; do + MATCHING_WHEEL=$(find "$wheels_dir" -name "$wheel_pattern" | head -1) + if [ -n "$MATCHING_WHEEL" ]; then + break + fi + done if [ -z "$MATCHING_WHEEL" ]; then echo "Available wheels:" ls "$wheels_dir"/*.whl 2>/dev/null || echo " (none)" - echo "ERROR: No wheel found matching: $WHEEL_PATTERN" + echo "ERROR: No wheel found matching: ${WHEEL_PATTERNS[*]}" exit 1 fi @@ -196,7 +216,7 @@ extract_and_verify() { # --- main --- FEED_URL="${FEED_URL:-https://pkgs.dev.azure.com/sqlclientdrivers/public/_packaging/mssql-rs_Public/nuget/v3/index.json}" -OUTPUT_DIR="${TMPDIR:-/tmp}/mssql-py-core-wheels" +OUTPUT_DIR="${TMPDIR:-/tmp}/mssql-python-rs-wheels" while [[ $# -gt 0 ]]; do case "$1" in diff --git a/eng/scripts/resolve_nuget_feed.py b/eng/scripts/resolve_nuget_feed.py index ea6c075e8..e3bb18b56 100644 --- a/eng/scripts/resolve_nuget_feed.py +++ b/eng/scripts/resolve_nuget_feed.py @@ -40,7 +40,7 @@ def resolve(feed_url: str) -> str: downloading .nupkg files by convention: {base}/{id}/{version}/{id}.{version}.nupkg - We need this base URL because we download the mssql-py-core-wheels + We need this base URL because we download the mssql-python-rs-wheels nupkg directly via HTTP rather than using the NuGet CLI. """ parsed = urllib.parse.urlparse(feed_url) From 2728ceb439eaae37b5a1173fb0c24dc3e2e291be Mon Sep 17 00:00:00 2001 From: gargsaumya Date: Tue, 8 Sep 2026 12:33:04 +0530 Subject: [PATCH 2/2] Fix wheel package fallback handling --- eng/scripts/install-mssql-py-core.ps1 | 4 ++++ eng/scripts/install-mssql-py-core.sh | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/eng/scripts/install-mssql-py-core.ps1 b/eng/scripts/install-mssql-py-core.ps1 index 00c91b733..42587cef5 100644 --- a/eng/scripts/install-mssql-py-core.ps1 +++ b/eng/scripts/install-mssql-py-core.ps1 @@ -115,6 +115,10 @@ function Get-NupkgFromFeed { } catch { Remove-Item $candidatePath -Force -ErrorAction SilentlyContinue + $statusCode = $_.Exception.Response.StatusCode + if (-not $statusCode -or [int]$statusCode -ne 404) { + throw + } Write-Host "Package not available: $packageId $script:PackageVersion" } } diff --git a/eng/scripts/install-mssql-py-core.sh b/eng/scripts/install-mssql-py-core.sh index 7aa176527..edba4364a 100644 --- a/eng/scripts/install-mssql-py-core.sh +++ b/eng/scripts/install-mssql-py-core.sh @@ -102,14 +102,25 @@ download_nupkg() { for package_id in "mssql-python-rs-wheels" "mssql-py-core-wheels"; do NUPKG_URL="${PACKAGE_BASE_URL}${package_id}/${version_lower}/${package_id}.${version_lower}.nupkg" local candidate_path="$output_dir/${package_id}.${version_lower}.nupkg" + local http_status echo "Downloading: $NUPKG_URL" - if curl -fsSL -o "$candidate_path" "$NUPKG_URL"; then + if ! http_status=$(curl -sSL -o "$candidate_path" -w '%{http_code}' "$NUPKG_URL"); then + rm -f "$candidate_path" + echo "ERROR: Failed to download NuGet package: $package_id $PACKAGE_VERSION" >&2 + exit 1 + fi + if [ "$http_status" = "200" ]; then NUPKG_PATH="$candidate_path" echo "Using NuGet package: $package_id" break fi rm -f "$candidate_path" - echo "Package not available: $package_id $PACKAGE_VERSION" + if [ "$http_status" = "404" ]; then + echo "Package not available: $package_id $PACKAGE_VERSION" + continue + fi + echo "ERROR: Failed to download NuGet package: $package_id $PACKAGE_VERSION (HTTP $http_status)" >&2 + exit 1 done if [ -z "$NUPKG_PATH" ]; then echo "ERROR: Package version $PACKAGE_VERSION was not found under the new or legacy package ID" @@ -147,7 +158,7 @@ find_matching_wheel() { MATCHING_WHEEL="" local wheel_pattern for wheel_pattern in "${WHEEL_PATTERNS[@]}"; do - MATCHING_WHEEL=$(find "$wheels_dir" -name "$wheel_pattern" | head -1) + MATCHING_WHEEL=$(find "$wheels_dir" -name "$wheel_pattern" -print -quit) if [ -n "$MATCHING_WHEEL" ]; then break fi