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
55 changes: 40 additions & 15 deletions eng/scripts/install-mssql-py-core.ps1
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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 = ""
)

Expand Down Expand Up @@ -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 {
Expand All @@ -97,14 +100,32 @@ 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
$statusCode = $_.Exception.Response.StatusCode
if (-not $statusCode -or [int]$statusCode -ne 404) {
throw
}
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)"
}
Expand All @@ -124,11 +145,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)"
Expand Down
63 changes: 47 additions & 16 deletions eng/scripts/install-mssql-py-core.sh
Original file line number Diff line number Diff line change
@@ -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 <repo-root>/mssql_py_core/ which contains:
# - __init__.py
Expand Down Expand Up @@ -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() {
Expand All @@ -92,16 +95,37 @@ 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"
local http_status
echo "Downloading: $NUPKG_URL"
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"
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"
exit 1
fi

local filesize
filesize=$(wc -c < "$NUPKG_PATH")
Expand Down Expand Up @@ -131,11 +155,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" -print -quit)
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

Expand Down Expand Up @@ -196,7 +227,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
Expand Down
2 changes: 1 addition & 1 deletion eng/scripts/resolve_nuget_feed.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading