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
245 changes: 185 additions & 60 deletions OneBranchPipelines/build-release-package-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,23 @@ parameters:
displayName: 'Run SDL Security Tasks'
type: boolean
default: true

# Which package to build. Both are produced from this same pipeline but are
# fully independent stage groups, so building only one halves the run time and
# lets you run two builds (one per package) concurrently.
# mssql-python -> Windows/macOS/Linux wheels + Consolidate
# mssql-python-odbc -> ODBC data wheels + ConsolidateOdbc
# both -> everything (previous default behaviour)
# Scheduled (daily) builds ignore this and always build 'both' (see
# effectiveBuildPackage below) so the nightly keeps producing every artifact.
- name: buildPackage
displayName: 'Package to Build'
type: string
values:
- 'mssql-python'
- 'mssql-python-odbc'
- 'both'
default: 'mssql-python'

# =========================
# PLATFORM CONFIGURATIONS
Expand Down Expand Up @@ -138,6 +155,33 @@ parameters:
- { tag: 'musllinux', arch: 'x86_64', platform: 'linux/amd64' }
- { tag: 'musllinux', arch: 'aarch64', platform: 'linux/arm64' }

# =========================
# ODBC PACKAGE CONFIGURATIONS (mssql-python-odbc)
# =========================
# The standalone mssql-python-odbc package ships ONLY pre-built ODBC driver
# binaries (data) — there is NO compiled extension — so ONE py3-none-<platform>
# wheel per platform serves every supported Python version. Hence there is no
# per-Python matrix here: 7 wheels total (2 Windows + 1 macOS + 4 Linux).
# These stages build alongside the mssql-python wheels and are consolidated
# SEPARATELY (see the ConsolidateOdbc stage) so the release pipeline can publish
# mssql-python and mssql-python-odbc independently.
- name: odbcWindowsConfigs
type: object
default:
- { arch: 'x64' }
- { arch: 'arm64' }
- name: odbcMacosConfigs
type: object
default:
- { name: 'universal2' }
- name: odbcLinuxConfigs
type: object
default:
- { tag: 'manylinux_2_28', arch: 'x86_64', platform: 'linux/amd64' }
- { tag: 'manylinux_2_28', arch: 'aarch64', platform: 'linux/arm64' }
- { tag: 'musllinux', arch: 'x86_64', platform: 'linux/amd64' }
- { tag: 'musllinux', arch: 'aarch64', platform: 'linux/arm64' }

# =========================
# PIPELINE VARIABLES
# =========================
Expand All @@ -149,6 +193,14 @@ variables:
value: 'Official'
${{ else }}:
value: '${{ parameters.oneBranchType }}'

# Determine which package(s) to build: scheduled (nightly) builds always build
# 'both' so every artifact keeps refreshing; manual/PR builds honour the parameter.
- name: effectiveBuildPackage
${{ if eq(variables['Build.Reason'], 'Schedule') }}:
value: 'both'
${{ else }}:
value: '${{ parameters.buildPackage }}'

# Variable template imports
# Each file provides specific variable groups:
Expand Down Expand Up @@ -338,8 +390,10 @@ extends:
# =========================
# PIPELINE STAGES
# =========================
# Total stages: 9 Windows + 5 macOS + 4 Linux + 1 Consolidate = 19 stages
# Stages run in parallel (no dependencies between platform builds)
# mssql-python: 9 Windows + 5 macOS + 4 Linux + 1 Consolidate = 19 stages
# mssql-python-odbc: 2 Windows + 1 macOS + 4 Linux + 1 ConsolidateOdbc = 8 stages
# Total: 27 stages. All build stages run in parallel; each Consolidate* stage
# waits only on its own package's build stages.
stages:
# =========================
# WINDOWS BUILD STAGES
Expand All @@ -355,16 +409,18 @@ extends:
# 5. Builds wheel
# 6. Publishes artifacts (wheels + PYD + PDB)
# 7. ESRP malware scanning
- ${{ each config in parameters.windowsConfigs }}:
- template: /OneBranchPipelines/stages/build-windows-single-stage.yml@self
parameters:
stageName: Win_py${{ config.pyVer }}_${{ config.arch }}
jobName: BuildWheel
# Convert pyVer '310' → pythonVersion '3.10'
pythonVersion: ${{ format('{0}.{1}', substring(config.pyVer, 0, 1), substring(config.pyVer, 1, 2)) }}
shortPyVer: ${{ config.pyVer }}
architecture: ${{ config.arch }}
oneBranchType: '${{ variables.effectiveOneBranchType }}'
# Gate: build mssql-python stages unless an odbc-only build was requested
- ${{ if ne(variables.effectiveBuildPackage, 'mssql-python-odbc') }}:
- ${{ each config in parameters.windowsConfigs }}:
- template: /OneBranchPipelines/stages/build-windows-single-stage.yml@self
parameters:
stageName: Win_py${{ config.pyVer }}_${{ config.arch }}
jobName: BuildWheel
# Convert pyVer '310' → pythonVersion '3.10'
pythonVersion: ${{ format('{0}.{1}', substring(config.pyVer, 0, 1), substring(config.pyVer, 1, 2)) }}
shortPyVer: ${{ config.pyVer }}
architecture: ${{ config.arch }}
oneBranchType: '${{ variables.effectiveOneBranchType }}'

# =========================
# MACOS BUILD STAGES
Expand All @@ -381,15 +437,16 @@ extends:
# 6. Builds wheel
# 7. Publishes artifacts (wheels + .so)
# 8. ESRP malware scanning
- ${{ each config in parameters.macosConfigs }}:
- template: /OneBranchPipelines/stages/build-macos-single-stage.yml@self
parameters:
stageName: MacOS_py${{ config.pyVer }}
jobName: BuildWheel
# Convert pyVer '310' → pythonVersion '3.10'
pythonVersion: ${{ format('{0}.{1}', substring(config.pyVer, 0, 1), substring(config.pyVer, 1, 2)) }}
shortPyVer: ${{ config.pyVer }}
oneBranchType: '${{ variables.effectiveOneBranchType }}'
- ${{ if ne(variables.effectiveBuildPackage, 'mssql-python-odbc') }}:
- ${{ each config in parameters.macosConfigs }}:
- template: /OneBranchPipelines/stages/build-macos-single-stage.yml@self
parameters:
stageName: MacOS_py${{ config.pyVer }}
jobName: BuildWheel
# Convert pyVer '310' → pythonVersion '3.10'
pythonVersion: ${{ format('{0}.{1}', substring(config.pyVer, 0, 1), substring(config.pyVer, 1, 2)) }}
shortPyVer: ${{ config.pyVer }}
oneBranchType: '${{ variables.effectiveOneBranchType }}'

# =========================
# LINUX BUILD STAGES
Expand All @@ -411,15 +468,16 @@ extends:
# d. Runs pytest against SQL Server
# 4. Publishes artifacts (all 5 wheels)
# 5. Component Governance + AntiMalware scanning
- ${{ each config in parameters.linuxConfigs }}:
- template: /OneBranchPipelines/stages/build-linux-single-stage.yml@self
parameters:
stageName: Linux_${{ config.tag }}_${{ config.arch }}
jobName: BuildWheels
linuxTag: ${{ config.tag }}
arch: ${{ config.arch }}
dockerPlatform: ${{ config.platform }}
oneBranchType: '${{ variables.effectiveOneBranchType }}'
- ${{ if ne(variables.effectiveBuildPackage, 'mssql-python-odbc') }}:
- ${{ each config in parameters.linuxConfigs }}:
- template: /OneBranchPipelines/stages/build-linux-single-stage.yml@self
parameters:
stageName: Linux_${{ config.tag }}_${{ config.arch }}
jobName: BuildWheels
linuxTag: ${{ config.tag }}
arch: ${{ config.arch }}
dockerPlatform: ${{ config.platform }}
oneBranchType: '${{ variables.effectiveOneBranchType }}'

# =========================
# CONSOLIDATE STAGE
Expand All @@ -433,36 +491,103 @@ extends:
# - dist/bindings/macOS/*.so (macOS universal2 binaries)
# - dist/bindings/Linux/*.so (Linux native extensions)
# This stage also runs final BinSkim scan on all binaries
- stage: Consolidate
displayName: 'Consolidate All Artifacts'
dependsOn:
# Windows dependencies (9 stages)
- Win_py310_x64
- Win_py311_x64
- Win_py312_x64
- Win_py313_x64
- Win_py314_x64
- Win_py311_arm64
- Win_py312_arm64
- Win_py313_arm64
- Win_py314_arm64
# macOS dependencies (5 stages)
- MacOS_py310
- MacOS_py311
- MacOS_py312
- MacOS_py313
- MacOS_py314
# Linux dependencies (4 stages)
- Linux_manylinux_2_28_x86_64
- Linux_manylinux_2_28_aarch64
- Linux_musllinux_x86_64
- Linux_musllinux_aarch64
jobs:
- template: /OneBranchPipelines/jobs/consolidate-artifacts-job.yml@self
parameters:
# CRITICAL: Use effectiveOneBranchType to ensure scheduled builds run as 'Official'
# Using parameters.oneBranchType would break scheduled builds (they'd run as 'NonOfficial')
oneBranchType: '${{ variables.effectiveOneBranchType }}'
- ${{ if ne(variables.effectiveBuildPackage, 'mssql-python-odbc') }}:
- stage: Consolidate
displayName: 'Consolidate All Artifacts'
dependsOn:
# Windows dependencies (9 stages)
- Win_py310_x64
- Win_py311_x64
- Win_py312_x64
- Win_py313_x64
- Win_py314_x64
- Win_py311_arm64
- Win_py312_arm64
- Win_py313_arm64
- Win_py314_arm64
# macOS dependencies (5 stages)
- MacOS_py310
- MacOS_py311
- MacOS_py312
- MacOS_py313
- MacOS_py314
# Linux dependencies (4 stages)
- Linux_manylinux_2_28_x86_64
- Linux_manylinux_2_28_aarch64
- Linux_musllinux_x86_64
- Linux_musllinux_aarch64
jobs:
- template: /OneBranchPipelines/jobs/consolidate-artifacts-job.yml@self
parameters:
# CRITICAL: Use effectiveOneBranchType to ensure scheduled builds run as 'Official'
# Using parameters.oneBranchType would break scheduled builds (they'd run as 'NonOfficial')
oneBranchType: '${{ variables.effectiveOneBranchType }}'

# Note: Symbol publishing handled directly in Windows build stages
# PDB files uploaded to Microsoft Symbol Server for debugging

# =========================================================================
# ODBC PACKAGE BUILD STAGES (mssql-python-odbc)
# =========================================================================
# 7 data-only wheels (no native compile, no pytest) built from setup_odbc.py.
# They run in parallel with the mssql-python stages and are consolidated by a
# SEPARATE ConsolidateOdbc stage so the release pipeline can ship each package
# independently. SDL "just works": these wheels contain the SAME ODBC driver
# binaries already scanned in mssql_python/libs by the main build — no new
# first-party native code is introduced.
#
# ODBC Windows stages (2): ODBC_Win_x64, ODBC_Win_arm64
# Gate: build mssql-python-odbc stages unless an mssql-python-only build was requested
- ${{ if ne(variables.effectiveBuildPackage, 'mssql-python') }}:
- ${{ each config in parameters.odbcWindowsConfigs }}:
- template: /OneBranchPipelines/stages/build-odbc-windows-stage.yml@self
parameters:
stageName: ODBC_Win_${{ config.arch }}
jobName: BuildWheel
architecture: ${{ config.arch }}
oneBranchType: '${{ variables.effectiveOneBranchType }}'

# ODBC macOS stage (1): ODBC_MacOS_universal2
- ${{ if ne(variables.effectiveBuildPackage, 'mssql-python') }}:
- ${{ each config in parameters.odbcMacosConfigs }}:
- template: /OneBranchPipelines/stages/build-odbc-macos-stage.yml@self
parameters:
stageName: ODBC_MacOS_${{ config.name }}
jobName: BuildWheel
oneBranchType: '${{ variables.effectiveOneBranchType }}'

# ODBC Linux stages (4): manylinux_2_28 x86_64/aarch64, musllinux x86_64/aarch64
- ${{ if ne(variables.effectiveBuildPackage, 'mssql-python') }}:
- ${{ each config in parameters.odbcLinuxConfigs }}:
- template: /OneBranchPipelines/stages/build-odbc-linux-stage.yml@self
parameters:
stageName: ODBC_Linux_${{ config.tag }}_${{ config.arch }}
jobName: BuildWheel
linuxTag: ${{ config.tag }}
arch: ${{ config.arch }}
dockerPlatform: ${{ config.platform }}
oneBranchType: '${{ variables.effectiveOneBranchType }}'

# =========================================================================
# CONSOLIDATE ODBC STAGE
# =========================================================================
# Collects the 7 mssql-python-odbc wheels into a single dist/ folder and
# publishes them as `drop_ConsolidateOdbc_ConsolidateArtifacts` (distinct from
# the mssql-python `drop_Consolidate_ConsolidateArtifacts`). The release
# pipeline selects one artifact based on its `releasePackage` parameter.
- ${{ if ne(variables.effectiveBuildPackage, 'mssql-python') }}:
- stage: ConsolidateOdbc
displayName: 'Consolidate All ODBC Artifacts'
dependsOn:
- ODBC_Win_x64
- ODBC_Win_arm64
- ODBC_MacOS_universal2
- ODBC_Linux_manylinux_2_28_x86_64
- ODBC_Linux_manylinux_2_28_aarch64
- ODBC_Linux_musllinux_x86_64
- ODBC_Linux_musllinux_aarch64
jobs:
- template: /OneBranchPipelines/jobs/consolidate-odbc-artifacts-job.yml@self
parameters:
oneBranchType: '${{ variables.effectiveOneBranchType }}'
expectedWheelCount: 7
Loading
Loading