Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3a8467d
Add SqlServer.Server as a sibling project reference
paulmedynski May 14, 2026
9da60b7
Gate UDT tests on SqlServer.Server strong-name signing
paulmedynski May 14, 2026
e22b8b7
Tokenize SqlServer.Server version in nuspec and fix BuildTests
paulmedynski May 13, 2026
01b0358
Plumb SqlServerPackageVersion through CI pipelines
paulmedynski May 14, 2026
972665d
Fix net462 build: enable implicit usings in TestCommon, fix typo
paulmedynski May 14, 2026
716a7a1
Add comments explaining Versions.props import-guard pattern
paulmedynski May 14, 2026
bb91c5f
Exclude UDT tests requiring signed assemblies on unsigned .NET Framew…
paulmedynski May 14, 2026
7306a00
Bump sibling package versions and fix Package-mode dependency ordering
paulmedynski May 14, 2026
5b3e87d
Updated CI package versions to match those in csproj.
paulmedynski May 15, 2026
3a1792e
Fix incorrect MSBuild property name in Azure test job
paulmedynski May 15, 2026
6dc9da5
Thread loggingPackageVersion through Azure test pipeline
paulmedynski May 15, 2026
ecbe841
Skipping the pack dependencies for Build* targets in build.proj for O…
paulmedynski May 19, 2026
376eecb
Add SqlServer artifact dependency to downstream OneBranch jobs
paulmedynski May 19, 2026
d8ccb8d
Enable InternalsVisibleTo for test projects in Package mode
paulmedynski May 20, 2026
2463f9a
Pipeline: run unit tests in both Project and Package modes
paulmedynski May 20, 2026
e91096e
Reverted some straggler leftover changes from previous attempts.
paulmedynski May 20, 2026
900ed25
Added new sqlclient-package CI pipeline.
paulmedynski May 14, 2026
21ad290
Updated pool choice to use the Azure DevOps project name.
paulmedynski May 14, 2026
2d0937c
Add CI package pipeline for building and publishing NuGet packages
paulmedynski May 14, 2026
60cfc11
Address Copilot review: declare signingKeyArg conditionally, remove d…
paulmedynski May 14, 2026
bef42de
Exclude the new CI pipeline files from PR checks.
paulmedynski May 14, 2026
c07c795
Address Copilot review: fix verbosity switch and boolean comparisons
paulmedynski May 20, 2026
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -376,3 +376,6 @@ MigrationBackup/

# MDS "Not Supported" GenAPI code
**/notsupported/*.cs

# C# language server cache
*.lscache
53 changes: 36 additions & 17 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,4 +1,33 @@
<Project>

<!-- ===================================================================== -->
<!--
Versions.props import strategy:

Each product has a Versions.props that computes its version properties (e.g.
SqlClientPackageVersion). These files can be imported from two places:

1. Here, in Directory.Packages.props (Package mode only) — imports ALL
Versions.props early so that centrally-managed PackageVersion items can
reference the computed version values for sibling package pinning.

2. In each product's own csproj (conditional) — imports the product's own
Versions.props so standalone / Project-mode builds still get versions.

To prevent double-evaluation when both paths fire, every Versions.props sets
an import-guard property (e.g. SqlClientVersionsImported=true) on first load.
The csproj-level import checks that guard and becomes a no-op if the file was
already imported here.
-->
<ImportGroup Condition="'$(ReferenceType)' == 'Package'">
<Import Project="src/Microsoft.Data.SqlClient/Versions.props" />
<Import Project="src/Microsoft.SqlServer.Server/Versions.props" />
<Import Project="src/Microsoft.Data.SqlClient.Internal/Logging/src/Versions.props" />
<Import Project="src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Versions.props" />
<Import Project="src/Microsoft.Data.SqlClient.Extensions/Azure/src/Versions.props" />
<Import Project="src/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider/src/Versions.props" />
</ImportGroup>

<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<!--
Expand All @@ -14,33 +43,23 @@
<!-- ===================================================================== -->
<!-- Driver Packages -->

<!-- Ordered from least dependent to most dependent, and then alphabetically. -->

<ItemGroup>
<!--
We never reference this package via its project, so we always need a
version specified.
-->
<PackageVersion Include="Microsoft.SqlServer.Server" Version="1.0.0" />
</ItemGroup>

<!--
We only need other driver package versions specified when building via
package references.
-->
<!-- The driver packages need version numbers when we build via Package references. -->
<ItemGroup Condition="'$(ReferenceType)' == 'Package'">
<PackageVersion
Include="Microsoft.SqlServer.Server"
Version="$(SqlServerPackageVersion)" />
<PackageVersion
Include="Microsoft.Data.SqlClient.Internal.Logging"
Version="$(LoggingPackageVersion)" />
<PackageVersion
Include="Microsoft.Data.SqlClient.Extensions.Abstractions"
Version="$(AbstractionsPackageVersion)" />
<PackageVersion
Include="Microsoft.Data.SqlClient.Extensions.Azure"
Version="$(AzurePackageVersion)" />
<PackageVersion
Include="Microsoft.Data.SqlClient"
Version="$(SqlClientPackageVersion)" />
<PackageVersion
Include="Microsoft.Data.SqlClient.Extensions.Azure"
Version="$(AzurePackageVersion)" />
<PackageVersion
Include="Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider"
Version="$(AkvProviderPackageVersion)" />
Expand Down
197 changes: 171 additions & 26 deletions build.proj

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions doc/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
<PackageVersion Include="Microsoft.Data.SqlClient" Version="7.0.0-preview4.26064.3" />
<PackageVersion Include="Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider" Version="7.0.0-preview1.26064.3" />
<PackageVersion Include="Microsoft.Data.SqlClient.Extensions.Azure" Version="1.0.0-preview1.26064.3" />
<PackageVersion Include="Microsoft.SqlServer.Server" Version="1.0.0" />
</ItemGroup>
</Project>
13 changes: 9 additions & 4 deletions doc/samples/Microsoft.Data.SqlClient.Samples.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,19 @@
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
</PropertyGroup>

<!-- The Samples only support referencing the SqlClient suite via package reference. -->
<ItemGroup>
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Azure.Core" />
<PackageReference Include="Microsoft.Identity.Client" />
<PackageReference Include="Microsoft.SqlServer.Server" />
<PackageReference Include="Microsoft.Data.SqlClient" />
<PackageReference Include="Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider" />
<PackageReference Include="Microsoft.Data.SqlClient.Extensions.Azure" />
<PackageReference Include="Microsoft.SqlServer.Server" />
</ItemGroup>

<!-- Other package references. -->
<ItemGroup>
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Azure.Core" />
<PackageReference Include="Microsoft.Identity.Client" />
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="System.Configuration.ConfigurationManager" />
</ItemGroup>
Expand Down
169 changes: 169 additions & 0 deletions eng/pipelines/ci/package/sqlclient-package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#################################################################################
# Licensed to the .NET Foundation under one or more agreements. #
# The .NET Foundation licenses this file to you under the MIT license. #
# See the LICENSE file in the project root for more information. #
#################################################################################

# This pipeline builds all packages using the build.proj Pack target with ReferenceType=Package,
# then publishes the resulting .nupkg and .snupkg files as a single pipeline artifact.
#
# It runs:
# - On pushes to GitHub main and ADO internal/main (batched)
# - Nightly at 00:00 UTC on both branches
#
# On internal/main the strong-name signing key is downloaded and used to sign assemblies during the
# build.
#
# GOTCHA: This pipeline definition is triggered by GitHub _and_ ADO CI. We distinguish the two via
# branch filters:
#
# - Only the GitHub repo has a 'main' branch.
# - Only the ADO repo has an 'internal/main' branch.

Comment thread
paulmedynski marked this conversation as resolved.
name: $(DayOfYear)$(Rev:rr)

# Do not trigger this pipeline for PRs.
pr: none

# Trigger on pushes to main and internal/main, batching concurrent commits.
trigger:
batch: true
branches:
include:
- main
- internal/main

# Nightly schedule at 00:00 UTC.
schedules:
- cron: '0 0 * * *'
displayName: Nightly Build
branches:
include:
- main
- internal/main
always: true

# Pipeline parameters visible in the Azure DevOps UI.
parameters:

# The agent image to use for the build. This must exist in both the ADO-1ES-Pool and
# ADO-CI-1ES-Pool agent pools.
- name: agentImage
displayName: Agent Image
type: string
default: ADO-UB24
Comment thread
paulmedynski marked this conversation as resolved.
values:
- ADO-UB24
- ADO-Win25

# The build configuration to use, either Debug or Release.
- name: buildConfiguration
displayName: Build Configuration
type: string
default: Release
values:
- Debug
- Release

# True to enable debug steps and output.
- name: debug
displayName: Enable debug output
type: boolean
default: false

# The verbosity level of dotnet CLI commands.
- name: dotnetVerbosity
displayName: dotnet CLI Verbosity
type: string
default: normal
values:
- quiet
- minimal
- normal
- detailed
- diagnostic

variables:
# Whether this is an internal (ADO.Net project) or public (Public project) build.
- name: isInternalBuild
value: ${{ eq(variables['System.TeamProject'], 'ADO.Net') }}

# Signing key argument passed to build.proj. On internal builds this references the secure file
# downloaded by DownloadSecureFile@1; on public builds it expands to empty.
- name: signingKeyArg
${{ if eq(variables.isInternalBuild, true) }}:
value: '-p:SigningKeyPath="$(keyFile.secureFilePath)"'
Comment thread
paulmedynski marked this conversation as resolved.
${{ else }}:
value: ''

jobs:
- job: pack_all_packages
displayName: Pack All Packages

pool:
${{ if eq(variables.isInternalBuild, true) }}:
name: ADO-1ES-Pool
${{ else }}:
name: ADO-CI-1ES-Pool
demands:
- ImageOverride -equals ${{ parameters.agentImage }}

Comment thread
paulmedynski marked this conversation as resolved.
steps:

# Emit environment variables if debug is enabled.
- ${{ if eq(parameters.debug, true) }}:
- pwsh: |
Get-ChildItem Env: | Sort-Object Name | Format-Table -AutoSize -Wrap
displayName: '[Debug] Print Environment Variables'

# Install the .NET SDK from global.json.
- template: /eng/pipelines/steps/install-dotnet.yml@self
parameters:
debug: ${{ parameters.debug }}

# Clean any pre-existing .nupkg / .snupkg files from the packages/ directory
# to ensure we only publish packages produced by this run.
- pwsh: |
Write-Host 'Cleaning packages/ directory...'
Remove-Item -Force "$(Build.SourcesDirectory)/packages/*.nupkg" -ErrorAction SilentlyContinue
Remove-Item -Force "$(Build.SourcesDirectory)/packages/*.snupkg" -ErrorAction SilentlyContinue
Write-Host 'Done.'
displayName: Clean packages/ directory

# On internal builds, download the strong-name signing key.
- ${{ if eq(variables.isInternalBuild, true) }}:
- task: DownloadSecureFile@1
displayName: Download Signing Key
inputs:
secureFile: netfxKeypair.snk
name: keyFile

# Run the Pack target via build.proj.
- task: DotNetCoreCLI@2
displayName: build.proj - Pack (ReferenceType=Package)
inputs:
command: build
projects: '$(Build.SourcesDirectory)/build.proj'
arguments: >-
-t:Pack
-p:Configuration=${{ parameters.buildConfiguration }}
-p:ReferenceType=Package
-p:BuildNumber="$(Build.BuildNumber)"
-p:BuildSuffix=ci
$(signingKeyArg)
--verbosity ${{ parameters.dotnetVerbosity }}

# List produced packages for diagnostics.
- pwsh: |
Write-Host 'Packages produced:'
Get-ChildItem "$(Build.SourcesDirectory)/packages/*.nupkg" -ErrorAction SilentlyContinue | Format-Table Name, Length -AutoSize -Wrap
Get-ChildItem "$(Build.SourcesDirectory)/packages/*.snupkg" -ErrorAction SilentlyContinue | Format-Table Name, Length -AutoSize -Wrap
displayName: List produced packages

# Publish all .nupkg and .snupkg files from packages/ as a pipeline artifact.
- task: PublishPipelineArtifact@1
displayName: Publish NuGet Packages
inputs:
targetPath: '$(Build.SourcesDirectory)/packages'
artifactName: Packages
publishLocation: pipeline
20 changes: 20 additions & 0 deletions eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ parameters:
- name: akvPackageVersion
type: string

# The version of the SqlServer package to depend on when referenceType is 'Package'.
- name: sqlServerPackageVersion
type: string
default: $(sqlServerPackageVersion)

# The name of the SqlServer pipeline artifact to download when referenceType is 'Package'.
- name: sqlServerArtifactsName
type: string
default: SqlServer.Artifacts

jobs:
- job: build_mds_akv_packages_job
displayName: Build MDS & AKV Packages
Expand Down Expand Up @@ -115,6 +125,12 @@ jobs:
artifactName: ${{ parameters.loggingArtifactsName }}
targetPath: $(localFeedPath)

- task: DownloadPipelineArtifact@2
displayName: Download SqlServer Package Artifacts
inputs:
artifactName: ${{ parameters.sqlServerArtifactsName }}
targetPath: $(localFeedPath)

# Install the .NET SDK.
- template: /eng/pipelines/steps/install-dotnet.yml@self

Expand All @@ -139,6 +155,7 @@ jobs:
build: MDS
abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}

- task: DotNetCoreCLI@2
displayName: 'Create MDS NuGet Package'
Expand All @@ -153,6 +170,7 @@ jobs:
-p:PackageVersionSqlClient=${{ parameters.mdsPackageVersion }}
-p:PackageVersionAbstractions=${{ parameters.abstractionsPackageVersion }}
-p:PackageVersionLogging=${{ parameters.loggingPackageVersion }}
-p:PackageVersionSqlServer=${{ parameters.sqlServerPackageVersion }}

# PackSqlClient outputs to artifacts/Microsoft.Data.SqlClient/<ReferenceType>-<Configuration>/.
# Downstream steps (local feed copy, AKV pack, artifact publish) all expect packages at
Expand Down Expand Up @@ -184,6 +202,7 @@ jobs:
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
akvPackageVersion: ${{ parameters.akvPackageVersion }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}

- task: DotNetCoreCLI@2
displayName: 'Create AKV Provider NuGet Package'
Expand All @@ -199,6 +218,7 @@ jobs:
-p:PackageVersionAbstractions=${{ parameters.abstractionsPackageVersion }}
-p:PackageVersionLogging=${{ parameters.loggingPackageVersion }}
-p:PackageVersionSqlClient=${{ parameters.mdsPackageVersion }}
-p:PackageVersionSqlServer=${{ parameters.sqlServerPackageVersion }}
-p:PackageVersionAkvProvider=${{ parameters.akvPackageVersion }}

- task: CopyFiles@2
Expand Down
18 changes: 18 additions & 0 deletions eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ parameters:
- name: mdsPackageVersion
type: string

# The name of the SqlServer pipeline artifact to download when referenceType is 'Package'.
- name: sqlServerArtifactsName
type: string
default: SqlServer.Artifacts

# The version of the SqlServer package to depend on when referenceType is 'Package'.
- name: sqlServerPackageVersion
type: string
default: $(sqlServerPackageVersion)

# TODO: What is this for?
- name: netcoreVersionTestUtils
type: string
Expand Down Expand Up @@ -194,6 +204,12 @@ jobs:
artifactName: ${{ parameters.mdsArtifactsName }}
targetPath: $(Build.SourcesDirectory)/packages

- task: DownloadPipelineArtifact@2
displayName: Download SqlServer Package Artifacts
inputs:
artifactName: ${{ parameters.sqlServerArtifactsName }}
targetPath: $(Build.SourcesDirectory)/packages

# Install the .NET SDK and Runtimes.
- template: /eng/pipelines/steps/install-dotnet.yml@self
parameters:
Expand Down Expand Up @@ -364,6 +380,7 @@ jobs:
abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}

- ${{ if and(eq(parameters.enableX86Test, true), eq(parameters.operatingSystem, 'Windows')) }}:
- template: /eng/pipelines/common/templates/steps/run-all-tests-step.yml@self
Expand All @@ -379,6 +396,7 @@ jobs:
abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}

- template: /eng/pipelines/common/templates/steps/publish-test-results-step.yml@self
parameters:
Expand Down
Loading
Loading