From e91297598c642f0dec9e9c1a03d063881592a665 Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Tue, 8 Jul 2025 08:31:05 -0300
Subject: [PATCH] User Story 37654: Create Extensions base package
- Added empty Extensions package with some sample class and docs to demonstrate packaging.
- Created CI stage to build, test, pack, and publish the Extensions NuGet package.
- Updated downstream CI stages/jobs to use the Extensions package.
- Updated build.proj Clean target to not delete packages/ dir.
- Updated BUILDGUIDE with instructions for the Extensions package.
- Cleaned up stale BUIDGUIDE sections.
- Added temporary GitHub Discussion content so the team can review before posting it as a real Discussion.
- Disable .pdb file inclusion in the application package.
---
.editorconfig | 5 +-
BUILDGUIDE.md | 87 +++--
NuGet.config | 5 +-
build.proj | 43 ++-
.../templates/jobs/ci-build-nugets-job.yml | 31 +-
.../templates/jobs/ci-run-tests-job.yml | 20 +-
.../templates/stages/ci-run-tests-stage.yml | 16 +-
.../templates/steps/build-all-tests-step.yml | 11 +-
.../templates/steps/ci-prebuild-step.yml | 7 +
.../templates/steps/ci-project-build-step.yml | 17 +-
.../update-nuget-config-local-feed-step.yml | 9 +-
eng/pipelines/dotnet-sqlclient-ci-core.yml | 183 +++++----
...qlclient-ci-package-reference-pipeline.yml | 15 +-
...qlclient-ci-project-reference-pipeline.yml | 15 +-
.../ci-build-extensions-package-stage.yml | 351 ++++++++++++++++++
src/Directory.Build.props | 15 +
src/Directory.Packages.props | 1 +
.../Extensions/Extensions.slnx | 8 +
.../Extensions/doc/Sample.xml | 18 +
.../Extensions/github-discussion.md | 261 +++++++++++++
.../Extensions/src/Extensions.csproj | 95 +++++
.../Extensions/src/Sample.cs | 20 +
.../Extensions/test/Extensions.Test.csproj | 26 ++
.../Extensions/test/SampleTest.cs | 19 +
src/Microsoft.Data.SqlClient.sln | 33 +-
src/Microsoft.Data.SqlClient/NuGet.config | 13 +
.../ref/Microsoft.Data.SqlClient.csproj | 1 +
.../src/Microsoft.Data.SqlClient.csproj | 1 +
.../netfx/ref/Microsoft.Data.SqlClient.csproj | 1 +
.../netfx/src/Microsoft.Data.SqlClient.csproj | 1 +
tools/props/Versions.props | 58 ++-
tools/specs/Microsoft.Data.SqlClient.nuspec | 4 +
32 files changed, 1210 insertions(+), 180 deletions(-)
create mode 100644 eng/pipelines/stages/ci-build-extensions-package-stage.yml
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Extensions/Extensions.slnx
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Extensions/doc/Sample.xml
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Extensions/github-discussion.md
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Extensions/src/Extensions.csproj
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Extensions/src/Sample.cs
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Extensions/test/Extensions.Test.csproj
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Extensions/test/SampleTest.cs
create mode 100644 src/Microsoft.Data.SqlClient/NuGet.config
diff --git a/.editorconfig b/.editorconfig
index f0ea20ec32..14f37d4e02 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -14,6 +14,9 @@ indent_size = 4
[*.{json,jsonc}]
indent_size = 2
+[*.{yml,yaml}]
+indent_size = 2
+
# C# files
[*.cs]
# New line preferences
@@ -160,7 +163,7 @@ indent_size = 2
indent_size = 2
# Xml files
-[*.{xml,stylecop,resx,ruleset}]
+[*.{xml,stylecop,resx,ruleset,slnx}]
indent_size = 2
# Xml config files
diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md
index efeb747cad..3c0b11dfa8 100644
--- a/BUILDGUIDE.md
+++ b/BUILDGUIDE.md
@@ -16,28 +16,34 @@ Once the environment is setup properly, execute the desired set of commands belo
### Targets
+The following build targets are defined in `build.proj`:
+
|Target|Description|
|-|-|
|`BuildAllConfigurations`|Default target. Builds the .NET Framework and .NET drivers for all target frameworks and operating systems.|
+|`BuildExtensionsPackage`|Restore, build, and pack the Extensions package, publishing the resulting NuGet into `packages/`.|
|`BuildNetCore`|Builds the .NET driver for all target frameworks.|
|`BuildNetCoreAllOS`|Builds the .NET driver for all target frameworks and operating systems.|
|`BuildNetFx`|Builds the .NET Framework driver for all target frameworks.|
|`BuildTestsNetCore`|Builds tests for the .NET driver.|
|`BuildTestsNetFx`|Builds tests for the .NET Framework driver.|
-|`Clean`|Cleans generated files.|
-|`Restore`|Restores Nuget packages.|
+|`Clean`|Cleans generated files, except for NuGet packages published to `packages/`.|
+|`CleanAll`|Cleans all generated files.|
+|`Restore`|Restores NuGet packages.|
|`RunTests`|Runs the unit, functional, and manual tests for the .NET Framework and .NET drivers|
|`RunUnitTests`|Runs just the unit tests for the .NET Framework and .NET drivers|
|`RunFunctionalTests`|Runs just the functional tests for the .NET Framework and .NET drivers|
|`RunManualTests`|Runs just the manual tests for the .NET Framework and .NET drivers|
|`BuildAkv`|Builds the Azure Key Vault Provider package for all supported platforms.|
-
### Parameters
+
+The following parameters may be defined as MSBuild properties to configure the
+build:
+
|Name|Supported Values|Default|Description|
|-|-|-|-|
|`Configuration`|`Debug`, `Release`|`Debug`|Sets the release configuration.|
-|`BuildNetFx`|`true`, `false`|`true` (Windows), `false` (other)|If false, skips building the .NET Framework driver on Windows.|
|`OSGroup`|`Unix`, `Windows_NT`, `AnyOS`|typically defaults to the client system's OS, unless using `BuildAllConfigurations` or an `AnyOS` specific target|The operating system to target.|
|`Platform`|`AnyCPU`, `x86`, `x64`, `ARM`, `ARM64`|`AnyCPU`|May only be set when using package reference type or running tests.|
|`TestSet`|`1`, `2`, `3`, `AE`|all|Build or run a subset of the manual tests. Omit (default) to target all tests.|
@@ -45,11 +51,12 @@ Once the environment is setup properly, execute the desired set of commands belo
|`TF`|`net8.0`, `net462`, `net47`, `net471`, `net472`, `net48`, `net481`|`net8.0` in netcore, `net462` in netfx|Sets the target framework when building or running tests. Not applicable when building the drivers.|
|`ResultsDirectory`|An absolute file path|./TestResults relative to current directory|Specifies where to write test results.|
-
## Example Workflows using MSBuild (Recommended)
+
Using the default configuration and running all tests:
```bash
+msbuild -t:BuildExtensionsPackage
msbuild
msbuild -t:BuildTestsNetFx -p:TF=net462
msbuild -t:BuildTestsNetCore
@@ -59,28 +66,31 @@ msbuild -t:RunTests
Using the Release configuration:
```bash
-msbuild -p:configuration=Release
-msbuild -t:BuildTestsNetFx -p:TF=net462 -p:configuration=Release
-msbuild -t:BuildTestsNetCore -p:configuration=Release
-msbuild -t:RunTests -p:configuration=Release
+msbuild -t:BuildExtensionsPackage -p:Configuration=Release
+msbuild -p:Configuration=Release
+msbuild -t:BuildTestsNetFx -p:TF=net462 -p:Configuration=Release
+msbuild -t:BuildTestsNetCore -p:Configuration=Release
+msbuild -t:RunTests -p:Configuration=Release
```
Running only the unit tests:
```bash
+msbuild -t:BuildExtensionsPackage
msbuild
msbuild -t:BuildTestsNetFx -p:TF=net462
msbuild -t:BuildTestsNetCore
msbuild -t:RunUnitTests
```
-Using a specific dotnet version/architecture:
+Using a specific .NET runtime to run tests:
```bash
-msbuild -p:configuration=Release
-msbuild -t:BuildTestsNetFx -p:TF=net462 -p:configuration=Release
-msbuild -t:BuildTestsNetCore -p:configuration=Release
-msbuild -t:RunTests -p:configuration=Release -p:DotnetPath=C:\net8-win-x86\
+msbuild -t:BuildExtensionsPackage
+msbuild
+msbuild -t:BuildTestsNetFx -p:TF=net462
+msbuild -t:BuildTestsNetCore
+msbuild -t:RunTests -p:DotnetPath=C:\net8-win-x86\
```
### Running Manual Tests
@@ -119,15 +129,13 @@ Manual Tests require the below setup to run:
|IsManagedInstance | (Optional) When set to `true` **TVP** related tests will use on non-Azure bs files to compare test results. this is needed when testing against Managed Instances or TVP Tests will fail on Test set 3. The default value is `false`. |
|PowerShellPath | The full path to PowerShell.exe. This is not required if the path is present in the PATH environment variable. | `D:\\escaped\\absolute\\path\\to\\PowerShell.exe` |
-
## Example workflows using the Dotnet SDK
-#### Run Functional Tests
+### Run Functional Tests
- Windows (`netfx x86`):
```bash
-msbuild
dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="x86" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
```
@@ -152,7 +160,8 @@ dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.S
```bash
dotnet test "src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Unixnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonlinuxtests&category!=nonuaptests"
```
-#### Run Manual Tests
+
+### Run Manual Tests
- Windows (`netfx x86`):
@@ -194,35 +203,40 @@ dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlCl
Tests can be built and run with custom "Reference Type" property that enables different styles of testing:
-- "Project" => Build and run tests with Microsoft.Data.SqlClient as Project Reference
-- "Package" => Build and run tests with Microsoft.Data.SqlClient as Package Reference with configured "TestMicrosoftDataSqlClientVersion" in "Versions.props" file.
+- "Project" => Build and run tests with Microsoft.Data.SqlClient as a Project Reference
+- "Package" => Build and run tests with Microsoft.Data.SqlClient as a Package Reference with configured "TestMicrosoftDataSqlClientVersion" in "Versions.props" file.
> ************** IMPORTANT NOTE BEFORE PROCEEDING WITH "PACKAGE" REFERENCE TYPE ***************
> CREATE A NUGET PACKAGE WITH BELOW COMMAND AND ADD TO LOCAL FOLDER + UPDATE NUGET CONFIG FILE TO READ FROM THAT LOCATION
>
> ```bash
-> msbuild -p:configuration=Release
+> msbuild -t:BuildExtensionsPackage -p:Configuration=Release
+> msbuild -p:Configuration=Release
> ```
A non-AnyCPU platform reference can only be used with package reference type. Otherwise, the specified platform will be replaced with AnyCPU in the build process.
### Building Tests with Reference Type
-For .NET, all 4 reference types are supported:
+For .NET:
```bash
+# Project is the default reference type. The below commands are equivalent:
+msbuild -t:BuildTestsNetCore
msbuild -t:BuildTestsNetCore -p:ReferenceType=Project
-# Default setting uses Project Reference.
+# Package reference type:
msbuild -t:BuildTestsNetCore -p:ReferenceType=Package
```
-For .NET Framework, below reference types are supported:
+For .NET Framework:
```bash
+# Project is the default reference type. The below commands are equivalent:
+msbuild -t:BuildTestsNetFx -p:TF=net462
msbuild -t:BuildTestsNetFx -p:TF=net462 -p:ReferenceType=Project
-# Default setting uses Project Reference.
+# Package reference type:
msbuild -t:BuildTestsNetFx -p:TF=net462 -p:ReferenceType=Package
```
@@ -241,26 +255,25 @@ Tests can be built and run with custom Target Frameworks. See the below examples
### Building Tests with custom target framework
```bash
-msbuild -t:BuildTestsNetFx -p:TF=net462
# Build the tests for custom .NET Framework target
+msbuild -t:BuildTestsNetFx -p:TF=net462
```
```bash
-msbuild -t:BuildTestsNetCore -p:TF=net8.0
# Build the tests for custom .NET target
+msbuild -t:BuildTestsNetCore -p:TF=net8.0
```
### Running Tests with custom target framework (traditional)
```bash
+# Run tests with custom .NET Framework target
dotnet test -p:TargetNetFxVersion=net462 ...
-# Use above property to run Functional Tests with custom .NET Framework target
+# Run tests with custom .NET target
dotnet test -p:TargetNetCoreVersion=net8.0 ...
-# Use above property to run Functional Tests with custom .NET target
```
-
## Using Managed SNI on Windows
Managed SNI can be enabled on Windows by enabling the below AppContext switch:
@@ -285,20 +298,6 @@ When connecting to a server, if a protocol lower than TLS 1.2 is negotiated, a s
`Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning`
-### Troubleshooting Docker issues
-
-There may be times where connection cannot be made to SQL Server, we found below ideas helpful:
-
-- Clear Docker images to create clean image from time-to-time, and clear docker cache if needed by running `docker system prune` in Command Prompt.
-
-- If you face `Microsoft.Data.SqlClient.SNI.dll not found` errors when debugging, try updating the below properties in the netcore\Microsoft.Data.SqlClient.csproj file and try again:
-
- ```xml
- Unix
- false
- true
- ```
-
## Collecting Code Coverage
### Using VSTest
diff --git a/NuGet.config b/NuGet.config
index d93875f3fb..32e4905f6d 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -2,10 +2,13 @@
-
+
+
+
+
diff --git a/build.proj b/build.proj
index 0443bbcf4e..7163f79e6e 100644
--- a/build.proj
+++ b/build.proj
@@ -51,6 +51,7 @@
+
@@ -91,6 +92,32 @@
+
+
+
+
+ ExtensionsPackageVersion=$(ExtensionsPackageVersion)
+
+
+
+
+
@@ -346,13 +373,17 @@
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml b/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
index cb3790262c..9563397a70 100644
--- a/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
@@ -12,9 +12,13 @@ parameters:
type: string
default: ADO-MMS22-SQL19
- - name: artifactName
+ - name: extensionsArtifactName
type: string
- default: Artifacts
+ default: Extensions.Artifact
+
+ - name: mdsArtifactName
+ type: string
+ default: MDS.Artifact
- name: platform
type: string
@@ -28,6 +32,11 @@ parameters:
type: stepList
default: []
+ - name: extensionsPackageVersion
+ displayName: Extensions Package Version Override
+ type: string
+ default: ''
+
jobs:
- job: build_nugets
@@ -44,12 +53,22 @@ jobs:
- ${{ if ne(parameters.prebuildSteps, '') }}:
- ${{ parameters.prebuildSteps }} # extra steps to run before the build like downloading sni and the required configuration
+ # Download the Extensions package artifacts and put them in the packages/
+ # directory in the repo root. This is where the MDS NuGet.config file will
+ # look for local packages.
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Extensions Package Artifact
+ inputs:
+ artifactName: ${{ parameters.extensionsArtifactName }}
+ targetPath: $(Build.SourcesDirectory)/packages
+
- template: ../steps/ci-project-build-step.yml@self
parameters:
platform: ${{ parameters.platform }}
configuration: ${{ parameters.configuration }}
operatingSystem: Windows
build: all
+ extensionsPackageVersion: ${{parameters.extensionsPackageVersion}}
- template: ../steps/generate-nuget-package-step.yml@self
parameters:
@@ -70,8 +89,8 @@ jobs:
installNuget: false
displayName: 'Generate NuGet package AKV Provider'
- - task: PublishBuildArtifacts@1
- displayName: 'Publish Artifact: Artifacts'
+ - task: PublishPipelineArtifact@1
+ displayName: 'Publish Pipeline Artifact'
inputs:
- PathtoPublish: $(packagePath)
- ArtifactName: ${{ parameters.artifactName }}
+ targetPath: $(packagePath)
+ artifactName: ${{ parameters.mdsArtifactName }}
diff --git a/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml b/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
index 9ad2c86e6a..2484bb63df 100644
--- a/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
@@ -29,13 +29,18 @@ parameters:
type: object
default: {} # - key: 'value'
+ - name: extensionsPackageVersion
+ displayName: Extensions Package Version Override
+ type: string
+ default: ''
+
- name: prebuildSteps
type: stepList
default: []
- - name: artifactName
+ - name: extensionsArtifactName
type: string
- default: Artifacts
+ default: Extensions.Artifact
- name: targetFramework
type: string
@@ -89,6 +94,16 @@ jobs:
value: '$(dotnetx86Path)'
steps:
+
+ # Download the Extensions package artifacts and put them in the packages/
+ # directory in the repo root. This is where the MDS NuGet.config file will
+ # look for local packages.
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Extensions Package Artifact
+ inputs:
+ artifactName: ${{ parameters.extensionsArtifactName }}
+ targetPath: $(Build.SourcesDirectory)/packages
+
- ${{ if ne(parameters.prebuildSteps, '') }}:
- ${{ parameters.prebuildSteps }} # extra steps to run before the build like downloading sni and the required configuration
@@ -220,6 +235,7 @@ jobs:
targetFramework: ${{ parameters.targetFramework }}
referenceType: ${{ parameters.buildType }}
testSet: ${{ parameters.testSet }}
+ extensionsPackageVersion: ${{ parameters.extensionsPackageVersion }}
${{ if ne(parameters.operatingSystem, 'Windows') }}:
OSGroup: Unix
diff --git a/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml b/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
index 3c1671a486..a485fac98f 100644
--- a/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
+++ b/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
@@ -12,8 +12,8 @@ parameters:
type: object
- name: dependsOn
- type: string
- default: ''
+ type: object
+ default: []
- name: buildType
displayName: 'Build Type'
@@ -22,6 +22,11 @@ parameters:
- Project
- Package
+ - name: extensionsPackageVersion
+ displayName: Extensions Package Version Override
+ type: string
+ default: ''
+
- name: prebuildSteps
type: stepList
default: []
@@ -34,10 +39,7 @@ stages:
- ${{ each config in parameters.testConfigurations }}:
- ${{ each image in config.value.images }}:
- stage: ${{ image.key }}
- ${{ if ne(parameters.dependsOn, '') }}:
- dependsOn: ${{ parameters.dependsOn }}
- ${{ else }}:
- dependsOn: []
+ dependsOn: ${{ parameters.dependsOn }}
jobs:
- ${{ each targetFramework in config.value.TargetFrameworks }}:
- ${{ each platform in config.value.buildPlatforms }}:
@@ -52,6 +54,7 @@ stages:
image: ${{ image.value }}
jobDisplayName: ${{ format('{0}_{1}_{2}', replace(targetFramework, '.', '_'), platform, testSet) }}
configProperties: ${{ config.value.configProperties }}
+ extensionsPackageVersion: ${{ parameters.extensionsPackageVersion }}
prebuildSteps: ${{ parameters.prebuildSteps }}
targetFramework: ${{ targetFramework }}
netcoreVersionTestUtils: ${{config.value.netcoreVersionTestUtils }}
@@ -81,6 +84,7 @@ stages:
jobDisplayName: ${{ format('{0}_{1}_{2}_{3}', replace(targetFramework, '.', '_'), platform, 'NativeSNI', testSet) }}
configProperties: ${{ config.value.configProperties }}
useManagedSNI: ${{ useManagedSNI }}
+ extensionsPackageVersion: ${{ parameters.extensionsPackageVersion }}
prebuildSteps: ${{ parameters.prebuildSteps }}
targetFramework: ${{ targetFramework }}
netcoreVersionTestUtils: ${{config.value.netcoreVersionTestUtils }}
diff --git a/eng/pipelines/common/templates/steps/build-all-tests-step.yml b/eng/pipelines/common/templates/steps/build-all-tests-step.yml
index 826be1df8b..41db9585c0 100644
--- a/eng/pipelines/common/templates/steps/build-all-tests-step.yml
+++ b/eng/pipelines/common/templates/steps/build-all-tests-step.yml
@@ -32,6 +32,11 @@ parameters:
- name: testSet
type: string
+ - name: extensionsPackageVersion
+ displayName: Extensions Package Version Override
+ type: string
+ default: ''
+
steps:
- ${{ if contains(parameters.targetFramework, 'net4') }}: # .NET Framework
- task: MSBuild@1
@@ -40,7 +45,7 @@ steps:
solution: build.proj
platform: '${{parameters.platform }}'
configuration: '${{parameters.configuration }}'
- msbuildArguments: '-t:BuildTestsNetFx -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }}'
+ msbuildArguments: '-t:BuildTestsNetFx -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }} -p:ExtensionsPackageVersion=${{ parameters.extensionsPackageVersion }}.$(Build.BuildNumber)'
# - ${{else if contains(parameters.targetFramework, 'netstandard')}}: # .NET Standard
# - task: MSBuild@1
@@ -59,7 +64,7 @@ steps:
solution: build.proj
platform: '${{parameters.platform }}'
configuration: '${{parameters.configuration }}'
- msbuildArguments: '-t:BuildTestsNetCore -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }}'
+ msbuildArguments: '-t:BuildTestsNetCore -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }} -p:ExtensionsPackageVersion=${{ parameters.extensionsPackageVersion }}.$(Build.BuildNumber)'
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
- ${{ else }}: # .NET on Unix
@@ -69,7 +74,7 @@ steps:
command: custom
projects: build.proj
custom: msbuild
- arguments: '-t:BuildTestsNetCore -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }} -p:OSGroup=${{parameters.OSGroup }} -p:platform=${{parameters.platform }} -p:Configuration=${{parameters.configuration }}'
+ arguments: '-t:BuildTestsNetCore -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }} -p:OSGroup=${{parameters.OSGroup }} -p:platform=${{parameters.platform }} -p:Configuration=${{parameters.configuration }} -p:ExtensionsPackageVersion=${{ parameters.extensionsPackageVersion }}.$(Build.BuildNumber)'
verbosityRestore: Detailed
verbosityPack: Detailed
condition: and(succeeded(), ne(variables['Agent.OS'], 'Windows_NT'))
diff --git a/eng/pipelines/common/templates/steps/ci-prebuild-step.yml b/eng/pipelines/common/templates/steps/ci-prebuild-step.yml
index efe17856d8..64529eeb3d 100644
--- a/eng/pipelines/common/templates/steps/ci-prebuild-step.yml
+++ b/eng/pipelines/common/templates/steps/ci-prebuild-step.yml
@@ -19,6 +19,11 @@ parameters:
- Project
- Package
+ - name: extensionsPackageVersion
+ displayName: Extensions Package Version Override
+ type: string
+ default: ''
+
steps:
- template: ensure-dotnet-version.yml
parameters:
@@ -50,8 +55,10 @@ steps:
parameters:
downloadedNugetPath: $(Pipeline.Workspace)\${{parameters.artifactName }}
debug: ${{ parameters.debug }}
+ extensionsPackageVersion: ${{ parameters.extensionsPackageVersion }}
- ${{ else }}: # project
- template: ci-project-build-step.yml@self
parameters:
build: allNoDocs
+ extensionsPackageVersion: ${{parameters.extensionsPackageVersion}}
diff --git a/eng/pipelines/common/templates/steps/ci-project-build-step.yml b/eng/pipelines/common/templates/steps/ci-project-build-step.yml
index e938c909fd..1d7cbaadda 100644
--- a/eng/pipelines/common/templates/steps/ci-project-build-step.yml
+++ b/eng/pipelines/common/templates/steps/ci-project-build-step.yml
@@ -34,6 +34,11 @@ parameters:
- all
- allNoDocs
+ - name: extensionsPackageVersion
+ displayName: Extensions Package Version Override
+ type: string
+ default: ''
+
steps:
- template: ./ensure-dotnet-version.yml@self
parameters:
@@ -53,7 +58,7 @@ steps:
inputs:
solution: build.proj
msbuildArchitecture: x64
- msbuildArguments: '-t:restore'
+ msbuildArguments: '-t:restore -p:ExtensionsPackageVersion=${{parameters.extensionsPackageVersion}}.${{parameters.buildNumber}}'
retryCountOnTaskFailure: 1
- ${{ if eq(parameters.build, 'allNoDocs') }}:
@@ -65,7 +70,7 @@ steps:
msbuildArchitecture: x64
platform: '${{ parameters.platform }}'
configuration: '${{ parameters.configuration }}'
- msbuildArguments: '-t:BuildAllConfigurations -p:GenerateDocumentationFile=false -p:GenerateNuGet=false -p:BuildNumber=${{ parameters.buildNumber }}'
+ msbuildArguments: '-t:BuildAllConfigurations -p:GenerateDocumentationFile=false -p:GenerateNuGet=false -p:BuildNumber=${{ parameters.buildNumber }} -p:ExtensionsPackageVersion=${{parameters.extensionsPackageVersion}}.${{parameters.buildNumber}}'
clean: true
- ${{ if or(eq(parameters.build, 'MDS'), eq(parameters.build, 'all')) }}:
@@ -77,7 +82,7 @@ steps:
msbuildArchitecture: x64
platform: '${{ parameters.platform }}'
configuration: '${{ parameters.configuration }}'
- msbuildArguments: '-t:BuildAllConfigurations -p:GenerateNuGet=false -p:BuildNumber=${{ parameters.buildNumber }}'
+ msbuildArguments: '-t:BuildAllConfigurations -p:GenerateNuGet=false -p:BuildNumber=${{ parameters.buildNumber }} -p:ExtensionsPackageVersion=${{parameters.extensionsPackageVersion}}.${{parameters.buildNumber}}'
clean: true
- ${{ if or(eq(parameters.build, 'AKV'), eq(parameters.build, 'all'), eq(parameters.build, 'allNoDocs')) }}:
@@ -89,7 +94,7 @@ steps:
msbuildArchitecture: x64
platform: '${{ parameters.platform }}'
configuration: '${{ parameters.configuration }}'
- msbuildArguments: '-t:BuildAKVNetFx -p:BuildNumber=${{ parameters.buildNumber }}'
+ msbuildArguments: '-t:BuildAKVNetFx -p:BuildNumber=${{ parameters.buildNumber }} -p:ExtensionsPackageVersion=${{parameters.extensionsPackageVersion}}.${{parameters.buildNumber}}'
- task: MSBuild@1
displayName: 'Build AKV Provider NetCore All OS [Win]'
@@ -99,7 +104,7 @@ steps:
msbuildArchitecture: x64
platform: '${{ parameters.platform }}'
configuration: '${{ parameters.configuration }}'
- msbuildArguments: '-t:BuildAKVNetCoreAllOS -p:BuildNumber=${{ parameters.buildNumber }}'
+ msbuildArguments: '-t:BuildAKVNetCoreAllOS -p:BuildNumber=${{ parameters.buildNumber }} -p:ExtensionsPackageVersion=${{parameters.extensionsPackageVersion}}.${{parameters.buildNumber}}'
- ${{ if or(eq(parameters.operatingSystem, 'Linux'), eq(parameters.operatingSystem, 'MacOS'), eq(parameters.operatingSystem, 'deferedToRuntime')) }}:
- task: DotNetCoreCLI@2
@@ -109,7 +114,7 @@ steps:
command: custom
projects: build.proj
custom: msbuild
- arguments: '-t:BuildAll -p:TestEnabled=true -p:GenerateDocumentationFile=false -p:configuration=${{ parameters.configuration }}'
+ arguments: '-t:BuildAll -p:TestEnabled=true -p:GenerateDocumentationFile=false -p:configuration=${{ parameters.configuration }} -p:ExtensionsPackageVersion=${{parameters.extensionsPackageVersion}}.${{parameters.buildNumber}}'
verbosityRestore: Detailed
verbosityPack: Detailed
retryCountOnTaskFailure: 1
diff --git a/eng/pipelines/common/templates/steps/update-nuget-config-local-feed-step.yml b/eng/pipelines/common/templates/steps/update-nuget-config-local-feed-step.yml
index 4eac341108..96f4ec4647 100644
--- a/eng/pipelines/common/templates/steps/update-nuget-config-local-feed-step.yml
+++ b/eng/pipelines/common/templates/steps/update-nuget-config-local-feed-step.yml
@@ -11,6 +11,11 @@ parameters:
- name: downloadedNugetPath # path to the downloaded nuget files
type: string
+ - name: extensionsPackageVersion
+ displayName: Extensions Package Version Override
+ type: string
+ default: ''
+
- name: nugetPackageVersion
type: string
default: $(NugetPackageVersion)
@@ -34,7 +39,7 @@ steps:
[Xml] $nugetConfig = Get-Content -Path "NuGet.config"
$Value = Resolve-Path ${{parameters.downloadedNugetPath }}
$newAdd = $nugetConfig.CreateElement("add")
- $newAdd.SetAttribute("key","Package source")
+ $newAdd.SetAttribute("key","pipeline")
$newAdd.SetAttribute("value", "$Value/" )
$nugetConfig.configuration.packageSources.AppendChild($newAdd)
$nugetConfig.Save("$rootFolder/NuGet.config")
@@ -51,7 +56,7 @@ steps:
inputs:
command: 'custom'
custom: 'msbuild'
- arguments: 'build.proj -t:restore'
+ arguments: 'build.proj -t:restore -p:ExtensionsPackageVersion=${{parameters.extensionsPackageVersion}}.$(buildNumber)'
feedsToUse: 'select'
- powershell: |
diff --git a/eng/pipelines/dotnet-sqlclient-ci-core.yml b/eng/pipelines/dotnet-sqlclient-ci-core.yml
index 877fc3c0d1..3f23c1ec04 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-core.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-core.yml
@@ -34,6 +34,11 @@ parameters:
type: object
default: [1, 2, 3]
+- name: extensionsPackageVersion
+ displayName: Extensions Package Version Override
+ type: string
+ default: ''
+
- name: useManagedSNI
displayName: |
Use Managed/Native SNI on Windows,
@@ -72,19 +77,38 @@ parameters:
variables:
- template: libraries/ci-build-variables.yml@self
- - name: artifactName
- value: Artifacts
+ - name: extensionsArtifactName
+ value: Extensions.Artifact
+
+ - name: mdsArtifactName
+ value: MDS.Artifact
- name: defaultHostedPoolName
value: 'Azure Pipelines'
stages:
+
+ # Build the Extensions package, and publish it to the pipeline artifacts
+ # under the name specified by the 'extensionsArtifactName' variable.
+ - template: stages/ci-build-extensions-package-stage.yml@self
+ parameters:
+ buildConfiguration: Release
+ packageVersion: ${{parameters.extensionsPackageVersion}}
+ buildNumber: $(buildNumber)
+ artifactName: $(extensionsArtifactName)
+ ${{if eq(parameters.debug, 'true')}}:
+ verbosity: diagnostic
+
+ # Build MDS and its NuGet packages.
- stage: build_nugets
displayName: 'Build NuGet Packages'
+ dependsOn: build_extensions_package_stage
jobs:
- template: common/templates/jobs/ci-build-nugets-job.yml@self
parameters:
- artifactName: $(artifactName)
+ extensionsPackageVersion: ${{parameters.extensionsPackageVersion}}
+ extensionsArtifactName: $(extensionsArtifactName)
+ mdsArtifactName: $(mdsArtifactName)
${{if ne(parameters.SNIVersion, '')}}:
prebuildSteps:
- template: common/templates/steps/override-sni-version.yml@self
@@ -96,8 +120,18 @@ stages:
parameters:
debug: ${{ parameters.debug }}
buildType: ${{ parameters.buildType }}
+ extensionsPackageVersion: ${{parameters.extensionsPackageVersion}}
+
+ # When testing MDS via packages, we must depend on the Extensions _and_
+ # MDS packages.
${{ if eq(parameters.buildType, 'Package') }}:
- dependsOn: build_nugets
+ dependsOn:
+ - build_extensions_package_stage
+ - build_nugets
+ # When testing MDS via projects, we only depend on the Extensions package.
+ ${{ else }}:
+ dependsOn:
+ - build_extensions_package_stage
${{if ne(parameters.SNIVersion, '')}}:
prebuildSteps: # steps to run prior to building and running tests on each job
@@ -108,15 +142,17 @@ stages:
- template: common/templates/steps/ci-prebuild-step.yml@self
parameters:
debug: ${{ parameters.debug }}
- artifactName: $(artifactName)
+ artifactName: $(mdsArtifactName)
buildType: ${{ parameters.buildType }}
+ extensionsPackageVersion: ${{parameters.extensionsPackageVersion}}
${{else}}:
prebuildSteps: # steps to run prior to building and running tests on each job
- template: common/templates/steps/ci-prebuild-step.yml@self
parameters:
debug: ${{ parameters.debug }}
- artifactName: $(artifactName)
+ artifactName: $(mdsArtifactName)
buildType: ${{ parameters.buildType }}
+ extensionsPackageVersion: ${{parameters.extensionsPackageVersion}}
${{ if eq(parameters.buildType, 'Project') }}: # only run the code coverage job if the build type is project
postTestJobs: # jobs to run after the tests are done
@@ -327,9 +363,8 @@ stages:
# ways to detect if they were present) won't run consistently across forks and non-forks.
${{ if eq(variables['system.pullRequest.isFork'], 'False') }}:
AADPasswordConnectionString: $(AAD_PASSWORD_CONN_STR)
- AADServicePrincipalId: $(AADServicePrincipalId)
- ${{ if eq(variables['system.pullRequest.isFork'], 'False') }}:
AADServicePrincipalSecret: $(AADServicePrincipalSecret)
+ AADServicePrincipalId: $(AADServicePrincipalId)
AzureKeyVaultUrl: $(AzureKeyVaultUrl)
AzureKeyVaultTenantId: $(AzureKeyVaultTenantId)
SupportsIntegratedSecurity: false
@@ -356,9 +391,8 @@ stages:
AADAuthorityURL: $(AADAuthorityURL)
${{ if eq(variables['system.pullRequest.isFork'], 'False') }}:
AADPasswordConnectionString: $(AAD_PASSWORD_CONN_STR_eastus)
- AADServicePrincipalId: $(AADServicePrincipalId)
- ${{ if eq(variables['system.pullRequest.isFork'], 'False') }}:
AADServicePrincipalSecret: $(AADServicePrincipalSecret)
+ AADServicePrincipalId: $(AADServicePrincipalId)
AzureKeyVaultUrl: $(AzureKeyVaultUrl)
AzureKeyVaultTenantId: $(AzureKeyVaultTenantId)
SupportsIntegratedSecurity: false
@@ -366,38 +400,6 @@ stages:
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
-# Enclave tests disabled as on 2025-08-05 due to azure capacity issues. Reenable once instances are available again.
-# ${{ if eq(variables['system.pullRequest.isFork'], 'False') }}: # only run enclave jobs if the password is available
-# windows_enclave_sql:
-# pool: ADO-CI-AE-1ES-Pool
-# images:
-# Win22_Enclave_Sql19: ADO-MMS22-SQL19
-# TargetFrameworks: ${{parameters.targetFrameworks }}
-# netcoreVersionTestUtils: ${{parameters.netcoreVersionTestUtils }}
-# buildPlatforms: ${{parameters.buildPlatforms }}
-# testSets: [AE]
-# useManagedSNI: ${{parameters.useManagedSNI }}
-# codeCovTargetFrameworks: ${{parameters.codeCovTargetFrameworks }}
-# configSqlFor: enclave
-# operatingSystem: Windows
-# configProperties:
-# # config.json properties
-# TCPConnectionStringHGSVBS: $(SQL_TCP_CONN_STRING_HGSVBS)
-# TCPConnectionStringNoneVBS: $(SQL_TCP_CONN_STRING_NoneVBS)
-# TCPConnectionStringAASSGX: $(SQL_TCP_CONN_STRING_AASSGX)
-# EnclaveEnabled: true
-# AADAuthorityURL: $(AADAuthorityURL)
-# AADServicePrincipalId: $(AADServicePrincipalId)
-# ${{ if eq(variables['system.pullRequest.isFork'], 'False') }}:
-# AADServicePrincipalSecret: $(AADServicePrincipalSecret)
-# AzureKeyVaultUrl: $(AzureKeyVaultUrl)
-# AzureKeyVaultTenantId: $(AzureKeyVaultTenantId)
-# SupportsIntegratedSecurity: $(SupportsIntegratedSecurity)
-# UserManagedIdentityClientId: $(UserManagedIdentityClientId)
-# AliasName: $(SQLAliasName)
-# LocalDbAppName: $(LocalDbAppName)
-# LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
-
# self hosted SQL Server on Linux
linux_sql_19_22:
pool: ${{parameters.defaultPoolName }}
@@ -443,9 +445,8 @@ stages:
AADAuthorityURL: $(AADAuthorityURL)
${{ if eq(variables['system.pullRequest.isFork'], 'False') }}:
AADPasswordConnectionString: $(AAD_PASSWORD_CONN_STR)
- AADServicePrincipalId: $(AADServicePrincipalId)
- ${{ if eq(variables['system.pullRequest.isFork'], 'False') }}:
AADServicePrincipalSecret: $(AADServicePrincipalSecret)
+ AADServicePrincipalId: $(AADServicePrincipalId)
AzureKeyVaultUrl: $(AzureKeyVaultUrl)
AzureKeyVaultTenantId: $(AzureKeyVaultTenantId)
SupportsIntegratedSecurity: false
@@ -453,36 +454,6 @@ stages:
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
-# Enclave tests disabled as on 2025-08-05 due to azure capacity issues. Reenable once instances are available again.
-# ${{ if eq(variables['system.pullRequest.isFork'], 'False') }}: # only run enclave jobs if the password is available
-# linux_enclave_sql:
-# pool: ADO-CI-AE-1ES-Pool
-# images:
-# Ubuntu20_Enclave_Sql19: ADO-UB20-Sql22
-# TargetFrameworks: ${{parameters.targetFrameworksLinux }}
-# netcoreVersionTestUtils: ${{parameters.netcoreVersionTestUtils }}
-# buildPlatforms: [AnyCPU]
-# testSets: [AE]
-# useManagedSNI: [true]
-# codeCovTargetFrameworks: ${{parameters.codeCovTargetFrameworks }}
-# configSqlFor: enclave
-# operatingSystem: Linux
-# configProperties:
-# # config.json properties
-# TCPConnectionStringHGSVBS: $(SQL_TCP_CONN_STRING_HGSVBS)
-# TCPConnectionStringNoneVBS: $(SQL_TCP_CONN_STRING_NoneVBS)
-# TCPConnectionStringAASSGX: $(SQL_TCP_CONN_STRING_AASSGX)
-# EnclaveEnabled: true
-# AADServicePrincipalId: $(AADServicePrincipalId)
-# ${{ if eq(variables['system.pullRequest.isFork'], 'False') }}:
-# AADServicePrincipalSecret: $(AADServicePrincipalSecret)
-# AzureKeyVaultUrl: $(AzureKeyVaultUrl)
-# AzureKeyVaultTenantId: $(AzureKeyVaultTenantId)
-# SupportsIntegratedSecurity: false
-# UserManagedIdentityClientId: $(UserManagedIdentityClientId)
-# LocalDbAppName: $(LocalDbAppName)
-# LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
-
# Self hosted SQL Server on Mac
mac_sql_22:
pool: $(defaultHostedPoolName)
@@ -505,3 +476,67 @@ stages:
ManagedIdentitySupported: false
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
+
+ # Enclave tests
+ #
+ # Only run enclave jobs if the password is available, which it won't be
+ # for forked PRs.
+ #
+ ${{ if eq(variables['system.pullRequest.isFork'], 'False') }}:
+ windows_enclave_sql:
+ pool: ADO-CI-AE-1ES-Pool
+ images:
+ Win22_Enclave_Sql19: ADO-MMS22-SQL19
+ TargetFrameworks: ${{parameters.targetFrameworks }}
+ netcoreVersionTestUtils: ${{parameters.netcoreVersionTestUtils }}
+ buildPlatforms: ${{parameters.buildPlatforms }}
+ testSets: [AE]
+ useManagedSNI: ${{parameters.useManagedSNI }}
+ codeCovTargetFrameworks: ${{parameters.codeCovTargetFrameworks }}
+ configSqlFor: enclave
+ operatingSystem: Windows
+ configProperties:
+ # config.json properties
+ TCPConnectionStringHGSVBS: $(SQL_TCP_CONN_STRING_HGSVBS)
+ TCPConnectionStringNoneVBS: $(SQL_TCP_CONN_STRING_NoneVBS)
+ TCPConnectionStringAASSGX: $(SQL_TCP_CONN_STRING_AASSGX)
+ EnclaveEnabled: true
+ AADAuthorityURL: $(AADAuthorityURL)
+ AADServicePrincipalId: $(AADServicePrincipalId)
+ ${{ if eq(variables['system.pullRequest.isFork'], 'False') }}:
+ AADServicePrincipalSecret: $(AADServicePrincipalSecret)
+ AzureKeyVaultUrl: $(AzureKeyVaultUrl)
+ AzureKeyVaultTenantId: $(AzureKeyVaultTenantId)
+ SupportsIntegratedSecurity: $(SupportsIntegratedSecurity)
+ UserManagedIdentityClientId: $(UserManagedIdentityClientId)
+ AliasName: $(SQLAliasName)
+ LocalDbAppName: $(LocalDbAppName)
+ LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
+
+ linux_enclave_sql:
+ pool: ADO-CI-AE-1ES-Pool
+ images:
+ Ubuntu20_Enclave_Sql19: ADO-UB20-Sql22
+ TargetFrameworks: ${{parameters.targetFrameworksLinux }}
+ netcoreVersionTestUtils: ${{parameters.netcoreVersionTestUtils }}
+ buildPlatforms: [AnyCPU]
+ testSets: [AE]
+ useManagedSNI: [true]
+ codeCovTargetFrameworks: ${{parameters.codeCovTargetFrameworks }}
+ configSqlFor: enclave
+ operatingSystem: Linux
+ configProperties:
+ # config.json properties
+ TCPConnectionStringHGSVBS: $(SQL_TCP_CONN_STRING_HGSVBS)
+ TCPConnectionStringNoneVBS: $(SQL_TCP_CONN_STRING_NoneVBS)
+ TCPConnectionStringAASSGX: $(SQL_TCP_CONN_STRING_AASSGX)
+ EnclaveEnabled: true
+ AADServicePrincipalId: $(AADServicePrincipalId)
+ ${{ if eq(variables['system.pullRequest.isFork'], 'False') }}:
+ AADServicePrincipalSecret: $(AADServicePrincipalSecret)
+ AzureKeyVaultUrl: $(AzureKeyVaultUrl)
+ AzureKeyVaultTenantId: $(AzureKeyVaultTenantId)
+ SupportsIntegratedSecurity: false
+ UserManagedIdentityClientId: $(UserManagedIdentityClientId)
+ LocalDbAppName: $(LocalDbAppName)
+ LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
diff --git a/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml b/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml
index 4956b15c89..162ee9eb57 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml
@@ -62,6 +62,11 @@ parameters: # parameters are shown up in ADO UI in a build queue time
type: object
default: [1, 2, 3]
+- name: extensionsPackageVersion
+ displayName: Extensions Package Version Override
+ type: string
+ default: 7.0.0
+
- name: useManagedSNI
displayName: |
Use Managed/Native SNI on Windows,
@@ -74,13 +79,6 @@ parameters: # parameters are shown up in ADO UI in a build queue time
type: object
default: [net462, net8.0]
-- name: buildType
- displayName: 'Build Type'
- default: Package
- values:
- - Project
- - Package
-
extends:
template: dotnet-sqlclient-ci-core.yml@self
parameters:
@@ -89,6 +87,7 @@ extends:
targetFrameworksLinux: ${{ parameters.targetFrameworksLinux }}
buildPlatforms: ${{ parameters.buildPlatforms }}
testSets: ${{ parameters.testSets }}
+ extensionsPackageVersion: ${{ parameters.extensionsPackageVersion }}
useManagedSNI: ${{ parameters.useManagedSNI }}
codeCovTargetFrameworks: ${{ parameters.codeCovTargetFrameworks }}
- buildType: ${{ parameters.buildType }}
+ buildType: Package
diff --git a/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml b/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
index ecdaacfafb..e60b41b0d9 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
@@ -54,6 +54,11 @@ parameters: # parameters are shown up in ADO UI in a build queue time
type: object
default: [1, 2, 3]
+- name: extensionsPackageVersion
+ displayName: Extensions Package Version Override
+ type: string
+ default: 7.0.0
+
- name: useManagedSNI
displayName: |
Use Managed/Native SNI on Windows,
@@ -66,13 +71,6 @@ parameters: # parameters are shown up in ADO UI in a build queue time
type: object
default: [net462, net8.0]
-- name: buildType
- displayName: 'Build Type'
- default: Project
- values:
- - Project
- - Package
-
extends:
template: dotnet-sqlclient-ci-core.yml@self
parameters:
@@ -81,6 +79,7 @@ extends:
targetFrameworksLinux: ${{ parameters.targetFrameworksLinux }}
buildPlatforms: ${{ parameters.buildPlatforms }}
testSets: ${{ parameters.testSets }}
+ extensionsPackageVersion: ${{ parameters.extensionsPackageVersion }}
useManagedSNI: ${{ parameters.useManagedSNI }}
codeCovTargetFrameworks: ${{ parameters.codeCovTargetFrameworks }}
- buildType: ${{ parameters.buildType }}
+ buildType: Project
diff --git a/eng/pipelines/stages/ci-build-extensions-package-stage.yml b/eng/pipelines/stages/ci-build-extensions-package-stage.yml
new file mode 100644
index 0000000000..3adcb22b18
--- /dev/null
+++ b/eng/pipelines/stages/ci-build-extensions-package-stage.yml
@@ -0,0 +1,351 @@
+################################################################################
+# 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 stage builds the Extensions package, runs tests, and publishes the
+# resulting NuGet packages as pipeline artifacts.
+#
+# The NuGet packages have the following properties:
+#
+# Name: Microsoft.Data.SqlClient.Extensions
+# Version: .
+#
+# Where and are the values of the
+# 'packageVersion' and 'buildNumber' parameters, respectively.
+#
+# The following NuGet packages are published:
+#
+# Microsoft.Data.SqlClient.Extensions..nupkg
+# Microsoft.Data.SqlClient.Extensions..snupkg (symbols)
+#
+# The packages are published to pipeline artifacts with the name specified by
+# the 'artifactName' parameter.
+#
+# This template defines a stage named 'build_extensions_package_stage' that can
+# be depended on by downstream stages.
+
+parameters:
+ # The type of build to produce (Release or Debug)
+ - name: buildConfiguration
+ displayName: Build Configuration
+ type: string
+ default: Release
+ values:
+ - Release
+ - Debug
+
+ # The version (Major.Minor.Patch) to apply to the package.
+ - name: packageVersion
+ displayName: Package Version Override
+ type: string
+ default: ''
+
+ # The build number of the pipeline.
+ - name: buildNumber
+ displayName: Build Number
+ type: string
+ default: $(Build.BuildNumber)
+
+ # The name of the pipeline artifact to publish.
+ - name: artifactName
+ displayName: Pipeline Artifact Name
+ type: string
+ default: Extensions.Artifact
+
+ # The list of .NET runtimes to test against.
+ - name: netTestRuntimes
+ displayName: .NET Test Runtimes
+ type: object
+ default: [net8.0, net9.0]
+
+ # The list of .NET Framework runtimes to test against.
+ - name: netFrameworkTestRuntimes
+ displayName: .NET Framework Test Runtimes
+ type: object
+ default: [net462, net47, net471, net472, net48, net481]
+
+ # The verbosity level for the dotnet CLI commands.
+ - name: verbosity
+ displayName: Dotnet CLI verbosity
+ type: string
+ default: normal
+ values:
+ - quiet
+ - minimal
+ - normal
+ - detailed
+ - diagnostic
+
+stages:
+ - stage: build_extensions_package_stage
+ displayName: Build Extensions Package
+
+ variables:
+ # The directory where dotnet artifacts will be staged. Not to be
+ # confused with pipeline artifact.
+ - name: dotnetArtifactsDir
+ value: $(Build.StagingDirectory)/dotnetArtifacts
+
+ # The directory where the NuGet packages will be staged before being
+ # published as pipeline artifacts.
+ - name: dotnetPackagesDir
+ value: $(Build.StagingDirectory)/dotnetPackages
+
+ # The Extensions solution file to use for all dotnet CLI commands.
+ - name: project
+ value: src/Microsoft.Data.SqlClient.Extensions/Extensions/Extensions.slnx
+
+ # dotnet CLI arguments common to all commands.
+ - name: commonArguments
+ value: >-
+ --verbosity ${{parameters.verbosity}}
+ --artifacts-path $(dotnetArtifactsDir)
+
+ # dotnet CLI arguments for build/test/pack commands
+ - name: buildArguments
+ value: >-
+ $(commonArguments)
+ --configuration ${{parameters.buildConfiguration}}
+ -p:BuildNumber=$(Build.BuildNumber)
+ -p:ExtensionsPackageVersion=${{parameters.packageVersion}}
+
+ # Explicitly unset the $PLATFORM environment variable that is set by the
+ # 'ADO Build properties' Library in the ADO SqlClientDrivers public
+ # project. This is defined with a non-standard Platform of 'AnyCPU',
+ # and will fail the builds if left defined. The Extensions package does
+ # not require any specific Platform, and so its solution file doesn't
+ # support any non-standard platforms.
+ #
+ # Note that Azure Pipelines will inject this variable as PLATFORM into
+ # the environment of all tasks in this job.
+ #
+ # See:
+ # https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch
+ #
+ - name: Platform
+ value: ''
+
+ # Do the same for $CONFIGURATION since we explicitly set it using our
+ # 'buildConfiguration' parameter, and we don't want the environment to
+ # override us.
+ - name: Configuration
+ value: ''
+
+ jobs:
+
+ # --------------------------------------------------------------------------
+ # Build and test on Linux.
+
+ - job: build_extensions_package_job_linux
+ displayName: '[Linux] Build Extensions Package'
+ pool:
+ name: Azure Pipelines
+ vmImage: ubuntu-latest
+
+ steps:
+
+ - task: UseDotNet@2
+ displayName: Install .NET 9.0 SDK
+ inputs:
+ packageType: sdk
+ version: 9.x
+
+ - task: UseDotNet@2
+ displayName: Install .NET 8.0 Runtime
+ inputs:
+ packageType: runtime
+ version: 8.x
+
+ # We use the 'custom' command because the DotNetCoreCLI@2 task doesn't
+ # support all of our argument combinations for the different build steps.
+ - task: DotNetCoreCLI@2
+ displayName: Restore Solution
+ inputs:
+ command: custom
+ custom: restore
+ projects: $(project)
+ arguments: $(commonArguments)
+
+ - task: DotNetCoreCLI@2
+ displayName: Build Solution
+ inputs:
+ command: custom
+ custom: build
+ projects: $(project)
+ arguments: $(buildArguments) --no-restore
+
+ - ${{ each runtime in parameters.netTestRuntimes }}:
+ - task: DotNetCoreCLI@2
+ displayName: Test [${{runtime}}]
+ inputs:
+ command: custom
+ custom: test
+ projects: $(project)
+ arguments: $(buildArguments) --no-build -f ${{runtime}}
+
+ # --------------------------------------------------------------------------
+ # Build and test on Windows.
+
+ - job: build_extensions_package_job_windows
+ displayName: '[Win] Build Extensions Package'
+ pool:
+ name: Azure Pipelines
+ # The Windows images include a suitable .NET Framework runtime, so we
+ # don't have to install one explicitly below.
+ vmImage: windows-latest
+
+ steps:
+
+ - task: UseDotNet@2
+ displayName: Install .NET 9.0 SDK
+ inputs:
+ packageType: sdk
+ version: 9.x
+
+ - task: UseDotNet@2
+ displayName: Install .NET 8.0 Runtime
+ inputs:
+ packageType: runtime
+ version: 8.x
+
+ - task: DotNetCoreCLI@2
+ displayName: Restore Solution
+ inputs:
+ command: custom
+ custom: restore
+ projects: $(project)
+ arguments: $(commonArguments)
+
+ - task: DotNetCoreCLI@2
+ displayName: Build Solution
+ inputs:
+ command: custom
+ custom: build
+ projects: $(project)
+ arguments: $(buildArguments) --no-restore
+
+ - ${{ each runtime in parameters.netTestRuntimes }}:
+ - task: DotNetCoreCLI@2
+ displayName: Test [${{runtime}}]
+ inputs:
+ command: custom
+ custom: test
+ projects: $(project)
+ arguments: $(buildArguments) --no-build -f ${{runtime}}
+
+ - ${{ each runtime in parameters.netFrameworkTestRuntimes }}:
+ - task: DotNetCoreCLI@2
+ displayName: Test [${{runtime}}]
+ inputs:
+ command: custom
+ custom: test
+ projects: $(project)
+ arguments: $(buildArguments) --no-build -f ${{runtime}}
+
+ # --------------------------------------------------------------------------
+ # Build and test on macOS
+
+ - job: build_extensions_package_job_macos
+ displayName: '[macOS] Build Extensions Package'
+ pool:
+ name: Azure Pipelines
+ vmImage: macos-latest
+
+ steps:
+
+ - task: UseDotNet@2
+ displayName: Install .NET 9.0 SDK
+ inputs:
+ packageType: sdk
+ version: 9.x
+
+ - task: UseDotNet@2
+ displayName: Install .NET 8.0 Runtime
+ inputs:
+ packageType: runtime
+ version: 8.x
+
+ - task: DotNetCoreCLI@2
+ displayName: Restore Solution
+ inputs:
+ command: custom
+ custom: restore
+ projects: $(project)
+ arguments: $(commonArguments)
+
+ - task: DotNetCoreCLI@2
+ displayName: Build Solution
+ inputs:
+ command: custom
+ custom: build
+ projects: $(project)
+ arguments: $(buildArguments) --no-restore
+
+ - ${{ each runtime in parameters.netTestRuntimes }}:
+ - task: DotNetCoreCLI@2
+ displayName: Test [${{runtime}}]
+ inputs:
+ command: custom
+ custom: test
+ projects: $(project)
+ arguments: $(buildArguments) --no-build -f ${{runtime}}
+
+ # --------------------------------------------------------------------------
+ # Create and publish the NuGet package.
+
+ - job: publish_extensions_package_job
+ displayName: Publish Extensions Package
+ dependsOn:
+ # We depend on all of the build jobs to ensure the tests pass before
+ # producing the NuGet package.
+ - build_extensions_package_job_linux
+ - build_extensions_package_job_windows
+ - build_extensions_package_job_macos
+ pool:
+ name: Azure Pipelines
+ vmImage: ubuntu-latest
+
+ steps:
+
+ - task: UseDotNet@2
+ displayName: Install .NET 9.0 SDK
+ inputs:
+ packageType: sdk
+ version: 9.x
+
+ # There is probably a way to avoid this restore and build, and just re-use
+ # the dotnet artifacts from a previous build job. Downloading the dotnet
+ # artifacts didn't work (further investigation TBD), so we just build them
+ # again.
+ - task: DotNetCoreCLI@2
+ displayName: Restore Solution
+ inputs:
+ command: custom
+ custom: restore
+ projects: $(project)
+ arguments: $(commonArguments)
+
+ - task: DotNetCoreCLI@2
+ displayName: Build Solution
+ inputs:
+ command: custom
+ custom: build
+ projects: $(project)
+ arguments: $(buildArguments) --no-restore
+
+ - task: DotNetCoreCLI@2
+ displayName: Create NuGet Package
+ inputs:
+ command: custom
+ custom: pack
+ projects: $(project)
+ arguments: $(buildArguments) --no-build -o $(dotnetPackagesDir)
+
+ - task: PublishPipelineArtifact@1
+ displayName: Publish Pipeline Artifact
+ inputs:
+ targetPath: $(dotnetPackagesDir)
+ artifactName: ${{parameters.artifactName}}
+ publishLocation: pipeline
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 73570b80df..14a4c1fa8c 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -20,6 +20,21 @@
> msbuild -p:configuration=Release
-->
Project
+
+
+ $(AllowedOutputExtensionsInPackageBuildOutputFolder)
+
$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index f897e55f77..71cf2a90f6 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -15,6 +15,7 @@
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Extensions/Extensions.slnx b/src/Microsoft.Data.SqlClient.Extensions/Extensions/Extensions.slnx
new file mode 100644
index 0000000000..bb6f9f35db
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Extensions/Extensions.slnx
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Extensions/doc/Sample.xml b/src/Microsoft.Data.SqlClient.Extensions/Extensions/doc/Sample.xml
new file mode 100644
index 0000000000..8d5f5c44d5
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Extensions/doc/Sample.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+ Sample class to demonstrate packaging and pipelines.
+
+
+
+ Construct with a name.
+ The name.
+
+
+ Gets the name.
+ The name.
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Extensions/github-discussion.md b/src/Microsoft.Data.SqlClient.Extensions/Extensions/github-discussion.md
new file mode 100644
index 0000000000..2fb9af5212
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Extensions/github-discussion.md
@@ -0,0 +1,261 @@
+Decoupling Azure Dependencies
+
+# Overview
+
+For the MDS 7.0.0 release, we are proposing the following package architecture
+changes that will decouple several large dependencies from MDS and move them
+into a new Azure extensions package:
+
+- Create a new Extensions base package that all other MDS packages depend on.
+ - This will contain types and definitions common to the other MDS packages,
+ such as base classes, enums, delegates, etc.
+- Create a new Azure package that will own the following implementations:
+ - Azure Authentication
+ - Azure Attestation
+ - Azure Key Vault interactions
+- Move the above implementations out of MDS and into the new Azure package.
+- Move the existing Azure Key Vault Provider implementation into the new Azure
+ extensions package.
+
+This will reduce the main MDS package dependency tree along with a moderate
+package size reduction.
+
+# Motivation
+
+Issue: #1108
+
+Customers and the developer community have voiced concerns with MDS being
+tightly coupled to Azure dependencies. Many customers do not use Azure and do
+not want to deploy unnecessary DLLs with their applications.
+
+Moving the Azure dependent implementations into a separate Azure extensions
+package achieves two goals:
+
+- Remove Azure packages as direct dependencies of MDS and reduce the MDS
+ dependency tree.
+- Clearly expose existing MDS extension points, prove their functionality, and
+ demonstrate how to use them.
+
+# Package Architecture
+
+```mermaid
+classDiagram
+class MDS
+class MDS.Extensions
+class MDS.Extensions.Azure
+class AKV Provider
+
+MDS --> MDS.Extensions
+MDS ..> MDS.Extensions.Azure
+MDS ..> AKV Provider
+MDS.Extensions.Azure --> MDS.Extensions
+AKV Provider --> MDS.Extensions.Azure
+
+MDS: Depend on MDS.Extensions
+MDS: Load Azure or AKV assembly
+MDS.Extensions: Azure Authentication Types
+MDS.Extensions: Azure Attestation Types
+MDS.Extensions: Azure Key Vault Types
+MDS.Extensions.Azure: Depend on MDS.Extensions
+MDS.Extensions.Azure: Authentication Implementation
+MDS.Extensions.Azure: Attestation Implementation
+MDS.Extensions.Azure: Key Vault Implementation
+AKV Provider: Depend on MDS.Extensions.Azure
+```
+
+In previous MDS versions, the AKV Provider package depended directly on the main
+MDS package through a ranged version (for example [6.0.0, 7.0.0) - all 6.x
+versions). With the new package architecture this is no longer the case.
+Extension packages will not depend on the main MDS package, nor will the main
+MDS package depend on any Extension packages. All dependencies between MDS and
+its extensions will occur through the Extensions base package.
+
+This new looser coupling gives applications the flexibility to depend on only
+the main MDS package, or on MDS and a subset of it extension packages if
+desired.
+
+# Consuming
+
+There are several ways that applications may consume MDS and its extensions:
+
+- MDS with without Azure features
+- MDS with MDS-supplied Azure features
+- MDS with externally supplied Azure features
+
+Applications never need to directly depend on the Extensions base package. This
+will be transitively depended on by other MDS packages.
+
+## Without Azure Features
+
+Applications that do not use any Azure features will no longer bring in those
+unwanted dependencies transitively. Simply include the main MDS package by
+itself:
+
+```xml
+
+
+
+```
+
+## With MDS Azure Features
+
+Applications that wish to use MDS-supplied Azure features will need to include
+the new Azure extensions package as a direct dependency alongside the main MDS
+package:
+
+```xml
+
+
+
+
+```
+
+## With External Azure Features
+
+Applications that wish to use Azure features supplied by another (non-MDS)
+package will need to include that package as a direct dependency alongside the
+main MDS package:
+
+```xml
+
+
+
+
+```
+
+Additionally, the applications will need to instruct MDS to use the external
+Azure feature implementations via the appropriate APIs at runtime:
+
+- Authentication: [SqlAuthenticationProvider](https://learn.microsoft.com/en-us/dotnet/api/microsoft.data.sqlclient.sqlauthenticationprovider?view=sqlclient-dotnet-core-6.0)
+- Attestation: TBD
+- Key Valut: [SqlColumnEncryptionKeyStoreProvider](https://learn.microsoft.com/en-us/dotnet/api/microsoft.data.sqlclient.sqlcolumnencryptionkeystoreprovider?view=sqlclient-dotnet-core-6.0)
+
+# Versioning Strategy
+
+The MDS suite of packages will be versioned together, similar to how .NET system
+packages are versioned with the major .NET version. The initial release of
+these packages will have the following versions:
+
+|Package|Version|
+|-|-|
+|Microsoft.Data.SqlClient.Extensions|7.0.0|
+|Microsoft.Data.SqlClient.|7.0.0|
+|Microsoft.Data.SqlClient.Extensions.Azure|7.0.0|
+|Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider|7.0.0|
+
+Going forward, the suite will be released with matching version numbers as
+changes are made. For example, if the next release is v7.1.0, the packages
+will be versioned as follows and released together:
+
+|Package|Version|
+|-|-|
+|Microsoft.Data.SqlClient.Extensions|7.1.0|
+|Microsoft.Data.SqlClient.|7.1.0|
+|Microsoft.Data.SqlClient.Extensions.Azure|7.1.0|
+
+**Note**: The AzureKeyVaultProvider package will remain at 7.0.0. It will be
+deprecated and eventually removed, as it has been replaced by the Azure
+extensions package.
+
+To ensure compatibility between the main MDS package and its extensions, all
+packages will maintain a strict dependency on their matching Extensions base
+package version. Once an application depends on a specific MDS package version,
+and it chooses to use an extension package, it will be forced to also to depend
+on the matching version of that extension package.
+
+For example, the following scenario would fail during NuGet restore because
+the Azure extension package depends on a different version of the Extensions
+base package than the main MDS package:
+
+|Package|Version|Extensions Base Version|
+|-|-|-|
+|Microsoft.Data.SqlClient.|7.1.0|7.1.0|
+|Microsoft.Data.SqlClient.Extensions.Azure|7.0.0|7.0.0|
+
+# Backwards Compatibility
+
+There are several backwards compatibility scenarios to consider for applications
+that rely on MDS Azure features currently living in the main MDS package and the
+Azure Key Vault Provider package. The new extensions package architecture aims
+to reduce the friction for these apps, but not all scenarios will be seamless.
+
+All of the scenarios below assume that the application is upgrading to the MDS
+7.0.0 suite of packages.
+
+## App using MDS Azure Authentication
+
+Applications currently using the MDS-supplied Azure Authentication features will
+need to add a dependency to the Azure extension package to their project
+alongside the main MDS package:
+
+```xml
+
+
+
+
+```
+
+All Azure Authentication namespaces and types will remain the same, so this
+should be the only change necessary for applications.
+
+## App using MDS Azure Attestation
+
+TBD
+
+## App using AKV Provider
+
+Applications currently using the MDS-supplied AKV Provider will have three
+options when upgrading to the v7.0.0 suite of packages. All options rely on the
+main MDS package finding and loading an appropriate DLL (assembly) at runtime.
+The absence of an appropriate DLL will cause Azure Key Vault operations to throw
+an exception.
+
+### Use Azure Extension
+
+This is the preferred approach. The application would be updated to depend
+on the main MDS package and the Azure extensions package:
+
+```xml
+
+
+
+
+```
+
+The Azure extensions package will contain the same namespaces and types as the
+current AKV Provider and will be a drop-in replacement. The main MDS v7.0.0
+package will look for the Azure extensions assembly and automatically load it.
+
+### Use AKV Provider v7.0.0
+
+This is a temporary solution and will removed in a future release. The
+applictaion would remain dependent on the AKV Provider, but must update to
+the v7.0.0 package to match the main MDS version:
+
+```xml
+
+
+
+
+```
+
+This v7.0.0 AKV Provider package will be empty and simply depend on the Azure
+extensions package to provide the Azure Key Vault features. This transitional
+package will be deprecated and eventually removed.
+
+### Use AKV Provider pre-v7.0.0
+
+This is not a recommended approach and will not be supported, although it will
+may work in the near term. While MDS will retain its ability to find and load
+the AKV Provider DLL (see the approach above), there is no guarantee that an
+older DLL will provide the functionality expected by the main MDS package.
+
+```xml
+
+
+
+
+```
+
+Note that the above example would fail to NuGet restore if the AKV Provider
+package didn't advertise that it depends on at least MDS v7.0.0.
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Extensions/src/Extensions.csproj b/src/Microsoft.Data.SqlClient.Extensions/Extensions/src/Extensions.csproj
new file mode 100644
index 0000000000..057d559d5a
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Extensions/src/Extensions.csproj
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+ $(ExtensionsPackageVersion)
+
+ $(PackageVersion).$(BuildNumber)
+
+
+
+
+ netstandard2.0;net462;net8.0;net9.0
+
+
+
+
+ enable
+ enable
+
+
+
+
+ Microsoft.Data.SqlClient.Extensions
+
+ $(ExtensionsPackageAssemblyVersion)
+ $(PackageVersion)
+ $(AssemblyFileVersion)
+
+ Microsoft.Data.SqlClient.Extensions
+
+
+
+
+ <_Parameter1>true
+
+
+
+
+
+
+
+
+
+
+
+
+ $(PackagesDir)
+ true
+ snupkg
+
+
+ $(OriginalAllowedOutputExtensions)
+
+ Microsoft Corporation
+ Microsoft Corporation
+ Microsoft.Data.SqlClient Extensions
+ https://github.com/dotnet/SqlClient
+ MIT
+ dotnet.png
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Extensions/src/Sample.cs b/src/Microsoft.Data.SqlClient.Extensions/Extensions/src/Sample.cs
new file mode 100644
index 0000000000..b779582d9f
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Extensions/src/Sample.cs
@@ -0,0 +1,20 @@
+namespace Microsoft.Data.SqlClient.Extensions;
+
+///
+public class Sample
+{
+ ///
+ public Sample(string name)
+ {
+ Name = name;
+ }
+
+ ///
+ public string Name { get; private set; }
+
+ // Update the name.
+ internal void SetName(string name)
+ {
+ Name = name;
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Extensions/test/Extensions.Test.csproj b/src/Microsoft.Data.SqlClient.Extensions/Extensions/test/Extensions.Test.csproj
new file mode 100644
index 0000000000..50644b27fa
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Extensions/test/Extensions.Test.csproj
@@ -0,0 +1,26 @@
+
+
+
+ net462;net47;net471;net472;net48;net481;net8.0;net9.0
+ enable
+ enable
+ false
+ true
+ Microsoft.Data.SqlClient.Extensions.Test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Extensions/test/SampleTest.cs b/src/Microsoft.Data.SqlClient.Extensions/Extensions/test/SampleTest.cs
new file mode 100644
index 0000000000..271bebb4aa
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Extensions/test/SampleTest.cs
@@ -0,0 +1,19 @@
+namespace Microsoft.Data.SqlClient.Extensions.Test;
+
+public class SampleTest
+{
+ [Fact]
+ public void Construction()
+ {
+ Assert.Equal("test", new Sample("test").Name);
+ }
+
+ [Fact]
+ public void SetName()
+ {
+ var sample = new Sample("test");
+ Assert.Equal("test", sample.Name);
+ sample.SetName("new name");
+ Assert.Equal("new name", sample.Name);
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient.sln b/src/Microsoft.Data.SqlClient.sln
index e4d29d999c..3947c0e5a6 100644
--- a/src/Microsoft.Data.SqlClient.sln
+++ b/src/Microsoft.Data.SqlClient.sln
@@ -1,6 +1,7 @@
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
-VisualStudioVersion = 17.0.31912.275
+VisualStudioVersion = 17.14.36203.30 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient", "Microsoft.Data.SqlClient\netfx\src\Microsoft.Data.SqlClient.csproj", "{407890AC-9876-4FEF-A6F1-F36A876BAADE}"
EndProject
@@ -571,6 +572,30 @@ Global
{67128EC0-30F5-6A98-448B-55F88A1DE707}.Release|x64.Build.0 = Release|x64
{67128EC0-30F5-6A98-448B-55F88A1DE707}.Release|x86.ActiveCfg = Release|x86
{67128EC0-30F5-6A98-448B-55F88A1DE707}.Release|x86.Build.0 = Release|x86
+ {AB71787B-C474-24D1-5EDF-345386CA2460}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AB71787B-C474-24D1-5EDF-345386CA2460}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AB71787B-C474-24D1-5EDF-345386CA2460}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AB71787B-C474-24D1-5EDF-345386CA2460}.Debug|x64.Build.0 = Debug|Any CPU
+ {AB71787B-C474-24D1-5EDF-345386CA2460}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AB71787B-C474-24D1-5EDF-345386CA2460}.Debug|x86.Build.0 = Debug|Any CPU
+ {AB71787B-C474-24D1-5EDF-345386CA2460}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AB71787B-C474-24D1-5EDF-345386CA2460}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AB71787B-C474-24D1-5EDF-345386CA2460}.Release|x64.ActiveCfg = Release|Any CPU
+ {AB71787B-C474-24D1-5EDF-345386CA2460}.Release|x64.Build.0 = Release|Any CPU
+ {AB71787B-C474-24D1-5EDF-345386CA2460}.Release|x86.ActiveCfg = Release|Any CPU
+ {AB71787B-C474-24D1-5EDF-345386CA2460}.Release|x86.Build.0 = Release|Any CPU
+ {3028DECE-90B8-2F58-6167-98722A3964D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3028DECE-90B8-2F58-6167-98722A3964D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3028DECE-90B8-2F58-6167-98722A3964D4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3028DECE-90B8-2F58-6167-98722A3964D4}.Debug|x64.Build.0 = Debug|Any CPU
+ {3028DECE-90B8-2F58-6167-98722A3964D4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3028DECE-90B8-2F58-6167-98722A3964D4}.Debug|x86.Build.0 = Debug|Any CPU
+ {3028DECE-90B8-2F58-6167-98722A3964D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3028DECE-90B8-2F58-6167-98722A3964D4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3028DECE-90B8-2F58-6167-98722A3964D4}.Release|x64.ActiveCfg = Release|Any CPU
+ {3028DECE-90B8-2F58-6167-98722A3964D4}.Release|x64.Build.0 = Release|Any CPU
+ {3028DECE-90B8-2F58-6167-98722A3964D4}.Release|x86.ActiveCfg = Release|Any CPU
+ {3028DECE-90B8-2F58-6167-98722A3964D4}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -621,6 +646,12 @@ Global
{AD738BD4-6A02-4B88-8F93-FBBBA49A74C8} = {4CAE9195-4F1A-4D48-854C-1C9FBC512C66}
{4461063D-2F2B-274C-7E6F-F235119D258E} = {0CC4817A-12F3-4357-912C-09315FAAD008}
{67128EC0-30F5-6A98-448B-55F88A1DE707} = {0CC4817A-12F3-4357-912C-09315FAAD008}
+ {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {4F3CD363-B1E6-4D6D-9466-97D78A56BE45}
+ {5612FCAA-05D3-4E79-94E5-EEDB2DC70524} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
+ {827E0CD3-B72D-47B6-A68D-7590B98EB39B} = {5612FCAA-05D3-4E79-94E5-EEDB2DC70524}
+ {AB71787B-C474-24D1-5EDF-345386CA2460} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
+ {0C88DD14-F956-CE84-757C-A364CCF449FC} = {5612FCAA-05D3-4E79-94E5-EEDB2DC70524}
+ {3028DECE-90B8-2F58-6167-98722A3964D4} = {0C88DD14-F956-CE84-757C-A364CCF449FC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {01D48116-37A2-4D33-B9EC-94793C702431}
diff --git a/src/Microsoft.Data.SqlClient/NuGet.config b/src/Microsoft.Data.SqlClient/NuGet.config
new file mode 100644
index 0000000000..f5809f8897
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/NuGet.config
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj
index 60eff24c1c..738caa3c5a 100644
--- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj
@@ -34,6 +34,7 @@
+
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
index f52e488239..d36e1982e3 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
@@ -1043,6 +1043,7 @@
+
diff --git a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj
index 6b507b5a0a..72114e5908 100644
--- a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj
@@ -34,6 +34,7 @@
+
All
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
index 0c2fe65f93..8fb18d42c2 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
@@ -953,6 +953,7 @@
+
All
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/tools/props/Versions.props b/tools/props/Versions.props
index 67e8010809..d6478f99e6 100644
--- a/tools/props/Versions.props
+++ b/tools/props/Versions.props
@@ -1,29 +1,61 @@
-
+
+
+
- 6.1.0
0
+
+
+
+
+
+
+ 7
- $(MdsVersionDefault).$(BuildNumber)
+ $(ExtensionsPackageMajorVersion).0.0
+
+ $(ExtensionsPackageMajorVersion).0.0.0
+
+
+
+
+ 6.1.0
+
+
+ $(MdsVersionDefault).$(BuildNumber)-dev
+
+
+ $(MdsVersionDefault).$(BuildNumber)
+
6.0.0.0
$(AssemblyFileVersion)
- $(MdsVersionDefault)-dev
$(NugetPackageVersion)
+
+
@@ -33,6 +65,8 @@
1.0.0-dev
$(SqlServerPackageVersion)
+
+
$(NugetPackageVersion)
diff --git a/tools/specs/Microsoft.Data.SqlClient.nuspec b/tools/specs/Microsoft.Data.SqlClient.nuspec
index 0f029b4c19..490ac0e6b9 100644
--- a/tools/specs/Microsoft.Data.SqlClient.nuspec
+++ b/tools/specs/Microsoft.Data.SqlClient.nuspec
@@ -31,6 +31,7 @@
+
@@ -44,6 +45,7 @@
+
@@ -56,6 +58,7 @@
+
@@ -68,6 +71,7 @@
+