Skip to content

Commit e0d975c

Browse files
saurabh500Copilot
andcommitted
Add mssql_py_core wheel installation to PR validation pipeline
- Add install-mssql-py-core.ps1 (Windows) and install-mssql-py-core.sh (Linux/macOS) scripts that download the mssql-py-core-wheels NuGet package from the public Azure Artifacts feed and pip install the platform-appropriate wheel - Add eng/versions/mssql-py-core.version to pin the NuGet package version (no fallback to latest - file is required) - Add 'Install mssql_py_core' step to all 10 test jobs in pr-validation-pipeline.yml - No authentication required (public feed), no nuget.exe dependency (raw HTTP + unzip) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent c4e647e commit e0d975c

4 files changed

Lines changed: 366 additions & 0 deletions

File tree

eng/pipelines/pr-validation-pipeline.yml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,13 @@ jobs:
230230
build.bat x64
231231
displayName: 'Build .pyd file'
232232
233+
# Install mssql_py_core from NuGet wheel package (enables _bulkcopy tests)
234+
- task: PowerShell@2
235+
displayName: 'Install mssql_py_core from NuGet wheels'
236+
inputs:
237+
targetType: 'filePath'
238+
filePath: 'eng/scripts/install-mssql-py-core.ps1'
239+
233240
# Run tests for LocalDB
234241
- script: |
235242
python -m pytest -v --junitxml=test-results-localdb.xml --cov=. --cov-report=xml:coverage-localdb.xml --capture=tee-sys --cache-clear
@@ -497,6 +504,12 @@ jobs:
497504
./build.sh
498505
displayName: 'Build pybind bindings (.so)'
499506
507+
# Install mssql_py_core from NuGet wheel package (enables _bulkcopy tests)
508+
- script: |
509+
chmod +x eng/scripts/install-mssql-py-core.sh
510+
./eng/scripts/install-mssql-py-core.sh
511+
displayName: 'Install mssql_py_core from NuGet wheels'
512+
500513
- script: |
501514
echo "Build successful, running tests now"
502515
python -m pytest -v --junitxml=test-results.xml --cov=. --cov-report=xml --capture=tee-sys --cache-clear
@@ -669,6 +682,15 @@ jobs:
669682
"
670683
displayName: 'Build pybind bindings (.so) in $(distroName) container'
671684
685+
# Install mssql_py_core from NuGet wheel package inside container
686+
- script: |
687+
docker exec test-container-$(distroName) bash -c "
688+
source /opt/venv/bin/activate
689+
chmod +x eng/scripts/install-mssql-py-core.sh
690+
./eng/scripts/install-mssql-py-core.sh
691+
"
692+
displayName: 'Install mssql_py_core in $(distroName) container'
693+
672694
- script: |
673695
# Uninstall ODBC Driver before running tests
674696
docker exec test-container-$(distroName) bash -c "
@@ -984,6 +1006,15 @@ jobs:
9841006
displayName: 'Build pybind bindings (.so) in $(distroName) ARM64 container'
9851007
retryCountOnTaskFailure: 2
9861008
1009+
# Install mssql_py_core from NuGet wheel package inside ARM64 container
1010+
- script: |
1011+
docker exec test-container-$(distroName)-$(archName) bash -c "
1012+
source /opt/venv/bin/activate
1013+
chmod +x eng/scripts/install-mssql-py-core.sh
1014+
./eng/scripts/install-mssql-py-core.sh
1015+
"
1016+
displayName: 'Install mssql_py_core in $(distroName) ARM64 container'
1017+
9871018
- script: |
9881019
# Uninstall ODBC Driver before running tests
9891020
docker exec test-container-$(distroName)-$(archName) bash -c "
@@ -1192,6 +1223,15 @@ jobs:
11921223
"
11931224
displayName: 'Build pybind bindings (.so) in RHEL 9 container'
11941225
1226+
# Install mssql_py_core from NuGet wheel package inside RHEL 9 container
1227+
- script: |
1228+
docker exec test-container-rhel9 bash -c "
1229+
source myvenv/bin/activate
1230+
chmod +x eng/scripts/install-mssql-py-core.sh
1231+
./eng/scripts/install-mssql-py-core.sh
1232+
"
1233+
displayName: 'Install mssql_py_core in RHEL 9 container'
1234+
11951235
- script: |
11961236
# Uninstall ODBC Driver before running tests
11971237
docker exec test-container-rhel9 bash -c "
@@ -1411,6 +1451,15 @@ jobs:
14111451
displayName: 'Build pybind bindings (.so) in RHEL 9 ARM64 container'
14121452
retryCountOnTaskFailure: 2
14131453
1454+
# Install mssql_py_core from NuGet wheel package inside RHEL 9 ARM64 container
1455+
- script: |
1456+
docker exec test-container-rhel9-arm64 bash -c "
1457+
source myvenv/bin/activate
1458+
chmod +x eng/scripts/install-mssql-py-core.sh
1459+
./eng/scripts/install-mssql-py-core.sh
1460+
"
1461+
displayName: 'Install mssql_py_core in RHEL 9 ARM64 container'
1462+
14141463
- script: |
14151464
# Uninstall ODBC Driver before running tests
14161465
docker exec test-container-rhel9-arm64 bash -c "
@@ -1638,6 +1687,15 @@ jobs:
16381687
"
16391688
displayName: 'Build pybind bindings (.so) in Alpine x86_64 container'
16401689
1690+
# Install mssql_py_core from NuGet wheel package inside Alpine container
1691+
- script: |
1692+
docker exec test-container-alpine bash -c "
1693+
source /workspace/venv/bin/activate
1694+
chmod +x eng/scripts/install-mssql-py-core.sh
1695+
./eng/scripts/install-mssql-py-core.sh
1696+
"
1697+
displayName: 'Install mssql_py_core in Alpine x86_64 container'
1698+
16411699
- script: |
16421700
# Uninstall ODBC Driver before running tests to use bundled libraries
16431701
docker exec test-container-alpine bash -c "
@@ -1883,6 +1941,15 @@ jobs:
18831941
displayName: 'Build pybind bindings (.so) in Alpine ARM64 container'
18841942
retryCountOnTaskFailure: 2
18851943
1944+
# Install mssql_py_core from NuGet wheel package inside Alpine ARM64 container
1945+
- script: |
1946+
docker exec test-container-alpine-arm64 bash -c "
1947+
source /workspace/venv/bin/activate
1948+
chmod +x eng/scripts/install-mssql-py-core.sh
1949+
./eng/scripts/install-mssql-py-core.sh
1950+
"
1951+
displayName: 'Install mssql_py_core in Alpine ARM64 container'
1952+
18861953
- script: |
18871954
# Uninstall ODBC Driver before running tests to use bundled libraries
18881955
docker exec test-container-alpine-arm64 bash -c "
@@ -2005,6 +2072,13 @@ jobs:
20052072
build.bat x64
20062073
displayName: 'Build .pyd file'
20072074
2075+
# Install mssql_py_core from NuGet wheel package (enables _bulkcopy tests)
2076+
- task: PowerShell@2
2077+
displayName: 'Install mssql_py_core from NuGet wheels'
2078+
inputs:
2079+
targetType: 'filePath'
2080+
filePath: 'eng/scripts/install-mssql-py-core.ps1'
2081+
20082082
- script: |
20092083
python -m pytest -v --junitxml=test-results-azuresql.xml --cov=. --cov-report=xml:coverage-azuresql.xml --capture=tee-sys --cache-clear
20102084
displayName: 'Run tests on Azure SQL Database'
@@ -2047,6 +2121,12 @@ jobs:
20472121
./build.sh
20482122
displayName: 'Build pybind bindings (.so)'
20492123
2124+
# Install mssql_py_core from NuGet wheel package (enables _bulkcopy tests)
2125+
- script: |
2126+
chmod +x eng/scripts/install-mssql-py-core.sh
2127+
./eng/scripts/install-mssql-py-core.sh
2128+
displayName: 'Install mssql_py_core from NuGet wheels'
2129+
20502130
- script: |
20512131
python -m pytest -v --junitxml=test-results-azuresql.xml --cov=. --cov-report=xml:coverage-azuresql.xml --capture=tee-sys --cache-clear
20522132
displayName: 'Run tests on Azure SQL Database'
@@ -2118,6 +2198,15 @@ jobs:
21182198
"
21192199
displayName: 'Build pybind bindings (.so) in Ubuntu container'
21202200
2201+
# Install mssql_py_core from NuGet wheel package inside Ubuntu container
2202+
- script: |
2203+
docker exec test-container-ubuntu-azuresql bash -c "
2204+
source /opt/venv/bin/activate
2205+
chmod +x eng/scripts/install-mssql-py-core.sh
2206+
./eng/scripts/install-mssql-py-core.sh
2207+
"
2208+
displayName: 'Install mssql_py_core in Ubuntu container'
2209+
21212210
- script: |
21222211
docker exec test-container-ubuntu-azuresql bash -c "
21232212
export DEBIAN_FRONTEND=noninteractive
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<#
2+
.SYNOPSIS
3+
Downloads the mssql-py-core-wheels NuGet package from a public Azure Artifacts
4+
feed and installs the appropriate wheel for the current platform into the
5+
Python environment so that 'import mssql_py_core' works.
6+
7+
The package version is read from eng/versions/mssql-py-core.version (required).
8+
9+
.PARAMETER FeedUrl
10+
The NuGet v3 feed URL. This is a public feed — no authentication required.
11+
12+
.PARAMETER OutputDir
13+
Temporary directory for downloaded artifacts. Cleaned up after install.
14+
Defaults to $env:TEMP\mssql-py-core-wheels.
15+
#>
16+
17+
param(
18+
[string]$FeedUrl = "https://pkgs.dev.azure.com/sqlclientdrivers/public/_packaging/mssql-rs_Public/nuget/v3/index.json",
19+
[string]$OutputDir = "$env:TEMP\mssql-py-core-wheels"
20+
)
21+
22+
$ErrorActionPreference = 'Stop'
23+
24+
Write-Host "=== Install mssql_py_core from NuGet wheel package ==="
25+
26+
# Read version from pinned version file (required)
27+
$repoRoot = (Get-Item "$PSScriptRoot\..\..").FullName
28+
$versionFile = Join-Path $repoRoot "eng\versions\mssql-py-core.version"
29+
if (-not (Test-Path $versionFile)) {
30+
throw "Version file not found: $versionFile. This file must exist and contain the mssql-py-core-wheels NuGet package version."
31+
}
32+
$PackageVersion = (Get-Content $versionFile -Raw).Trim()
33+
if (-not $PackageVersion) {
34+
throw "Version file is empty: $versionFile"
35+
}
36+
Write-Host "Using version from $versionFile : $PackageVersion"
37+
38+
# Determine platform info
39+
$pyVersion = & python -c "import sys; print(f'cp{sys.version_info.major}{sys.version_info.minor}')"
40+
$platform = & python -c "import platform; print(platform.system().lower())"
41+
$arch = & python -c "import platform; print(platform.machine().lower())"
42+
43+
Write-Host "Python: $pyVersion | Platform: $platform | Arch: $arch"
44+
45+
# Map to wheel filename platform tags
46+
switch ($platform) {
47+
'windows' {
48+
switch -Regex ($arch) {
49+
'amd64|x86_64' { $wheelPlatform = "win_amd64" }
50+
'arm64|aarch64' { $wheelPlatform = "win_arm64" }
51+
default { throw "Unsupported Windows architecture: $arch" }
52+
}
53+
}
54+
'linux' {
55+
switch -Regex ($arch) {
56+
'x86_64|amd64' { $wheelPlatform = "manylinux_2_28_x86_64" }
57+
'aarch64|arm64' { $wheelPlatform = "manylinux_2_28_aarch64" }
58+
default { throw "Unsupported Linux architecture: $arch" }
59+
}
60+
}
61+
'darwin' {
62+
$wheelPlatform = "macosx_15_0_universal2"
63+
}
64+
default { throw "Unsupported platform: $platform" }
65+
}
66+
67+
$wheelPattern = "mssql_py_core-*-$pyVersion-$pyVersion-$wheelPlatform.whl"
68+
Write-Host "Looking for wheel matching: $wheelPattern"
69+
70+
# Create temp directory
71+
if (Test-Path $OutputDir) { Remove-Item $OutputDir -Recurse -Force }
72+
New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null
73+
74+
# Download NuGet package
75+
$nugetDir = "$OutputDir\nuget"
76+
New-Item -ItemType Directory -Path $nugetDir -Force | Out-Null
77+
78+
# Resolve NuGet v3 feed to find package base URL
79+
Write-Host "Resolving feed: $FeedUrl"
80+
$feedIndex = Invoke-RestMethod -Uri $FeedUrl
81+
$packageBaseUrl = ($feedIndex.resources | Where-Object { $_.'@type' -like 'PackageBaseAddress*' }).'@id'
82+
if (-not $packageBaseUrl) { throw "Could not resolve PackageBaseAddress from feed" }
83+
Write-Host "Package base: $packageBaseUrl"
84+
85+
$packageId = "mssql-py-core-wheels"
86+
$packageIdLower = $packageId.ToLower()
87+
88+
$versionLower = $PackageVersion.ToLower()
89+
$nupkgUrl = "$packageBaseUrl$packageIdLower/$versionLower/$packageIdLower.$versionLower.nupkg"
90+
$nupkgPath = "$nugetDir\$packageIdLower.$versionLower.nupkg"
91+
92+
Write-Host "Downloading: $nupkgUrl"
93+
Invoke-WebRequest -Uri $nupkgUrl -OutFile $nupkgPath
94+
Write-Host "Downloaded: $nupkgPath ($([math]::Round((Get-Item $nupkgPath).Length / 1MB, 2)) MB)"
95+
96+
# Extract NuGet (it's a ZIP — rename so Expand-Archive accepts it)
97+
$zipPath = "$nugetDir\$packageIdLower.$versionLower.zip"
98+
Rename-Item -Path $nupkgPath -NewName (Split-Path $zipPath -Leaf)
99+
$extractDir = "$nugetDir\extracted"
100+
Expand-Archive -Path $zipPath -DestinationPath $extractDir -Force
101+
102+
# Find the matching wheel
103+
$wheelsDir = "$extractDir\wheels"
104+
if (-not (Test-Path $wheelsDir)) {
105+
throw "No 'wheels' directory found in NuGet package. Contents: $(Get-ChildItem $extractDir -Recurse | Select-Object -ExpandProperty Name)"
106+
}
107+
108+
$matchingWheel = Get-ChildItem $wheelsDir -Filter $wheelPattern | Select-Object -First 1
109+
if (-not $matchingWheel) {
110+
Write-Host "Available wheels:"
111+
Get-ChildItem $wheelsDir -Filter *.whl | ForEach-Object { Write-Host " $_" }
112+
throw "No wheel found matching pattern: $wheelPattern"
113+
}
114+
115+
Write-Host "Found matching wheel: $($matchingWheel.Name)"
116+
117+
# Install the wheel with pip
118+
Write-Host "Installing wheel with pip..."
119+
& python -m pip install $matchingWheel.FullName --force-reinstall --no-deps
120+
if ($LASTEXITCODE -ne 0) { throw "pip install failed with exit code $LASTEXITCODE" }
121+
122+
# Verify import works
123+
Write-Host "Verifying mssql_py_core import..."
124+
& python -c "import mssql_py_core; print(f'mssql_py_core loaded successfully: {dir(mssql_py_core)}')"
125+
if ($LASTEXITCODE -ne 0) { throw "Failed to import mssql_py_core" }
126+
127+
# Cleanup
128+
Remove-Item $OutputDir -Recurse -Force -ErrorAction SilentlyContinue
129+
130+
Write-Host "=== mssql_py_core installed successfully ==="

0 commit comments

Comments
 (0)