From f6bbbafefdbaa748240efed95433dc286c4f93c9 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 01/30] User Story 37654: Create Abstractions 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.
- Renamed Extensions package to Abstractions.
- Updated README related to extensions design.
---
.editorconfig | 2 +-
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 | 172 +++++----
...qlclient-ci-package-reference-pipeline.yml | 15 +-
...qlclient-ci-project-reference-pipeline.yml | 15 +-
.../build-abstractions-package-ci-stage.yml | 351 ++++++++++++++++++
src/Directory.Build.props | 15 +
src/Directory.Packages.props | 1 +
.../Abstractions/Abstractions.slnx | 8 +
.../Abstractions/README.md | 285 ++++++++++++++
.../Abstractions/doc/Sample.xml | 18 +
.../Abstractions/src/Abstractions.csproj | 95 +++++
.../Abstractions/src/Sample.cs | 20 +
.../test/Abstractions.Test.csproj | 26 ++
.../Abstractions/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 | 59 ++-
tools/specs/Microsoft.Data.SqlClient.nuspec | 4 +
32 files changed, 1228 insertions(+), 173 deletions(-)
create mode 100644 eng/pipelines/stages/build-abstractions-package-ci-stage.yml
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/README.md
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/doc/Sample.xml
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Sample.cs
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/SampleTest.cs
create mode 100644 src/Microsoft.Data.SqlClient/NuGet.config
diff --git a/.editorconfig b/.editorconfig
index ff6d9f3bd7..14f37d4e02 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -163,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..62dc090372 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.|
+|`BuildAbstractionsPackage`|Restore, build, and pack the Abstractions 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:BuildAbstractionsPackage
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:BuildAbstractionsPackage -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:BuildAbstractionsPackage
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:BuildAbstractionsPackage
+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:BuildAbstractionsPackage -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..0cf4efd4de 100644
--- a/build.proj
+++ b/build.proj
@@ -51,6 +51,7 @@
+
@@ -91,6 +92,32 @@
+
+
+
+
+ AbstractionsPackageVersion=$(AbstractionsPackageVersion)
+
+
+
+
+
@@ -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..bd165dac31 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: abstractionsArtifactName
type: string
- default: Artifacts
+ default: Abstractions.Artifact
+
+ - name: mdsArtifactName
+ type: string
+ default: MDS.Artifact
- name: platform
type: string
@@ -28,6 +32,11 @@ parameters:
type: stepList
default: []
+ - name: abstractionsPackageVersion
+ displayName: Abstractions 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 Abstractions 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 Abstractions Package Artifact
+ inputs:
+ artifactName: ${{ parameters.abstractionsArtifactName }}
+ targetPath: $(Build.SourcesDirectory)/packages
+
- template: ../steps/ci-project-build-step.yml@self
parameters:
platform: ${{ parameters.platform }}
configuration: ${{ parameters.configuration }}
operatingSystem: Windows
build: all
+ abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
- 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 dbf5b10028..20cf0cd33d 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: abstractionsPackageVersion
+ displayName: Abstractions Package Version Override
+ type: string
+ default: ''
+
- name: prebuildSteps
type: stepList
default: []
- - name: artifactName
+ - name: abstractionsArtifactName
type: string
- default: Artifacts
+ default: Abstractions.Artifact
- name: targetFramework
type: string
@@ -98,6 +103,16 @@ jobs:
value: '$(dotnetx86Path)'
steps:
+
+ # Download the Abstractions 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 Abstractions Package Artifact
+ inputs:
+ artifactName: ${{ parameters.abstractionsArtifactName }}
+ targetPath: $(Build.SourcesDirectory)/packages
+
- ${{ if ne(parameters.prebuildSteps, '') }}:
- ${{ parameters.prebuildSteps }} # extra steps to run before the build like downloading sni and the required configuration
@@ -229,6 +244,7 @@ jobs:
targetFramework: ${{ parameters.targetFramework }}
referenceType: ${{ parameters.buildType }}
testSet: ${{ parameters.testSet }}
+ abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
${{ 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 e07685407f..da73ca4eb2 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: abstractionsPackageVersion
+ displayName: Abstractions Package Version Override
+ type: string
+ default: ''
+
- name: prebuildSteps
type: stepList
default: []
@@ -39,10 +44,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 }}:
@@ -58,6 +60,7 @@ stages:
image: ${{ image.value }}
jobDisplayName: ${{ format('{0}_{1}_{2}', replace(targetFramework, '.', '_'), platform, testSet) }}
configProperties: ${{ config.value.configProperties }}
+ abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
prebuildSteps: ${{ parameters.prebuildSteps }}
targetFramework: ${{ targetFramework }}
netcoreVersionTestUtils: ${{config.value.netcoreVersionTestUtils }}
@@ -88,6 +91,7 @@ stages:
jobDisplayName: ${{ format('{0}_{1}_{2}_{3}', replace(targetFramework, '.', '_'), platform, 'NativeSNI', testSet) }}
configProperties: ${{ config.value.configProperties }}
useManagedSNI: ${{ useManagedSNI }}
+ abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
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..a953d832d5 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: abstractionsPackageVersion
+ displayName: Abstractions 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:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}.$(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:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}.$(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:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}.$(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..48cab965ea 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: abstractionsPackageVersion
+ displayName: Abstractions 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 }}
+ abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
- ${{ else }}: # project
- template: ci-project-build-step.yml@self
parameters:
build: allNoDocs
+ abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
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..1edcdb1b51 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: abstractionsPackageVersion
+ displayName: Abstractions 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:AbstractionsPackageVersion=${{parameters.abstractionsPackageVersion}}.${{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:AbstractionsPackageVersion=${{parameters.abstractionsPackageVersion}}.${{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:AbstractionsPackageVersion=${{parameters.abstractionsPackageVersion}}.${{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:AbstractionsPackageVersion=${{parameters.abstractionsPackageVersion}}.${{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:AbstractionsPackageVersion=${{parameters.abstractionsPackageVersion}}.${{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:AbstractionsPackageVersion=${{parameters.abstractionsPackageVersion}}.${{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..6753a14b48 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: abstractionsPackageVersion
+ displayName: Abstractions 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:AbstractionsPackageVersion=${{parameters.abstractionsPackageVersion}}.$(buildNumber)'
feedsToUse: 'select'
- powershell: |
diff --git a/eng/pipelines/dotnet-sqlclient-ci-core.yml b/eng/pipelines/dotnet-sqlclient-ci-core.yml
index 353122828b..7415169212 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: abstractionsPackageVersion
+ displayName: Abstractions Package Version Override
+ type: string
+ default: ''
+
- name: useManagedSNI
displayName: |
Use Managed/Native SNI on Windows,
@@ -89,20 +94,39 @@ parameters:
variables:
- template: libraries/ci-build-variables.yml@self
- - name: artifactName
- value: Artifacts
+ - name: abstractionsArtifactName
+ value: Abstractions.Artifact
+
+ - name: mdsArtifactName
+ value: MDS.Artifact
- name: defaultHostedPoolName
value: 'Azure Pipelines'
stages:
+
+ # Build the Abstractions package, and publish it to the pipeline artifacts
+ # under the name specified by the 'abstractionsArtifactName' variable.
+ - template: stages/build-abstractions-package-ci-stage.yml@self
+ parameters:
+ buildConfiguration: Release
+ packageVersion: ${{parameters.abstractionsPackageVersion}}
+ buildNumber: $(buildNumber)
+ artifactName: $(abstractionsArtifactName)
+ ${{if eq(parameters.debug, 'true')}}:
+ verbosity: diagnostic
+
+ # Build MDS and its NuGet packages.
- stage: build_nugets
displayName: 'Build NuGet Packages'
+ dependsOn: build_abstractions_package_stage
jobs:
- template: common/templates/jobs/ci-build-nugets-job.yml@self
parameters:
configuration: ${{ parameters.buildConfiguration }}
- artifactName: $(artifactName)
+ abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
+ abstractionsArtifactName: $(abstractionsArtifactName)
+ mdsArtifactName: $(mdsArtifactName)
${{if ne(parameters.SNIVersion, '')}}:
prebuildSteps:
- template: common/templates/steps/override-sni-version.yml@self
@@ -125,8 +149,19 @@ stages:
debug: ${{ parameters.debug }}
buildType: ${{ parameters.buildType }}
testsTimeout: ${{ parameters.testsTimeout }}
+ abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
+
+ # When testing MDS via packages, we must depend on the Abstractions _and_
+ # MDS packages.
${{ if eq(parameters.buildType, 'Package') }}:
- dependsOn: build_nugets
+ dependsOn:
+ - build_abstractions_package_stage
+ - build_nugets
+ # When testing MDS via projects, we only depend on the Abstrations
+ # package.
+ ${{ else }}:
+ dependsOn:
+ - build_abstractions_package_stage
${{if ne(parameters.SNIVersion, '')}}:
prebuildSteps: # steps to run prior to building and running tests on each job
@@ -137,15 +172,17 @@ stages:
- template: common/templates/steps/ci-prebuild-step.yml@self
parameters:
debug: ${{ parameters.debug }}
- artifactName: $(artifactName)
+ artifactName: $(mdsArtifactName)
buildType: ${{ parameters.buildType }}
+ abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
${{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 }}
+ abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
${{ 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
@@ -354,9 +391,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
@@ -383,9 +419,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
@@ -393,37 +428,6 @@ stages:
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
- ${{ 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 }}
@@ -469,9 +473,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
@@ -479,7 +482,65 @@ stages:
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
- ${{ if eq(variables['system.pullRequest.isFork'], 'False') }}: # only run enclave jobs if the password is available
+ # Self hosted SQL Server on Mac
+ mac_sql_22:
+ pool: $(defaultHostedPoolName)
+ hostedPool: true
+ images:
+ MacOSLatest_Sql22: macos-latest
+ TargetFrameworks: ${{parameters.targetFrameworksLinux }}
+ netcoreVersionTestUtils: ${{parameters.netcoreVersionTestUtils }}
+ buildPlatforms: [AnyCPU]
+ testSets: ${{parameters.testSets }}
+ useManagedSNI: [true]
+ codeCovTargetFrameworks: ${{parameters.codeCovTargetFrameworks }}
+ configSqlFor: local
+ operatingSystem: Mac
+ configProperties:
+ # config.json properties
+ TCPConnectionString: $(SQL_TCP_CONN_STRING)
+ NPConnectionString: $(SQL_NP_CONN_STRING)
+ SupportsIntegratedSecurity: false
+ 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:
@@ -507,26 +568,3 @@ stages:
UserManagedIdentityClientId: $(UserManagedIdentityClientId)
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
-
- # Self hosted SQL Server on Mac
- mac_sql_22:
- pool: $(defaultHostedPoolName)
- hostedPool: true
- images:
- MacOSLatest_Sql22: macos-latest
- TargetFrameworks: ${{parameters.targetFrameworksLinux }}
- netcoreVersionTestUtils: ${{parameters.netcoreVersionTestUtils }}
- buildPlatforms: [AnyCPU]
- testSets: ${{parameters.testSets }}
- useManagedSNI: [true]
- codeCovTargetFrameworks: ${{parameters.codeCovTargetFrameworks }}
- configSqlFor: local
- operatingSystem: Mac
- configProperties:
- # config.json properties
- TCPConnectionString: $(SQL_TCP_CONN_STRING)
- NPConnectionString: $(SQL_NP_CONN_STRING)
- SupportsIntegratedSecurity: false
- ManagedIdentitySupported: false
- 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 336bd97ab5..e6da796d05 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: abstractionsPackageVersion
+ displayName: Abstractions Package Version Override
+ type: string
+ default: 1.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
-
- name: buildConfiguration
displayName: 'Build Configuration'
default: Release
@@ -107,9 +105,10 @@ extends:
targetFrameworksLinux: ${{ parameters.targetFrameworksLinux }}
buildPlatforms: ${{ parameters.buildPlatforms }}
testSets: ${{ parameters.testSets }}
+ abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
useManagedSNI: ${{ parameters.useManagedSNI }}
codeCovTargetFrameworks: ${{ parameters.codeCovTargetFrameworks }}
- buildType: ${{ parameters.buildType }}
+ buildType: Package
buildConfiguration: ${{ parameters.buildConfiguration }}
enableStressTests: ${{ parameters.enableStressTests }}
testsTimeout: ${{ parameters.testsTimeout }}
diff --git a/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml b/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
index 38325d38ca..ba17cf1fa5 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: abstractionsPackageVersion
+ displayName: Abstractions Package Version Override
+ type: string
+ default: 1.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
-
- name: buildConfiguration
displayName: 'Build Configuration'
default: Release
@@ -99,9 +97,10 @@ extends:
targetFrameworksLinux: ${{ parameters.targetFrameworksLinux }}
buildPlatforms: ${{ parameters.buildPlatforms }}
testSets: ${{ parameters.testSets }}
+ abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
useManagedSNI: ${{ parameters.useManagedSNI }}
codeCovTargetFrameworks: ${{ parameters.codeCovTargetFrameworks }}
- buildType: ${{ parameters.buildType }}
+ buildType: Project
buildConfiguration: ${{ parameters.buildConfiguration }}
enableStressTests: ${{ parameters.enableStressTests }}
testsTimeout: ${{ parameters.testsTimeout }}
diff --git a/eng/pipelines/stages/build-abstractions-package-ci-stage.yml b/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
new file mode 100644
index 0000000000..4a8b0087df
--- /dev/null
+++ b/eng/pipelines/stages/build-abstractions-package-ci-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 Abstractions package, runs tests, and publishes the
+# resulting NuGet packages as pipeline artifacts.
+#
+# The NuGet packages have the following properties:
+#
+# Name: Microsoft.Data.SqlClient.Extensions.Abstractions Version:
+# .
+#
+# Where and are the values of the
+# 'packageVersion' and 'buildNumber' parameters, respectively.
+#
+# The following NuGet packages are published:
+#
+# Microsoft.Data.SqlClient.Extensions.Abstractions..nupkg
+# Microsoft.Data.SqlClient.Extensions.Abstractions..snupkg (symbols)
+#
+# The packages are published to pipeline artifacts with the name specified by
+# the 'artifactName' parameter.
+#
+# This template defines a stage named 'build_abstractions_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: Abstractions.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_abstractions_package_stage
+ displayName: Build Abstractions 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 Abstractions solution file to use for all dotnet CLI commands.
+ - name: project
+ value: src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.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:AbstractionsPackageVersion=${{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 Abstractions 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_abstractions_package_job_linux
+ displayName: '[Linux] Build Abstractions 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_abstractions_package_job_windows
+ displayName: '[Win] Build Abstractions 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_abstractions_package_job_macos
+ displayName: '[macOS] Build Abstractions 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_abstractions_package_job
+ displayName: Publish Abstractions Package
+ dependsOn:
+ # We depend on all of the build jobs to ensure the tests pass before
+ # producing the NuGet package.
+ - build_abstractions_package_job_linux
+ - build_abstractions_package_job_windows
+ - build_abstractions_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 4e4c30ae4a..49db0c4b1a 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -15,6 +15,7 @@
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
new file mode 100644
index 0000000000..9632efff88
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/README.md b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/README.md
new file mode 100644
index 0000000000..d2a24b898c
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/README.md
@@ -0,0 +1,285 @@
+# MDS Azure Extension Design
+
+## 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` extension package:
+
+- Create a new `Abstractions` 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 `AzureKeyVaultProvider` (AKV) implementation into the new
+ `Azure` extension package.
+
+This will reduce the main MDS package dependency tree along with a moderate
+package size reduction.
+
+## Motivation
+
+Issue: [#1108](https://github.com/dotnet/SqlClient/issues/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` extension
+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.
+
+The following dependencies will be removed from the main MDS package:
+
+- `Azure.Identity`
+ - `Azure.Core` (transitive)
+ - `Microsoft.Identity.Client` (transitive)
+- `Microsoft.IdentityModel.JsonWebTokens`
+ - `Microsoft.IdentityModel.Tokens` (transitive)
+ - `Microsoft.IdentityModel.Logging` (transitive)
+- `Microsoft.IdentityModel.Protocols.OpenIdConnect`
+ - `Microsoft.IdentityModel.Protocols` (transitive)
+
+The following dependencies will be removed from the AKV Provider package:
+
+- `Azure.Core`
+- `Azure.Security.KeyVault.Keys`
+
+## Package Architecture
+
+```mermaid
+classDiagram
+class MDS
+class MDS.Extensions.Abstractions
+class MDS.Extensions.Azure
+class AKV Provider
+
+MDS --> MDS.Extensions.Abstractions
+MDS ..> MDS.Extensions.Azure
+MDS ..> AKV Provider
+MDS.Extensions.Azure --> MDS.Extensions.Abstractions
+AKV Provider --> MDS.Extensions.Azure
+
+MDS: Depend on MDS.Extensions.Abstractions
+MDS: Load Azure or AKV assembly
+MDS.Extensions.Abstractions: Azure Authentication Types
+MDS.Extensions.Abstractions: Azure Attestation Types
+MDS.Extensions.Abstractions: Azure Key Vault Types
+MDS.Extensions.Azure: Depend on MDS.Extensions.Abstractions
+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 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 `Abstractions` 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 `Abstractions` 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
+
+
+
+```
+
+Calls to MDS APIs that require Azure features will throw an exception, since
+no Azure feature implementation is present.
+
+### With MDS Azure Features
+
+Applications that wish to use MDS-supplied Azure features will need to include
+the new `Azure` extension package as a direct dependency alongside the main MDS
+package:
+
+```xml
+
+
+
+
+```
+
+MDS will automatically detect the `Azure` extension assemblies and load them.
+
+### 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, 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: _**New API will be exposed.**_
+- 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 independently. This provides
+flexibility to update APIs and implementations for packages as needed, avoiding
+unnecessary version bumps and releases. The initial release of these packages
+will have the following versions:
+
+|Package|Version|Comment|
+|-|-|-|
+|`Microsoft.Data.SqlClient.Extensions.Abstractions`|1.0.0|First version of this package.|
+|`Microsoft.Data.SqlClient`|7.0.0|Major version bump due to breaking changes described in this document.|
+|`Microsoft.Data.SqlClient.Extensions.Azure`|1.0.0|First version of this package.|
+|`Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider`|7.0.0|_**Deprecated.**_|
+
+Going forward, each package will be versioned appropriately based on the nature
+of the changes included with subsequent releases.
+
+**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`
+extension package.
+
+## Intradependence
+
+The main MDS package and the new `Azure` package will depend on the
+`Abstractions` package. When APIs are added, modified, or removed from the
+`Abstractions` package, corresponding changes will be made to the dependent
+packages as well. Those dependent packages will then take a strict dependency
+on the appropriate `Abstractions` package version. This ensures that only
+compatible extensions package versions can co-exist with the main MDS package.
+
+For example, imagine that a new extensible conenction pooling feature is added
+to MDS. The `Abstractions` package would be updated to include any new pooling
+APIs, the main MDS package would be updated to accept extensible pooling, and
+the new pooling implementation would be included in a new `ConnectionPooling`
+extension package. The versions of these packages would look something like
+this:
+
+|Package|Version|
+|-|-|
+|`Microsoft.Data.SqlClient.Extensions.Abstractions`|1.1.0|
+|`Microsoft.Data.SqlClient`|7.1.0|
+|`Microsoft.Data.SqlClient.Extensions.ConnectionPooling`|1.0.0|
+
+Both the main MDS package and the new `ConnectionPooling` package would depend
+on `Abstractions` v1.1.0.
+
+An application wishing to use the new `ConnectionPooling` v1.0.0 package must
+also update the main MDS package to v7.1.0. The applictaion would not be able
+to use `ConnectionPooling` v1.0.0 and MDS v7.0.0.
+
+## Backwards Compatibility
+
+There are several backwards compatibility scenarios to consider for applications
+that rely on MDS Azure features currently implemented in the main MDS package
+and the AKV 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
+latest versions of MDS packages.
+
+### Apps using MDS Azure Authentication
+
+Applications currently using the MDS-supplied Azure Authentication features will
+need to add a dependency on 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.
+
+### Apps using MDS Azure Attestation
+
+Applications currently using the MDS-supplied Azure Attestation features will
+need to add a dependency on the `Azure` extension package to their project
+alongside the main MDS package:
+
+```xml
+
+
+
+
+```
+
+All Azure Attestation namespaces and types will remain the same, so this should
+be the only change necessary for applications.
+
+### Apps using AKV Provider
+
+Applications currently using the MDS-supplied AKV provider will have two options
+when upgrading to MDS v7.0.0. Both 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` extension package:
+
+```xml
+
+
+
+
+```
+
+The `Azure` extension 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` extension assembly and automatically load it.
+
+#### Use AKV Provider v7.0.0
+
+This is a temporary solution. The AKV provider v7.0.0 will be marked as
+deprecated and removed entirely at some point in the future. The applictaion
+would remain dependent on the AKV provider, but must update to the v7.0.0
+package. Previous AKV package versions do not support main MDS package versions
+beyond the v6.x range.
+
+```xml
+
+
+
+
+```
+
+This AKV Provider v7.0.0 package will be empty and simply depend on the `Azure`
+extension package to transitively provide the Azure Key Vault features.
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/doc/Sample.xml b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/doc/Sample.xml
new file mode 100644
index 0000000000..8d5f5c44d5
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/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/Abstractions/src/Abstractions.csproj b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
new file mode 100644
index 0000000000..1537c33630
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+ $(AbstractionsPackageVersion)
+
+ $(PackageVersion).$(BuildNumber)
+
+
+
+
+ netstandard2.0
+
+
+
+
+ enable
+ enable
+
+
+
+
+ Microsoft.Data.SqlClient.Extensions.Abstractions
+
+ $(AbstractionsPackageAssemblyVersion)
+ $(PackageVersion)
+ $(AssemblyFileVersion)
+
+ Microsoft.Data.SqlClient.Extensions.Abstractions
+
+
+
+
+ <_Parameter1>true
+
+
+
+
+
+
+
+
+
+
+
+
+ $(PackagesDir)
+ true
+ snupkg
+
+
+ $(OriginalAllowedOutputExtensions)
+
+ Microsoft Corporation
+ Microsoft Corporation
+ Microsoft.Data.SqlClient Extensions Abstractions
+ https://github.com/dotnet/SqlClient
+ MIT
+ dotnet.png
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Sample.cs b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Sample.cs
new file mode 100644
index 0000000000..bf22119436
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Sample.cs
@@ -0,0 +1,20 @@
+namespace Microsoft.Data.SqlClient.Extensions.Abstractions;
+
+///
+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/Abstractions/test/Abstractions.Test.csproj b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
new file mode 100644
index 0000000000..118b215737
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
@@ -0,0 +1,26 @@
+
+
+
+ net462;net47;net471;net472;net48;net481;net8.0;net9.0
+ enable
+ enable
+ false
+ true
+ Microsoft.Data.SqlClient.Extensions.Abstractions.Test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/SampleTest.cs b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/SampleTest.cs
new file mode 100644
index 0000000000..ab8e9da052
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/SampleTest.cs
@@ -0,0 +1,19 @@
+namespace Microsoft.Data.SqlClient.Extensions.Abstractions.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..3bfab46bfa
--- /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 0944a4aea0..2539ff8402 100644
--- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj
@@ -35,6 +35,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 383c97cd6c..d5d5897e9c 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
@@ -1047,6 +1047,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 445fcca7a7..de5b162026 100644
--- a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj
@@ -35,6 +35,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 746925de3c..4b42356608 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
@@ -962,6 +962,7 @@
+
All
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/tools/props/Versions.props b/tools/props/Versions.props
index ad42c4964a..a3b807b1fb 100644
--- a/tools/props/Versions.props
+++ b/tools/props/Versions.props
@@ -1,29 +1,62 @@
-
+
+
+
- 7.0.0
0
+
+
+
+
+
+
+ 1
- $(MdsVersionDefault).$(BuildNumber)
+ $(AbstractionsPackageMajorVersion).0.0
+
+ $(AbstractionsPackageMajorVersion).0.0.0
+
+
+
+
+ 7.0.0
+
+
+ $(MdsVersionDefault).$(BuildNumber)-dev
+
+
+ $(MdsVersionDefault).$(BuildNumber)
+
+
7.0.0.0
$(AssemblyFileVersion)
- $(MdsVersionDefault)-dev
$(NugetPackageVersion)
+
+
@@ -33,6 +66,8 @@
1.0.0-dev
$(SqlServerPackageVersion)
+
+
$(NugetPackageVersion)
diff --git a/tools/specs/Microsoft.Data.SqlClient.nuspec b/tools/specs/Microsoft.Data.SqlClient.nuspec
index bc177256cb..a1b8ef129e 100644
--- a/tools/specs/Microsoft.Data.SqlClient.nuspec
+++ b/tools/specs/Microsoft.Data.SqlClient.nuspec
@@ -32,6 +32,7 @@
+
@@ -46,6 +47,7 @@
+
@@ -59,6 +61,7 @@
+
@@ -72,6 +75,7 @@
+
From a9aaf951db5ad94d218ce1891e059db469430cc5 Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Mon, 15 Sep 2025 10:36:41 -0300
Subject: [PATCH 02/30] User Story 37654: Create Abstractions package
- Addressed some of the review comments.
---
NuGet.config | 20 +-
.../build-abstractions-package-ci-stage.yml | 470 +++++++++---------
packages/.gitignore | 12 +
tools/props/Versions.props | 5 +-
4 files changed, 269 insertions(+), 238 deletions(-)
create mode 100644 packages/.gitignore
diff --git a/NuGet.config b/NuGet.config
index 32e4905f6d..53f672d23b 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -1,14 +1,30 @@
+
+
-
+
+
+
+
+
-
+
diff --git a/eng/pipelines/stages/build-abstractions-package-ci-stage.yml b/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
index 4a8b0087df..5517850296 100644
--- a/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
+++ b/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
@@ -27,6 +27,13 @@
# can be depended on by downstream stages.
parameters:
+
+ # The name of the pipeline artifact to publish.
+ - name: artifactName
+ displayName: Pipeline Artifact Name
+ type: string
+ default: Abstractions.Artifact
+
# The type of build to produce (Release or Debug)
- name: buildConfiguration
displayName: Build Configuration
@@ -36,23 +43,17 @@ parameters:
- 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: Abstractions.Artifact
+ # 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 list of .NET runtimes to test against.
- name: netTestRuntimes
@@ -60,11 +61,11 @@ parameters:
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 version (Major.Minor.Patch) to apply to the package.
+ - name: packageVersion
+ displayName: Package Version Override
+ type: string
+ default: ''
# The verbosity level for the dotnet CLI commands.
- name: verbosity
@@ -79,10 +80,12 @@ parameters:
- diagnostic
stages:
+
- stage: build_abstractions_package_stage
displayName: Build Abstractions Package
variables:
+
# The directory where dotnet artifacts will be staged. Not to be
# confused with pipeline artifact.
- name: dotnetArtifactsDir
@@ -100,16 +103,16 @@ stages:
# dotnet CLI arguments common to all commands.
- name: commonArguments
value: >-
- --verbosity ${{parameters.verbosity}}
+ --verbosity ${{ parameters.verbosity }}
--artifacts-path $(dotnetArtifactsDir)
# dotnet CLI arguments for build/test/pack commands
- name: buildArguments
value: >-
$(commonArguments)
- --configuration ${{parameters.buildConfiguration}}
+ --configuration ${{ parameters.buildConfiguration }}
-p:BuildNumber=$(Build.BuildNumber)
- -p:AbstractionsPackageVersion=${{parameters.packageVersion}}
+ -p:AbstractionsPackageVersion=${{ parameters.packageVersion }}
# Explicitly unset the $PLATFORM environment variable that is set by the
# 'ADO Build properties' Library in the ADO SqlClientDrivers public
@@ -135,217 +138,218 @@ stages:
jobs:
- # --------------------------------------------------------------------------
- # Build and test on Linux.
-
- - job: build_abstractions_package_job_linux
- displayName: '[Linux] Build Abstractions 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_abstractions_package_job_windows
- displayName: '[Win] Build Abstractions 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_abstractions_package_job_macos
- displayName: '[macOS] Build Abstractions 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_abstractions_package_job
- displayName: Publish Abstractions Package
- dependsOn:
- # We depend on all of the build jobs to ensure the tests pass before
- # producing the NuGet package.
- - build_abstractions_package_job_linux
- - build_abstractions_package_job_windows
- - build_abstractions_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
+ # ------------------------------------------------------------------------
+ # Build and test on Linux.
+
+ - job: build_abstractions_package_job_linux
+ displayName: '[Linux] Build Abstractions 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_abstractions_package_job_windows
+ displayName: '[Win] Build Abstractions 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_abstractions_package_job_macos
+ displayName: '[macOS] Build Abstractions 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_abstractions_package_job
+ displayName: Publish Abstractions Package
+ dependsOn:
+ # We depend on all of the build jobs to ensure the tests pass before
+ # producing the NuGet package.
+ - build_abstractions_package_job_linux
+ - build_abstractions_package_job_windows
+ - build_abstractions_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/packages/.gitignore b/packages/.gitignore
new file mode 100644
index 0000000000..b275e0d002
--- /dev/null
+++ b/packages/.gitignore
@@ -0,0 +1,12 @@
+# The packages/ directory must exist for local development due to the various
+# NuGet.config files that refer to it. However, we never want any files in
+# this directory to be included in source control.
+#
+# Git doesn't track directories, only files, so we need this .gitignore file
+# to force Git into tracking the packages/ directory itself.
+
+# Ignore everything in this directory
+*
+
+# Except this file
+!.gitignore
diff --git a/tools/props/Versions.props b/tools/props/Versions.props
index a3b807b1fb..7981910485 100644
--- a/tools/props/Versions.props
+++ b/tools/props/Versions.props
@@ -13,9 +13,8 @@
1
+
From 1b1ddec734777940dfa29fdc92473d7cebd771dc Mon Sep 17 00:00:00 2001
From: Yusuf Mohammed <67040622+SAY14489@users.noreply.github.com>
Date: Tue, 16 Sep 2025 07:52:27 -0700
Subject: [PATCH 04/30] Optimization: Use Environment.TickCount for
SqlStatistics execution timing (#3609)
---
.../src/Microsoft/Data/Common/AdapterUtil.cs | 7 +++
.../Microsoft/Data/SqlClient/SqlStatistics.cs | 21 +++----
.../SQL/SqlBulkCopyTest/CopyAllFromReader.cs | 2 -
.../Data/SqlClient/TickCountElapsedTest.cs | 56 +++++++++++++++++++
4 files changed, 74 insertions(+), 12 deletions(-)
create mode 100644 src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/TickCountElapsedTest.cs
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs
index 41f2c571ff..60ea8cbc7b 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs
@@ -629,6 +629,13 @@ internal static Delegate FindBuilder(MulticastDelegate mcd)
internal static long TimerCurrent() => DateTime.UtcNow.ToFileTimeUtc();
+ internal static long FastTimerCurrent() => Environment.TickCount;
+
+ internal static uint CalculateTickCountElapsed(long startTick, long endTick)
+ {
+ return (uint)(endTick - startTick);
+ }
+
internal static long TimerFromSeconds(int seconds)
{
long result = checked((long)seconds * TimeSpan.TicksPerSecond);
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlStatistics.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlStatistics.cs
index 4152245971..e03630bafb 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlStatistics.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlStatistics.cs
@@ -38,7 +38,7 @@ internal static ValueSqlStatisticsScope TimedScope(SqlStatistics statistics)
// internal values that are not exposed through properties
internal long _closeTimestamp;
internal long _openTimestamp;
- internal long _startExecutionTimestamp;
+ internal long? _startExecutionTimestamp;
internal long _startFetchTimestamp;
internal long _startNetworkServerTimestamp;
@@ -80,7 +80,7 @@ internal bool WaitForDoneAfterRow
internal void ContinueOnNewConnection()
{
- _startExecutionTimestamp = 0;
+ _startExecutionTimestamp = null;
_startFetchTimestamp = 0;
_waitForDoneAfterRow = false;
_waitForReply = false;
@@ -108,7 +108,7 @@ internal IDictionary GetDictionary()
{ "UnpreparedExecs", _unpreparedExecs },
{ "ConnectionTime", ADP.TimerToMilliseconds(_connectionTime) },
- { "ExecutionTime", ADP.TimerToMilliseconds(_executionTime) },
+ { "ExecutionTime", _executionTime },
{ "NetworkServerTime", ADP.TimerToMilliseconds(_networkServerTime) }
};
Debug.Assert(dictionary.Count == Count);
@@ -117,9 +117,9 @@ internal IDictionary GetDictionary()
internal bool RequestExecutionTimer()
{
- if (_startExecutionTimestamp == 0)
+ if (!_startExecutionTimestamp.HasValue)
{
- _startExecutionTimestamp = ADP.TimerCurrent();
+ _startExecutionTimestamp = ADP.FastTimerCurrent();
return true;
}
return false;
@@ -127,7 +127,7 @@ internal bool RequestExecutionTimer()
internal void RequestNetworkServerTimer()
{
- Debug.Assert(_startExecutionTimestamp != 0, "No network time expected outside execution period");
+ Debug.Assert(_startExecutionTimestamp.HasValue, "No network time expected outside execution period");
if (_startNetworkServerTimestamp == 0)
{
_startNetworkServerTimestamp = ADP.TimerCurrent();
@@ -137,10 +137,11 @@ internal void RequestNetworkServerTimer()
internal void ReleaseAndUpdateExecutionTimer()
{
- if (_startExecutionTimestamp > 0)
+ if (_startExecutionTimestamp.HasValue)
{
- _executionTime += (ADP.TimerCurrent() - _startExecutionTimestamp);
- _startExecutionTimestamp = 0;
+ uint elapsed = ADP.CalculateTickCountElapsed(_startExecutionTimestamp.Value, ADP.FastTimerCurrent());
+ _executionTime += elapsed;
+ _startExecutionTimestamp = null;
}
}
@@ -176,7 +177,7 @@ internal void Reset()
_unpreparedExecs = 0;
_waitForDoneAfterRow = false;
_waitForReply = false;
- _startExecutionTimestamp = 0;
+ _startExecutionTimestamp = null;
_startNetworkServerTimestamp = 0;
}
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/CopyAllFromReader.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/CopyAllFromReader.cs
index 4d1dd14cfb..beb8df7992 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/CopyAllFromReader.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/SqlBulkCopyTest/CopyAllFromReader.cs
@@ -52,8 +52,6 @@ public static void Test(string srcConstr, string dstConstr, string dstTable)
Assert.True(0 < (long)stats["BytesReceived"], "BytesReceived is non-positive.");
Assert.True(0 < (long)stats["BytesSent"], "BytesSent is non-positive.");
- Assert.True((long)stats["ConnectionTime"] >= (long)stats["ExecutionTime"], "Connection Time is less than Execution Time.");
- Assert.True((long)stats["ExecutionTime"] >= (long)stats["NetworkServerTime"], "Execution Time is less than Network Server Time.");
DataTestUtility.AssertEqualsWithDescription((long)0, (long)stats["UnpreparedExecs"], "Non-zero UnpreparedExecs value: " + (long)stats["UnpreparedExecs"]);
DataTestUtility.AssertEqualsWithDescription((long)0, (long)stats["PreparedExecs"], "Non-zero PreparedExecs value: " + (long)stats["PreparedExecs"]);
DataTestUtility.AssertEqualsWithDescription((long)0, (long)stats["Prepares"], "Non-zero Prepares value: " + (long)stats["Prepares"]);
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/TickCountElapsedTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/TickCountElapsedTest.cs
new file mode 100644
index 0000000000..38a555d356
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/TickCountElapsedTest.cs
@@ -0,0 +1,56 @@
+// 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.
+
+using Microsoft.Data.Common;
+using Xunit;
+
+namespace Microsoft.Data.SqlClient.UnitTests;
+
+///
+/// Tests for Environment.TickCount elapsed time calculation with wraparound handling.
+///
+public sealed class TickCountElapsedTest
+{
+ ///
+ /// Verifies that normal elapsed time calculation works correctly.
+ ///
+ [Fact]
+ public void CalculateTickCountElapsed_NormalCase_ReturnsCorrectElapsed()
+ {
+ uint elapsed = ADP.CalculateTickCountElapsed(1000, 1500);
+ Assert.Equal(500u, elapsed);
+ }
+
+ ///
+ /// Verifies that wraparound from int.MaxValue to int.MinValue is handled correctly.
+ ///
+ [Fact]
+ public void CalculateTickCountElapsed_MaxWraparound_ReturnsOne()
+ {
+ uint elapsed = ADP.CalculateTickCountElapsed(int.MaxValue, int.MinValue);
+ Assert.Equal(1u, elapsed);
+ }
+
+ ///
+ /// Verifies that partial wraparound scenarios work correctly.
+ ///
+ [Theory]
+ [InlineData(2147483600, -2147483600, 96u)]
+ [InlineData(2147483647, -2147483647, 2u)]
+ public void CalculateTickCountElapsed_PartialWraparound_ReturnsCorrectElapsed(long start, long end, uint expected)
+ {
+ uint elapsed = ADP.CalculateTickCountElapsed(start, end);
+ Assert.Equal(expected, elapsed);
+ }
+
+ ///
+ /// Verifies that zero elapsed time returns zero.
+ ///
+ [Fact]
+ public void CalculateTickCountElapsed_ZeroElapsed_ReturnsZero()
+ {
+ uint elapsed = ADP.CalculateTickCountElapsed(1000, 1000);
+ Assert.Equal(0u, elapsed);
+ }
+}
From 780db7309dc9ab1188ea7a4393e20be06036a2b0 Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Tue, 16 Sep 2025 12:54:12 -0300
Subject: [PATCH 05/30] [7.0.0-preview1] Prepare release notes (#3616)
* Task 38530: Prepare release notes
- Added 7.0.0 Preview 1 release notes.
* Task 38530: Prepare release notes
- Addressed review comments.
* Task 38530: Prepare release notes
- Filled in actual build number.
---
CHANGELOG.md | 62 +++++++++++++
release-notes/7.0/7.0.0-preview1.md | 139 ++++++++++++++++++++++++++++
release-notes/7.0/README.md | 7 ++
release-notes/README.md | 1 +
4 files changed, 209 insertions(+)
create mode 100644 release-notes/7.0/7.0.0-preview1.md
create mode 100644 release-notes/7.0/README.md
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ddcb3e38bd..04afcc4446 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,68 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
+## [Preview Release 7.0.0-preview1.25257.1] - 2025-09-12
+
+This update brings the following changes since the [6.1.0](release-notes/6.1/6.1.0.md)
+release:
+
+### Breaking Changes
+
+- Removed `Constrained Execution Region` error handling blocks and associated
+ `SqlConnection` cleanup which may affect how potentially-broken connections
+ are expunged from the pool.
+ ([#3535](https://github.com/dotnet/SqlClient/pull/3535))
+
+### Bug Fixes
+
+- Packet multiplexing disabled by default, and several bug fixes.
+ ([#3534](https://github.com/dotnet/SqlClient/pull/3534),
+ [#3537](https://github.com/dotnet/SqlClient/pull/3537))
+
+### Added
+
+- `SqlColumnEncryptionCertificateStoreProvider` now works on Windows, Linux,
+ and macOS.
+ ([#3014](https://github.com/dotnet/SqlClient/pull/3014))
+
+### Changed
+
+- Updated `SqlVector.Null` to return a nullable `SqlVector` instance in the
+ reference API to match the implementation.
+ ([#3521](https://github.com/dotnet/SqlClient/pull/3521))
+
+- Performance improvements for all built-in
+ `SqlColumnEncryptionKeyStoreProvider` implementations.
+ ([#3554](https://github.com/dotnet/SqlClient/pull/3554))
+
+- Various test improvements.
+ ([#3456](https://github.com/dotnet/SqlClient/pull/3456),
+ [#2968](https://github.com/dotnet/SqlClient/pull/2968),
+ [#3458](https://github.com/dotnet/SqlClient/pull/3458),
+ [#3494](https://github.com/dotnet/SqlClient/pull/3494),
+ [#3559](https://github.com/dotnet/SqlClient/pull/3559),
+ [#3575](https://github.com/dotnet/SqlClient/pull/3575))
+
+- Codebase merge project and related cleanup.
+ ([#3436](https://github.com/dotnet/SqlClient/pull/3436),
+ [#3434](https://github.com/dotnet/SqlClient/pull/3434),
+ [#3448](https://github.com/dotnet/SqlClient/pull/3448),
+ [#3454](https://github.com/dotnet/SqlClient/pull/3454),
+ [#3462](https://github.com/dotnet/SqlClient/pull/3462),
+ [#3435](https://github.com/dotnet/SqlClient/pull/3435),
+ [#3492](https://github.com/dotnet/SqlClient/pull/3492),
+ [#3473](https://github.com/dotnet/SqlClient/pull/3473),
+ [#3469](https://github.com/dotnet/SqlClient/pull/3469),
+ [#3394](https://github.com/dotnet/SqlClient/pull/3394),
+ [#3493](https://github.com/dotnet/SqlClient/pull/3493),
+ [#3593](https://github.com/dotnet/SqlClient/pull/3593))
+
+- Documentation improvements.
+ ([#3490](https://github.com/dotnet/SqlClient/pull/3490))
+
+- Updated `Azure.Identity` dependency to v1.14.2.
+ ([#3538](https://github.com/dotnet/SqlClient/pull/3538))
+
## [Stable Release 6.1.1] - 2025-08-14
This update includes the following changes since the [6.1.0](6.1.0.md) release:
diff --git a/release-notes/7.0/7.0.0-preview1.md b/release-notes/7.0/7.0.0-preview1.md
new file mode 100644
index 0000000000..045d3e9857
--- /dev/null
+++ b/release-notes/7.0/7.0.0-preview1.md
@@ -0,0 +1,139 @@
+# Release Notes
+
+## Preview Release 7.0.0-preview1.25257.1 - 2025-09-12
+
+This update brings the following changes since the [6.1.0](../6.1/6.1.0.md)
+release:
+
+### Breaking Changes
+
+- Removed `Constrained Execution Region` error handling blocks and associated
+ `SqlConnection` cleanup which may affect how potentially-broken connections
+ are expunged from the pool.
+ ([#3535](https://github.com/dotnet/SqlClient/pull/3535))
+
+### Bug Fixes
+
+- Packet multiplexing disabled by default, and several bug fixes.
+ ([#3534](https://github.com/dotnet/SqlClient/pull/3534),
+ [#3537](https://github.com/dotnet/SqlClient/pull/3537))
+
+### Added
+
+- `SqlColumnEncryptionCertificateStoreProvider` now works on Windows, Linux,
+ and macOS.
+ ([#3014](https://github.com/dotnet/SqlClient/pull/3014))
+
+### Changed
+
+- Updated `SqlVector.Null` to return a nullable `SqlVector` instance in the
+ reference API to match the implementation.
+ ([#3521](https://github.com/dotnet/SqlClient/pull/3521))
+
+- Performance improvements for all built-in
+ `SqlColumnEncryptionKeyStoreProvider` implementations.
+ ([#3554](https://github.com/dotnet/SqlClient/pull/3554))
+
+- Various test improvements.
+ ([#3456](https://github.com/dotnet/SqlClient/pull/3456),
+ [#2968](https://github.com/dotnet/SqlClient/pull/2968),
+ [#3458](https://github.com/dotnet/SqlClient/pull/3458),
+ [#3494](https://github.com/dotnet/SqlClient/pull/3494),
+ [#3559](https://github.com/dotnet/SqlClient/pull/3559),
+ [#3575](https://github.com/dotnet/SqlClient/pull/3575))
+
+- Codebase merge project and related cleanup.
+ ([#3436](https://github.com/dotnet/SqlClient/pull/3436),
+ [#3434](https://github.com/dotnet/SqlClient/pull/3434),
+ [#3448](https://github.com/dotnet/SqlClient/pull/3448),
+ [#3454](https://github.com/dotnet/SqlClient/pull/3454),
+ [#3462](https://github.com/dotnet/SqlClient/pull/3462),
+ [#3435](https://github.com/dotnet/SqlClient/pull/3435),
+ [#3492](https://github.com/dotnet/SqlClient/pull/3492),
+ [#3473](https://github.com/dotnet/SqlClient/pull/3473),
+ [#3469](https://github.com/dotnet/SqlClient/pull/3469),
+ [#3394](https://github.com/dotnet/SqlClient/pull/3394),
+ [#3493](https://github.com/dotnet/SqlClient/pull/3493),
+ [#3593](https://github.com/dotnet/SqlClient/pull/3593))
+
+- Documentation improvements.
+ ([#3490](https://github.com/dotnet/SqlClient/pull/3490))
+
+- Updated `Azure.Identity` dependency to v1.14.2.
+ ([#3538](https://github.com/dotnet/SqlClient/pull/3538))
+
+## Contributors
+
+We thank the following public contributors. Their efforts toward this project
+are very much appreciated.
+
+- [edwardneal](https://github.com/edwardneal)
+- [emmanuel-ferdman](https://github.com/emmanuel-ferdman)
+- [ErikEJ](https://github.com/ErikEJ)
+- [twsouthwick](https://github.com/twsouthwick)
+- [Wraith2](https://github.com/Wraith2)
+
+### New Contributors
+
+- [frankbuckley](https://github.com/frankbuckley) made their first contribution
+ in [#3521](https://github.com/dotnet/SqlClient/pull/3521)
+
+## Target Platform Support
+
+- .NET Framework 4.6.2+ (Windows ARM64, Windows x86, Windows x64)
+- .NET 8.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Standard 2.0
+
+- Azure.Identity 1.14.2
+- Microsoft.Bcl.Cryptography 9.0.5
+- Microsoft.Data.SqlClient.SNI.runtime 6.0.2
+- Microsoft.Extensions.Caching.Memory 9.0.5
+- Microsoft.IdentityModel.JsonWebTokens 7.7.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 7.7.1
+- Microsoft.SqlServer.Server 1.0.0
+- System.Configuration.ConfigurationManager 9.0.5
+- System.Security.Cryptography.Pkcs 9.0.5
+- System.Text.Json 9.0.5
+
+#### .NET Framework 4.6.2+
+
+- Azure.Identity 1.14.2
+- Microsoft.Bcl.Cryptography 8.0.0
+- Microsoft.Data.SqlClient.SNI 6.0.2
+- Microsoft.Extensions.Caching.Memory 8.0.1
+- Microsoft.IdentityModel.JsonWebTokens 7.7.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 7.7.1
+- System.Buffers 4.5.1
+- System.Data.Common 4.3.0
+- System.Security.Cryptography.Pkcs 8.0.1
+- System.Text.Encodings.Web 8.0.0
+- System.Text.Json 8.0.5
+
+#### .NET 8.0
+
+- Azure.Identity 1.14.2
+- Microsoft.Bcl.Cryptography 8.0.0
+- Microsoft.Data.SqlClient.SNI.runtime 6.0.2
+- Microsoft.Extensions.Caching.Memory 8.0.1
+- Microsoft.IdentityModel.JsonWebTokens 7.7.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 7.7.1
+- Microsoft.SqlServer.Server 1.0.0
+- System.Configuration.ConfigurationManager 8.0.1
+- System.Security.Cryptography.Pkcs 8.0.1
+- System.Text.Json 8.0.5
+
+#### .NET 9.0
+
+- Azure.Identity 1.14.2
+- Microsoft.Bcl.Cryptography 9.0.5
+- Microsoft.Data.SqlClient.SNI.runtime 6.0.2
+- Microsoft.Extensions.Caching.Memory 9.0.5
+- Microsoft.IdentityModel.JsonWebTokens 7.7.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 7.7.1
+- Microsoft.SqlServer.Server 1.0.0
+- System.Configuration.ConfigurationManager 9.0.5
+- System.Security.Cryptography.Pkcs 9.0.5
+- System.Text.Json 9.0.5
diff --git a/release-notes/7.0/README.md b/release-notes/7.0/README.md
new file mode 100644
index 0000000000..6cbd345392
--- /dev/null
+++ b/release-notes/7.0/README.md
@@ -0,0 +1,7 @@
+# Microsoft.Data.SqlClient 7.0 Releases
+
+The following Microsoft.Data.SqlClient 7.0 releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2025-09-12 | 7.0.0-preview1.25257.1 | [Release Notes](7.0.0-preview1.md) |
diff --git a/release-notes/README.md b/release-notes/README.md
index 612316204e..f2d7c0b452 100644
--- a/release-notes/README.md
+++ b/release-notes/README.md
@@ -4,6 +4,7 @@ The latest stable release is [Microsoft.Data.SqlClient 6.0](6.0).
## Release Information
+- [Microsoft.Data.SqlClient 7.0](7.0)
- [Microsoft.Data.SqlClient 6.1](6.1)
- [Microsoft.Data.SqlClient 6.0](6.0)
- [Microsoft.Data.SqlClient 5.2](5.2)
From 1765de5988e2ad0981d00f82365b6ab64b693c0d Mon Sep 17 00:00:00 2001
From: Edward Neal <55035479+edwardneal@users.noreply.github.com>
Date: Tue, 16 Sep 2025 23:39:41 +0100
Subject: [PATCH 06/30] Merge | TdsParser functional changes (#3555)
* netcore, netfx: sync declarations of TdsOperationStatus variables
* netcore: reorder TryProcessUDTMetadata
* netfx: reorder WriteTceFeatureRequest
* netfx: reorder WriteAzureSQLSupportFeatureRequest
* netcore, netfx: merge WriteInt and SerializeInt
netcore: removed a simple WriteInt which did nothing besides call BinaryPrimitives.
netcore: when there's space in the packet buffer, WriteInt will now write to it directly (rather than write to a stack-allocated span and copy.)
* netcore: remove ConstructGuid method
* netcore, netfx: refactor and sync serialization of guids
* netcore, netfx: refactor and sync serialization of floats and doubles
This removes the need for TdsParser.netcore.cs.
* netfx: adjust TraceString - parameter was being passed to it which was never referenced in the format string
* netcore: sync exception messages with netfx
Messages of the netfx exceptions are more detailed
* netfx, netcore: centralise masking of received server options
Added mask to netcore logic.
Also removed mask on _encryptionOption from netfx - this will never be outside the range of EncryptionOptions.OPTIONS_MASK.
* netcore: enforce server certificate validation if AccessTokenCallback is set and certificate is not automatically trusted
* netfx: add static lambda to TdsExecuteSQLBatch
* netfx: remove failed attempt at static lambda
This passed state around, but never passed enough state to remove the state machine. Sync with netcore.
* netfx: sync reference to length of JSON metadata substitution sequence
* netfx: pre-PR correction: match previous behaviour when writing Guid instances from WriteUnterminatedSqlValue
* Flip order of debug assertion
* Next round of code review
Remove unnecessary conditional compilation.
Add XML documentation to clarify SerializeShort, WriteShort et al.
* netcore, netfx: sync TraceString
Both platforms will now show the TransparentNetworkIPResolution status. This is always disabled on netcore.
* Expand ParametersTest to include SqlGuid (including null value)
* netfx: port RequestContinue call from netcore
---
.../src/Microsoft.Data.SqlClient.csproj | 1 -
.../src/Microsoft/Data/SqlClient/TdsParser.cs | 501 +++++++++++-------
.../Data/SqlClient/TdsParser.netcore.cs | 25 -
.../src/Microsoft/Data/SqlClient/TdsParser.cs | 442 +++++++++------
.../SQL/ParameterTest/ParametersTest.cs | 9 +
5 files changed, 575 insertions(+), 403 deletions(-)
delete mode 100644 src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.netcore.cs
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 395f3df11d..50b04819ba 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
@@ -822,7 +822,6 @@
-
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs
index 8fbeb3050c..4d1eb4e75e 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs
@@ -833,13 +833,13 @@ private void SendPreLoginHandshake(
break;
case (int)PreLoginOptions.TRACEID:
- FillGuidBytes(_connHandler._clientConnectionId, payload.AsSpan(payloadLength, GUID_SIZE));
+ SerializeGuid(_connHandler._clientConnectionId, payload.AsSpan(payloadLength, GUID_SIZE));
payloadLength += GUID_SIZE;
offset += GUID_SIZE;
optionDataSize = GUID_SIZE;
ActivityCorrelator.ActivityId actId = ActivityCorrelator.Next();
- FillGuidBytes(actId.Id, payload.AsSpan(payloadLength, GUID_SIZE));
+ SerializeGuid(actId.Id, payload.AsSpan(payloadLength, GUID_SIZE));
payloadLength += GUID_SIZE;
payload[payloadLength++] = (byte)(0x000000ff & actId.Sequence);
payload[payloadLength++] = (byte)((0x0000ff00 & actId.Sequence) >> 8);
@@ -968,7 +968,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(
if (_physicalStateObj._inBytesPacket > TdsEnums.MAX_PACKET_SIZE || _physicalStateObj._inBytesPacket <= 0)
{
- throw SQL.ParsingError();
+ throw SQL.ParsingError(ParsingErrorState.CorruptedTdsStream);
}
byte[] payload = new byte[_physicalStateObj._inBytesPacket];
@@ -1017,7 +1017,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(
payloadOffset = payload[offset++] << 8 | payload[offset++];
payloadLength = payload[offset++] << 8 | payload[offset++];
- EncryptionOptions serverOption = (EncryptionOptions)payload[payloadOffset];
+ EncryptionOptions serverOption = ((EncryptionOptions)payload[payloadOffset]) & EncryptionOptions.OPTIONS_MASK;
/* internal enum EncryptionOptions {
OFF,
@@ -1160,7 +1160,8 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(
// Validate Certificate if Trust Server Certificate=false and Encryption forced (EncryptionOptions.ON) from Server.
bool shouldValidateServerCert = (_encryptionOption == EncryptionOptions.ON && !trustServerCert) ||
- (_connHandler._accessTokenInBytes != null && !trustServerCert);
+ ((_connHandler._accessTokenInBytes != null || _connHandler._accessTokenCallback != null) && !trustServerCert);
+
uint info = (shouldValidateServerCert ? TdsEnums.SNI_SSL_VALIDATE_CERTIFICATE : 0)
| TdsEnums.SNI_SSL_USE_SCHANNEL_CACHE;
@@ -1679,9 +1680,12 @@ internal void CheckResetConnection(TdsParserStateObject stateObj)
#endif
}
- //
- // Takes a 16 bit short and writes it to the returned buffer.
- //
+ ///
+ /// Serializes a 16 bit short to the returned buffer.
+ ///
+ /// The value to serialize.
+ /// containing the cached buffer bytes.
+ /// The serialized 16 bit short.
internal byte[] SerializeShort(int v, TdsParserStateObject stateObj)
{
if (stateObj._bShortBytes == null)
@@ -1700,9 +1704,11 @@ internal byte[] SerializeShort(int v, TdsParserStateObject stateObj)
return bytes;
}
- //
- // Takes a 16 bit short and writes it.
- //
+ ///
+ /// Writes a 16 bit short to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteShort(int v, TdsParserStateObject stateObj)
{
if ((stateObj._outBytesUsed + 2) > stateObj._outBuff.Length)
@@ -1720,27 +1726,97 @@ internal void WriteShort(int v, TdsParserStateObject stateObj)
}
}
+ ///
+ /// Writes a 16 bit unsigned short to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteUnsignedShort(ushort us, TdsParserStateObject stateObj)
{
WriteShort((short)us, stateObj);
}
- //
- // Takes a long and writes out an unsigned int
- //
+ ///
+ /// Serializes a Guid to the specified buffer.
+ ///
+ /// The value to serialize.
+ /// The buffer to serialize to. The size of this buffer must be 16 bytes or larger.
+ private static void SerializeGuid(in Guid v, Span buffer)
+ {
+ Debug.Assert(buffer.Length >= GUID_SIZE);
+#if NET
+ v.TryWriteBytes(buffer, bigEndian: false, out _);
+#else
+ byte[] guidBytes = v.ToByteArray();
+ guidBytes.AsSpan().CopyTo(buffer);
+#endif
+ }
+
+ ///
+ /// Writes a SqlGuid to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
+ private static void WriteGuid(in SqlGuid v, TdsParserStateObject stateObj)
+ {
+ Guid innerValue = v.IsNull ? Guid.Empty : v.Value;
+
+ WriteGuid(in innerValue, stateObj);
+ }
+
+ ///
+ /// Writes a Guid to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
+ private static void WriteGuid(in Guid v, TdsParserStateObject stateObj)
+ {
+ if ((stateObj._outBytesUsed + GUID_SIZE) > stateObj._outBuff.Length)
+ {
+ Span buffer = stackalloc byte[GUID_SIZE];
+
+ SerializeGuid(in v, buffer);
+ // if all of the guid doesn't fit into the buffer
+ for (int index = 0; index < buffer.Length; index++)
+ {
+ stateObj.WriteByte(buffer[index]);
+ }
+ }
+ else
+ {
+ // all of the guid fits into the buffer
+ SerializeGuid(in v, stateObj._outBuff.AsSpan(stateObj._outBytesUsed, GUID_SIZE));
+ stateObj._outBytesUsed += GUID_SIZE;
+ }
+ }
+
+ ///
+ /// Serializes an unsigned 32 bit integer to the returned buffer.
+ ///
+ /// The value to serialize.
+ /// containing the cached buffer bytes.
+ /// The serialized unsigned 32 bit integer.
internal byte[] SerializeUnsignedInt(uint i, TdsParserStateObject stateObj)
{
return SerializeInt((int)i, stateObj);
}
+ ///
+ /// Writes an unsigned 32 bit integer to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteUnsignedInt(uint i, TdsParserStateObject stateObj)
{
WriteInt((int)i, stateObj);
}
- //
- // Takes an int and writes it as an int.
- //
+ ///
+ /// Serializes a signed 32 bit integer to the returned buffer.
+ ///
+ /// The value to serialize.
+ /// containing the cached buffer bytes.
+ /// The serialized signed 32 bit integer.
internal byte[] SerializeInt(int v, TdsParserStateObject stateObj)
{
if (stateObj._bIntBytes == null)
@@ -1752,16 +1828,22 @@ internal byte[] SerializeInt(int v, TdsParserStateObject stateObj)
Debug.Assert(sizeof(int) == stateObj._bIntBytes.Length);
}
- WriteInt(stateObj._bIntBytes.AsSpan(), v);
+ BinaryPrimitives.WriteInt32LittleEndian(stateObj._bIntBytes, v);
return stateObj._bIntBytes;
}
+ ///
+ /// Writes a signed 32 bit integer to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteInt(int v, TdsParserStateObject stateObj)
{
- Span buffer = stackalloc byte[sizeof(int)];
- WriteInt(buffer, v);
if ((stateObj._outBytesUsed + 4) > stateObj._outBuff.Length)
{
+ Span buffer = stackalloc byte[sizeof(int)];
+
+ BinaryPrimitives.WriteInt32LittleEndian(buffer, v);
// if all of the int doesn't fit into the buffer
for (int index = 0; index < sizeof(int); index++)
{
@@ -1771,19 +1853,16 @@ internal void WriteInt(int v, TdsParserStateObject stateObj)
else
{
// all of the int fits into the buffer
- buffer.CopyTo(stateObj._outBuff.AsSpan(stateObj._outBytesUsed, sizeof(int)));
+ BinaryPrimitives.WriteInt32LittleEndian(stateObj._outBuff.AsSpan(stateObj._outBytesUsed, sizeof(int)), v);
stateObj._outBytesUsed += 4;
}
}
- internal static void WriteInt(Span buffer, int value)
- {
- BinaryPrimitives.TryWriteInt32LittleEndian(buffer, value);
- }
-
- //
- // Takes a float and writes it as a 32 bit float.
- //
+ ///
+ /// Serializes a float to the returned buffer.
+ ///
+ /// The value to serialize.
+ /// The serialized float.
internal byte[] SerializeFloat(float v)
{
if (Single.IsInfinity(v) || Single.IsNaN(v))
@@ -1796,16 +1875,24 @@ internal byte[] SerializeFloat(float v)
return bytes;
}
+ ///
+ /// Writes a float to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteFloat(float v, TdsParserStateObject stateObj)
{
Span bytes = stackalloc byte[sizeof(float)];
- FillFloatBytes(v, bytes);
+ BinaryPrimitives.WriteInt32LittleEndian(bytes, BitConverterCompatible.SingleToInt32Bits(v));
stateObj.WriteByteSpan(bytes);
}
- //
- // Takes a long and writes it as a long.
- //
+ ///
+ /// Serializes a signed 64 bit long to the returned buffer.
+ ///
+ /// The value to serialize.
+ /// containing the cached buffer bytes.
+ /// The serialized signed 64 bit long.
internal byte[] SerializeLong(long v, TdsParserStateObject stateObj)
{
int current = 0;
@@ -1829,6 +1916,11 @@ internal byte[] SerializeLong(long v, TdsParserStateObject stateObj)
return bytes;
}
+ ///
+ /// Writes a signed 64 bit long to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteLong(long v, TdsParserStateObject stateObj)
{
if ((stateObj._outBytesUsed + 8) > stateObj._outBuff.Length)
@@ -1855,9 +1947,12 @@ internal void WriteLong(long v, TdsParserStateObject stateObj)
}
}
- //
- // Takes a long and writes part of it
- //
+ ///
+ /// Serializes the first bytes of a signed 64 bit long to the returned buffer.
+ ///
+ /// The value to serialize.
+ /// The number of bytes to serialize.
+ /// The serialized signed 64 bit long.
internal byte[] SerializePartialLong(long v, int length)
{
Debug.Assert(length <= 8, "Length specified is longer than the size of a long");
@@ -1874,6 +1969,12 @@ internal byte[] SerializePartialLong(long v, int length)
return bytes;
}
+ ///
+ /// Writes the first bytes of a signed 64 bit long to the wire.
+ ///
+ /// The value to write.
+ /// The number of bytes to serialize.
+ /// containing the wire buffer.
internal void WritePartialLong(long v, int length, TdsParserStateObject stateObj)
{
Debug.Assert(length <= 8, "Length specified is longer than the size of a long");
@@ -1898,17 +1999,21 @@ internal void WritePartialLong(long v, int length, TdsParserStateObject stateObj
}
}
- //
- // Takes a ulong and writes it as a ulong.
- //
+ ///
+ /// Writes an unsigned 64 bit long to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteUnsignedLong(ulong uv, TdsParserStateObject stateObj)
{
WriteLong((long)uv, stateObj);
}
- //
- // Takes a double and writes it as a 64 bit double.
- //
+ ///
+ /// Serializes a double to the returned buffer.
+ ///
+ /// The value to serialize.
+ /// The serialized double.
internal byte[] SerializeDouble(double v)
{
if (double.IsInfinity(v) || double.IsNaN(v))
@@ -1921,10 +2026,15 @@ internal byte[] SerializeDouble(double v)
return bytes;
}
+ ///
+ /// Writes a double to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteDouble(double v, TdsParserStateObject stateObj)
{
Span bytes = stackalloc byte[sizeof(double)];
- FillDoubleBytes(v, bytes);
+ BinaryPrimitives.WriteInt64LittleEndian(bytes, BitConverter.DoubleToInt64Bits(v));
stateObj.WriteByteSpan(bytes);
}
@@ -2071,7 +2181,7 @@ internal TdsOperationStatus TryRun(RunBehavior runBehavior, SqlCommand cmdHandle
#if DEBUG
throw new InvalidOperationException(message);
#else
- throw SQL.ParsingError();
+ throw SQL.ParsingErrorToken(ParsingErrorState.InvalidTdsTokenReceived, token); // MDAC 82443
#endif
}
@@ -2728,14 +2838,13 @@ private TdsOperationStatus TryProcessEnvChange(int tokenLength, TdsParserStateOb
int processedLength = 0;
SqlEnvChange head = null;
SqlEnvChange tail = null;
- TdsOperationStatus result;
sqlEnvChange = null;
while (tokenLength > processedLength)
{
SqlEnvChange env = new SqlEnvChange();
- result = stateObj.TryReadByte(out env._type);
+ TdsOperationStatus result = stateObj.TryReadByte(out env._type);
if (result != TdsOperationStatus.Done)
{
return result;
@@ -3641,7 +3750,7 @@ private TdsOperationStatus TryProcessSessionState(TdsParserStateObject stateObj,
{
if (length < 5)
{
- throw SQL.ParsingError();
+ throw SQL.ParsingErrorLength(ParsingErrorState.SessionStateLengthTooShort, length);
}
uint seqNum;
TdsOperationStatus result = stateObj.TryReadUInt32(out seqNum);
@@ -3661,7 +3770,7 @@ private TdsOperationStatus TryProcessSessionState(TdsParserStateObject stateObj,
}
if (status > 1)
{
- throw SQL.ParsingError();
+ throw SQL.ParsingErrorStatus(ParsingErrorState.SessionStateInvalidStatus, status);
}
bool recoverable = status != 0;
length -= 5;
@@ -4670,9 +4779,11 @@ internal void DrainData(TdsParserStateObject stateObj)
if (sharedState != null && sharedState._dataReady)
{
_SqlMetaDataSet metadata = stateObj._cleanupMetaData;
+ TdsOperationStatus result;
if (stateObj._partialHeaderBytesRead > 0)
{
- if (stateObj.TryProcessHeader() != TdsOperationStatus.Done)
+ result = stateObj.TryProcessHeader();
+ if (result != TdsOperationStatus.Done)
{
throw SQL.SynchronousCallMayNotPend();
}
@@ -4680,7 +4791,8 @@ internal void DrainData(TdsParserStateObject stateObj)
if (0 == sharedState._nextColumnHeaderToRead)
{
// i. user called read but didn't fetch anything
- if (stateObj.Parser.TrySkipRow(stateObj._cleanupMetaData, stateObj) != TdsOperationStatus.Done)
+ result = stateObj.Parser.TrySkipRow(stateObj._cleanupMetaData, stateObj);
+ if (result != TdsOperationStatus.Done)
{
throw SQL.SynchronousCallMayNotPend();
}
@@ -4694,7 +4806,8 @@ internal void DrainData(TdsParserStateObject stateObj)
{
if (stateObj._longlen != 0)
{
- if (TrySkipPlpValue(ulong.MaxValue, stateObj, out _) != TdsOperationStatus.Done)
+ result = TrySkipPlpValue(ulong.MaxValue, stateObj, out _);
+ if (result != TdsOperationStatus.Done)
{
throw SQL.SynchronousCallMayNotPend();
}
@@ -4703,7 +4816,8 @@ internal void DrainData(TdsParserStateObject stateObj)
else if (0 < sharedState._columnDataBytesRemaining)
{
- if (stateObj.TrySkipLongBytes(sharedState._columnDataBytesRemaining) != TdsOperationStatus.Done)
+ result = stateObj.TrySkipLongBytes(sharedState._columnDataBytesRemaining);
+ if (result != TdsOperationStatus.Done)
{
throw SQL.SynchronousCallMayNotPend();
}
@@ -4712,7 +4826,8 @@ internal void DrainData(TdsParserStateObject stateObj)
// Read the remaining values off the wire for this row
- if (stateObj.Parser.TrySkipRow(metadata, sharedState._nextColumnHeaderToRead, stateObj) != TdsOperationStatus.Done)
+ result = stateObj.Parser.TrySkipRow(metadata, sharedState._nextColumnHeaderToRead, stateObj);
+ if (result != TdsOperationStatus.Done)
{
throw SQL.SynchronousCallMayNotPend();
}
@@ -5303,6 +5418,85 @@ private TdsOperationStatus TryCommonProcessMetaData(TdsParserStateObject stateOb
return TdsOperationStatus.Done;
}
+ private TdsOperationStatus TryProcessUDTMetaData(SqlMetaDataPriv metaData, TdsParserStateObject stateObj)
+ {
+ ushort shortLength;
+ byte byteLength;
+
+ // max byte size
+ TdsOperationStatus result = stateObj.TryReadUInt16(out shortLength);
+ if (result != TdsOperationStatus.Done)
+ {
+ return result;
+ }
+ metaData.length = shortLength;
+
+ // database name
+ result = stateObj.TryReadByte(out byteLength);
+ if (result != TdsOperationStatus.Done)
+ {
+ return result;
+ }
+ if (metaData.udt is null)
+ {
+ metaData.udt = new SqlMetaDataUdt();
+ }
+ if (byteLength != 0)
+ {
+ result = stateObj.TryReadString(byteLength, out metaData.udt.DatabaseName);
+ if (result != TdsOperationStatus.Done)
+ {
+ return result;
+ }
+ }
+
+ // schema name
+ result = stateObj.TryReadByte(out byteLength);
+ if (result != TdsOperationStatus.Done)
+ {
+ return result;
+ }
+ if (byteLength != 0)
+ {
+ result = stateObj.TryReadString(byteLength, out metaData.udt.SchemaName);
+ if (result != TdsOperationStatus.Done)
+ {
+ return result;
+ }
+ }
+
+ // type name
+ result = stateObj.TryReadByte(out byteLength);
+ if (result != TdsOperationStatus.Done)
+ {
+ return result;
+ }
+ if (byteLength != 0)
+ {
+ result = stateObj.TryReadString(byteLength, out metaData.udt.TypeName);
+ if (result != TdsOperationStatus.Done)
+ {
+ return result;
+ }
+ }
+
+ result = stateObj.TryReadUInt16(out shortLength);
+ if (result != TdsOperationStatus.Done)
+ {
+ return result;
+ }
+ if (shortLength != 0)
+ {
+ result = stateObj.TryReadString(shortLength, out metaData.udt.AssemblyQualifiedName);
+ if (result != TdsOperationStatus.Done)
+ {
+ return result;
+ }
+ }
+
+ return TdsOperationStatus.Done;
+ }
+
private void WriteUDTMetaData(object value, string database, string schema, string type,
TdsParserStateObject stateObj)
{
@@ -6536,9 +6730,8 @@ internal TdsOperationStatus TryReadSqlValue(SqlBuffer value,
private TdsOperationStatus TryReadSqlDateTime(SqlBuffer value, byte tdsType, int length, byte scale, TdsParserStateObject stateObj)
{
Span datetimeBuffer = ((uint)length <= 16) ? stackalloc byte[16] : new byte[length];
- TdsOperationStatus result;
- result = stateObj.TryReadByteArray(datetimeBuffer, length);
+ TdsOperationStatus result = stateObj.TryReadByteArray(datetimeBuffer, length);
if (result != TdsOperationStatus.Done)
{
return result;
@@ -6770,13 +6963,17 @@ internal TdsOperationStatus TryReadSqlValueInternal(SqlBuffer value, byte tdsTyp
{
Debug.Assert(length == GUID_SIZE, "invalid length for SqlGuid type!");
+#if NET
Span b = stackalloc byte[GUID_SIZE];
+#else
+ byte[] b = (_tempGuidBytes ??= new byte[GUID_SIZE]);
+#endif
result = stateObj.TryReadByteArray(b, length);
if (result != TdsOperationStatus.Done)
{
return result;
}
- value.Guid = ConstructGuid(b);
+ value.Guid = new Guid(b);
break;
}
@@ -7122,12 +7319,8 @@ internal Task WriteSqlVariantValue(object value, int length, int offset, TdsPars
case TdsEnums.SQLUNIQUEID:
{
- System.Guid guid = (System.Guid)value;
- Span b = stackalloc byte[16];
- TdsParser.FillGuidBytes(guid, b);
-
- Debug.Assert((length == b.Length) && (length == 16), "Invalid length for guid type in com+ object");
- stateObj.WriteByteSpan(b);
+ Debug.Assert(length == 16, "Invalid length for guid type in com+ object");
+ WriteGuid((Guid)value, stateObj);
break;
}
@@ -7280,14 +7473,8 @@ internal Task WriteSqlVariantDataRowValue(object value, TdsParserStateObject sta
case TdsEnums.SQLUNIQUEID:
{
- System.Guid guid = (System.Guid)value;
- Span b = stackalloc byte[16];
- FillGuidBytes(guid, b);
-
- length = b.Length;
- Debug.Assert(length == 16, "Invalid length for guid type in com+ object");
WriteSqlVariantHeader(18, metatype.TDSType, metatype.PropBytes, stateObj);
- stateObj.WriteByteSpan(b);
+ WriteGuid((Guid)value, stateObj);
break;
}
@@ -8060,47 +8247,45 @@ internal TdsOperationStatus TryGetTokenLength(byte token, TdsParserStateObject s
return stateObj.TryReadInt32(out tokenLength);
}
+ if (token == TdsEnums.SQLUDT)
+ { // special case for UDTs
+ tokenLength = -1; // Should we return -1 or not call GetTokenLength for UDTs?
+ return TdsOperationStatus.Done;
+ }
+ else if (token == TdsEnums.SQLRETURNVALUE)
{
- if (token == TdsEnums.SQLUDT)
- { // special case for UDTs
- tokenLength = -1; // Should we return -1 or not call GetTokenLength for UDTs?
- return TdsOperationStatus.Done;
- }
- else if (token == TdsEnums.SQLRETURNVALUE)
- {
- tokenLength = -1; // In 2005, the RETURNVALUE token stream no longer has length
- return TdsOperationStatus.Done;
- }
- else if (token == TdsEnums.SQLXMLTYPE)
- {
- ushort value;
- result = stateObj.TryReadUInt16(out value);
- if (result != TdsOperationStatus.Done)
- {
- tokenLength = 0;
- return result;
- }
- tokenLength = (int)value;
- Debug.Assert(tokenLength == TdsEnums.SQL_USHORTVARMAXLEN, "Invalid token stream for xml datatype");
- return TdsOperationStatus.Done;
- }
- else if (token == TdsEnums.SQLJSON)
+ tokenLength = -1; // In 2005, the RETURNVALUE token stream no longer has length
+ return TdsOperationStatus.Done;
+ }
+ else if (token == TdsEnums.SQLXMLTYPE)
+ {
+ ushort value;
+ result = stateObj.TryReadUInt16(out value);
+ if (result != TdsOperationStatus.Done)
{
- tokenLength = -1;
- return TdsOperationStatus.Done;
+ tokenLength = 0;
+ return result;
}
- else if (token == TdsEnums.SQLVECTOR)
+ tokenLength = (int)value;
+ Debug.Assert(tokenLength == TdsEnums.SQL_USHORTVARMAXLEN, "Invalid token stream for xml datatype");
+ return TdsOperationStatus.Done;
+ }
+ else if (token == TdsEnums.SQLJSON)
+ {
+ tokenLength = -1;
+ return TdsOperationStatus.Done;
+ }
+ else if (token == TdsEnums.SQLVECTOR)
+ {
+ ushort value;
+ result = stateObj.TryReadUInt16(out value);
+ if (result != TdsOperationStatus.Done)
{
- ushort value;
- result = stateObj.TryReadUInt16(out value);
- if (result != TdsOperationStatus.Done)
- {
- tokenLength = 0;
- return result;
- }
- tokenLength = value;
- return TdsOperationStatus.Done;
+ tokenLength = 0;
+ return result;
}
+ tokenLength = value;
+ return TdsOperationStatus.Done;
}
switch (token & TdsEnums.SQLLenMask)
@@ -11664,26 +11849,16 @@ private Task WriteUnterminatedSqlValue(object value, MetaType type, int actualLe
case TdsEnums.SQLUNIQUEID:
{
Debug.Assert(actualLength == 16, "Invalid length for guid type in com+ object");
- Span b = stackalloc byte[16];
if (value is Guid guid)
{
- FillGuidBytes(guid, b);
+ WriteGuid(in guid, stateObj);
}
else
{
SqlGuid sqlGuid = (SqlGuid)value;
- if (sqlGuid.IsNull)
- {
- b.Clear(); // this is needed because initlocals may be supressed in framework assemblies meaning the memory is not automaticaly zeroed
- }
- else
- {
- FillGuidBytes(sqlGuid.Value, b);
- }
+ WriteGuid(in sqlGuid, stateObj);
}
- stateObj.WriteByteSpan(b);
break;
-
}
case TdsEnums.SQLBITN:
@@ -12340,9 +12515,7 @@ private Task WriteUnterminatedValue(object value, MetaType type, byte scale, int
case TdsEnums.SQLUNIQUEID:
{
Debug.Assert(actualLength == 16, "Invalid length for guid type in com+ object");
- Span b = stackalloc byte[16];
- FillGuidBytes((System.Guid)value, b);
- stateObj.WriteByteSpan(b);
+ WriteGuid((Guid)value, stateObj);
break;
}
@@ -13541,86 +13714,6 @@ internal ulong PlpBytesTotalLength(TdsParserStateObject stateObj)
return stateObj._longlen;
}
- private TdsOperationStatus TryProcessUDTMetaData(SqlMetaDataPriv metaData, TdsParserStateObject stateObj)
- {
-
- ushort shortLength;
- byte byteLength;
- // max byte size
-
- TdsOperationStatus result = stateObj.TryReadUInt16(out shortLength);
- if (result != TdsOperationStatus.Done)
- {
- return result;
- }
- metaData.length = shortLength;
-
- // database name
- result = stateObj.TryReadByte(out byteLength);
- if (result != TdsOperationStatus.Done)
- {
- return result;
- }
- if (metaData.udt is null)
- {
- metaData.udt = new SqlMetaDataUdt();
- }
- if (byteLength != 0)
- {
- result = stateObj.TryReadString(byteLength, out metaData.udt.DatabaseName);
- if (result != TdsOperationStatus.Done)
- {
- return result;
- }
- }
-
- // schema name
- result = stateObj.TryReadByte(out byteLength);
- if (result != TdsOperationStatus.Done)
- {
- return result;
- }
- if (byteLength != 0)
- {
- result = stateObj.TryReadString(byteLength, out metaData.udt.SchemaName);
- if (result != TdsOperationStatus.Done)
- {
- return result;
- }
- }
-
- // type name
- result = stateObj.TryReadByte(out byteLength);
- if (result != TdsOperationStatus.Done)
- {
- return result;
- }
- if (byteLength != 0)
- {
- result = stateObj.TryReadString(byteLength, out metaData.udt.TypeName);
- if (result != TdsOperationStatus.Done)
- {
- return result;
- }
- }
-
- result = stateObj.TryReadUInt16(out shortLength);
- if (result != TdsOperationStatus.Done)
- {
- return result;
- }
- if (shortLength != 0)
- {
- result = stateObj.TryReadString(shortLength, out metaData.udt.AssemblyQualifiedName);
- if (result != TdsOperationStatus.Done)
- {
- return result;
- }
- }
-
- return TdsOperationStatus.Done;
- }
-
const string StateTraceFormatString = "\n\t"
+ " _physicalStateObj = {0}\n\t"
+ " _pMarsPhysicalConObj = {1}\n\t"
@@ -13645,8 +13738,9 @@ private TdsOperationStatus TryProcessUDTMetaData(SqlMetaDataPriv metaData, TdsPa
+ " _attentionWarnings = {20}\n\t"
+ " _statistics = {21}\n\t"
+ " _statisticsIsInTransaction = {22}\n\t"
- + " _fPreserveTransaction = {23}"
- + " _fParallel = {24}"
+ + " _fPreserveTransaction = {23}\n\t"
+ + " _multiSubnetFailover = {24}\n\t"
+ + " _transparentNetworkIPResolution = {25}"
;
internal string TraceString()
{
@@ -13676,7 +13770,8 @@ internal string TraceString()
_statistics == null ? bool.TrueString : bool.FalseString,
_statisticsIsInTransaction ? bool.TrueString : bool.FalseString,
_fPreserveTransaction ? bool.TrueString : bool.FalseString,
- _connHandler == null ? "(null)" : _connHandler.ConnectionOptions.MultiSubnetFailover.ToString((IFormatProvider)null));
+ _connHandler == null ? "(null)" : _connHandler.ConnectionOptions.MultiSubnetFailover.ToString((IFormatProvider)null),
+ _connHandler == null ? "(null)" : bool.FalseString);
}
private string TraceObjectClass(object instance)
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.netcore.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.netcore.cs
deleted file mode 100644
index 95dd0d9731..0000000000
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.netcore.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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.
-
-using System;
-using System.Diagnostics;
-using System.Buffers.Binary;
-
-namespace Microsoft.Data.SqlClient
-{
- internal sealed partial class TdsParser
- {
- internal static void FillGuidBytes(Guid guid, Span buffer) => guid.TryWriteBytes(buffer);
-
- internal static void FillDoubleBytes(double value, Span buffer) => BinaryPrimitives.TryWriteInt64LittleEndian(buffer, BitConverter.DoubleToInt64Bits(value));
-
- internal static void FillFloatBytes(float value, Span buffer) => BinaryPrimitives.TryWriteInt32LittleEndian(buffer, BitConverterCompatible.SingleToInt32Bits(value));
-
- internal static Guid ConstructGuid(ReadOnlySpan bytes)
- {
- Debug.Assert(bytes.Length >= 16, "not enough bytes to set guid");
- return new Guid(bytes);
- }
- }
-}
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs
index d38190a359..670ed07dac 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs
@@ -885,16 +885,13 @@ private void SendPreLoginHandshake(
break;
case (int)PreLoginOptions.TRACEID:
- byte[] connectionIdBytes = _connHandler._clientConnectionId.ToByteArray();
- Debug.Assert(GUID_SIZE == connectionIdBytes.Length);
- Buffer.BlockCopy(connectionIdBytes, 0, payload, payloadLength, GUID_SIZE);
+ SerializeGuid(_connHandler._clientConnectionId, payload.AsSpan(payloadLength, GUID_SIZE));
payloadLength += GUID_SIZE;
offset += GUID_SIZE;
optionDataSize = GUID_SIZE;
ActivityCorrelator.ActivityId actId = ActivityCorrelator.Next();
- connectionIdBytes = actId.Id.ToByteArray();
- Buffer.BlockCopy(connectionIdBytes, 0, payload, payloadLength, GUID_SIZE);
+ SerializeGuid(actId.Id, payload.AsSpan(payloadLength, GUID_SIZE));
payloadLength += GUID_SIZE;
payload[payloadLength++] = (byte)(0x000000ff & actId.Sequence);
payload[payloadLength++] = (byte)((0x0000ff00 & actId.Sequence) >> 8);
@@ -1085,7 +1082,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(
payloadOffset = payload[offset++] << 8 | payload[offset++];
payloadLength = payload[offset++] << 8 | payload[offset++];
- EncryptionOptions serverOption = (EncryptionOptions)payload[payloadOffset];
+ EncryptionOptions serverOption = ((EncryptionOptions)payload[payloadOffset]) & EncryptionOptions.OPTIONS_MASK;
/* internal enum EncryptionOptions {
OFF,
@@ -1097,26 +1094,26 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(
} */
// Any response other than NOT_SUP means the server supports encryption.
- serverSupportsEncryption = (serverOption & EncryptionOptions.OPTIONS_MASK) != EncryptionOptions.NOT_SUP;
+ serverSupportsEncryption = serverOption != EncryptionOptions.NOT_SUP;
- switch (_encryptionOption & EncryptionOptions.OPTIONS_MASK)
+ switch (_encryptionOption)
{
case (EncryptionOptions.OFF):
- if ((serverOption & EncryptionOptions.OPTIONS_MASK) == EncryptionOptions.OFF)
+ if (serverOption == EncryptionOptions.OFF)
{
// Only encrypt login.
- _encryptionOption = EncryptionOptions.LOGIN | (_encryptionOption & ~EncryptionOptions.OPTIONS_MASK);
+ _encryptionOption = EncryptionOptions.LOGIN;
}
- else if ((serverOption & EncryptionOptions.OPTIONS_MASK) == EncryptionOptions.REQ)
+ else if (serverOption == EncryptionOptions.REQ)
{
// Encrypt all.
- _encryptionOption = EncryptionOptions.ON | (_encryptionOption & ~EncryptionOptions.OPTIONS_MASK);
+ _encryptionOption = EncryptionOptions.ON;
}
// NOT_SUP: No encryption.
break;
case (EncryptionOptions.NOT_SUP):
- if ((serverOption & EncryptionOptions.OPTIONS_MASK) == EncryptionOptions.REQ)
+ if (serverOption == EncryptionOptions.REQ)
{
// Server requires encryption, but client does not support it.
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByClient(), "", 0));
@@ -1127,7 +1124,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(
break;
default:
// Any other client option needs encryption
- if ((serverOption & EncryptionOptions.OPTIONS_MASK) == EncryptionOptions.NOT_SUP)
+ if (serverOption == EncryptionOptions.NOT_SUP)
{
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByServer(), "", 0));
_physicalStateObj.Dispose();
@@ -1216,8 +1213,8 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(
}
}
- if ((_encryptionOption & EncryptionOptions.OPTIONS_MASK) == EncryptionOptions.ON ||
- (_encryptionOption & EncryptionOptions.OPTIONS_MASK) == EncryptionOptions.LOGIN)
+ if (_encryptionOption == EncryptionOptions.ON ||
+ _encryptionOption == EncryptionOptions.LOGIN)
{
if (!serverSupportsEncryption)
{
@@ -1227,7 +1224,8 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(
}
// Validate Certificate if Trust Server Certificate=false and Encryption forced (EncryptionOptions.ON) from Server.
- bool shouldValidateServerCert = (_encryptionOption == EncryptionOptions.ON && !trustServerCert) || ((_connHandler._accessTokenInBytes != null || _connHandler._accessTokenCallback != null) && !trustServerCert);
+ bool shouldValidateServerCert = (_encryptionOption == EncryptionOptions.ON && !trustServerCert) ||
+ ((_connHandler._accessTokenInBytes != null || _connHandler._accessTokenCallback != null) && !trustServerCert);
uint info = (shouldValidateServerCert ? TdsEnums.SNI_SSL_VALIDATE_CERTIFICATE : 0)
| TdsEnums.SNI_SSL_USE_SCHANNEL_CACHE;
@@ -1708,9 +1706,12 @@ internal void CheckResetConnection(TdsParserStateObject stateObj)
#endif
}
- //
- // Takes a 16 bit short and writes it to the returned buffer.
- //
+ ///
+ /// Serializes a 16 bit short to the returned buffer.
+ ///
+ /// The value to serialize.
+ /// containing the cached buffer bytes.
+ /// The serialized 16 bit short.
internal byte[] SerializeShort(int v, TdsParserStateObject stateObj)
{
if (stateObj._bShortBytes == null)
@@ -1729,9 +1730,11 @@ internal byte[] SerializeShort(int v, TdsParserStateObject stateObj)
return bytes;
}
- //
- // Takes a 16 bit short and writes it.
- //
+ ///
+ /// Writes a 16 bit short to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteShort(int v, TdsParserStateObject stateObj)
{
if ((stateObj._outBytesUsed + 2) > stateObj._outBuff.Length)
@@ -1749,27 +1752,97 @@ internal void WriteShort(int v, TdsParserStateObject stateObj)
}
}
+ ///
+ /// Writes a 16 bit unsigned short to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteUnsignedShort(ushort us, TdsParserStateObject stateObj)
{
WriteShort((short)us, stateObj);
}
- //
- // Takes a long and writes out an unsigned int
- //
+ ///
+ /// Serializes a Guid to the specified buffer.
+ ///
+ /// The value to serialize.
+ /// The buffer to serialize to. The size of this buffer must be 16 bytes or larger.
+ private static void SerializeGuid(in Guid v, Span buffer)
+ {
+ Debug.Assert(buffer.Length >= GUID_SIZE);
+#if NET
+ v.TryWriteBytes(buffer, bigEndian: false, out _);
+#else
+ byte[] guidBytes = v.ToByteArray();
+ guidBytes.AsSpan().CopyTo(buffer);
+#endif
+ }
+
+ ///
+ /// Writes a SqlGuid to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
+ private static void WriteGuid(in SqlGuid v, TdsParserStateObject stateObj)
+ {
+ Guid innerValue = v.IsNull ? Guid.Empty : v.Value;
+
+ WriteGuid(in innerValue, stateObj);
+ }
+
+ ///
+ /// Writes a Guid to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
+ private static void WriteGuid(in Guid v, TdsParserStateObject stateObj)
+ {
+ if ((stateObj._outBytesUsed + GUID_SIZE) > stateObj._outBuff.Length)
+ {
+ Span buffer = stackalloc byte[GUID_SIZE];
+
+ SerializeGuid(in v, buffer);
+ // if all of the guid doesn't fit into the buffer
+ for (int index = 0; index < buffer.Length; index++)
+ {
+ stateObj.WriteByte(buffer[index]);
+ }
+ }
+ else
+ {
+ // all of the guid fits into the buffer
+ SerializeGuid(in v, stateObj._outBuff.AsSpan(stateObj._outBytesUsed, GUID_SIZE));
+ stateObj._outBytesUsed += GUID_SIZE;
+ }
+ }
+
+ ///
+ /// Serializes an unsigned 32 bit integer to the returned buffer.
+ ///
+ /// The value to serialize.
+ /// containing the cached buffer bytes.
+ /// The serialized unsigned 32 bit integer.
internal byte[] SerializeUnsignedInt(uint i, TdsParserStateObject stateObj)
{
return SerializeInt((int)i, stateObj);
}
+ ///
+ /// Writes an unsigned 32 bit integer to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteUnsignedInt(uint i, TdsParserStateObject stateObj)
{
WriteInt((int)i, stateObj);
}
- //
- // Takes an int and writes it as an int.
- //
+ ///
+ /// Serializes a signed 32 bit integer to the returned buffer.
+ ///
+ /// The value to serialize.
+ /// containing the cached buffer bytes.
+ /// The serialized signed 32 bit integer.
internal byte[] SerializeInt(int v, TdsParserStateObject stateObj)
{
if (stateObj._bIntBytes == null)
@@ -1781,40 +1854,41 @@ internal byte[] SerializeInt(int v, TdsParserStateObject stateObj)
Debug.Assert(sizeof(int) == stateObj._bIntBytes.Length);
}
- int current = 0;
- byte[] bytes = stateObj._bIntBytes;
- bytes[current++] = (byte)(v & 0xff);
- bytes[current++] = (byte)((v >> 8) & 0xff);
- bytes[current++] = (byte)((v >> 16) & 0xff);
- bytes[current++] = (byte)((v >> 24) & 0xff);
- return bytes;
+ BinaryPrimitives.WriteInt32LittleEndian(stateObj._bIntBytes, v);
+ return stateObj._bIntBytes;
}
+ ///
+ /// Writes a signed 32 bit integer to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteInt(int v, TdsParserStateObject stateObj)
{
if ((stateObj._outBytesUsed + 4) > stateObj._outBuff.Length)
{
+ Span buffer = stackalloc byte[sizeof(int)];
+
+ BinaryPrimitives.WriteInt32LittleEndian(buffer, v);
// if all of the int doesn't fit into the buffer
- for (int shiftValue = 0; shiftValue < sizeof(int) * 8; shiftValue += 8)
+ for (int index = 0; index < sizeof(int); index++)
{
- stateObj.WriteByte((byte)((v >> shiftValue) & 0xff));
+ stateObj.WriteByte(buffer[index]);
}
}
else
{
// all of the int fits into the buffer
- // NOTE: We don't use a loop here for performance
- stateObj._outBuff[stateObj._outBytesUsed] = (byte)(v & 0xff);
- stateObj._outBuff[stateObj._outBytesUsed + 1] = (byte)((v >> 8) & 0xff);
- stateObj._outBuff[stateObj._outBytesUsed + 2] = (byte)((v >> 16) & 0xff);
- stateObj._outBuff[stateObj._outBytesUsed + 3] = (byte)((v >> 24) & 0xff);
+ BinaryPrimitives.WriteInt32LittleEndian(stateObj._outBuff.AsSpan(stateObj._outBytesUsed, sizeof(int)), v);
stateObj._outBytesUsed += 4;
}
}
- //
- // Takes a float and writes it as a 32 bit float.
- //
+ ///
+ /// Serializes a float to the returned buffer.
+ ///
+ /// The value to serialize.
+ /// The serialized float.
internal byte[] SerializeFloat(float v)
{
if (Single.IsInfinity(v) || Single.IsNaN(v))
@@ -1825,16 +1899,24 @@ internal byte[] SerializeFloat(float v)
return BitConverter.GetBytes(v);
}
+ ///
+ /// Writes a float to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteFloat(float v, TdsParserStateObject stateObj)
{
- byte[] bytes = BitConverter.GetBytes(v);
-
- stateObj.WriteByteArray(bytes, bytes.Length, 0);
+ Span bytes = stackalloc byte[sizeof(float)];
+ BinaryPrimitives.WriteInt32LittleEndian(bytes, BitConverterCompatible.SingleToInt32Bits(v));
+ stateObj.WriteByteSpan(bytes);
}
- //
- // Takes a long and writes it as a long.
- //
+ ///
+ /// Serializes a signed 64 bit long to the returned buffer.
+ ///
+ /// The value to serialize.
+ /// containing the cached buffer bytes.
+ /// The serialized signed 64 bit long.
internal byte[] SerializeLong(long v, TdsParserStateObject stateObj)
{
int current = 0;
@@ -1858,6 +1940,11 @@ internal byte[] SerializeLong(long v, TdsParserStateObject stateObj)
return bytes;
}
+ ///
+ /// Writes a signed 64 bit long to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteLong(long v, TdsParserStateObject stateObj)
{
if ((stateObj._outBytesUsed + 8) > stateObj._outBuff.Length)
@@ -1884,9 +1971,12 @@ internal void WriteLong(long v, TdsParserStateObject stateObj)
}
}
- //
- // Takes a long and writes part of it
- //
+ ///
+ /// Serializes the first bytes of a signed 64 bit long to the returned buffer.
+ ///
+ /// The value to serialize.
+ /// The number of bytes to serialize.
+ /// The serialized signed 64 bit long.
internal byte[] SerializePartialLong(long v, int length)
{
Debug.Assert(length <= 8, "Length specified is longer than the size of a long");
@@ -1903,6 +1993,12 @@ internal byte[] SerializePartialLong(long v, int length)
return bytes;
}
+ ///
+ /// Writes the first bytes of a signed 64 bit long to the wire.
+ ///
+ /// The value to write.
+ /// The number of bytes to serialize.
+ /// containing the wire buffer.
internal void WritePartialLong(long v, int length, TdsParserStateObject stateObj)
{
Debug.Assert(length <= 8, "Length specified is longer than the size of a long");
@@ -1927,17 +2023,21 @@ internal void WritePartialLong(long v, int length, TdsParserStateObject stateObj
}
}
- //
- // Takes a ulong and writes it as a ulong.
- //
+ ///
+ /// Writes an unsigned 64 bit long to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteUnsignedLong(ulong uv, TdsParserStateObject stateObj)
{
WriteLong((long)uv, stateObj);
}
- //
- // Takes a double and writes it as a 64 bit double.
- //
+ ///
+ /// Serializes a double to the returned buffer.
+ ///
+ /// The value to serialize.
+ /// The serialized double.
internal byte[] SerializeDouble(double v)
{
if (double.IsInfinity(v) || double.IsNaN(v))
@@ -1948,11 +2048,16 @@ internal byte[] SerializeDouble(double v)
return BitConverter.GetBytes(v);
}
+ ///
+ /// Writes a double to the wire.
+ ///
+ /// The value to write.
+ /// containing the wire buffer.
internal void WriteDouble(double v, TdsParserStateObject stateObj)
{
- byte[] bytes = BitConverter.GetBytes(v);
-
- stateObj.WriteByteArray(bytes, bytes.Length, 0);
+ Span bytes = stackalloc byte[sizeof(double)];
+ BinaryPrimitives.WriteInt64LittleEndian(bytes, BitConverter.DoubleToInt64Bits(v));
+ stateObj.WriteByteSpan(bytes);
}
internal void PrepareResetConnection(bool preserveTransaction)
@@ -4139,11 +4244,10 @@ internal TdsOperationStatus TryProcessReturnValue(int length,
out SqlReturnValue returnValue,
SqlCommandColumnEncryptionSetting columnEncryptionSetting)
{
- TdsOperationStatus result;
returnValue = null;
SqlReturnValue rec = new SqlReturnValue();
rec.length = length; // In 2005 this length is -1
- result = stateObj.TryReadUInt16(out rec.parmIndex);
+ TdsOperationStatus result = stateObj.TryReadUInt16(out rec.parmIndex);
if (result != TdsOperationStatus.Done)
{
return result;
@@ -4695,9 +4799,10 @@ internal void DrainData(TdsParserStateObject stateObj)
if (sharedState != null && sharedState._dataReady)
{
var metadata = stateObj._cleanupMetaData;
+ TdsOperationStatus result;
if (stateObj._partialHeaderBytesRead > 0)
{
- TdsOperationStatus result = stateObj.TryProcessHeader();
+ result = stateObj.TryProcessHeader();
if (result != TdsOperationStatus.Done)
{
throw SQL.SynchronousCallMayNotPend();
@@ -4706,7 +4811,7 @@ internal void DrainData(TdsParserStateObject stateObj)
if (0 == sharedState._nextColumnHeaderToRead)
{
// i. user called read but didn't fetch anything
- TdsOperationStatus result = stateObj.Parser.TrySkipRow(stateObj._cleanupMetaData, stateObj);
+ result = stateObj.Parser.TrySkipRow(stateObj._cleanupMetaData, stateObj);
if (result != TdsOperationStatus.Done)
{
throw SQL.SynchronousCallMayNotPend();
@@ -4721,7 +4826,7 @@ internal void DrainData(TdsParserStateObject stateObj)
{
if (stateObj._longlen != 0)
{
- TdsOperationStatus result = TrySkipPlpValue(UInt64.MaxValue, stateObj, out _);
+ result = TrySkipPlpValue(ulong.MaxValue, stateObj, out _);
if (result != TdsOperationStatus.Done)
{
throw SQL.SynchronousCallMayNotPend();
@@ -4731,7 +4836,7 @@ internal void DrainData(TdsParserStateObject stateObj)
else if (0 < sharedState._columnDataBytesRemaining)
{
- TdsOperationStatus result = stateObj.TrySkipLongBytes(sharedState._columnDataBytesRemaining);
+ result = stateObj.TrySkipLongBytes(sharedState._columnDataBytesRemaining);
if (result != TdsOperationStatus.Done)
{
throw SQL.SynchronousCallMayNotPend();
@@ -4742,7 +4847,8 @@ internal void DrainData(TdsParserStateObject stateObj)
// Read the remaining values off the wire for this row
- if (stateObj.Parser.TrySkipRow(metadata, sharedState._nextColumnHeaderToRead, stateObj) != TdsOperationStatus.Done)
+ result = stateObj.Parser.TrySkipRow(metadata, sharedState._nextColumnHeaderToRead, stateObj);
+ if (result != TdsOperationStatus.Done)
{
throw SQL.SynchronousCallMayNotPend();
}
@@ -5069,9 +5175,10 @@ internal TdsOperationStatus TryProcessMetaData(int cColumns, TdsParserStateObjec
// Read the cipher info table first
SqlTceCipherInfoTable cipherTable = null;
+ TdsOperationStatus result;
if (IsColumnEncryptionSupported)
{
- TdsOperationStatus result = TryProcessCipherInfoTable(stateObj, out cipherTable);
+ result = TryProcessCipherInfoTable(stateObj, out cipherTable);
if (result != TdsOperationStatus.Done)
{
metaData = null;
@@ -5083,7 +5190,7 @@ internal TdsOperationStatus TryProcessMetaData(int cColumns, TdsParserStateObjec
_SqlMetaDataSet newMetaData = new _SqlMetaDataSet(cColumns, cipherTable);
for (int i = 0; i < cColumns; i++)
{
- TdsOperationStatus result = TryCommonProcessMetaData(stateObj, newMetaData[i], cipherTable, fColMD: true, columnEncryptionSetting: columnEncryptionSetting);
+ result = TryCommonProcessMetaData(stateObj, newMetaData[i], cipherTable, fColMD: true, columnEncryptionSetting: columnEncryptionSetting);
if (result != TdsOperationStatus.Done)
{
metaData = null;
@@ -5302,10 +5409,9 @@ private TdsOperationStatus TryCommonProcessMetaData(TdsParserStateObject stateOb
{
byte byteLen;
uint userType;
- TdsOperationStatus result;
// read user type - 4 bytes 2005, 2 backwards
- result = stateObj.TryReadUInt32(out userType);
+ TdsOperationStatus result = stateObj.TryReadUInt32(out userType);
if (result != TdsOperationStatus.Done)
{
return result;
@@ -5637,13 +5743,12 @@ private TdsOperationStatus TryProcessColInfo(_SqlMetaDataSet columns, SqlDataRea
Debug.Assert(columns != null && columns.Length > 0, "no metadata available!");
metaData = null;
- TdsOperationStatus result;
for (int i = 0; i < columns.Length; i++)
{
_SqlMetaData col = columns[i];
- result = stateObj.TryReadByte(out _);
+ TdsOperationStatus result = stateObj.TryReadByte(out _);
if (result != TdsOperationStatus.Done)
{
return result;
@@ -6932,18 +7037,17 @@ internal TdsOperationStatus TryReadSqlValueInternal(SqlBuffer value, byte tdsTyp
{
Debug.Assert(length == GUID_SIZE, "invalid length for SqlGuid type!");
- byte[] b = _tempGuidBytes;
- if (b is null)
- {
- b = new byte[GUID_SIZE];
- }
+#if NET
+ Span b = stackalloc byte[GUID_SIZE];
+#else
+ byte[] b = (_tempGuidBytes ??= new byte[GUID_SIZE]);
+#endif
result = stateObj.TryReadByteArray(b, length);
if (result != TdsOperationStatus.Done)
{
return result;
}
value.Guid = new Guid(b);
- _tempGuidBytes = b;
break;
}
@@ -7289,11 +7393,8 @@ internal Task WriteSqlVariantValue(object value, int length, int offset, TdsPars
case TdsEnums.SQLUNIQUEID:
{
- System.Guid guid = (System.Guid)value;
- byte[] b = guid.ToByteArray();
-
- Debug.Assert((length == b.Length) && (length == 16), "Invalid length for guid type in com+ object");
- stateObj.WriteByteArray(b, length, 0);
+ Debug.Assert(length == 16, "Invalid length for guid type in com+ object");
+ WriteGuid((Guid)value, stateObj);
break;
}
@@ -7446,13 +7547,8 @@ internal Task WriteSqlVariantDataRowValue(object value, TdsParserStateObject sta
case TdsEnums.SQLUNIQUEID:
{
- System.Guid guid = (System.Guid)value;
- byte[] b = guid.ToByteArray();
-
- length = b.Length;
- Debug.Assert(length == 16, "Invalid length for guid type in com+ object");
WriteSqlVariantHeader(18, metatype.TDSType, metatype.PropBytes, stateObj);
- stateObj.WriteByteArray(b, length, 0);
+ WriteGuid((Guid)value, stateObj);
break;
}
@@ -8208,6 +8304,7 @@ internal TdsOperationStatus TryGetDataLength(SqlMetaDataPriv colmeta, TdsParserS
internal TdsOperationStatus TryGetTokenLength(byte token, TdsParserStateObject stateObj, out int tokenLength)
{
Debug.Assert(token != 0, "0 length token!");
+ TdsOperationStatus result;
switch (token)
{ // rules about SQLLenMask no longer apply to new tokens (as of 7.4)
@@ -8219,8 +8316,6 @@ internal TdsOperationStatus TryGetTokenLength(byte token, TdsParserStateObject s
return stateObj.TryReadInt32(out tokenLength);
}
- TdsOperationStatus result;
-
if (token == TdsEnums.SQLUDT)
{ // special case for UDTs
tokenLength = -1; // Should we return -1 or not call GetTokenLength for UDTs?
@@ -8590,63 +8685,63 @@ internal int WriteFedAuthFeatureRequest(FederatedAuthenticationFeatureExtensionD
return totalLen;
}
- internal int WriteDataClassificationFeatureRequest(bool write /* if false just calculates the length */)
+ internal int WriteTceFeatureRequest(bool write /* if false just calculates the length */)
{
int len = 6; // 1byte = featureID, 4bytes = featureData length, 1 bytes = Version
if (write)
{
- // Write Feature ID, length of the version# field and Sensitivity Classification Version#
- _physicalStateObj.WriteByte(TdsEnums.FEATUREEXT_DATACLASSIFICATION);
+ // Write Feature ID, length of the version# field and TCE Version#
+ _physicalStateObj.WriteByte(TdsEnums.FEATUREEXT_TCE);
WriteInt(1, _physicalStateObj);
- _physicalStateObj.WriteByte(TdsEnums.DATA_CLASSIFICATION_VERSION_MAX_SUPPORTED);
+ _physicalStateObj.WriteByte(TdsEnums.MAX_SUPPORTED_TCE_VERSION);
}
return len; // size of data written
}
- internal int WriteTceFeatureRequest(bool write /* if false just calculates the length */)
+ internal int WriteAzureSQLSupportFeatureRequest(bool write /* if false just calculates the length */)
{
- int len = 6; // 1byte = featureID, 4bytes = featureData length, 1 bytes = Version
+ int len = 6; // 1byte = featureID, 4bytes = featureData length, 1 bytes = featureData
if (write)
{
- // Write Feature ID, length of the version# field and TCE Version#
- _physicalStateObj.WriteByte(TdsEnums.FEATUREEXT_TCE);
- WriteInt(1, _physicalStateObj);
- _physicalStateObj.WriteByte(TdsEnums.MAX_SUPPORTED_TCE_VERSION);
+ // Write Feature ID
+ _physicalStateObj.WriteByte(TdsEnums.FEATUREEXT_AZURESQLSUPPORT);
+
+ // Feature Data length
+ WriteInt(s_featureExtDataAzureSQLSupportFeatureRequest.Length, _physicalStateObj);
+
+ _physicalStateObj.WriteByteArray(s_featureExtDataAzureSQLSupportFeatureRequest, s_featureExtDataAzureSQLSupportFeatureRequest.Length, 0);
}
- return len; // size of data written
+ return len;
}
- internal int WriteGlobalTransactionsFeatureRequest(bool write /* if false just calculates the length */)
+ internal int WriteDataClassificationFeatureRequest(bool write /* if false just calculates the length */)
{
- int len = 5; // 1byte = featureID, 4bytes = featureData length
+ int len = 6; // 1byte = featureID, 4bytes = featureData length, 1 bytes = Version
if (write)
{
- // Write Feature ID
- _physicalStateObj.WriteByte(TdsEnums.FEATUREEXT_GLOBALTRANSACTIONS);
- WriteInt(0, _physicalStateObj); // we don't send any data
+ // Write Feature ID, length of the version# field and Sensitivity Classification Version#
+ _physicalStateObj.WriteByte(TdsEnums.FEATUREEXT_DATACLASSIFICATION);
+ WriteInt(1, _physicalStateObj);
+ _physicalStateObj.WriteByte(TdsEnums.DATA_CLASSIFICATION_VERSION_MAX_SUPPORTED);
}
- return len;
+ return len; // size of data written
}
- internal int WriteAzureSQLSupportFeatureRequest(bool write /* if false just calculates the length */)
+ internal int WriteGlobalTransactionsFeatureRequest(bool write /* if false just calculates the length */)
{
- int len = 6; // 1byte = featureID, 4bytes = featureData length, 1 bytes = featureData
+ int len = 5; // 1byte = featureID, 4bytes = featureData length
if (write)
{
// Write Feature ID
- _physicalStateObj.WriteByte(TdsEnums.FEATUREEXT_AZURESQLSUPPORT);
-
- // Feature Data length
- WriteInt(s_featureExtDataAzureSQLSupportFeatureRequest.Length, _physicalStateObj);
-
- _physicalStateObj.WriteByteArray(s_featureExtDataAzureSQLSupportFeatureRequest, s_featureExtDataAzureSQLSupportFeatureRequest.Length, 0);
+ _physicalStateObj.WriteByte(TdsEnums.FEATUREEXT_GLOBALTRANSACTIONS);
+ WriteInt(0, _physicalStateObj); // we don't send any data
}
return len;
@@ -9533,29 +9628,34 @@ internal Task TdsExecuteSQLBatch(string text, int timeout, SqlNotificationReques
// Need to wait for flush - continuation will unlock the connection
bool taskReleaseConnectionLock = releaseConnectionLock;
releaseConnectionLock = false;
- return executeTask.ContinueWith(t =>
- {
- Debug.Assert(!t.IsCanceled, "Task should not be canceled");
- try
- {
- if (t.IsFaulted)
- {
- FailureCleanup(stateObj, t.Exception.InnerException);
- throw t.Exception.InnerException;
- }
- else
+ return executeTask.ContinueWith(
+ static (Task task, object state) =>
+ {
+ Debug.Assert(!task.IsCanceled, "Task should not be canceled");
+ var parameters = (Tuple)state;
+ TdsParser parser = parameters.Item1;
+ TdsParserStateObject tdsParserStateObject = parameters.Item2;
+ SqlInternalConnectionTds internalConnectionTds = parameters.Item3;
+ try
{
- stateObj.SniContext = SniContext.Snix_Read;
+ if (task.IsFaulted)
+ {
+ parser.FailureCleanup(tdsParserStateObject, task.Exception.InnerException);
+ throw task.Exception.InnerException;
+ }
+ else
+ {
+ tdsParserStateObject.SniContext = SniContext.Snix_Read;
+ }
}
- }
- finally
- {
- if (taskReleaseConnectionLock)
+ finally
{
- _connHandler._parserLock.Release();
+ internalConnectionTds?._parserLock.Release();
}
- }
- }, TaskScheduler.Default);
+ },
+ Tuple.Create(this, stateObj, taskReleaseConnectionLock ? _connHandler : null),
+ TaskScheduler.Default
+ );
}
// Finished sync
@@ -10329,27 +10429,23 @@ private Task TDSExecuteRPCAddParameter(TdsParserStateObject stateObj, SqlParamet
// This is in its own method to avoid always allocating the lambda in TDSExecuteRPCParameter
private void TDSExecuteRPCParameterSetupWriteCompletion(SqlCommand cmd, IList<_SqlRPC> rpcArray, int timeout, bool inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, bool isCommandProc, bool sync, TaskCompletionSource
-
+
+
+
+
+
+
+
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 bb83a62401..0032ba4bf6 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
@@ -1056,7 +1056,6 @@
-
@@ -1069,6 +1068,19 @@
+
+
+
+
+
+
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 716a687c22..f73b8682a0 100644
--- a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj
@@ -35,7 +35,6 @@
-
All
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -50,5 +49,19 @@
+
+
+
+
+
+
+
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 54d8d5c6d3..a378ef5f51 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
@@ -1025,7 +1025,6 @@
-
All
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -1041,6 +1040,20 @@
+
+
+
+
+
+
+
From beaf9c393eeaaad69e246e7c49a6abea21f48455 Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Wed, 17 Sep 2025 12:51:06 -0300
Subject: [PATCH 09/30] User Story 37654: Create Abstractions package
- Modularized Abstractions CI templates.
---
build.proj | 25 +-
eng/pipelines/dotnet-sqlclient-ci-core.yml | 11 +-
.../jobs/pack-abstractions-package-ci-job.yml | 143 ++++++++
eng/pipelines/jobs/stress-tests-ci-job.yml | 2 +-
.../jobs/test-abstractions-package-ci-job.yml | 174 ++++++++++
.../build-abstractions-package-ci-stage.yml | 305 +++---------------
6 files changed, 382 insertions(+), 278 deletions(-)
create mode 100644 eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
create mode 100644 eng/pipelines/jobs/test-abstractions-package-ci-job.yml
diff --git a/build.proj b/build.proj
index 27aa557b54..082dd58f31 100644
--- a/build.proj
+++ b/build.proj
@@ -51,7 +51,8 @@
-
+
+
@@ -120,6 +121,28 @@
Properties="$(BuildProperties)" />
+
+
+ AbstractionsPackageVersion=$(AbstractionsPackageVersion)
+
+
+
+
+
+
+
+ AbstractionsPackageVersion=$(AbstractionsPackageVersion)
+
+
+
+
+
diff --git a/eng/pipelines/dotnet-sqlclient-ci-core.yml b/eng/pipelines/dotnet-sqlclient-ci-core.yml
index a569581e80..903f39d17d 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-core.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-core.yml
@@ -117,8 +117,8 @@ stages:
verbosity: diagnostic
# Build MDS and its NuGet packages.
- - stage: build_nugets
- displayName: 'Build NuGet Packages'
+ - stage: build_mds_package
+ displayName: 'Build MDS Package'
# When building MDS via packages, we must depend on the Abstractions
# package.
@@ -157,17 +157,12 @@ stages:
testsTimeout: ${{ parameters.testsTimeout }}
abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
- # When testing MDS via packages, we must depend on the Abstractions _and_
+ # When testing MDS via packages, we must depend on the Abstractions and
# MDS packages.
${{ if eq(parameters.buildType, 'Package') }}:
dependsOn:
- build_abstractions_package_stage
- build_nugets
- # When testing MDS via projects, we only depend on the Abstrations
- # package.
- ${{ else }}:
- dependsOn:
- - build_abstractions_package_stage
${{if ne(parameters.SNIVersion, '')}}:
prebuildSteps: # steps to run prior to building and running tests on each job
diff --git a/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml b/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
new file mode 100644
index 0000000000..d7a6807474
--- /dev/null
+++ b/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
@@ -0,0 +1,143 @@
+################################################################################
+# 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 job packs the Abstractions package into NuGet and symbols packages and
+# publishes them as a named pipeline artifact.
+#
+# This template defines a job named 'pack_abstractions_package_job' that can be
+# depended on by downstream jobs.
+
+parameters:
+
+ # The name to apply to the published pipeline artifact.
+ - name: artifactName
+ type: string
+ default: Abstractions.Artifact
+
+ # The type of build to test (Release or Debug)
+ - name: buildConfiguration
+ type: string
+ values:
+ - Release
+ - Debug
+
+ # The list of upstream jobs to depend on.
+ - name: dependsOn
+ type: object
+ default: []
+
+ # The verbosity level for the dotnet CLI commands.
+ - name: verbosity
+ type: string
+ default: normal
+ values:
+ - quiet
+ - minimal
+ - normal
+ - detailed
+ - diagnostic
+
+jobs:
+
+ - job: pack_abstractions_package_job
+ displayName: 'Pack Abstractions Package'
+
+ dependsOn: ${{ parameters.dependsOn }}
+
+ pool:
+ name: Azure Pipelines
+ vmImage: ubuntu-latest
+
+ variables:
+
+ # The Abstractions solution file to use for all dotnet CLI commands.
+ - name: solution
+ value: src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
+
+ # The directory where the NuGet packages will be staged before being
+ # published as pipeline artifacts.
+ - name: dotnetPackagesDir
+ value: $(Build.StagingDirectory)/dotnetPackages
+
+ # dotnet CLI arguments common to all commands.
+ - name: commonArguments
+ value: >-
+ --verbosity ${{ parameters.verbosity }}
+
+ # dotnet CLI arguments for build/test/pack commands
+ - name: buildArguments
+ value: >-
+ $(commonArguments)
+ --configuration ${{ parameters.buildConfiguration }}
+
+ # 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 stress tests solution 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: ''
+
+ steps:
+
+ # Install the .NET 9.0 SDK.
+ - task: UseDotNet@2
+ displayName: Install .NET 9.0 SDK
+ inputs:
+ packageType: sdk
+ version: 9.x
+
+ # We use the 'custom' command because the DotNetCoreCLI@2 task doesn't
+ # support all of our argument combinations for the different build steps.
+
+ # Restore the solution.
+ - task: DotNetCoreCLI@2
+ displayName: Restore Solution
+ inputs:
+ command: custom
+ custom: restore
+ projects: $(solution)
+ arguments: $(commonArguments)
+
+ # Build the solution.
+ - task: DotNetCoreCLI@2
+ displayName: Build Solution
+ inputs:
+ command: custom
+ custom: build
+ projects: $(solution)
+ arguments: $(buildArguments) --no-restore
+
+ # Create the NuGet packages.
+ - task: DotNetCoreCLI@2
+ displayName: Create NuGet Package
+ inputs:
+ command: custom
+ custom: pack
+ projects: $(solution)
+ arguments: $(buildArguments) --no-build -o $(dotnetPackagesDir)
+
+ # Publish the NuGet packages as a named pipeline artifact.
+ - task: PublishPipelineArtifact@1
+ displayName: Publish Pipeline Artifact
+ inputs:
+ targetPath: $(dotnetPackagesDir)
+ artifactName: ${{ parameters.artifactName }}
+ publishLocation: pipeline
diff --git a/eng/pipelines/jobs/stress-tests-ci-job.yml b/eng/pipelines/jobs/stress-tests-ci-job.yml
index 2e01470fe5..cc2913c367 100644
--- a/eng/pipelines/jobs/stress-tests-ci-job.yml
+++ b/eng/pipelines/jobs/stress-tests-ci-job.yml
@@ -4,7 +4,7 @@
# file in the project root for more information.
################################################################################
-# This stage builds and runs stress tests against an MDS NuGet package available
+# This job builds and runs stress tests against an MDS NuGet package available
# as a pipeline artifact.
#
# The stress tests are located here:
diff --git a/eng/pipelines/jobs/test-abstractions-package-ci-job.yml b/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
new file mode 100644
index 0000000000..a2b25966d4
--- /dev/null
+++ b/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
@@ -0,0 +1,174 @@
+################################################################################
+# 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 job builds the Abstractions package and runs its tests for a set of .NET
+# runtimes.
+#
+# This template defines a job named 'test_abstractions_package_job_'
+# that can be depended on by downstream jobs.
+
+parameters:
+
+ # The type of build to test (Release or Debug)
+ - name: buildConfiguration
+ type: string
+ values:
+ - Release
+ - Debug
+
+ # The prefix to prepend to the job's display name:
+ #
+ # [] Run Stress Tests
+ #
+ - name: displayNamePrefix
+ type: string
+
+ # The suffix to append to the job name.
+ - name: jobNameSuffix
+ type: string
+
+ # The list of .NET Framework runtimes to test against.
+ - name: netFrameworkRuntimes
+ type: object
+ default: []
+
+ # The list of .NET runtimes to test against.
+ - name: netRuntimes
+ type: object
+ default: []
+
+ # The name of the Azure Pipelines pool to use.
+ - name: poolName
+ type: string
+
+ # The verbosity level for the dotnet CLI commands.
+ - name: verbosity
+ type: string
+ default: normal
+ values:
+ - quiet
+ - minimal
+ - normal
+ - detailed
+ - diagnostic
+
+ # The pool VM image to use.
+ - name: vmImage
+ type: string
+
+jobs:
+
+ - job: test_abstractions_package_job_${{ parameters.jobNameSuffix }}
+ displayName: '[${{ parameters.displayNamePrefix }}] Test Abstractions Package'
+ pool:
+ name: ${{ parameters.poolName }}
+
+ # Images provided by Azure Pipelines must be selected using 'vmImage'.
+ ${{ if eq(parameters.poolName, 'Azure Pipelines') }}:
+ vmImage: ${{ parameters.vmImage }}
+ # Images provided by 1ES must be selected using a demand.
+ ${{ else }}:
+ demands:
+ - imageOverride -equals ${{ parameters.vmImage }}
+
+ variables:
+
+ # The Abstractions solution file to use for all dotnet CLI commands.
+ - name: solution
+ value: src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
+
+ # dotnet CLI arguments common to all commands.
+ - name: commonArguments
+ value: >-
+ --verbosity ${{ parameters.verbosity }}
+
+ # dotnet CLI arguments for build/test/pack commands
+ - name: buildArguments
+ value: >-
+ $(commonArguments)
+ --configuration ${{ parameters.buildConfiguration }}
+
+ # 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 stress tests solution 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: ''
+
+ steps:
+
+ # Install the .NET 9.0 SDK.
+ - task: UseDotNet@2
+ displayName: Install .NET 9.0 SDK
+ inputs:
+ packageType: sdk
+ version: 9.x
+
+ # Install the .NET 8.0 runtime.
+ - task: UseDotNet@2
+ displayName: Install .NET 8.0 Runtime
+ inputs:
+ packageType: runtime
+ version: 8.x
+
+ # The Windows agent images include a suitable .NET Framework runtime, so
+ # we don't have to install one explicitly.
+
+ # We use the 'custom' command because the DotNetCoreCLI@2 task doesn't
+ # support all of our argument combinations for the different build steps.
+
+ # Restore the solution.
+ - task: DotNetCoreCLI@2
+ displayName: Restore Solution
+ inputs:
+ command: custom
+ custom: restore
+ projects: $(solution)
+ arguments: $(commonArguments)
+
+ # Build the solution.
+ - task: DotNetCoreCLI@2
+ displayName: Build Solution
+ inputs:
+ command: custom
+ custom: build
+ projects: $(solution)
+ arguments: $(buildArguments) --no-restore
+
+ # Run the tests for each .NET runtime.
+ - ${{ each runtime in parameters.netRuntimes }}:
+ - task: DotNetCoreCLI@2
+ displayName: Test [${{ runtime }}]
+ inputs:
+ command: custom
+ custom: test
+ projects: $(solution)
+ arguments: $(buildArguments) --no-build -f ${{ runtime }}
+
+ # Run the tests for each .NET Framework runtime.
+ - ${{ each runtime in parameters.netFrameworkRuntimes }}:
+ - task: DotNetCoreCLI@2
+ displayName: Test [${{ runtime }}]
+ inputs:
+ command: custom
+ custom: test
+ projects: $(solution)
+ arguments: $(buildArguments) --no-build -f ${{ runtime }}
diff --git a/eng/pipelines/stages/build-abstractions-package-ci-stage.yml b/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
index 5517850296..8e71ffad66 100644
--- a/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
+++ b/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
@@ -30,13 +30,11 @@ parameters:
# The name of the pipeline artifact to publish.
- name: artifactName
- displayName: Pipeline Artifact Name
type: string
default: Abstractions.Artifact
# The type of build to produce (Release or Debug)
- name: buildConfiguration
- displayName: Build Configuration
type: string
default: Release
values:
@@ -45,31 +43,16 @@ parameters:
# The build number of the pipeline.
- name: buildNumber
- displayName: Build Number
type: string
default: $(Build.BuildNumber)
- # 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 list of .NET runtimes to test against.
- - name: netTestRuntimes
- displayName: .NET Test Runtimes
- type: object
- default: [net8.0, net9.0]
-
# The version (Major.Minor.Patch) to apply to the package.
- name: packageVersion
- displayName: Package Version Override
type: string
default: ''
# The verbosity level for the dotnet CLI commands.
- name: verbosity
- displayName: Dotnet CLI verbosity
type: string
default: normal
values:
@@ -84,272 +67,58 @@ stages:
- stage: build_abstractions_package_stage
displayName: Build Abstractions 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 Abstractions solution file to use for all dotnet CLI commands.
- - name: project
- value: src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.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:AbstractionsPackageVersion=${{ 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 Abstractions 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_abstractions_package_job_linux
- displayName: '[Linux] Build Abstractions Package'
- pool:
- name: Azure Pipelines
+ - template: ../jobs/test-abstractions-package-ci-job.yml@self
+ parameters:
+ jobNameSuffix: linux
+ displayNamePrefix: Linux
+ poolName: 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 }}
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ netRuntimes: [net8.0, net9.0]
+ netFrameworkRuntimes: []
# ------------------------------------------------------------------------
- # Build and test on Windows.
+ # Build and test on Windows
- - job: build_abstractions_package_job_windows
- displayName: '[Win] Build Abstractions Package'
- pool:
- name: Azure Pipelines
- # The Windows images include a suitable .NET Framework runtime, so we
- # don't have to install one explicitly below.
+ - template: ../jobs/test-abstractions-package-ci-job.yml@self
+ parameters:
+ jobNameSuffix: windows
+ displayNamePrefix: Win
+ poolName: Azure Pipelines
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 }}
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ netRuntimes: [net8.0, net9.0]
+ netFrameworkRuntimes: [net462, net47, net471, net472, net48, net481]
# ------------------------------------------------------------------------
- # Build and test on macOS
+ # Build and test on macOS.
- - job: build_abstractions_package_job_macos
- displayName: '[macOS] Build Abstractions Package'
- pool:
- name: Azure Pipelines
+ - template: ../jobs/test-abstractions-package-ci-job.yml
+ parameters:
+ jobNameSuffix: macos
+ displayNamePrefix: macOS
+ poolName: 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 }}
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ netRuntimes: [net8.0, net9.0]
+ netFrameworkRuntimes: []
# ------------------------------------------------------------------------
# Create and publish the NuGet package.
- - job: publish_abstractions_package_job
- displayName: Publish Abstractions Package
- dependsOn:
- # We depend on all of the build jobs to ensure the tests pass before
- # producing the NuGet package.
- - build_abstractions_package_job_linux
- - build_abstractions_package_job_windows
- - build_abstractions_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
+ - template: ../jobs/pack-abstractions-package-ci-job.yml@self
+ parameters:
+ artifactName: ${{ parameters.artifactName }}
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ verbosity: ${{ parameters.verbosity }}
+ dependsOn:
+ # We depend on all of the test jobs to ensure the tests pass before
+ # producing the NuGet package.
+ - test_abstractions_package_job_linux
+ - test_abstractions_package_job_windows
+ - test_abstractions_package_job_macos
From 66cd30990d1603468d8f86678f93fabe7491d3df Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Wed, 17 Sep 2025 15:20:59 -0300
Subject: [PATCH 10/30] User Story 37654: Create Abstractions package
- Cleaned up the project vs package pathways.
---
.../templates/jobs/ci-build-nugets-job.yml | 28 ++--
.../templates/jobs/ci-run-tests-job.yml | 121 ++++++++++--------
.../templates/stages/ci-run-tests-stage.yml | 53 +++++---
.../templates/steps/build-all-tests-step.yml | 49 +++----
.../templates/steps/ci-prebuild-step.yml | 31 +----
.../templates/steps/ci-project-build-step.yml | 3 +-
.../update-nuget-config-local-feed-step.yml | 45 -------
eng/pipelines/dotnet-sqlclient-ci-core.yml | 46 ++++---
...qlclient-ci-package-reference-pipeline.yml | 4 +-
...qlclient-ci-project-reference-pipeline.yml | 4 +-
10 files changed, 163 insertions(+), 221 deletions(-)
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 bd165dac31..fbb21b81e2 100644
--- a/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
@@ -4,6 +4,13 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
+
+ - name: referenceType
+ type: string
+ values:
+ - Project
+ - Package
+
- name: poolName
type: string
default: $(ci_var_defaultPoolName)
@@ -33,12 +40,11 @@ parameters:
default: []
- name: abstractionsPackageVersion
- displayName: Abstractions Package Version Override
type: string
- default: ''
jobs:
-- job: build_nugets
+- job: build_mds_packages_job
+ displayName: Build MDS Packages
pool:
name: ${{parameters.poolName }}
@@ -53,14 +59,14 @@ jobs:
- ${{ if ne(parameters.prebuildSteps, '') }}:
- ${{ parameters.prebuildSteps }} # extra steps to run before the build like downloading sni and the required configuration
- # Download the Abstractions 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 Abstractions Package Artifact
- inputs:
- artifactName: ${{ parameters.abstractionsArtifactName }}
- targetPath: $(Build.SourcesDirectory)/packages
+ # If we're testing in Package mode, download the Abstractions package
+ # artifacts and put them in the packages/ directory in the repo root.
+ - ${{ if eq(parameters.referenceType, 'Package') }}:
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Abstractions Package Artifact
+ inputs:
+ artifactName: ${{ parameters.abstractionsArtifactName }}
+ targetPath: $(Build.SourcesDirectory)/packages
- template: ../steps/ci-project-build-step.yml@self
parameters:
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 20cf0cd33d..20b39095b5 100644
--- a/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
@@ -4,12 +4,37 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
+ - name: abstractionsArtifactName
+ type: string
+
+ - name: abstractionsPackageVersion
+ type: string
+
+ - name: referenceType
+ type: string
+ values:
+ - Project
+ - Package
+
+ - name: configProperties
+ type: object
+ default: {} # - key: 'value'
+
+ - name: configSqlFor
+ type: string # local, azure, or enclave
+ default: local
+
- name: debug
type: boolean
default: false
- - name: poolName
- type: string
+ - name: enableX64Test
+ type: boolean
+ default: true
+
+ - name: enableX86Test
+ type: boolean
+ default: false
- name: hostedPool
type: boolean
@@ -21,68 +46,45 @@ parameters:
- name: jobDisplayName
type: string
- - name: usemanagedSNI
- type: boolean
- default: false
-
- - name: configProperties
- type: object
- default: {} # - key: 'value'
-
- - name: abstractionsPackageVersion
- displayName: Abstractions Package Version Override
+ - name: mdsArtifactName
type: string
- default: ''
-
- - name: prebuildSteps
- type: stepList
- default: []
- - name: abstractionsArtifactName
+ - name: mdsPackageVersion
type: string
- default: Abstractions.Artifact
- - name: targetFramework
+ - name: netcoreVersionTestUtils
type: string
+
+ - name: operatingSystem
+ type: string
+ default: ''
- - name: netcoreVersionTestUtils
+ - name: poolName
type: string
- - name: enableX86Test
+ - name: prebuildSteps
+ type: stepList
+ default: []
+
+ - name: publishTestResults
type: boolean
default: false
- - name: enableX64Test
- type: boolean
- default: true
+ - name: targetFramework
+ type: string
- name: testSet
type: string
- - name: publishTestResults
- type: boolean
- default: false
-
- - name: configSqlFor
- type: string # local, azure, or enclave
- default: local
-
- - name: operatingSystem
- type: string
- default: ''
-
- - name: buildType
- displayName: 'Build Type'
- default: Project
- values:
- - Project
- - Package
-
# The timeout, in minutes, for this job.
- name: timeout
type: string
default: 90
+ - name: usemanagedSNI
+ type: boolean
+ default: false
+
jobs:
- job: ${{ format('{0}', coalesce(parameters.jobDisplayName, parameters.image, 'unknown_image')) }}
@@ -104,14 +106,20 @@ jobs:
steps:
- # Download the Abstractions 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 Abstractions Package Artifact
- inputs:
- artifactName: ${{ parameters.abstractionsArtifactName }}
- targetPath: $(Build.SourcesDirectory)/packages
+ # If we're testing in Package mode, download the Abstractions and MDS package
+ # artifacts and put them in the packages/ directory in the repo root.
+ - ${{ if eq(parameters.referenceType, 'Package') }}:
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Abstractions Package Artifact
+ inputs:
+ artifactName: ${{ parameters.abstractionsArtifactName }}
+ targetPath: $(Build.SourcesDirectory)/packages
+
+ - task: DownloadPipelineArtifact@2
+ displayName: Download MDS Package Artifact
+ inputs:
+ artifactName: ${{ parameters.mdsArtifactName }}
+ targetPath: $(Build.SourcesDirectory)/packages
- ${{ if ne(parameters.prebuildSteps, '') }}:
- ${{ parameters.prebuildSteps }} # extra steps to run before the build like downloading sni and the required configuration
@@ -242,9 +250,10 @@ jobs:
- template: ../steps/build-all-tests-step.yml@self # build tests
parameters:
targetFramework: ${{ parameters.targetFramework }}
- referenceType: ${{ parameters.buildType }}
+ referenceType: ${{ parameters.referenceType }}
testSet: ${{ parameters.testSet }}
abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
+ mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
${{ if ne(parameters.operatingSystem, 'Windows') }}:
OSGroup: Unix
@@ -253,7 +262,7 @@ jobs:
parameters:
debug: ${{ parameters.debug }}
targetFramework: ${{ parameters.targetFramework }}
- referenceType: ${{ parameters.buildType }}
+ referenceType: ${{ parameters.referenceType }}
testSet: ${{ parameters.testSet }}
operatingSystem: ${{ parameters.operatingSystem }}
@@ -295,13 +304,13 @@ jobs:
parameters:
debug: ${{ parameters.debug }}
targetFramework: ${{ parameters.targetFramework }}
- referenceType: ${{ parameters.buildType }}
+ referenceType: ${{ parameters.referenceType }}
testSet: ${{ parameters.testSet }}
msbuildArchitecture: x86
dotnetx86RootPath: $(dotnetx86RootPath)
operatingSystem: ${{ parameters.operatingSystem }}
- - ${{ if and(eq(parameters.publishTestResults, true), eq(parameters.buildType, 'Project')) }}: # publish test results if build type is project
+ - ${{ if and(eq(parameters.publishTestResults, true), eq(parameters.referenceType, 'Project')) }}: # publish test results if build type is project
- template: ../steps/publish-test-results-step.yml@self
parameters:
debug: ${{ parameters.debug }}
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 da73ca4eb2..994bb4f345 100644
--- a/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
+++ b/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
@@ -4,37 +4,44 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
+ - name: abstractionsArtifactName
+ type: string
+
+ - name: abstractionsPackageVersion
+ type: string
+
+ - name: referenceType
+ default: Project
+ values:
+ - Project
+ - Package
+
- name: debug
type: boolean
default: false
- - name: testConfigurations
- type: object
-
- name: dependsOn
type: object
default: []
- - name: buildType
- displayName: 'Build Type'
- default: Project
- values:
- - Project
- - Package
-
- - name: abstractionsPackageVersion
- displayName: Abstractions Package Version Override
+ - name: mdsArtifactName
type: string
- default: ''
+ default: MDS.Artifact
- - name: prebuildSteps
- type: stepList
- default: []
+ - name: mdsPackageVersion
+ type: string
- name: postTestJobs
type: jobList
default: []
+ - name: prebuildSteps
+ type: stepList
+ default: []
+
+ - name: testConfigurations
+ type: object
+
# The timeout, in minutes, for each test job.
- name: testsTimeout
type: string
@@ -53,14 +60,17 @@ stages:
- template: ../jobs/ci-run-tests-job.yml@self
parameters:
debug: ${{ parameters.debug }}
- buildType: ${{ parameters.buildType }}
+ referenceType: ${{ parameters.referenceType }}
timeout: ${{ parameters.testsTimeout }}
poolName: ${{ config.value.pool }}
hostedPool: ${{ eq(config.value.hostedPool, true) }}
image: ${{ image.value }}
jobDisplayName: ${{ format('{0}_{1}_{2}', replace(targetFramework, '.', '_'), platform, testSet) }}
configProperties: ${{ config.value.configProperties }}
- abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
+ abstractionsArtifactName: ${{ parameters.abstractionsArtifactName }}
+ abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
+ mdsArtifactName: ${{ parameters.mdsArtifactName }}
+ mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
prebuildSteps: ${{ parameters.prebuildSteps }}
targetFramework: ${{ targetFramework }}
netcoreVersionTestUtils: ${{config.value.netcoreVersionTestUtils }}
@@ -80,7 +90,7 @@ stages:
- template: ../jobs/ci-run-tests-job.yml@self
parameters:
debug: ${{ parameters.debug }}
- buildType: ${{ parameters.buildType }}
+ referenceType: ${{ parameters.referenceType }}
timeout: ${{ parameters.testsTimeout }}
poolName: ${{ config.value.pool }}
hostedPool: ${{ eq(config.value.hostedPool, true) }}
@@ -91,7 +101,10 @@ stages:
jobDisplayName: ${{ format('{0}_{1}_{2}_{3}', replace(targetFramework, '.', '_'), platform, 'NativeSNI', testSet) }}
configProperties: ${{ config.value.configProperties }}
useManagedSNI: ${{ useManagedSNI }}
- abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
+ abstractionsArtifactName: ${{ parameters.abstractionsArtifactName }}
+ abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
+ mdsArtifactName: ${{ parameters.mdsArtifactName }}
+ mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
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 a953d832d5..2742376c1f 100644
--- a/eng/pipelines/common/templates/steps/build-all-tests-step.yml
+++ b/eng/pipelines/common/templates/steps/build-all-tests-step.yml
@@ -4,38 +4,35 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
- - name: targetFramework
+ - name: abstractionsPackageVersion
type: string
+
+ - name: configuration
+ type: string
+ default: '$(Configuration)'
- - name: nugetPackageVersion
+ - name: mdsPackageVersion
type: string
- default: $(NugetPackageVersion)
+
+ - name: osGroup
+ type: string
+ default: ''
- name: platform
type: string
default: $(Platform)
-
- - name: configuration
- type: string
- default: '$(Configuration)'
- name: referenceType
- default: Package
+ type: string
values:
- Project
- Package
-
- - name: OSGroup
- type: string
- default: ''
- - name: testSet
+ - name: targetFramework
type: string
-
- - name: abstractionsPackageVersion
- displayName: Abstractions Package Version Override
+
+ - name: testSet
type: string
- default: ''
steps:
- ${{ if contains(parameters.targetFramework, 'net4') }}: # .NET Framework
@@ -45,26 +42,16 @@ 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 }} -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}.$(Build.BuildNumber)'
-
-# - ${{else if contains(parameters.targetFramework, 'netstandard')}}: # .NET Standard
-# - task: MSBuild@1
-# displayName: 'Build Tests NetStandard'
-# inputs:
-# solution: build.proj
-# platform: '${{parameters.platform }}'
-# configuration: '${{parameters.configuration }}'
-# msbuildArguments: '-t:BuildTestsNetCore -p:ReferenceType=NetStandard -p:TargetNetStandardVersion=${{parameters.targetNetStandardVersion }} -p:TF=${{parameters.targetFramework }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }}'
-# condition: and(succeeded(), not(startsWith(variables['TF'], 'net4')), startsWith(variables['TargetNetStandardVersion'], 'netstandard'))
+ msbuildArguments: '-t:BuildTestsNetFx -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}.$(Build.BuildNumber)'
-- ${{elseif eq(parameters.OSGroup, '')}}: # .NET on Windows
+- ${{elseif eq(parameters.osGroup, '')}}: # .NET on Windows
- task: MSBuild@1
displayName: 'Build Tests NetCore [Win]'
inputs:
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 }} -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}.$(Build.BuildNumber)'
+ msbuildArguments: '-t:BuildTestsNetCore -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}.$(Build.BuildNumber)'
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
- ${{ else }}: # .NET on Unix
@@ -74,7 +61,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 }} -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}.$(Build.BuildNumber)'
+ arguments: '-t:BuildTestsNetCore -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} -p:OSGroup=${{parameters.osGroup }} -p:platform=${{parameters.platform }} -p:Configuration=${{parameters.configuration }} -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}.$(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 48cab965ea..4eedd5dfd4 100644
--- a/eng/pipelines/common/templates/steps/ci-prebuild-step.yml
+++ b/eng/pipelines/common/templates/steps/ci-prebuild-step.yml
@@ -8,22 +8,12 @@ parameters:
type: boolean
default: false
- - name: artifactName
+ - name: referenceType
type: string
- default: Artifacts
-
- - name: buildType
- displayName: 'Build Type'
- default: Project
values:
- Project
- Package
- - name: abstractionsPackageVersion
- displayName: Abstractions Package Version Override
- type: string
- default: ''
-
steps:
- template: ensure-dotnet-version.yml
parameters:
@@ -42,23 +32,8 @@ steps:
Get-ChildItem env: | Sort-Object Name
displayName: 'List Environment Variables [debug]'
-- ${{if eq(parameters.buildType, 'Package')}}:
- - task: DownloadPipelineArtifact@2
- displayName: 'Download NuGet Package'
- inputs:
- buildType: current
- artifact: ${{parameters.artifactName }}
- patterns: '**/*.nupkg'
- targetPath: $(Pipeline.Workspace)/${{parameters.artifactName }}
-
+- ${{if eq(parameters.referenceType, 'Package')}}:
- template: update-nuget-config-local-feed-step.yml@self
parameters:
- downloadedNugetPath: $(Pipeline.Workspace)\${{parameters.artifactName }}
+ downloadedNugetPath: $(Build.SourcesDirectory)/packages
debug: ${{ parameters.debug }}
- abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
-
-- ${{ else }}: # project
- - template: ci-project-build-step.yml@self
- parameters:
- build: allNoDocs
- abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
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 1edcdb1b51..fa6779616e 100644
--- a/eng/pipelines/common/templates/steps/ci-project-build-step.yml
+++ b/eng/pipelines/common/templates/steps/ci-project-build-step.yml
@@ -35,9 +35,8 @@ parameters:
- allNoDocs
- name: abstractionsPackageVersion
- displayName: Abstractions Package Version Override
+ displayName: Abstractions Package Version
type: string
- default: ''
steps:
- template: ./ensure-dotnet-version.yml@self
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 6753a14b48..f7bf252ebe 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,15 +11,6 @@ parameters:
- name: downloadedNugetPath # path to the downloaded nuget files
type: string
- - name: abstractionsPackageVersion
- displayName: Abstractions Package Version Override
- type: string
- default: ''
-
- - name: nugetPackageVersion
- type: string
- default: $(NugetPackageVersion)
-
steps:
- powershell: |
# Get a list of package sources available
@@ -50,39 +41,3 @@ steps:
# Display the content of the NuGet.config file
Get-Content -Path "NuGet.config"
displayName: 'Read NuGet.config [debug]'
-
-- task: DotNetCoreCLI@2
- displayName: 'Restore NuGets'
- inputs:
- command: 'custom'
- custom: 'msbuild'
- arguments: 'build.proj -t:restore -p:AbstractionsPackageVersion=${{parameters.abstractionsPackageVersion}}.$(buildNumber)'
- feedsToUse: 'select'
-
-- powershell: |
- $Doc = [xml](Get-Content "./Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj")
- $parent_xpath = '/Project/ItemGroup/ProjectReference'
- $node = $Doc.SelectSingleNode($parent_xpath)
- $parentNode = $node.ParentNode
- while($node -ne $null) {
- $node.ParentNode.RemoveChild($node)
- $node = $Doc.SelectSingleNode($parent_xpath)
- }
-
- $parent_xpath = '/Project/ItemGroup/PackageReference[@Include="Microsoft.Data.SqlClient"]'
- $node = $Doc.SelectSingleNode($parent_xpath)
-
- if($node -eq $null){
- $packagerefnode = $doc.createelement("packagereference")
- $value = $doc.selectsinglenode('/project/itemgroup/projectreference')
- $attrinclude = $doc.createattribute("include")
- $attrinclude.value = "microsoft.data.sqlclient"
- $packagerefnode.attributes.append($attrinclude)
- $parentNode.AppendChild($packageRefNode)
- }
-
- $currentFolder = Get-Location
- $filePath = Join-Path $currentFolder "Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj"
- $Doc.Save($filePath)
- workingDirectory: 'src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider'
- displayName: 'Update AKV Project Ref to Package Ref (.NET Framework/Core)'
diff --git a/eng/pipelines/dotnet-sqlclient-ci-core.yml b/eng/pipelines/dotnet-sqlclient-ci-core.yml
index 903f39d17d..0a54fc894e 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-core.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-core.yml
@@ -63,9 +63,12 @@ parameters:
type: object
default: [net462, net8.0]
-- name: buildType
- displayName: 'Build Type'
- default: Project
+# The way we will reference sibling projects in the .csproj files:
+# Project - use references.
+# Package - use references to NuGet packages in the
+# packages/ directory.
+- name: referenceType
+ displayName: 'Reference Type'
values:
- Project
- Package
@@ -122,13 +125,14 @@ stages:
# When building MDS via packages, we must depend on the Abstractions
# package.
- ${{ if eq(parameters.buildType, 'Package') }}:
+ ${{ if eq(parameters.referenceType, 'Package') }}:
dependsOn:
- build_abstractions_package_stage
jobs:
- template: common/templates/jobs/ci-build-nugets-job.yml@self
parameters:
+ referenceType: ${{ parameters.referenceType }}
configuration: ${{ parameters.buildConfiguration }}
abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
abstractionsArtifactName: $(abstractionsArtifactName)
@@ -144,7 +148,7 @@ stages:
- template: stages/stress-tests-ci-stage.yml@self
parameters:
buildConfiguration: ${{ parameters.buildConfiguration }}
- dependsOn: [build_nugets]
+ dependsOn: [build_mds_packages_job]
pipelineArtifactName: $(artifactName)
mdsPackageVersion: $(NugetPackageVersion)
${{ if eq(parameters.debug, 'true') }}:
@@ -153,39 +157,33 @@ stages:
- template: common/templates/stages/ci-run-tests-stage.yml@self
parameters:
debug: ${{ parameters.debug }}
- buildType: ${{ parameters.buildType }}
+ referenceType: ${{ parameters.referenceType }}
testsTimeout: ${{ parameters.testsTimeout }}
+ abstractionsArtifactName: $(abstractionsArtifactName)
abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
+ mdsArtifactName: $(mdsArtifactName)
+ mdsPackageVersion: $(NugetPackageVersion)
# When testing MDS via packages, we must depend on the Abstractions and
# MDS packages.
- ${{ if eq(parameters.buildType, 'Package') }}:
+ ${{ if eq(parameters.referenceType, 'Package') }}:
dependsOn:
- build_abstractions_package_stage
- build_nugets
- ${{if ne(parameters.SNIVersion, '')}}:
- prebuildSteps: # steps to run prior to building and running tests on each job
+ prebuildSteps: # steps to run prior to building and running tests on each job
+ - ${{if ne(parameters.SNIVersion, '')}}:
- template: common/templates/steps/override-sni-version.yml@self
parameters:
SNIVersion: ${{parameters.SNIVersion}}
SNIValidationFeed: ${{parameters.SNIValidationFeed}}
- - template: common/templates/steps/ci-prebuild-step.yml@self
- parameters:
- debug: ${{ parameters.debug }}
- artifactName: $(mdsArtifactName)
- buildType: ${{ parameters.buildType }}
- abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
- ${{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: $(mdsArtifactName)
- buildType: ${{ parameters.buildType }}
- abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
- ${{ if eq(parameters.buildType, 'Project') }}: # only run the code coverage job if the build type is project
+ - template: common/templates/steps/ci-prebuild-step.yml@self
+ parameters:
+ debug: ${{ parameters.debug }}
+ referenceType: ${{ parameters.referenceType }}
+
+ ${{ if eq(parameters.referenceType, 'Project') }}: # only run the code coverage job if the build type is project
postTestJobs: # jobs to run after the tests are done
- template: common/templates/jobs/ci-code-coverage-job.yml@self
parameters:
diff --git a/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml b/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml
index e6da796d05..1ca58a910d 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml
@@ -63,7 +63,7 @@ parameters: # parameters are shown up in ADO UI in a build queue time
default: [1, 2, 3]
- name: abstractionsPackageVersion
- displayName: Abstractions Package Version Override
+ displayName: Abstractions Package Version
type: string
default: 1.0.0
@@ -108,7 +108,7 @@ extends:
abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
useManagedSNI: ${{ parameters.useManagedSNI }}
codeCovTargetFrameworks: ${{ parameters.codeCovTargetFrameworks }}
- buildType: Package
+ referenceType: Package
buildConfiguration: ${{ parameters.buildConfiguration }}
enableStressTests: ${{ parameters.enableStressTests }}
testsTimeout: ${{ parameters.testsTimeout }}
diff --git a/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml b/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
index ba17cf1fa5..1217339c97 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
@@ -55,7 +55,7 @@ parameters: # parameters are shown up in ADO UI in a build queue time
default: [1, 2, 3]
- name: abstractionsPackageVersion
- displayName: Abstractions Package Version Override
+ displayName: Abstractions Package Version
type: string
default: 1.0.0
@@ -100,7 +100,7 @@ extends:
abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
useManagedSNI: ${{ parameters.useManagedSNI }}
codeCovTargetFrameworks: ${{ parameters.codeCovTargetFrameworks }}
- buildType: Project
+ referenceType: Project
buildConfiguration: ${{ parameters.buildConfiguration }}
enableStressTests: ${{ parameters.enableStressTests }}
testsTimeout: ${{ parameters.testsTimeout }}
From e472245d0d6c6f9e2fb27bf8615d57f5dbb0d731 Mon Sep 17 00:00:00 2001
From: Benjamin Russell
Date: Wed, 17 Sep 2025 18:07:36 -0500
Subject: [PATCH 11/30] Merge | SqlCommand Public Properties (#3611)
* Merge:
* _parameters
* _pendingCancel
* _preparedConnectionCloseCount
* _preparedConnectionReconnectCount
* _prepareHandle
* s_cachedInvalidPrepareHandle
* Statistics
* Merge Connection, DbConnection
* Merging RetryLogicProvider and _retryLogicProvider
# Conflicts:
# src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.cs
* Merge Transaction, DbTransaction
* Merge CommandText
* Replace "" with string.Empty
* Merge CommandTimeout, _commandTimeout, and ADP.InvalidCommandTimeout
* Merge CommandType
* Removed temp storage of _commandType
* Merge ColumnEncryptionSetting, _columnEncryptionSetting
* Merge Parameters and DbParameterCollection
* Merging DesignTimeVisible, _designTimeVisible
* Merging EnableOptimizedParameterBinding, UpdatedRowSource, _updatedRowSource
* Merge StatementCompleted and _statementCompletedEventHandler
* Merging Notification, NotificationAutoEnlist, _notification, _notificationAutoEnlist, _sqlDep
* Merge DefaultCommandTimeout, InternalTdsConnection, IsColumnEncryptionEnabled, InternalRecordsAffected, _rowsAffected, PropertyChanging()
* merge _transaction and _batchRPCMode
* Restore ResetCommandTimeout that got accidentally obliterated in a previous commit
* Fix logic issue in IsColumnEncryptionEnabled, reinstate TypeDescriptor.Refresh on netfx
---
.../Data/SqlClient/SqlCommand.netcore.cs | 447 +--------------
.../Data/SqlClient/SqlCommand.netfx.cs | 465 +--------------
.../src/Microsoft/Data/Common/AdapterUtil.cs | 17 +-
.../Microsoft/Data/SqlClient/SqlCommand.cs | 541 +++++++++++++++++-
4 files changed, 540 insertions(+), 930 deletions(-)
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.netcore.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.netcore.cs
index d43b71ff32..5fd97e3b13 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.netcore.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.netcore.cs
@@ -107,24 +107,11 @@ protected override void AfterCleared(SqlCommand owner)
}
}
- private int? _commandTimeout;
- private UpdateRowSource _updatedRowSource = UpdateRowSource.Both;
- private bool _designTimeInvisible;
-
///
/// Indicates if the column encryption setting was set at-least once in the batch rpc mode, when using AddBatchCommand.
///
private bool _wasBatchModeColumnEncryptionSettingSetOnce;
- ///
- /// Column Encryption Override. Defaults to SqlConnectionSetting, in which case
- /// it will be Enabled if SqlConnectionOptions.IsColumnEncryptionSettingEnabled = true, Disabled if false.
- /// This may also be used to set other behavior which overrides connection level setting.
- ///
- private SqlCommandColumnEncryptionSetting _columnEncryptionSetting = SqlCommandColumnEncryptionSetting.UseConnectionSetting;
-
- internal SqlDependency _sqlDep;
-
#if DEBUG
///
/// Force the client to sleep during sp_describe_parameter_encryption in the function TryFetchInputParameterEncryptionInfo.
@@ -157,10 +144,6 @@ protected override void AfterCleared(SqlCommand owner)
internal static readonly Action
+
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs
new file mode 100644
index 0000000000..246d9a73f0
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs
@@ -0,0 +1,62 @@
+// 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.
+
+using System;
+using System.IO;
+using Microsoft.Data.SqlClient.Server;
+using Microsoft.Data.SqlClient.UnitTests.UdtSerialization.SerializedTypes;
+using Microsoft.SqlServer.Server;
+using Xunit;
+
+namespace Microsoft.Data.SqlClient.UnitTests.UdtSerialization;
+
+///
+/// Attempts to serialize types which do not meet the requirements for either user-defined or native serialization.
+///
+public sealed class InvalidSerializationTest : IDisposable
+{
+ private readonly MemoryStream _stream;
+
+ ///
+ /// Initializes the MemoryStream used for all tests in this class.
+ ///
+ public InvalidSerializationTest()
+ {
+ _stream = new MemoryStream();
+ }
+
+ void IDisposable.Dispose()
+ {
+ _stream.Dispose();
+ }
+
+ ///
+ /// Attempts to serialize a class that does not have the SqlUserDefinedType attribute. Verifies that this fails.
+ ///
+ [Fact]
+ public void Serialize_MissingSqlUserDefinedTypeAttribute_Throws()
+ {
+ Action serialize = () => SerializationHelperSql9.Serialize(_stream, new ClassMissingSqlUserDefinedTypeAttribute());
+ var exception = Assert.Throws(serialize);
+
+ Assert.Equal($"'{typeof(ClassMissingSqlUserDefinedTypeAttribute).FullName}' is an invalid user defined type, reason: no UDT attribute.", exception.Message);
+ }
+
+ ///
+ /// Attempts to serialize a class that has a SqlUserDefinedType attribute, but specifies a Format enumeration value of
+ /// Unknown. Verifies that this fails.
+ ///
+ [Fact]
+ public void Serialize_UnknownFormattedType_Throws()
+ {
+ Action serialize = () => SerializationHelperSql9.Serialize(_stream, new UnknownFormattedClass());
+ var exception = Assert.Throws("Format", serialize);
+
+#if NET
+ Assert.Equal("The Format enumeration value, 0, is not supported by the format method. (Parameter 'Format')", exception.Message);
+#else
+ Assert.Equal("The Format enumeration value, Unknown, is not supported by the format method.\r\nParameter name: Format", exception.Message);
+#endif
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
new file mode 100644
index 0000000000..3369a66985
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
@@ -0,0 +1,491 @@
+// 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.
+
+using Microsoft.Data.SqlClient.Server;
+using Microsoft.Data.SqlClient.UnitTests.UdtSerialization.SerializedTypes;
+using System;
+using System.Collections.Generic;
+using System.Data.SqlTypes;
+using System.IO;
+using Xunit;
+
+namespace Microsoft.Data.SqlClient.UnitTests.UdtSerialization;
+
+///
+/// Tests the serialization method defined by MS-SSCLRT. Ensures that combinations of primitives and custom types round-trip.
+///
+///
+public sealed class NativeSerializationTest : IDisposable
+{
+ private readonly MemoryStream _stream;
+
+ ///
+ /// Initializes the MemoryStream used for all tests in this class.
+ ///
+ public NativeSerializationTest()
+ {
+ _stream = new MemoryStream();
+ }
+
+ void IDisposable.Dispose()
+ {
+ _stream.Dispose();
+ }
+
+ ///
+ /// Provides a collection of test data representing non-null primitive type values and their corresponding
+ /// serialized byte arrays.
+ ///
+ ///
+ public static TheoryData SerializedNonNullPrimitiveTypeValues() =>
+ new()
+ {
+ {
+ new BoolWrapperStruct { Field1 = true },
+ new byte[] { 0x01 }
+ },
+ {
+ new ByteWrapperStruct { Field1 = 0x20 },
+ new byte[] { 0x20 }
+ },
+ {
+ new SByteWrapperStruct { Field1 = -0x1 },
+ new byte[] { 0x7F }
+ },
+ {
+ new UShortWrapperStruct { Field1 = 0x8000 },
+ new byte[] { 0x80, 0x00 }
+ },
+ {
+ new ShortWrapperStruct { Field1 = 0x1234 },
+ new byte[] { 0x92, 0x34 }
+ },
+ {
+ new UIntWrapperStruct { Field1 = 0xFFFFFFFF },
+ new byte[] { 0xFF, 0xFF, 0xFF, 0xFF }
+ },
+ {
+ new IntWrapperStruct { Field1 = -0x12345678 },
+ new byte[] { 0x6D, 0xCB, 0xA9, 0x88 }
+ },
+ {
+ new ULongWrapperStruct { Field1 = ulong.MaxValue },
+ new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+ },
+ {
+ new LongWrapperStruct { Field1 = long.MinValue },
+ new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+ },
+ {
+ new FloatWrapperStruct { Field1 = -0 },
+ new byte[] { 0x80, 0x00, 0x00, 0x00 }
+ },
+ {
+ new DoubleWrapperStruct { Field1 = Math.PI },
+ new byte[] { 0xC0, 0x09, 0x21, 0xFB, 0x54, 0x44, 0x2D, 0x18 }
+ },
+ {
+ new SqlByteWrapperStruct { Field1 = 0x20 },
+ new byte[] { 0x01, 0x20 }
+ },
+ {
+ new SqlInt16WrapperStruct { Field1 = 0x1234 },
+ new byte[] { 0x01, 0x92, 0x34 }
+ },
+ {
+ new SqlInt32WrapperStruct { Field1 = -0x12345678 },
+ new byte[] { 0x01, 0x6D, 0xCB, 0xA9, 0x88 }
+ },
+ {
+ new SqlInt64WrapperStruct { Field1 = long.MinValue },
+ new byte[] { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+ },
+ {
+ new SqlBooleanWrapperStruct { Field1 = false },
+ new byte[] { 0x01 }
+ },
+ {
+ new SqlSingleWrapperStruct { Field1 = -1 },
+ new byte[] { 0x01, 0x40, 0x7F, 0xFF, 0xFF }
+ },
+ {
+ new SqlDoubleWrapperStruct { Field1 = -Math.PI },
+ new byte[] { 0x01, 0x3F, 0xF6, 0xDE, 0x04, 0xAB, 0xBB, 0xD2, 0xE7 }
+ },
+ {
+ new SqlDateTimeWrapperStruct { Field1 = new DateTime(2000, 1, 1, 12, 34, 56, 500) },
+ new byte[] { 0x01, 0x80, 0x00, 0x8E, 0xAC, 0x80, 0xCF, 0x59, 0xD6 }
+ },
+ {
+ new SqlMoneyWrapperStruct { Field1 = 1.10m },
+ new byte[] { 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xF8 }
+ }
+ };
+
+ ///
+ /// Provides a collection of test data representing serialized values of nested non-null primitive types.
+ ///
+ ///
+ public static TheoryData SerializedNestedNonNullPrimitiveTypeValues() =>
+ new()
+ {
+ {
+ new NestedBoolWrapperStruct { Field1 = true, Field2 = new BoolWrapperStruct { Field1 = false } },
+ new byte[]
+ {
+ // Field1
+ 0x01,
+ // Field2
+ 0x00
+ }
+ },
+ {
+ new NestedByteWrapperStruct { Field1 = 0x20, Field2 = new ByteWrapperStruct { Field1 = 0x30 } },
+ new byte[]
+ {
+ // Field1
+ 0x20,
+ // Field2
+ 0x30
+ }
+ },
+ {
+ new NestedSByteWrapperStruct { Field1 = -0x01, Field2 = new SByteWrapperStruct { Field1 = 0x01 } },
+ new byte[]
+ {
+ // Field1
+ 0x7F,
+ // Field2
+ 0x81
+ }
+ },
+ {
+ new NestedUShortWrapperStruct { Field1 = 0x8000, Field2 = new UShortWrapperStruct { Field1 = 0x8014 } },
+ new byte[]
+ {
+ // Field1
+ 0x80, 0x00,
+ // Field2.Field1
+ 0x80, 0x14
+ }
+ },
+ {
+ new NestedShortWrapperStruct { Field1 = 0x1234, Field2 = new ShortWrapperStruct { Field1 = 0x4321 } },
+ new byte[]
+ {
+ // Field1
+ 0x92, 0x34,
+ // Field2.Field1
+ 0xC3, 0x21
+ }
+ },
+ {
+ new NestedUIntWrapperStruct { Field1 = 0xFFFFFFFF, Field2 = new UIntWrapperStruct { Field1 = 0x00000000 } },
+ new byte[]
+ {
+ // Field1
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ // Field2.Field1
+ 0x00, 0x00, 0x00, 0x00
+ }
+ },
+ {
+ new NestedIntWrapperStruct { Field1 = -0x12345678, Field2 = new IntWrapperStruct { Field1 = 0x12345678 } },
+ new byte[]
+ {
+ /// Field1
+ 0x6D, 0xCB, 0xA9, 0x88,
+ // Field2.Field1
+ 0x92, 0x34, 0x56, 0x78
+ }
+ },
+ {
+ new NestedULongWrapperStruct { Field1 = ulong.MaxValue, Field2 = new ULongWrapperStruct { Field1 = long.MaxValue } },
+ new byte[]
+ {
+ // Field1
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ // Field2.Field1
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+ }
+ },
+ {
+ new NestedLongWrapperStruct { Field1 = long.MinValue, Field2 = new LongWrapperStruct { Field1 = long.MaxValue } },
+ new byte[]
+ {
+ // Field1
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Field2.Field1
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+ }
+ },
+ {
+ new NestedFloatWrapperStruct { Field1 = -0, Field2 = new FloatWrapperStruct { Field1 = +0 } },
+ new byte[]
+ {
+ // Field1
+ 0x80, 0x00, 0x00, 0x00,
+ // Field2.Field1
+ 0x80, 0x00, 0x00, 0x00
+ }
+ },
+ {
+ new NestedDoubleWrapperStruct { Field1 = Math.PI, Field2 = new DoubleWrapperStruct { Field1 = Math.PI } },
+ new byte[]
+ {
+ // Field1
+ 0xC0, 0x09, 0x21, 0xFB, 0x54, 0x44, 0x2D, 0x18,
+ // Field2.Field1
+ 0xC0, 0x09, 0x21, 0xFB, 0x54, 0x44, 0x2D, 0x18
+ }
+ },
+ {
+ new NestedSqlByteWrapperStruct { Field1 = 0x20, Field2 = new SqlByteWrapperStruct { Field1 = 0x30 } },
+ new byte[]
+ {
+ // Field1
+ 0x01, 0x20,
+ // Field2.Field1
+ 0x01, 0x30
+ }
+ },
+ {
+ new NestedSqlInt16WrapperStruct { Field1 = 0x1234, Field2 = new SqlInt16WrapperStruct { Field1 = 0x4321 } },
+ new byte[]
+ {
+ // Field1
+ 0x01, 0x92, 0x34,
+ // Field2.Field1
+ 0x01, 0xC3, 0x21
+ }
+ },
+ {
+ new NestedSqlInt32WrapperStruct { Field1 = -0x12345678, Field2 = new SqlInt32WrapperStruct { Field1 = 0x12345678 } },
+ new byte[]
+ {
+ // Field1
+ 0x01, 0x6D, 0xCB, 0xA9, 0x88,
+ // Field2.Field1
+ 0x01, 0x92, 0x34, 0x56, 0x78
+ }
+ },
+ {
+ new NestedSqlInt64WrapperStruct { Field1 = long.MinValue, Field2 = new SqlInt64WrapperStruct { Field1 = long.MaxValue } },
+ new byte[]
+ {
+ // Field1
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // Field2.Field1
+ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+ }
+ },
+ {
+ new NestedSqlBooleanWrapperStruct { Field1 = false, Field2 = new SqlBooleanWrapperStruct { Field1 = true } },
+ new byte[]
+ {
+ // Field1
+ 0x01,
+ // Field2.Field1
+ 0x02
+ }
+ },
+ {
+ new NestedSqlSingleWrapperStruct { Field1 = -0, Field2 = new SqlSingleWrapperStruct { Field1 = +0 } },
+ new byte[]
+ {
+ // Field1
+ 0x01, 0x80, 0x00, 0x00, 0x00,
+ // Field2.Field1
+ 0x01, 0x80, 0x00, 0x00, 0x00
+ }
+ },
+ {
+ new NestedSqlDoubleWrapperStruct { Field1 = Math.PI, Field2 = new SqlDoubleWrapperStruct { Field1 = Math.PI } },
+ new byte[]
+ {
+ // Field1
+ 0x01, 0xC0, 0x09, 0x21, 0xFB, 0x54, 0x44, 0x2D, 0x18,
+ // Field2.Field1
+ 0x01, 0xC0, 0x09, 0x21, 0xFB, 0x54, 0x44, 0x2D, 0x18
+ }
+ },
+ {
+ new NestedSqlDateTimeWrapperStruct { Field1 = new DateTime(2000, 1, 1, 12, 34, 56, 500), Field2 = new SqlDateTimeWrapperStruct { Field1 = new DateTime(2000, 1, 1) } },
+ new byte[]
+ {
+ // Field1
+ 0x01, 0x80, 0x00, 0x8E, 0xAC, 0x80, 0xCF, 0x59, 0xD6,
+ // Field2.Field1
+ 0x01, 0x80, 0x00, 0x8E, 0xAC, 0x80, 0x00, 0x00, 0x00
+ }
+ },
+ {
+ new NestedSqlMoneyWrapperStruct { Field1 = 1.10m, Field2 = new SqlMoneyWrapperStruct { Field1 = -2.55m } },
+ new byte[]
+ {
+ // Field1
+ 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xF8,
+ // Field2.Field1
+ 0x01, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9C, 0x64
+ }
+ }
+ };
+
+ ///
+ /// Provides a collection of test data representing serialized null values for various primitive types.
+ ///
+ ///
+ public static TheoryData SerializedNullPrimitiveTypeValues() =>
+ new()
+ {
+ {
+ new SqlByteWrapperStruct { Field1 = SqlByte.Null },
+ new byte[] { 0x00, 0x00 }
+ },
+ {
+ new SqlInt16WrapperStruct { Field1 = SqlInt16.Null },
+ new byte[] { 0x00, 0x80, 0x00 }
+ },
+ {
+ new SqlInt32WrapperStruct { Field1 = SqlInt32.Null },
+ new byte[] { 0x00, 0x80, 0x00, 0x00, 0x00 }
+ },
+ {
+ new SqlInt64WrapperStruct { Field1 = SqlInt64.Null },
+ new byte[] { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+ },
+ {
+ new SqlBooleanWrapperStruct { Field1 = SqlBoolean.Null },
+ new byte[] { 0x00 }
+ },
+ {
+ new SqlSingleWrapperStruct { Field1 = SqlSingle.Null },
+ new byte[] { 0x00, 0x80, 0x00, 0x00, 0x00 }
+ },
+ {
+ new SqlDoubleWrapperStruct { Field1 = SqlDouble.Null },
+ new byte[] { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+ },
+ {
+ new SqlDateTimeWrapperStruct { Field1 = SqlDateTime.Null },
+ new byte[] { 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }
+ },
+ {
+ new SqlMoneyWrapperStruct { Field1 = SqlMoney.Null },
+ new byte[] { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+ }
+ };
+
+ ///
+ /// Attempts to serialize various structs containing non-null primitive types.
+ /// Verifies that the method does not throw, that serialized byte output is correct, and that the value round-trips.
+ ///
+ /// Primitive to serialize and to compare against.
+ /// Expected byte output.
+ [Theory]
+ [MemberData(nameof(SerializedNonNullPrimitiveTypeValues))]
+ public void Serialize_PrimitiveType_Roundtrips(object primitive, byte[] expectedValue) =>
+ RoundtripType(primitive, expectedValue);
+
+ ///
+ /// Attempts to serialize a nested struct hierarchy containing non-null primitive types.
+ /// Verifies that the method does not throw, that serialized byte output is correct, and that the value round-trips.
+ ///
+ /// Primitive to serialize and to compare against.
+ /// Expected byte output.
+ [Theory]
+ [MemberData(nameof(SerializedNestedNonNullPrimitiveTypeValues))]
+ public void Serialize_NestedPrimitiveType_Roundtrips(object primitive, byte[] expectedValue) =>
+ RoundtripType(primitive, expectedValue);
+
+ ///
+ /// Attempts to serialize various structs containing null-valued primitive types.
+ /// Verifies that the method does not throw, that serialized byte output is correct, and that the value round-trips.
+ ///
+ /// Primitive to serialize and to compare against.
+ /// Expected byte output.
+ [Theory]
+ [MemberData(nameof(SerializedNullPrimitiveTypeValues))]
+ public void Serialize_NullPrimitiveType_Roundtrips(object primitive, byte[] expectedValue) =>
+ RoundtripType(primitive, expectedValue);
+
+ ///
+ /// Attempts to serialize an instance of a class.
+ ///
+ ///
+ [Fact]
+ public void Serialize_TopLevelClass_Succeeds()
+ {
+ NestedBoolWrapperClass validWrapper = new()
+ {
+ Field1 = true,
+ Field2 = new BoolWrapperStruct() { Field1 = true }
+ };
+
+ SerializationHelperSql9.Serialize(_stream, validWrapper);
+ }
+
+ ///
+ /// Attempts to serialize a field referring to an instance of a class.
+ /// Verifies that this fails, and that Native format serialization only operates with primitive types and value types containing these.
+ ///
+ ///
+ [Fact]
+ public void Serialize_NestedClass_Throws()
+ {
+ InvalidNestedBoolWrapperClass invalidWrapper = new()
+ {
+ Field1 = true,
+ Field2 = new BoolWrapperClass() { Field1 = true }
+ };
+
+ var ex = Assert.Throws(() => SerializationHelperSql9.Serialize(_stream, invalidWrapper));
+ string expectedException = StringsHelper.GetString(Strings.SQL_CannotCreateNormalizer, invalidWrapper.Field2.GetType().FullName);
+
+ Assert.Equal(expectedException, ex.Message);
+ }
+
+ ///
+ /// Attempts to serialize a struct containing non-primitive value types.
+ /// Verifies that this fails.
+ ///
+ [Fact]
+ public void Serialize_NonPrimitiveType_Throws()
+ {
+ InvalidIntPtrAndByteWrapperStruct invalidWrapper = new()
+ {
+ Field1 = 1,
+ Field2 = IntPtr.Zero
+ };
+
+ var ex = Assert.Throws(() => SerializationHelperSql9.Serialize(_stream, invalidWrapper));
+ string expectedException = StringsHelper.GetString(Strings.SQL_CannotCreateNormalizer, invalidWrapper.Field2.GetType().FullName);
+
+ Assert.Equal(expectedException, ex.Message);
+ }
+
+ ///
+ /// Serializes an object, verifies the value and the size of the object, then roundtrips it and verifies the result is identical.
+ ///
+ /// Object to serialize.
+ /// Expected serialization output.
+ private void RoundtripType(object inputValue, byte[] expectedValue)
+ {
+ int typeSize = SerializationHelperSql9.SizeInBytes(inputValue.GetType());
+ int objectSize = SerializationHelperSql9.SizeInBytes(inputValue);
+ int maxTypeSize = SerializationHelperSql9.GetUdtMaxLength(inputValue.GetType());
+
+ SerializationHelperSql9.Serialize(_stream, inputValue);
+ _stream.Seek(0, SeekOrigin.Begin);
+ object readPrimitive = SerializationHelperSql9.Deserialize(_stream, inputValue.GetType());
+
+ // For native formatting, the type size, the object size and the maximum object size will always be identical
+ Assert.Equal(typeSize, objectSize);
+ Assert.Equal(expectedValue.Length, typeSize);
+ Assert.Equal(typeSize, maxTypeSize);
+
+ Assert.Equal(expectedValue, _stream.ToArray());
+ Assert.Equal(inputValue, readPrimitive);
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs
new file mode 100644
index 0000000000..a02c213e01
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs
@@ -0,0 +1,335 @@
+// 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.
+
+using Microsoft.SqlServer.Server;
+using System;
+using System.Data.SqlTypes;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace Microsoft.Data.SqlClient.UnitTests.UdtSerialization.SerializedTypes;
+
+// Simple cases: a struct containing one of the designated primitive types
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct BoolWrapperStruct { public bool Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct ByteWrapperStruct { public byte Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct SByteWrapperStruct { public sbyte Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct UShortWrapperStruct { public ushort Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct ShortWrapperStruct { public short Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct UIntWrapperStruct { public uint Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct IntWrapperStruct { public int Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct ULongWrapperStruct { public ulong Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct LongWrapperStruct { public long Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct FloatWrapperStruct { public float Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct DoubleWrapperStruct { public double Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct SqlByteWrapperStruct { public SqlByte Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct SqlInt16WrapperStruct { public SqlInt16 Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct SqlInt32WrapperStruct { public SqlInt32 Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct SqlInt64WrapperStruct { public SqlInt64 Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct SqlBooleanWrapperStruct { public SqlBoolean Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct SqlSingleWrapperStruct { public SqlSingle Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct SqlDoubleWrapperStruct { public SqlDouble Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct SqlDateTimeWrapperStruct { public SqlDateTime Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct SqlMoneyWrapperStruct { public SqlMoney Field1; }
+
+
+// Success case: a class containing one of the designated primitive types
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal class BoolWrapperClass { public bool Field1; }
+
+// Success case: a struct containing one designated primitive type and one nested struct
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedBoolWrapperStruct { public bool Field1; public BoolWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedByteWrapperStruct { public byte Field1; public ByteWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedSByteWrapperStruct { public sbyte Field1; public SByteWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedUShortWrapperStruct { public ushort Field1; public UShortWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedShortWrapperStruct { public short Field1; public ShortWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedUIntWrapperStruct { public uint Field1; public UIntWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedIntWrapperStruct { public int Field1; public IntWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedULongWrapperStruct { public ulong Field1; public ULongWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedLongWrapperStruct { public long Field1; public LongWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedFloatWrapperStruct { public float Field1; public FloatWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedDoubleWrapperStruct { public double Field1; public DoubleWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedSqlByteWrapperStruct { public SqlByte Field1; public SqlByteWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedSqlInt16WrapperStruct { public SqlInt16 Field1; public SqlInt16WrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedSqlInt32WrapperStruct { public SqlInt32 Field1; public SqlInt32WrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedSqlInt64WrapperStruct { public SqlInt64 Field1; public SqlInt64WrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedSqlBooleanWrapperStruct { public SqlBoolean Field1; public SqlBooleanWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedSqlSingleWrapperStruct { public SqlSingle Field1; public SqlSingleWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedSqlDoubleWrapperStruct { public SqlDouble Field1; public SqlDoubleWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedSqlDateTimeWrapperStruct { public SqlDateTime Field1; public SqlDateTimeWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct NestedSqlMoneyWrapperStruct { public SqlMoney Field1; public SqlMoneyWrapperStruct Field2; }
+
+
+// Success case: a class containing one designated primitive type and a nested struct
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal class NestedBoolWrapperClass { public bool Field1; public BoolWrapperStruct Field2; }
+
+// Failure case: a struct or a class containing one designated primitive type and a nested class
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal class InvalidNestedBoolWrapperClass { public bool Field1; public BoolWrapperClass? Field2; }
+
+// Failure case: a struct or a class containing a field which is not a designated primitive type
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+internal struct InvalidIntPtrAndByteWrapperStruct { public byte Field1; public IntPtr Field2; }
+
+// Success case: a struct or a class implementing IBinarySerialize which would not otherwise be serializable
+internal interface IFormattingProgress
+{
+ bool ParameterlessConstructorInvoked { get; }
+ bool ReadInvoked { get; }
+ bool WriteInvoked { get; }
+}
+
+[SqlUserDefinedType(Format.UserDefined, MaxByteSize = 11)]
+internal struct UserDefinedFormattedStruct : IBinarySerialize, IFormattingProgress, IEquatable
+{
+ public IntPtr Field1;
+ public bool ParameterlessConstructorInvoked { get; }
+ public bool ReadInvoked { get; private set; }
+ public bool WriteInvoked { get; private set; }
+
+ public UserDefinedFormattedStruct()
+ {
+ ParameterlessConstructorInvoked = true;
+ }
+
+ public UserDefinedFormattedStruct(IntPtr field1)
+ {
+ Field1 = field1;
+ }
+
+ public void Read(BinaryReader r)
+ {
+ Field1 = IntPtr.Size switch
+ {
+ sizeof(uint) => (IntPtr)r.ReadUInt32(),
+ sizeof(ulong) => (IntPtr)r.ReadUInt64(),
+ _ => throw new Exception("Invalid IntPtr size")
+ };
+
+ ReadInvoked = true;
+ }
+
+ public void Write(BinaryWriter w)
+ {
+ if (IntPtr.Size == sizeof(uint))
+ {
+ w.Write((uint)Field1);
+ }
+ else if (IntPtr.Size == sizeof(ulong))
+ {
+ w.Write((ulong)Field1);
+ }
+ else
+ {
+ throw new Exception("Invalid IntPtr size");
+ }
+
+ WriteInvoked = true;
+ }
+
+ public bool Equals(UserDefinedFormattedStruct other)
+ => other.Field1 == Field1;
+}
+
+[SqlUserDefinedType(Format.UserDefined, MaxByteSize = 11)]
+internal class UserDefinedFormattedClass : IBinarySerialize, IFormattingProgress, IEquatable
+{
+ public IntPtr Field1;
+ public bool ParameterlessConstructorInvoked { get; }
+ public bool ReadInvoked { get; private set; }
+ public bool WriteInvoked { get; private set; }
+
+ public UserDefinedFormattedClass()
+ {
+ ParameterlessConstructorInvoked = true;
+ }
+
+ public UserDefinedFormattedClass(IntPtr field1)
+ {
+ Field1 = field1;
+ }
+
+ public void Read(BinaryReader r)
+ {
+ Field1 = IntPtr.Size switch
+ {
+ sizeof(uint) => (IntPtr)r.ReadUInt32(),
+ sizeof(ulong) => (IntPtr)r.ReadUInt64(),
+ _ => throw new Exception("Invalid IntPtr size")
+ };
+
+ ReadInvoked = true;
+ }
+
+ public void Write(BinaryWriter w)
+ {
+ if (IntPtr.Size == sizeof(uint))
+ {
+ w.Write((uint)Field1);
+ }
+ else if (IntPtr.Size == sizeof(ulong))
+ {
+ w.Write((ulong)Field1);
+ }
+ else
+ {
+ throw new Exception("Invalid IntPtr size");
+ }
+
+ WriteInvoked = true;
+ }
+
+ public bool Equals(UserDefinedFormattedClass? other)
+ => other is not null && other.Field1 == Field1;
+}
+
+// Failure cases: type does not have a public constructor, does not implement IBinarySerialize, does not have a SqlUserDefinedType attribute,
+// or has a SqlUserDefinedType attribute with a Format of Unknown.
+
+[SqlUserDefinedType(Format.UserDefined)]
+internal class UserDefinedMissingPublicConstructor : IBinarySerialize
+{
+ public UserDefinedMissingPublicConstructor(bool _) { }
+
+ public void Read(BinaryReader r) { }
+
+ public void Write(BinaryWriter w) { }
+}
+
+[SqlUserDefinedType(Format.UserDefined)]
+internal class UserDefinedDoesNotImplementIBinarySerialize
+{
+ public UserDefinedDoesNotImplementIBinarySerialize() { }
+}
+
+internal class ClassMissingSqlUserDefinedTypeAttribute
+{
+}
+
+[SqlUserDefinedType(Format.Unknown)]
+internal class UnknownFormattedClass
+{
+}
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
new file mode 100644
index 0000000000..4d7ea799fd
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
@@ -0,0 +1,123 @@
+// 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.
+
+using Microsoft.Data.SqlClient.Server;
+using Microsoft.Data.SqlClient.UnitTests.UdtSerialization.SerializedTypes;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Xunit;
+
+namespace Microsoft.Data.SqlClient.UnitTests.UdtSerialization;
+
+///
+/// Tests the user-defined UDT serialization method. Verifies that custom types round-trip.
+///
+public sealed class UserDefinedSerializationTest : IDisposable
+{
+ private readonly MemoryStream _stream;
+
+ ///
+ /// Initializes the MemoryStream used for all tests in this class.
+ ///
+ public UserDefinedSerializationTest()
+ {
+ _stream = new MemoryStream();
+ }
+
+ void IDisposable.Dispose()
+ {
+ _stream.Dispose();
+ }
+
+ ///
+ /// Attempts to serialize and deserialize an instance of a struct with a user-defined serialization method.
+ ///
+ ///
+ [Fact]
+ public void Serialize_Struct_Roundtrips() =>
+ RoundtripType(new UserDefinedFormattedStruct((IntPtr)0x12345678));
+
+ ///
+ /// Attempts to serialize and deserialize an instance of a class with a user-defined serialization method.
+ ///
+ ///
+ [Fact]
+ public void Serialize_Class_Roundtrips() =>
+ RoundtripType(new UserDefinedFormattedClass((IntPtr)0x12345678));
+
+ ///
+ /// Attempts to deserialize an instance of a type with a user-defined serialization method but without a public
+ /// parameterless constructor. Verifies that this fails.
+ ///
+ [Fact]
+ public void Deserialize_MissingPublicParameterlessConstructor_Throws()
+ {
+ SerializationHelperSql9.Serialize(_stream, new UserDefinedMissingPublicConstructor(true));
+ _stream.Seek(0, SeekOrigin.Begin);
+
+ Action deserialize = () => SerializationHelperSql9.Deserialize(_stream, typeof(UserDefinedMissingPublicConstructor));
+
+ Assert.Throws(deserialize);
+ }
+
+ ///
+ /// Attempts to deserialize an instance of a type with a user-defined serialization method but which does not,
+ /// implement IBinarySerialize. Verifies that this fails.
+ ///
+ [Fact]
+ public void Serialize_DoesNotImplementIBinarySerialize_Throws()
+ {
+ Action serialize = () => SerializationHelperSql9.Serialize(_stream, new UserDefinedDoesNotImplementIBinarySerialize());
+
+ Assert.Throws(serialize);
+ }
+
+ private void RoundtripType(T userObject)
+ where T : IFormattingProgress
+ {
+ int typeSize = SerializationHelperSql9.SizeInBytes(userObject.GetType());
+ int objectSize = SerializationHelperSql9.SizeInBytes(userObject);
+ int maxTypeSize = SerializationHelperSql9.GetUdtMaxLength(userObject.GetType());
+
+ SerializationHelperSql9.Serialize(_stream, userObject);
+ _stream.Seek(0, SeekOrigin.Begin);
+ byte[] serializedValue = _stream.ToArray();
+ T readInstance = (T)SerializationHelperSql9.Deserialize(_stream, userObject.GetType());
+
+ // If this is a struct, it will have been copied by value and the write to WriteInvoked will have been made
+ // to another copy of our object
+ if (!typeof(T).IsValueType)
+ {
+ Assert.True(userObject.WriteInvoked);
+ }
+
+ Assert.Equal(IntPtr.Size, typeSize);
+ Assert.Equal(IntPtr.Size, objectSize);
+ Assert.Equal(11, maxTypeSize);
+
+ Assert.Equal(IntPtr.Size, serializedValue.Length);
+ if (IntPtr.Size == 8)
+ {
+ Assert.Equal([0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00], serializedValue);
+ }
+ else if (IntPtr.Size == 4)
+ {
+ Assert.Equal([0x78, 0x56, 0x34, 0x12], serializedValue);
+ }
+ else
+ {
+ Assert.Fail("Invalid IntPtr size.");
+ }
+
+ // In .NET Framework, Activator.CreateInstance does not invoke a struct's parameterless constructor
+#if NET
+ Assert.NotEqual(userObject.ParameterlessConstructorInvoked, readInstance.ParameterlessConstructorInvoked);
+ Assert.True(readInstance.ParameterlessConstructorInvoked);
+#endif
+ Assert.True(readInstance.ReadInvoked);
+
+ Assert.Equal(userObject, readInstance);
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlTypes/SqlTypeWorkaroundsTests.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlTypes/SqlTypeWorkaroundsTests.cs
index f7cd1811ed..cf97f21a39 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlTypes/SqlTypeWorkaroundsTests.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlTypes/SqlTypeWorkaroundsTests.cs
@@ -20,7 +20,7 @@ public class SqlTypeWorkaroundsTests
#region SqlBinary
public static TheoryData ByteArrayToSqlBinary_NonNullInput_Data =>
- new TheoryData
+ new()
{
Array.Empty(),
new byte[] { 1, 2, 3, 4},
@@ -53,7 +53,7 @@ public void ByteArrayToSqlBinary_NullInput()
#region SqlDecimal
public static TheoryData SqlDecimalWriteTdsValue_NonNullInput_Data =>
- new TheoryData
+ new()
{
SqlDecimal.MinValue,
new SqlDecimal(-1.2345678),
@@ -102,7 +102,7 @@ public void SqlDecimalWriteTdsValue_NullInput()
#region SqlGuid
public static TheoryData ByteArrayToSqlGuid_InvalidInput_Data =>
- new TheoryData
+ new()
{
null,
Array.Empty(),
@@ -122,7 +122,7 @@ public void ByteArrayToSqlGuid_InvalidInput(byte[]? input)
}
public static TheoryData ByteArrayToSqlGuid_ValidInput_Data =>
- new TheoryData
+ new()
{
new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }
@@ -145,7 +145,7 @@ public void ByteArrayToSqlGuid_ValidInput(byte[] input)
#region SqlMoney
public static TheoryData LongToSqlMoney_Data =>
- new TheoryData
+ new()
{
{ long.MinValue, SqlMoney.MinValue },
{ (long)((decimal)-123000000 / 10000), new SqlMoney(-1.23) },
@@ -166,7 +166,7 @@ public void LongToSqlMoney(long input, SqlMoney expected)
}
public static TheoryData SqlMoneyToLong_NonNullInput_Data =>
- new TheoryData
+ new()
{
{ SqlMoney.MinValue, long.MinValue },
{ new SqlMoney(-1.23), (long)(new SqlMoney(-1.23).ToDecimal() * 10000) },
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/TdsParserInternalsTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/TdsParserInternalsTest.cs
index f0b3729d6f..17a4ad8b5a 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/TdsParserInternalsTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/TdsParserInternalsTest.cs
@@ -92,7 +92,7 @@ public void WriteUserAgentFeatureRequest_WriteTrue_AppendsOnlyExtensionBytes()
bufferAfter[start + 5]);
// slice into the existing buffer
- ReadOnlySpan writtenSpan = new ReadOnlySpan(
+ ReadOnlySpan writtenSpan = new(
bufferAfter,
start + 6,
appended - 6);
From 600803b06fb78a9d9b71663a9f02c261ad253e90 Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Thu, 18 Sep 2025 16:06:54 -0300
Subject: [PATCH 18/30] User Story 37654: Create Abstractions package
- Removed obsolete ADO Library inclusion in CI variables.
- Moved MDS CI versions numbers into CI variables.
- Fixed Abstractions versioning to handle CI version format.
---
eng/pipelines/dotnet-sqlclient-ci-core.yml | 2 +-
.../libraries/ci-build-variables.yml | 7 +-
.../Abstractions/src/Abstractions.csproj | 72 +++++++++++--------
3 files changed, 47 insertions(+), 34 deletions(-)
diff --git a/eng/pipelines/dotnet-sqlclient-ci-core.yml b/eng/pipelines/dotnet-sqlclient-ci-core.yml
index be694f92de..cc6f9bf201 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-core.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-core.yml
@@ -165,7 +165,7 @@ stages:
${{ if eq(parameters.referenceType, 'Package') }}:
dependsOn:
- build_abstractions_package_stage
- - build_nugets
+ - build_mds_akv_packages_stage
prebuildSteps: # steps to run prior to building and running tests on each job
- ${{if ne(parameters.SNIVersion, '')}}:
diff --git a/eng/pipelines/libraries/ci-build-variables.yml b/eng/pipelines/libraries/ci-build-variables.yml
index 6ae1032de2..6b6ac2a825 100644
--- a/eng/pipelines/libraries/ci-build-variables.yml
+++ b/eng/pipelines/libraries/ci-build-variables.yml
@@ -6,7 +6,6 @@
variables:
- group: 'ADO Build properties'
- - group: 'ADO CI Packaging'
- group: 'ADO Test Configuration Properties'
- name: buildNumber
@@ -16,11 +15,11 @@ variables:
- name: SQLTarget
value: 'localhost'
- name: abstractionsPackageVersion
- value: 1.0.0.$(buildNumber)
+ value: 1.0.0.$(buildNumber)-ci
- name: akvPackageVersion
- value: 7.0.0.$(buildNumber)
+ value: 7.0.0.$(buildNumber)-ci
- name: mdsPackageVersion
- value: $(Major).$(Minor)$(Patch)-pull.1$(buildnumber)
+ value: 7.0.0.$(buildNumber)-ci
- name: skipComponentGovernanceDetection
value: true
- name: runCodesignValidationInjection
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
index 367a35f8e1..bab743d838 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
@@ -8,28 +8,41 @@
-
- 1
-
- -dev
- $(AbstractionsPackageMajorVersion).0.0.$(BuildNumber)
-
- $(AbstractionsPackageMajorVersion).0.0.0
+
+ 1
+
+
+
+ $(AbstractionsAssemblyFileVersion)
+
+ $(AbstractionsPackageVersion.Split('-')[0])
+
+ $(DefaultMajorVersion).0.0.$(BuildNumber)
+
+
+ $(AbstractionsPackageVersion)
+ $(DefaultMajorVersion).0.0.$(BuildNumber)-dev
@@ -48,10 +61,15 @@
Microsoft.Data.SqlClient.Extensions.Abstractions
Microsoft.Data.SqlClient.Extensions.Abstractions
- $(AbstractionsPackageAssemblyVersion)
- $(AbstractionsPackageVersion)
- $(AssemblyFileVersion)
- $(AbstractionsPackageVersion)$(AbstractionsPackageVersionSuffix)
+
+ $(DefaultMajorVersion).0.0.0
+
+ $(OurAssemblyFileVersion)
+ $(OurAssemblyFileVersion)
+ $(OurPackageVersion)
@@ -69,12 +87,8 @@
See: https://learn.microsoft.com/en-us/nuget/reference/msbuild-targets#pack-target
-->
-
-
- $(Version)
+ $(AssemblyName)
+ $(OurPackageVersion)
$(PackagesDir)
true
snupkg
From 327df5e952578cd9263a4b22923276592a4ba2ec Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Fri, 19 Sep 2025 08:55:31 -0300
Subject: [PATCH 19/30] User Story 37654: Create Abstractions package
- Addressed my own review comments.
---
NuGet.config | 2 +-
build.proj | 5 +++--
.../templates/jobs/build-signed-package-job.yml | 5 ++++-
.../templates/jobs/ci-build-nugets-job.yml | 8 ++++----
.../common/templates/jobs/ci-run-tests-job.yml | 12 ++++++------
.../templates/stages/ci-run-tests-stage.yml | 12 ++++++------
.../steps/generate-nuget-package-step.yml | 9 +++------
eng/pipelines/dotnet-sqlclient-ci-core.yml | 4 +++-
.../Abstractions/src/Abstractions.csproj | 4 ++--
tools/targets/GenerateMdsPackage.targets | 17 +++++++++++++++++
...targets => GenerateSqlServerPackage.targets} | 14 --------------
...ckage.targets => GenerateAkvPackage.targets} | 2 +-
12 files changed, 50 insertions(+), 44 deletions(-)
create mode 100644 tools/targets/GenerateMdsPackage.targets
rename tools/targets/{GenerateNugetPackage.targets => GenerateSqlServerPackage.targets} (53%)
rename tools/targets/add-ons/{GenerateAKVProviderNugetPackage.targets => GenerateAkvPackage.targets} (90%)
diff --git a/NuGet.config b/NuGet.config
index 53f672d23b..3e762e7fe9 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -13,7 +13,7 @@
https://sqlclientdrivers.visualstudio.com/public/_artifacts/feed/sqlclient
-->
-
+
diff --git a/build.proj b/build.proj
index fc22196202..7efa49d8bb 100644
--- a/build.proj
+++ b/build.proj
@@ -2,8 +2,9 @@
-
-
+
+
+
diff --git a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
index 53403d9d57..72b4e8e716 100644
--- a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
+++ b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
@@ -50,7 +50,10 @@ jobs:
- template: ../steps/generate-nuget-package-step.yml@self
parameters:
- OutputDirectory: $(artifactDirectory)
+ nuspecPath: $(nuspecPath)
+ packageVersion: $(mdsPackageVersion)
+ outputDirectory: $(artifactDirectory)
+ displayName: 'Create MDS NuGet Package'
- template: ../steps/esrp-code-signing-step.yml@self
parameters:
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 2066df3340..fd9755f32c 100644
--- a/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
@@ -78,19 +78,19 @@ jobs:
- template: ../steps/generate-nuget-package-step.yml@self
parameters:
- mdsPackageVersion: $(mdsPackageVersion)
+ packageVersion: $(mdsPackageVersion)
configuration: $(Configuration)
nuspecPath: 'tools/specs/Microsoft.Data.SqlClient.nuspec'
- OutputDirectory: $(packagePath)
+ outputDirectory: $(packagePath)
generateSymbolsPackage: false
displayName: 'Create MDS NuGet Package'
- template: ../steps/generate-nuget-package-step.yml@self
parameters:
- mdsPackageVersion: $(mdsPackageVersion)
+ packageVersion: $(akvPackageVersion)
configuration: $(Configuration)
nuspecPath: 'tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec'
- OutputDirectory: $(packagePath)
+ outputDirectory: $(packagePath)
generateSymbolsPackage: false
installNuget: false
displayName: 'Create AKV NuGet Package'
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 20b39095b5..06bc31911b 100644
--- a/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
@@ -10,12 +10,6 @@ parameters:
- name: abstractionsPackageVersion
type: string
- - name: referenceType
- type: string
- values:
- - Project
- - Package
-
- name: configProperties
type: object
default: {} # - key: 'value'
@@ -70,6 +64,12 @@ parameters:
type: boolean
default: false
+ - name: referenceType
+ type: string
+ values:
+ - Project
+ - Package
+
- name: targetFramework
type: string
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 994bb4f345..46318f8e06 100644
--- a/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
+++ b/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
@@ -10,12 +10,6 @@ parameters:
- name: abstractionsPackageVersion
type: string
- - name: referenceType
- default: Project
- values:
- - Project
- - Package
-
- name: debug
type: boolean
default: false
@@ -39,6 +33,12 @@ parameters:
type: stepList
default: []
+ - name: referenceType
+ default: Project
+ values:
+ - Project
+ - Package
+
- name: testConfigurations
type: object
diff --git a/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml
index 1afd22c063..816a9b7a7a 100644
--- a/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml
+++ b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml
@@ -6,17 +6,15 @@
parameters:
- name: nuspecPath
type: string
- default: '$(nuspecPath)'
- - name: mdsPackageVersion
+ - name: packageVersion
type: string
- default: '$(mdsPackageVersion)'
- - name: OutputDirectory
+ - name: outputDirectory
type: string
default: '$(Build.SourcesDirectory)/packages'
- - name: Configuration
+ - name: configuration
type: string
default: '$(Configuration)'
@@ -26,7 +24,6 @@ parameters:
- name: displayName
type: string
- default: 'NuGet pack with snupkg'
- name: installNuget
type: boolean
diff --git a/eng/pipelines/dotnet-sqlclient-ci-core.yml b/eng/pipelines/dotnet-sqlclient-ci-core.yml
index cc6f9bf201..df7e1993f1 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-core.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-core.yml
@@ -122,6 +122,8 @@ stages:
${{ if eq(parameters.referenceType, 'Package') }}:
dependsOn:
- build_abstractions_package_stage
+ ${{ else }}:
+ dependsOn: []
jobs:
- template: common/templates/jobs/ci-build-nugets-job.yml@self
@@ -143,7 +145,7 @@ stages:
- template: stages/stress-tests-ci-stage.yml@self
parameters:
buildConfiguration: ${{ parameters.buildConfiguration }}
- dependsOn: [build_mds_packages_job]
+ dependsOn: [build_mds_akv_packages_stage]
pipelineArtifactName: $(artifactName)
mdsPackageVersion: $(mdsPackageVersion)
${{ if eq(parameters.debug, 'true') }}:
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
index bab743d838..b214f69b19 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
@@ -17,7 +17,7 @@
- Used as the base value of the assembly attribute
'AssemblyInformationalVersion' generated by MSBuild.
- If not specified, defaults to:
- $(AbstractionsPackageMajorVersion).0.0.$(BuildNumber)-dev.
+ $(DefaultMajorVersion).0.0.$(BuildNumber)-dev.
AbstractionsAssemblyFileVersion:
- Used as the value of the assembly attribute 'AssemblyFileVersion'
@@ -26,7 +26,7 @@
- If $(AbstractionsPackageVersion) is specified, use the numeric
parts of its value, for example 1.0.0.345.
- Otherwise, defaults to:
- $(AbstractionsPackageMajorVersion).0.0.$(BuildNumber).
+ $(DefaultMajorVersion).0.0.$(BuildNumber).
-->
diff --git a/tools/targets/GenerateMdsPackage.targets b/tools/targets/GenerateMdsPackage.targets
new file mode 100644
index 0000000000..033b9a338b
--- /dev/null
+++ b/tools/targets/GenerateMdsPackage.targets
@@ -0,0 +1,17 @@
+
+
+
+
+ $(MdsPackageVersion)-debug
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/targets/GenerateNugetPackage.targets b/tools/targets/GenerateSqlServerPackage.targets
similarity index 53%
rename from tools/targets/GenerateNugetPackage.targets
rename to tools/targets/GenerateSqlServerPackage.targets
index 7b674ebfdb..f7a2da0301 100644
--- a/tools/targets/GenerateNugetPackage.targets
+++ b/tools/targets/GenerateSqlServerPackage.targets
@@ -1,19 +1,5 @@
-
-
- $(MdsPackageVersion)-debug
-
-
-
-
-
-
-
-
-
-
$(SqlServerPackageVersion)-debug
diff --git a/tools/targets/add-ons/GenerateAKVProviderNugetPackage.targets b/tools/targets/add-ons/GenerateAkvPackage.targets
similarity index 90%
rename from tools/targets/add-ons/GenerateAKVProviderNugetPackage.targets
rename to tools/targets/add-ons/GenerateAkvPackage.targets
index aa50a32463..f63afe95a8 100644
--- a/tools/targets/add-ons/GenerateAKVProviderNugetPackage.targets
+++ b/tools/targets/add-ons/GenerateAkvPackage.targets
@@ -1,6 +1,6 @@
-
+
$(AkvPackageVersion)-debug
From 6dcb0db1ae495dbaeb65c6b0336f953b45a75b8e Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Fri, 19 Sep 2025 09:00:08 -0300
Subject: [PATCH 20/30] User Story 37654: Create Abstractions package
- Fixed parameter typo in YAML.
---
.../common/templates/steps/generate-nuget-package-step.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml
index 816a9b7a7a..a9ce1f2d83 100644
--- a/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml
+++ b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml
@@ -52,6 +52,6 @@ steps:
inputs:
command: custom
${{ if parameters.generateSymbolsPackage }}:
- arguments: 'pack -Symbols -SymbolPackageFormat snupkg ${{parameters.nuspecPath}} -Version ${{parameters.mdsPackageVersion}} -OutputDirectory ${{parameters.OutputDirectory}} -properties "COMMITID=$(CommitHead);Configuration=${{parameters.Configuration}};ReferenceType=${{parameters.referenceType}}"'
+ arguments: 'pack -Symbols -SymbolPackageFormat snupkg ${{parameters.nuspecPath}} -Version ${{parameters.packageVersion}} -OutputDirectory ${{parameters.outputDirectory}} -properties "COMMITID=$(CommitHead);Configuration=${{parameters.Configuration}};ReferenceType=${{parameters.referenceType}}"'
${{else }}:
- arguments: 'pack ${{parameters.nuspecPath}} -Version ${{parameters.mdsPackageVersion}} -OutputDirectory ${{parameters.OutputDirectory}} -properties "COMMITID=$(CommitHead);Configuration=${{parameters.Configuration}};ReferenceType=${{parameters.referenceType}}"'
+ arguments: 'pack ${{parameters.nuspecPath}} -Version ${{parameters.packageVersion}} -OutputDirectory ${{parameters.outputDirectory}} -properties "COMMITID=$(CommitHead);Configuration=${{parameters.Configuration}};ReferenceType=${{parameters.referenceType}}"'
From 88e95d573bede54c8f9c4263c1618f3486fe7ef7 Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Fri, 19 Sep 2025 17:29:26 -0300
Subject: [PATCH 21/30] User Story 37654: Create Abstractions package
- Fixed Abstractions package versioning in official builds.
- Fixed broken assembly version checks in official builds.
- Removed Abstractions solution file.
---
.../templates/jobs/build-signed-package-job.yml | 6 +++++-
.../templates/jobs/validate-signed-package-job.yml | 10 ++++++++--
.../build-all-configurations-signed-dlls-step.yml | 9 ++++++++-
.../jobs/pack-abstractions-package-ci-job.yml | 12 ++++++------
.../jobs/test-abstractions-package-ci-job.yml | 14 +++++++-------
eng/pipelines/libraries/common-variables.yml | 14 ++++++++++++++
.../Abstractions/Abstractions.slnx | 8 --------
tools/props/Versions.props | 2 +-
8 files changed, 49 insertions(+), 26 deletions(-)
delete mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
diff --git a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
index 72b4e8e716..89c621b877 100644
--- a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
+++ b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
@@ -39,7 +39,11 @@ jobs:
name: GetBuildType
- template: ../steps/build-all-configurations-signed-dlls-step.yml@self
-
+ parameters:
+ # These values are sourced from common-variables.yml.
+ abstractionsPackageVersion: $(abstractionsPackageVersion)
+ abstractionsAssemblyFileVersion: $(abstractionsAssemblyFileVersion)
+
- template: ../steps/code-analyze-step.yml@self
parameters:
analyzeType: all
diff --git a/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml b/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml
index 333e78ffd4..8f88a402ed 100644
--- a/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml
+++ b/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml
@@ -344,10 +344,16 @@ jobs:
- powershell: |
# Check assembly versions.
+ #
+ # GOTCHA: This expects the Versions.props file having XML elements in a
+ # certain order. If the order changes, this check will fail!
+ #
+ # TODO: This also isn't checking the versions of the actual assemblies in
+ # the package, so it isn't terribly useful.
[Xml] $versionprops = Get-Content -Path "tools/props/Versions.props"
- $AssemblyFileVersion = $versionprops.Project.PropertyGroup[0].AssemblyFileVersion
- $AssemblyVersion = $versionprops.Project.PropertyGroup[0].AssemblyVersion
+ $AssemblyFileVersion = $versionprops.Project.PropertyGroup[1].AssemblyFileVersion
+ $AssemblyVersion = $versionprops.Project.PropertyGroup[1].AssemblyVersion
if($AssemblyFileVersion -eq $AssemblyVersion)
{
diff --git a/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml b/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml
index e6a6c0443a..736193b8ec 100644
--- a/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml
+++ b/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml
@@ -4,6 +4,13 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
+
+ - name: abstractionsPackageVersion
+ type: string
+
+ - name: abstractionsAssemblyFileVersion
+ type: string
+
- name: AssemblyFileVersion
type: string
default: $(AssemblyFileVersion)
@@ -47,4 +54,4 @@ steps:
inputs:
solution: '**/build.proj'
configuration: '${{parameters.Configuration }}'
- msbuildArguments: '-p:AssemblyFileVersion=${{parameters.AssemblyFileVersion }} -t:BuildAllConfigurations -p:GenerateNuget=false -p:SigningKeyPath=$(Agent.TempDirectory)\netfxKeypair.snk'
+ msbuildArguments: '-p:AssemblyFileVersion=${{parameters.AssemblyFileVersion }} -t:BuildAllConfigurations -p:GenerateNuget=false -p:SigningKeyPath=$(Agent.TempDirectory)\netfxKeypair.snk -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }} -p:AbstractionsAssemblyFileVersion=${{ parameters.abstractionsAssemblyFileVersion }}'
diff --git a/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml b/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
index 795fbd4373..13bf3618fb 100644
--- a/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
+++ b/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
@@ -57,9 +57,9 @@ jobs:
variables:
- # The Abstractions solution file to use for all dotnet CLI commands.
- - name: solution
- value: src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
+ # The Abstractions project file to use for all dotnet CLI commands.
+ - name: project
+ value: src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
# The directory where the NuGet packages will be staged before being
# published as pipeline artifacts.
@@ -118,7 +118,7 @@ jobs:
inputs:
command: custom
custom: restore
- projects: $(solution)
+ projects: $(project)
arguments: $(commonArguments)
# Build the solution.
@@ -127,7 +127,7 @@ jobs:
inputs:
command: custom
custom: build
- projects: $(solution)
+ projects: $(project)
arguments: $(buildArguments) --no-restore
# Create the NuGet packages.
@@ -136,7 +136,7 @@ jobs:
inputs:
command: custom
custom: pack
- projects: $(solution)
+ projects: $(project)
arguments: $(buildArguments) --no-build -o $(dotnetPackagesDir)
# Publish the NuGet packages as a named pipeline artifact.
diff --git a/eng/pipelines/jobs/test-abstractions-package-ci-job.yml b/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
index a2b25966d4..a5e0f98978 100644
--- a/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
+++ b/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
@@ -76,9 +76,9 @@ jobs:
variables:
- # The Abstractions solution file to use for all dotnet CLI commands.
- - name: solution
- value: src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
+ # The Abstractions test project file to use for all dotnet CLI commands.
+ - name: project
+ value: src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
# dotnet CLI arguments common to all commands.
- name: commonArguments
@@ -141,7 +141,7 @@ jobs:
inputs:
command: custom
custom: restore
- projects: $(solution)
+ projects: $(project)
arguments: $(commonArguments)
# Build the solution.
@@ -150,7 +150,7 @@ jobs:
inputs:
command: custom
custom: build
- projects: $(solution)
+ projects: $(project)
arguments: $(buildArguments) --no-restore
# Run the tests for each .NET runtime.
@@ -160,7 +160,7 @@ jobs:
inputs:
command: custom
custom: test
- projects: $(solution)
+ projects: $(project)
arguments: $(buildArguments) --no-build -f ${{ runtime }}
# Run the tests for each .NET Framework runtime.
@@ -170,5 +170,5 @@ jobs:
inputs:
command: custom
custom: test
- projects: $(solution)
+ projects: $(project)
arguments: $(buildArguments) --no-build -f ${{ runtime }}
diff --git a/eng/pipelines/libraries/common-variables.yml b/eng/pipelines/libraries/common-variables.yml
index b7df898497..94eb5103a3 100644
--- a/eng/pipelines/libraries/common-variables.yml
+++ b/eng/pipelines/libraries/common-variables.yml
@@ -26,6 +26,20 @@ variables:
- name: artifactDirectory
value: '$(REPOROOT)/packages'
+ # ----------------------------------------------------------------------------
+ # Abstractions Package Versions
+ #
+ # These are version values that will be used by the official build. They
+ # should be updated after each release to reflect the next release's versions.
+
+ # The NuGet package version for the Abstractions package.
+ - name: abstractionsPackageVersion
+ value: 1.0.0.$(Build.BuildNumber)
+
+ # The AssemblyFileVersion for all assemblies in the Abstractions package.
+ - name: abstractionsAssemblyFileVersion
+ value: '1.0.0.0'
+
# Update this after every release. This is used to generate the MDS NuGet package version.
- name: Major
value: '7'
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
deleted file mode 100644
index 9632efff88..0000000000
--- a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/tools/props/Versions.props b/tools/props/Versions.props
index c8595f574a..e4935f8c91 100644
--- a/tools/props/Versions.props
+++ b/tools/props/Versions.props
@@ -20,7 +20,7 @@
-->
+
+
+ AbstractionsPackageVersion=$(AbstractionsPackageVersion)
+
+
-
-
- AbstractionsPackageVersion=$(AbstractionsPackageVersion)
-
-
+ Properties="$(AbstractionsProperties)" />
-
- AbstractionsPackageVersion=$(AbstractionsPackageVersion)
-
-
+ Properties="$(AbstractionsProperties)" />
-
- AbstractionsPackageVersion=$(AbstractionsPackageVersion)
-
-
+ Properties="$(AbstractionsProperties)" />
-
- AbstractionsPackageVersion=$(AbstractionsPackageVersion)
-
-
+ Properties="$(AbstractionsProperties)" />
diff --git a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
index 54cac5100e..80cf59d5a7 100644
--- a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
+++ b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
@@ -46,6 +46,7 @@ jobs:
${{ else }}:
abstractionsPackageVersion: $(abstractionsPackagePreviewVersion)
abstractionsAssemblyFileVersion: $(abstractionsAssemblyFileVersion)
+ mdsAssemblyFileVersion: $(mdsAssemblyFileVersion)
- template: ../steps/code-analyze-step.yml@self
parameters:
diff --git a/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml b/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml
index 6289c7dae0..8040b991a8 100644
--- a/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml
+++ b/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml
@@ -13,7 +13,6 @@ parameters:
- name: mdsAssemblyFileVersion
type: string
- default: $(mdsAssemblyFileVersion)
- name: Configuration
type: string
diff --git a/eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml b/eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml
index 098286866c..3b18dcf5bc 100644
--- a/eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml
+++ b/eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml
@@ -83,6 +83,6 @@ steps:
$software = '${{parameters.softwareFolder}}'
$symbols = '${{parameters.symbolsFolder}}'
- Get-ChildItem -recurse "$software\*.dll"
- Get-ChildItem -recurse "$symbols\*.pdb"
+ Get-ChildItem -recurse "$software\*.dll" | ForEach-Object VersionInfo
+ Get-ChildItem -recurse "$symbols\*.pdb" | ForEach-Object VersionInfo
displayName: 'List the prepared files'
From 9f49ffe307a488c0948098805b1a25c43b985388 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 29/30] User Story 37654: Create Abstractions 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.
- Renamed Extensions package to Abstractions.
- Updated README related to extensions design.
- Changed MDS to reference Abstractions via project or package depending on build parameters.
- Removed obsolete package reference files.
- Updated CI pipelines to build Abstractions in parallel for Project-based builds.
- Modularized Abstractions CI templates.
- Cleaned up the project vs package pathways.
- Replaced generic "NugetPackageVersion" with variables names specific to the package (i.e. MdsPackageVersion, AkvPackageVersion, etc).
- Removed top-level Abstractions package version parameters in favour of a variable.
- Fixes to Abstractions version number construction.
- Fixes for some build.proj targets.
---
BUILDGUIDE.md | 86 +++---
NuGet.config | 21 +-
build.proj | 150 +++++++--
eng/pipelines/akv-official-pipeline.yml | 5 +-
.../jobs/build-signed-package-job.yml | 6 +-
.../templates/jobs/ci-build-nugets-job.yml | 43 ++-
.../templates/jobs/ci-run-tests-job.yml | 113 ++++---
.../jobs/run-tests-package-reference-job.yml | 6 +-
.../jobs/validate-signed-package-job.yml | 14 +-
.../templates/stages/ci-run-tests-stage.yml | 53 ++--
.../templates/steps/build-all-tests-step.yml | 44 ++-
.../build-and-run-tests-netcore-step.yml | 12 +-
.../steps/build-and-run-tests-netfx-step.yml | 12 +-
.../templates/steps/ci-prebuild-step.yml | 24 +-
.../templates/steps/ci-project-build-step.yml | 22 +-
.../steps/generate-nuget-package-step.yml | 8 +-
.../templates/steps/publish-symbols-step.yml | 2 +-
.../templates/steps/run-all-tests-step.yml | 22 +-
.../update-nuget-config-local-feed-step.yml | 42 +--
eng/pipelines/dotnet-sqlclient-ci-core.yml | 212 +++++++------
...qlclient-ci-package-reference-pipeline.yml | 9 +-
...qlclient-ci-project-reference-pipeline.yml | 9 +-
.../dotnet-sqlclient-signing-pipeline.yml | 2 +-
eng/pipelines/jobs/build-akv-official-job.yml | 19 +-
.../jobs/pack-abstractions-package-ci-job.yml | 143 +++++++++
eng/pipelines/jobs/stress-tests-ci-job.yml | 2 +-
.../jobs/test-abstractions-package-ci-job.yml | 174 +++++++++++
.../libraries/ci-build-variables.yml | 4 +-
eng/pipelines/libraries/common-variables.yml | 4 +-
.../libraries/mds-validation-variables.yml | 2 +-
.../build-abstractions-package-ci-stage.yml | 124 ++++++++
.../steps/compound-build-akv-step.yml | 10 +-
.../steps/roslyn-analyzers-akv-step.yml | 6 +-
.../variables/akv-official-variables.yml | 4 +-
src/Directory.Build.props | 15 +
src/Directory.Packages.props | 7 +
.../Abstractions/Abstractions.slnx | 8 +
.../Abstractions/README.md | 285 ++++++++++++++++++
.../Abstractions/doc/Sample.xml | 18 ++
.../Abstractions/src/Abstractions.csproj | 109 +++++++
.../Abstractions/src/Sample.cs | 20 ++
.../test/Abstractions.Test.csproj | 26 ++
.../Abstractions/test/SampleTest.cs | 19 ++
src/Microsoft.Data.SqlClient.sln | 44 ++-
.../ref/Microsoft.Data.SqlClient.csproj | 15 +-
.../src/Microsoft.Data.SqlClient.csproj | 13 +
.../netfx/ref/Microsoft.Data.SqlClient.csproj | 14 +
.../netfx/src/Microsoft.Data.SqlClient.csproj | 14 +
tools/props/Versions.props | 43 ++-
tools/specs/Microsoft.Data.SqlClient.nuspec | 4 +
tools/targets/GenerateNugetPackage.targets | 8 +-
.../GenerateAKVProviderNugetPackage.targets | 6 +-
52 files changed, 1632 insertions(+), 445 deletions(-)
create mode 100644 eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
create mode 100644 eng/pipelines/jobs/test-abstractions-package-ci-job.yml
create mode 100644 eng/pipelines/stages/build-abstractions-package-ci-stage.yml
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/README.md
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/doc/Sample.xml
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Sample.cs
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
create mode 100644 src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/SampleTest.cs
diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md
index efeb747cad..178c3fc2d6 100644
--- a/BUILDGUIDE.md
+++ b/BUILDGUIDE.md
@@ -16,28 +16,33 @@ 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.|
+|`BuildAbstractionsPackage`|Restore, build, and pack the Abstractions 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 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 +50,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:BuildAbstractionsPackage
msbuild
msbuild -t:BuildTestsNetFx -p:TF=net462
msbuild -t:BuildTestsNetCore
@@ -59,28 +65,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:BuildAbstractionsPackage -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:BuildAbstractionsPackage
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:BuildAbstractionsPackage
+msbuild
+msbuild -t:BuildTestsNetFx -p:TF=net462
+msbuild -t:BuildTestsNetCore
+msbuild -t:RunTests -p:DotnetPath=C:\net8-win-x86\
```
### Running Manual Tests
@@ -119,15 +128,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 +159,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 +202,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:BuildAbstractionsPackage -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 +254,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 +297,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..53f672d23b 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -1,11 +1,30 @@
+
+
-
+
+
+
+
+
+
+
+
diff --git a/build.proj b/build.proj
index 0443bbcf4e..fc22196202 100644
--- a/build.proj
+++ b/build.proj
@@ -29,7 +29,7 @@
true
Configuration=$(Configuration);AssemblyVersion=$(SqlServerAssemblyVersion);AssemblyFileVersion=$(SqlServerAssemblyFileVersion);Version=$(SqlServerPackageVersion);
Configuration=$(Configuration);AssemblyFileVersion=$(AssemblyFileVersion);TargetsWindows=$(TargetsWindows);TargetsUnix=$(TargetsUnix);
- BuildProjectReferences=false;$(ProjectProperties);BuildForRelease=false;TargetNetCoreVersion=$(TargetNetCoreVersion);TargetNetFxVersion=$(TargetNetFxVersion)
+ $(ProjectProperties);BuildForRelease=false;TargetNetCoreVersion=$(TargetNetCoreVersion);TargetNetFxVersion=$(TargetNetFxVersion)
TestResults
+
+
@@ -84,32 +86,91 @@
-
-
-
+
+
+
-
-
+
+
+
+
+
+
+ AbstractionsPackageVersion=$(AbstractionsPackageVersion)
+
+
+
+
+
+
+
+ AbstractionsPackageVersion=$(AbstractionsPackageVersion)
+
+
+
+
+
+
+
+ AbstractionsPackageVersion=$(AbstractionsPackageVersion)
+
+
+
+
+
+
+
+ AbstractionsPackageVersion=$(AbstractionsPackageVersion)
+
+
+
+
+
+
-
+
-
+
-
+
-
+
@@ -122,7 +183,10 @@
-
+
@@ -139,27 +203,37 @@
-
+
-
+
+
-
+
-
-
+
+
@@ -168,7 +242,9 @@
-
+
@@ -177,12 +253,18 @@
-
+
-
+
@@ -191,7 +273,10 @@
-
+
@@ -346,13 +431,13 @@
-
+
-
-
-
-
-
+
+
+
+
+
@@ -388,7 +473,10 @@
-
+
@@ -398,7 +486,9 @@
-
+
@@ -408,7 +498,9 @@
-
+
diff --git a/eng/pipelines/akv-official-pipeline.yml b/eng/pipelines/akv-official-pipeline.yml
index d7bc900bb8..fcaa1bb3e2 100644
--- a/eng/pipelines/akv-official-pipeline.yml
+++ b/eng/pipelines/akv-official-pipeline.yml
@@ -113,7 +113,7 @@ extends:
sbom:
enabled: ${{ parameters.runSdlTasks }}
packageName: 'Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider'
- packageVersion: ${{ variables.nugetPackageVersion }}
+ packageVersion: ${{ variables.akvPackageVersion }}
tsa:
# OneBranch publishes all sdl results to TSA. If TSA is disabled all SDL tools will
@@ -131,8 +131,7 @@ extends:
apiScanPdbPath: '${{ variables.apiScanPdbPath }}'
assemblyFileVersion: '${{ variables.assemblyFileVersion }}'
buildConfiguration: '${{ parameters.buildConfiguration }}'
- nugetPackageVersion: '${{ variables.nugetPackageVersion }}'
- mdsPackageVersion: '${{ variables.mdsPackageVersion }}'
+ akvPackageVersion: '${{ variables.akvPackageVersion }}'
publishSymbols: '${{ parameters.publishSymbols }}'
signingAppRegistrationClientId: '$(SigningAppRegistrationClientId)'
signingAppRegistrationTenantId: '$(SigningAppRegistrationTenantId)'
diff --git a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
index 91eb864337..53403d9d57 100644
--- a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
+++ b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
@@ -27,8 +27,8 @@ jobs:
variables:
- template: ../../../libraries/variables.yml@self
- ${{ if parameters.isPreview }}:
- - name: NugetPackageVersion
- value: $(PreviewNugetPackageVersion)
+ - name: mdsPackageVersion
+ value: $(previewMdsPackageVersion)
steps:
- script: SET
@@ -64,4 +64,4 @@ jobs:
- template: ../steps/publish-symbols-step.yml@self
parameters:
publishSymbols: ${{ parameters['PublishSymbols'] }}
- symbolsArtifactName: mds_symbols_$(System.TeamProject)_$(Build.Repository.Name)_$(Build.SourceBranchName)_$(NuGetPackageVersion)_$(System.TimelineId)
+ symbolsArtifactName: mds_symbols_$(System.TeamProject)_$(Build.Repository.Name)_$(Build.SourceBranchName)_$(mdsPackageVersion)_$(System.TimelineId)
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..63f99cae76 100644
--- a/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
@@ -4,6 +4,13 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
+
+ - name: referenceType
+ type: string
+ values:
+ - Project
+ - Package
+
- name: poolName
type: string
default: $(ci_var_defaultPoolName)
@@ -12,9 +19,13 @@ parameters:
type: string
default: ADO-MMS22-SQL19
- - name: artifactName
+ - name: abstractionsArtifactName
+ type: string
+ default: Abstractions.Artifact
+
+ - name: mdsArtifactName
type: string
- default: Artifacts
+ default: MDS.Artifact
- name: platform
type: string
@@ -28,8 +39,12 @@ parameters:
type: stepList
default: []
+ - name: abstractionsPackageVersion
+ type: string
+
jobs:
-- job: build_nugets
+- job: build_mds_packages_job
+ displayName: Build MDS Packages
pool:
name: ${{parameters.poolName }}
@@ -44,16 +59,26 @@ jobs:
- ${{ if ne(parameters.prebuildSteps, '') }}:
- ${{ parameters.prebuildSteps }} # extra steps to run before the build like downloading sni and the required configuration
+ # If we're testing in Package mode, download the Abstractions package
+ # artifacts and put them in the packages/ directory in the repo root.
+ - ${{ if eq(parameters.referenceType, 'Package') }}:
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Abstractions Package Artifact
+ inputs:
+ artifactName: ${{ parameters.abstractionsArtifactName }}
+ targetPath: $(Build.SourcesDirectory)/packages
+
- template: ../steps/ci-project-build-step.yml@self
parameters:
platform: ${{ parameters.platform }}
configuration: ${{ parameters.configuration }}
operatingSystem: Windows
build: all
+ abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
- template: ../steps/generate-nuget-package-step.yml@self
parameters:
- NugetPackageVersion: $(NugetPackageVersion)
+ mdsPackageVersion: $(mdsPackageVersion)
configuration: $(Configuration)
nuspecPath: 'tools/specs/Microsoft.Data.SqlClient.nuspec'
OutputDirectory: $(packagePath)
@@ -62,7 +87,7 @@ jobs:
- template: ../steps/generate-nuget-package-step.yml@self
parameters:
- NugetPackageVersion: $(NugetPackageVersion)
+ mdsPackageVersion: $(mdsPackageVersion)
configuration: $(Configuration)
nuspecPath: 'tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec'
OutputDirectory: $(packagePath)
@@ -70,8 +95,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 dbf5b10028..20b39095b5 100644
--- a/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
@@ -4,12 +4,37 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
+ - name: abstractionsArtifactName
+ type: string
+
+ - name: abstractionsPackageVersion
+ type: string
+
+ - name: referenceType
+ type: string
+ values:
+ - Project
+ - Package
+
+ - name: configProperties
+ type: object
+ default: {} # - key: 'value'
+
+ - name: configSqlFor
+ type: string # local, azure, or enclave
+ default: local
+
- name: debug
type: boolean
default: false
- - name: poolName
- type: string
+ - name: enableX64Test
+ type: boolean
+ default: true
+
+ - name: enableX86Test
+ type: boolean
+ default: false
- name: hostedPool
type: boolean
@@ -21,63 +46,45 @@ parameters:
- name: jobDisplayName
type: string
- - name: usemanagedSNI
- type: boolean
- default: false
-
- - name: configProperties
- type: object
- default: {} # - key: 'value'
-
- - name: prebuildSteps
- type: stepList
- default: []
-
- - name: artifactName
+ - name: mdsArtifactName
type: string
- default: Artifacts
- - name: targetFramework
+ - name: mdsPackageVersion
type: string
- name: netcoreVersionTestUtils
type: string
+
+ - name: operatingSystem
+ type: string
+ default: ''
- - name: enableX86Test
- type: boolean
- default: false
-
- - name: enableX64Test
- type: boolean
- default: true
-
- - name: testSet
+ - name: poolName
type: string
+
+ - name: prebuildSteps
+ type: stepList
+ default: []
- name: publishTestResults
type: boolean
default: false
-
- - name: configSqlFor
- type: string # local, azure, or enclave
- default: local
-
- - name: operatingSystem
+
+ - name: targetFramework
type: string
- default: ''
-
- - name: buildType
- displayName: 'Build Type'
- default: Project
- values:
- - Project
- - Package
+ - name: testSet
+ type: string
+
# The timeout, in minutes, for this job.
- name: timeout
type: string
default: 90
+ - name: usemanagedSNI
+ type: boolean
+ default: false
+
jobs:
- job: ${{ format('{0}', coalesce(parameters.jobDisplayName, parameters.image, 'unknown_image')) }}
@@ -98,6 +105,22 @@ jobs:
value: '$(dotnetx86Path)'
steps:
+
+ # If we're testing in Package mode, download the Abstractions and MDS package
+ # artifacts and put them in the packages/ directory in the repo root.
+ - ${{ if eq(parameters.referenceType, 'Package') }}:
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Abstractions Package Artifact
+ inputs:
+ artifactName: ${{ parameters.abstractionsArtifactName }}
+ targetPath: $(Build.SourcesDirectory)/packages
+
+ - task: DownloadPipelineArtifact@2
+ displayName: Download MDS Package Artifact
+ inputs:
+ artifactName: ${{ parameters.mdsArtifactName }}
+ targetPath: $(Build.SourcesDirectory)/packages
+
- ${{ if ne(parameters.prebuildSteps, '') }}:
- ${{ parameters.prebuildSteps }} # extra steps to run before the build like downloading sni and the required configuration
@@ -227,8 +250,10 @@ jobs:
- template: ../steps/build-all-tests-step.yml@self # build tests
parameters:
targetFramework: ${{ parameters.targetFramework }}
- referenceType: ${{ parameters.buildType }}
+ referenceType: ${{ parameters.referenceType }}
testSet: ${{ parameters.testSet }}
+ abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
+ mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
${{ if ne(parameters.operatingSystem, 'Windows') }}:
OSGroup: Unix
@@ -237,7 +262,7 @@ jobs:
parameters:
debug: ${{ parameters.debug }}
targetFramework: ${{ parameters.targetFramework }}
- referenceType: ${{ parameters.buildType }}
+ referenceType: ${{ parameters.referenceType }}
testSet: ${{ parameters.testSet }}
operatingSystem: ${{ parameters.operatingSystem }}
@@ -279,13 +304,13 @@ jobs:
parameters:
debug: ${{ parameters.debug }}
targetFramework: ${{ parameters.targetFramework }}
- referenceType: ${{ parameters.buildType }}
+ referenceType: ${{ parameters.referenceType }}
testSet: ${{ parameters.testSet }}
msbuildArchitecture: x86
dotnetx86RootPath: $(dotnetx86RootPath)
operatingSystem: ${{ parameters.operatingSystem }}
- - ${{ if and(eq(parameters.publishTestResults, true), eq(parameters.buildType, 'Project')) }}: # publish test results if build type is project
+ - ${{ if and(eq(parameters.publishTestResults, true), eq(parameters.referenceType, 'Project')) }}: # publish test results if build type is project
- template: ../steps/publish-test-results-step.yml@self
parameters:
debug: ${{ parameters.debug }}
diff --git a/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml b/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml
index 14aea42411..c422ffdc34 100644
--- a/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml
+++ b/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml
@@ -52,8 +52,6 @@ jobs:
- template: ../steps/update-nuget-config-local-feed-step.yml
parameters:
downloadedNugetPath: $(Pipeline.Workspace)\${{parameters.packageFolderName }}
- ${{ if parameters.isPreview }}:
- nugetPackageVersion: $(PreviewNugetPackageVersion)
- template: ../steps/update-config-file-step.yml
parameters:
@@ -68,11 +66,11 @@ jobs:
parameters:
referenceType: Package
${{ if parameters.isPreview }}:
- nugetPackageVersion: $(PreviewNugetPackageVersion)
+ mdsPackageVersion: $(previewMdsPackageVersion)
- template: ../steps/build-and-run-tests-netcore-step.yml
parameters:
referenceType: Package
cleanFirst: true
${{ if parameters.isPreview }}:
- nugetPackageVersion: $(PreviewNugetPackageVersion)
+ mdsPackageVersion: $(previewMdsPackageVersion)
diff --git a/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml b/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml
index 009e6f2647..333e78ffd4 100644
--- a/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml
+++ b/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml
@@ -54,18 +54,18 @@ jobs:
value: $(Pipeline.Workspace)\${{parameters.packageFolderName }}
- name: ProductVersion #MDS product version (MDS validation)
- value: $(NugetPackageVersion)
+ value: $(mdsPackageVersion)
- name: BuildType
value: $[ stageDependencies.buildMDS.build_signed_package.outputs['GetBuildType.CDP_BUILD_TYPE_COPY'] ]
- ${{ if parameters.isPreview }}:
- name: extractedNugetPath
- value: $(extractedNugetRootPath).$(PreviewNugetPackageVersion)
- - name: NugetPackageVersion
- value: $(PreviewNugetPackageVersion)
+ value: $(extractedNugetRootPath).$(previewMdsPackageVersion)
+ - name: mdsPackageVersion
+ value: $(previewMdsPackageVersion)
- name: ProductVersion
- value: $(PreviewNugetPackageVersion)
+ value: $(previewMdsPackageVersion)
steps:
- script: SET
@@ -75,7 +75,7 @@ jobs:
displayName: 'Use NuGet'
- powershell: |
- #Sets Variables for AssemblyFileVersion, AssemblyVersion and NugetPackageVersion
+ # Sets the pipeline ASSEMBLY_VERSION variable.
[Xml] $versionprops = Get-Content -Path ".\tools\props\Versions.props"
Write-Host $versionprops.Project.PropertyGroup[0].AssemblyFileVersion
@@ -336,7 +336,7 @@ jobs:
[Xml] $versionprops = Get-Content -Path "tools/props/Versions.props"
$versionpropspath = "tools\props\Versions.props"
- $versionprops.Project.PropertyGroup[$versionprops.Project.PropertyGroup.Count-1].TestMicrosoftDataSqlClientVersion ="$(NugetPackageVersion)"
+ $versionprops.Project.PropertyGroup[$versionprops.Project.PropertyGroup.Count-1].TestMicrosoftDataSqlClientVersion ="$(mdsPackageVersion)"
Write-Host "Saving Test nuget version at $rootfolder\props ...." -ForegroundColor Green
$versionprops.Save($versionpropspath)
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 e07685407f..994bb4f345 100644
--- a/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
+++ b/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
@@ -4,32 +4,44 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
- - name: debug
- type: boolean
- default: false
-
- - name: testConfigurations
- type: object
+ - name: abstractionsArtifactName
+ type: string
- - name: dependsOn
+ - name: abstractionsPackageVersion
type: string
- default: ''
- - name: buildType
- displayName: 'Build Type'
+ - name: referenceType
default: Project
values:
- Project
- Package
- - name: prebuildSteps
- type: stepList
+ - name: debug
+ type: boolean
+ default: false
+
+ - name: dependsOn
+ type: object
default: []
+
+ - name: mdsArtifactName
+ type: string
+ default: MDS.Artifact
+
+ - name: mdsPackageVersion
+ type: string
- name: postTestJobs
type: jobList
default: []
+ - name: prebuildSteps
+ type: stepList
+ default: []
+
+ - name: testConfigurations
+ type: object
+
# The timeout, in minutes, for each test job.
- name: testsTimeout
type: string
@@ -39,10 +51,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 }}:
@@ -51,13 +60,17 @@ stages:
- template: ../jobs/ci-run-tests-job.yml@self
parameters:
debug: ${{ parameters.debug }}
- buildType: ${{ parameters.buildType }}
+ referenceType: ${{ parameters.referenceType }}
timeout: ${{ parameters.testsTimeout }}
poolName: ${{ config.value.pool }}
hostedPool: ${{ eq(config.value.hostedPool, true) }}
image: ${{ image.value }}
jobDisplayName: ${{ format('{0}_{1}_{2}', replace(targetFramework, '.', '_'), platform, testSet) }}
configProperties: ${{ config.value.configProperties }}
+ abstractionsArtifactName: ${{ parameters.abstractionsArtifactName }}
+ abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
+ mdsArtifactName: ${{ parameters.mdsArtifactName }}
+ mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
prebuildSteps: ${{ parameters.prebuildSteps }}
targetFramework: ${{ targetFramework }}
netcoreVersionTestUtils: ${{config.value.netcoreVersionTestUtils }}
@@ -77,7 +90,7 @@ stages:
- template: ../jobs/ci-run-tests-job.yml@self
parameters:
debug: ${{ parameters.debug }}
- buildType: ${{ parameters.buildType }}
+ referenceType: ${{ parameters.referenceType }}
timeout: ${{ parameters.testsTimeout }}
poolName: ${{ config.value.pool }}
hostedPool: ${{ eq(config.value.hostedPool, true) }}
@@ -88,6 +101,10 @@ stages:
jobDisplayName: ${{ format('{0}_{1}_{2}_{3}', replace(targetFramework, '.', '_'), platform, 'NativeSNI', testSet) }}
configProperties: ${{ config.value.configProperties }}
useManagedSNI: ${{ useManagedSNI }}
+ abstractionsArtifactName: ${{ parameters.abstractionsArtifactName }}
+ abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
+ mdsArtifactName: ${{ parameters.mdsArtifactName }}
+ mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
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..43ecb6aafa 100644
--- a/eng/pipelines/common/templates/steps/build-all-tests-step.yml
+++ b/eng/pipelines/common/templates/steps/build-all-tests-step.yml
@@ -4,31 +4,33 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
- - name: targetFramework
+ - name: abstractionsPackageVersion
+ type: string
+
+ - name: configuration
+ type: string
+ default: '$(Configuration)'
+
+ - name: mdsPackageVersion
type: string
- - name: nugetPackageVersion
+ - name: osGroup
type: string
- default: $(NugetPackageVersion)
+ default: ''
- name: platform
type: string
default: $(Platform)
-
- - name: configuration
- type: string
- default: '$(Configuration)'
- name: referenceType
- default: Package
+ type: string
values:
- Project
- Package
-
- - name: OSGroup
- type: string
- default: ''
+ - name: targetFramework
+ type: string
+
- name: testSet
type: string
@@ -40,26 +42,16 @@ 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 }}'
-
-# - ${{else if contains(parameters.targetFramework, 'netstandard')}}: # .NET Standard
-# - task: MSBuild@1
-# displayName: 'Build Tests NetStandard'
-# inputs:
-# solution: build.proj
-# platform: '${{parameters.platform }}'
-# configuration: '${{parameters.configuration }}'
-# msbuildArguments: '-t:BuildTestsNetCore -p:ReferenceType=NetStandard -p:TargetNetStandardVersion=${{parameters.targetNetStandardVersion }} -p:TF=${{parameters.targetFramework }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }}'
-# condition: and(succeeded(), not(startsWith(variables['TF'], 'net4')), startsWith(variables['TargetNetStandardVersion'], 'netstandard'))
+ msbuildArguments: '-t:BuildTestsNetFx -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}'
-- ${{elseif eq(parameters.OSGroup, '')}}: # .NET on Windows
+- ${{elseif eq(parameters.osGroup, '')}}: # .NET on Windows
- task: MSBuild@1
displayName: 'Build Tests NetCore [Win]'
inputs:
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.mdsPackageVersion }} -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}'
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
- ${{ else }}: # .NET on Unix
@@ -69,7 +61,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.mdsPackageVersion }} -p:OSGroup=${{parameters.osGroup }} -p:platform=${{parameters.platform }} -p:Configuration=${{parameters.configuration }} -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}'
verbosityRestore: Detailed
verbosityPack: Detailed
condition: and(succeeded(), ne(variables['Agent.OS'], 'Windows_NT'))
diff --git a/eng/pipelines/common/templates/steps/build-and-run-tests-netcore-step.yml b/eng/pipelines/common/templates/steps/build-and-run-tests-netcore-step.yml
index c70fe776a7..43eea4449d 100644
--- a/eng/pipelines/common/templates/steps/build-and-run-tests-netcore-step.yml
+++ b/eng/pipelines/common/templates/steps/build-and-run-tests-netcore-step.yml
@@ -18,9 +18,9 @@ parameters:
- Project
- Package
- - name: NugetPackageVersion
+ - name: mdsPackageVersion
type: string
- default: $(NugetPackageVersion)
+ default: $(mdsPackageVersion)
- name: platform
type: string
@@ -55,14 +55,14 @@ steps:
inputs:
solution: build.proj
msbuildArchitecture: x64
- msbuildArguments: '-p:Configuration=${{parameters.configuration }} -t:BuildAKVNetCore -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.NugetPackageVersion }}'
+ msbuildArguments: '-p:Configuration=${{parameters.configuration }} -t:BuildAKVNetCore -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }}'
- task: MSBuild@1
displayName: 'MSBuild Build Tests for ${{parameters.TargetNetCoreVersion }}'
inputs:
solution: build.proj
msbuildArchitecture: x64
- msbuildArguments: '-t:BuildTestsNetCore -p:ReferenceType=${{parameters.referenceType }} -p:TargetNetCoreVersion=${{parameters.TargetNetCoreVersion }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.NugetPackageVersion }} -p:Configuration=${{parameters.configuration }}'
+ msbuildArguments: '-t:BuildTestsNetCore -p:ReferenceType=${{parameters.referenceType }} -p:TargetNetCoreVersion=${{parameters.TargetNetCoreVersion }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} -p:Configuration=${{parameters.configuration }}'
# Don't run unit tests using package reference. Unit tests are only run using project reference.
@@ -71,12 +71,12 @@ steps:
inputs:
command: test
projects: 'src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.FunctionalTests.csproj'
- arguments: '-p:Platform=${{parameters.platform }} -p:TestTargetOS="${{parameters.TestTargetOS }}" -p:TargetNetCoreVersion=${{parameters.TargetNetCoreVersion }} -p:ReferenceType=${{parameters.referenceType }} -p:Configuration=${{parameters.configuration }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.NugetPackageVersion }} --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests"'
+ arguments: '-p:Platform=${{parameters.platform }} -p:TestTargetOS="${{parameters.TestTargetOS }}" -p:TargetNetCoreVersion=${{parameters.TargetNetCoreVersion }} -p:ReferenceType=${{parameters.referenceType }} -p:Configuration=${{parameters.configuration }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests"'
- task: DotNetCoreCLI@2
displayName: 'Run Manual Tests for ${{parameters.TargetNetCoreVersion }}'
inputs:
command: test
projects: 'src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj'
- arguments: '-p:Platform=${{parameters.platform }} -p:TestTargetOS="${{parameters.TestTargetOS }}" -p:TargetNetCoreVersion=${{parameters.TargetNetCoreVersion }} -p:ReferenceType=${{parameters.referenceType }} -p:Configuration=${{parameters.configuration }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.NugetPackageVersion }} --no-build -v n --filter category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests --collect "Code Coverage"'
+ arguments: '-p:Platform=${{parameters.platform }} -p:TestTargetOS="${{parameters.TestTargetOS }}" -p:TargetNetCoreVersion=${{parameters.TargetNetCoreVersion }} -p:ReferenceType=${{parameters.referenceType }} -p:Configuration=${{parameters.configuration }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} --no-build -v n --filter category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests --collect "Code Coverage"'
retryCountOnTaskFailure: ${{parameters.retryCountOnManualTests }}
diff --git a/eng/pipelines/common/templates/steps/build-and-run-tests-netfx-step.yml b/eng/pipelines/common/templates/steps/build-and-run-tests-netfx-step.yml
index 5d9f194c48..e7b35f653e 100644
--- a/eng/pipelines/common/templates/steps/build-and-run-tests-netfx-step.yml
+++ b/eng/pipelines/common/templates/steps/build-and-run-tests-netfx-step.yml
@@ -18,9 +18,9 @@ parameters:
- Project
- Package
- - name: NugetPackageVersion
+ - name: mdsPackageVersion
type: string
- default: $(NugetPackageVersion)
+ default: $(mdsPackageVersion)
- name: platform
type: string
@@ -55,13 +55,13 @@ steps:
inputs:
solution: build.proj
msbuildArchitecture: x64
- msbuildArguments: '-p:Configuration=${{parameters.configuration }} -t:BuildAKVNetFx -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.NugetPackageVersion }}'
+ msbuildArguments: '-p:Configuration=${{parameters.configuration }} -t:BuildAKVNetFx -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }}'
- task: MSBuild@1
displayName: 'MSBuild Build Tests for ${{parameters.TargetNetFxVersion }}'
inputs:
solution: build.proj
- msbuildArguments: ' -t:BuildTestsNetFx -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.NugetPackageVersion }} -p:TargetNetFxVersion=${{parameters.TargetNetFxVersion }} -p:Configuration=${{parameters.configuration }} -p:Platform=${{parameters.platform }}'
+ msbuildArguments: ' -t:BuildTestsNetFx -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} -p:TargetNetFxVersion=${{parameters.TargetNetFxVersion }} -p:Configuration=${{parameters.configuration }} -p:Platform=${{parameters.platform }}'
# Don't run unit tests using package reference. Unit tests are only run using project reference.
@@ -70,12 +70,12 @@ steps:
inputs:
command: test
projects: 'src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.FunctionalTests.csproj'
- arguments: '-p:Platform=${{parameters.platform }} -p:TestTargetOS="${{parameters.TestTargetOS }}" -p:TargetNetFxVersion=${{parameters.TargetNetFxVersion }} -p:ReferenceType=${{parameters.referenceType }} -p:Configuration=${{parameters.configuration }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.NugetPackageVersion }} --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" --collect "Code Coverage"'
+ arguments: '-p:Platform=${{parameters.platform }} -p:TestTargetOS="${{parameters.TestTargetOS }}" -p:TargetNetFxVersion=${{parameters.TargetNetFxVersion }} -p:ReferenceType=${{parameters.referenceType }} -p:Configuration=${{parameters.configuration }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" --collect "Code Coverage"'
- task: DotNetCoreCLI@2
displayName: 'Run Manual Tests for ${{parameters.TargetNetFxVersion }}'
inputs:
command: test
projects: 'src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj'
- arguments: '-p:Platform=${{parameters.platform }} -p:TestTargetOS="${{parameters.TestTargetOS }}" -p:TargetNetFxVersion=${{parameters.TargetNetFxVersion }} -p:ReferenceType=${{parameters.referenceType }} -p:Configuration=${{parameters.configuration }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.NugetPackageVersion }} --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" --collect "Code Coverage"'
+ arguments: '-p:Platform=${{parameters.platform }} -p:TestTargetOS="${{parameters.TestTargetOS }}" -p:TargetNetFxVersion=${{parameters.TargetNetFxVersion }} -p:ReferenceType=${{parameters.referenceType }} -p:Configuration=${{parameters.configuration }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" --collect "Code Coverage"'
retryCountOnTaskFailure: ${{parameters.retryCountOnManualTests }}
diff --git a/eng/pipelines/common/templates/steps/ci-prebuild-step.yml b/eng/pipelines/common/templates/steps/ci-prebuild-step.yml
index efe17856d8..4eedd5dfd4 100644
--- a/eng/pipelines/common/templates/steps/ci-prebuild-step.yml
+++ b/eng/pipelines/common/templates/steps/ci-prebuild-step.yml
@@ -8,13 +8,8 @@ parameters:
type: boolean
default: false
- - name: artifactName
+ - name: referenceType
type: string
- default: Artifacts
-
- - name: buildType
- displayName: 'Build Type'
- default: Project
values:
- Project
- Package
@@ -37,21 +32,8 @@ steps:
Get-ChildItem env: | Sort-Object Name
displayName: 'List Environment Variables [debug]'
-- ${{if eq(parameters.buildType, 'Package')}}:
- - task: DownloadPipelineArtifact@2
- displayName: 'Download NuGet Package'
- inputs:
- buildType: current
- artifact: ${{parameters.artifactName }}
- patterns: '**/*.nupkg'
- targetPath: $(Pipeline.Workspace)/${{parameters.artifactName }}
-
+- ${{if eq(parameters.referenceType, 'Package')}}:
- template: update-nuget-config-local-feed-step.yml@self
parameters:
- downloadedNugetPath: $(Pipeline.Workspace)\${{parameters.artifactName }}
+ downloadedNugetPath: $(Build.SourcesDirectory)/packages
debug: ${{ parameters.debug }}
-
-- ${{ else }}: # project
- - template: ci-project-build-step.yml@self
- parameters:
- build: allNoDocs
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..8353779198 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,10 @@ parameters:
- all
- allNoDocs
+ - name: abstractionsPackageVersion
+ displayName: Abstractions Package Version
+ type: string
+
steps:
- template: ./ensure-dotnet-version.yml@self
parameters:
@@ -48,24 +52,24 @@ steps:
- ${{ if or(eq(parameters.operatingSystem, 'Windows'), eq(parameters.operatingSystem, 'deferedToRuntime')) }}:
- ${{ if or(eq(parameters.build, 'MDS'), eq(parameters.build, 'all'), eq(parameters.build, 'allNoDocs')) }}:
- task: MSBuild@1
- displayName: 'Restore nugets [Win]'
+ displayName: 'Restore [Win]'
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
inputs:
solution: build.proj
msbuildArchitecture: x64
- msbuildArguments: '-t:restore'
+ msbuildArguments: '-t:restore -p:AbstractionsPackageVersion=${{parameters.abstractionsPackageVersion}}'
retryCountOnTaskFailure: 1
- ${{ if eq(parameters.build, 'allNoDocs') }}:
- task: MSBuild@1
- displayName: 'Build Driver [Win]'
+ displayName: 'Build Driver (no docs) [Win]'
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
inputs:
solution: build.proj
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:AbstractionsPackageVersion=${{parameters.abstractionsPackageVersion}}'
clean: true
- ${{ if or(eq(parameters.build, 'MDS'), eq(parameters.build, 'all')) }}:
@@ -77,7 +81,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:AbstractionsPackageVersion=${{parameters.abstractionsPackageVersion}}'
clean: true
- ${{ if or(eq(parameters.build, 'AKV'), eq(parameters.build, 'all'), eq(parameters.build, 'allNoDocs')) }}:
@@ -89,7 +93,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:AbstractionsPackageVersion=${{parameters.abstractionsPackageVersion}}'
- task: MSBuild@1
displayName: 'Build AKV Provider NetCore All OS [Win]'
@@ -99,17 +103,17 @@ steps:
msbuildArchitecture: x64
platform: '${{ parameters.platform }}'
configuration: '${{ parameters.configuration }}'
- msbuildArguments: '-t:BuildAKVNetCoreAllOS -p:BuildNumber=${{ parameters.buildNumber }}'
+ msbuildArguments: '-t:BuildAKVNetCoreAllOS -p:BuildNumber=${{ parameters.buildNumber }} -p:AbstractionsPackageVersion=${{parameters.abstractionsPackageVersion}}'
- ${{ if or(eq(parameters.operatingSystem, 'Linux'), eq(parameters.operatingSystem, 'MacOS'), eq(parameters.operatingSystem, 'deferedToRuntime')) }}:
- task: DotNetCoreCLI@2
- displayName: 'Build Driver [non-Win]'
+ displayName: 'Build Driver [${{ parameters.operatingSystem }}]'
condition: and(succeeded(), ne(variables['Agent.OS'], 'Windows_NT'))
inputs:
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:AbstractionsPackageVersion=${{parameters.abstractionsPackageVersion}}'
verbosityRestore: Detailed
verbosityPack: Detailed
retryCountOnTaskFailure: 1
diff --git a/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml
index 4e32f989c3..1afd22c063 100644
--- a/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml
+++ b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml
@@ -8,9 +8,9 @@ parameters:
type: string
default: '$(nuspecPath)'
- - name: NugetPackageVersion
+ - name: mdsPackageVersion
type: string
- default: '$(NugetPackageVersion)'
+ default: '$(mdsPackageVersion)'
- name: OutputDirectory
type: string
@@ -55,6 +55,6 @@ steps:
inputs:
command: custom
${{ if parameters.generateSymbolsPackage }}:
- arguments: 'pack -Symbols -SymbolPackageFormat snupkg ${{parameters.nuspecPath}} -Version ${{parameters.NugetPackageVersion}} -OutputDirectory ${{parameters.OutputDirectory}} -properties "COMMITID=$(CommitHead);Configuration=${{parameters.Configuration}};ReferenceType=${{parameters.referenceType}}"'
+ arguments: 'pack -Symbols -SymbolPackageFormat snupkg ${{parameters.nuspecPath}} -Version ${{parameters.mdsPackageVersion}} -OutputDirectory ${{parameters.OutputDirectory}} -properties "COMMITID=$(CommitHead);Configuration=${{parameters.Configuration}};ReferenceType=${{parameters.referenceType}}"'
${{else }}:
- arguments: 'pack ${{parameters.nuspecPath}} -Version ${{parameters.NugetPackageVersion}} -OutputDirectory ${{parameters.OutputDirectory}} -properties "COMMITID=$(CommitHead);Configuration=${{parameters.Configuration}};ReferenceType=${{parameters.referenceType}}"'
+ arguments: 'pack ${{parameters.nuspecPath}} -Version ${{parameters.mdsPackageVersion}} -OutputDirectory ${{parameters.OutputDirectory}} -properties "COMMITID=$(CommitHead);Configuration=${{parameters.Configuration}};ReferenceType=${{parameters.referenceType}}"'
diff --git a/eng/pipelines/common/templates/steps/publish-symbols-step.yml b/eng/pipelines/common/templates/steps/publish-symbols-step.yml
index 5f8d2e6a7d..8999a6cc1d 100644
--- a/eng/pipelines/common/templates/steps/publish-symbols-step.yml
+++ b/eng/pipelines/common/templates/steps/publish-symbols-step.yml
@@ -15,7 +15,7 @@ parameters:
- name: symbolsVersion
type: string
- default: '$(NuGetPackageVersion)'
+ default: '$(mdsPackageVersion)'
- name: symbolServer
type: string
diff --git a/eng/pipelines/common/templates/steps/run-all-tests-step.yml b/eng/pipelines/common/templates/steps/run-all-tests-step.yml
index b9a870ada4..27da9e4e73 100644
--- a/eng/pipelines/common/templates/steps/run-all-tests-step.yml
+++ b/eng/pipelines/common/templates/steps/run-all-tests-step.yml
@@ -11,9 +11,9 @@ parameters:
- name: targetFramework
type: string
- - name: nugetPackageVersion
+ - name: mdsPackageVersion
type: string
- default: $(NugetPackageVersion)
+ default: $(mdsPackageVersion)
- name: platform
type: string
@@ -62,9 +62,9 @@ steps:
platform: '${{parameters.platform }}'
configuration: '${{parameters.configuration }}'
${{ if eq(parameters.msbuildArchitecture, 'x64') }}:
- msbuildArguments: '-t:RunUnitTests -p:TF=${{parameters.targetFramework }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }}'
+ msbuildArguments: '-t:RunUnitTests -p:TF=${{parameters.targetFramework }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }}'
${{ else }}: # x86
- msbuildArguments: '-t:RunUnitTests -p:TF=${{parameters.targetFramework }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }} -p:DotnetPath=${{parameters.dotnetx86RootPath }}'
+ msbuildArguments: '-t:RunUnitTests -p:TF=${{parameters.targetFramework }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} -p:DotnetPath=${{parameters.dotnetx86RootPath }}'
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
retryCountOnTaskFailure: 1
@@ -76,9 +76,9 @@ steps:
platform: '${{parameters.platform }}'
configuration: '${{parameters.configuration }}'
${{ if eq(parameters.msbuildArchitecture, 'x64') }}:
- msbuildArguments: '-t:RunFunctionalTests -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }}'
+ msbuildArguments: '-t:RunFunctionalTests -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }}'
${{ else }}: # x86
- msbuildArguments: '-t:RunFunctionalTests -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }} -p:DotnetPath=${{parameters.dotnetx86RootPath }}'
+ msbuildArguments: '-t:RunFunctionalTests -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} -p:DotnetPath=${{parameters.dotnetx86RootPath }}'
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
retryCountOnTaskFailure: 1
@@ -90,9 +90,9 @@ steps:
platform: '${{parameters.platform }}'
configuration: '${{parameters.configuration }}'
${{ if eq(parameters.msbuildArchitecture, 'x64') }}:
- msbuildArguments: '-t:RunManualTests -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }}'
+ msbuildArguments: '-t:RunManualTests -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }}'
${{ else }}: # x86
- msbuildArguments: '-t:RunManualTests -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }} -p:DotnetPath=${{parameters.dotnetx86RootPath }}'
+ msbuildArguments: '-t:RunManualTests -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} -p:DotnetPath=${{parameters.dotnetx86RootPath }}'
condition: eq(variables['Agent.OS'], 'Windows_NT')
retryCountOnTaskFailure: 2
@@ -104,7 +104,7 @@ steps:
command: custom
projects: build.proj
custom: msbuild
- arguments: '-t:RunUnitTests -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }} -p:platform=${{parameters.platform }} -p:Configuration=${{parameters.configuration }}'
+ arguments: '-t:RunUnitTests -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} -p:platform=${{parameters.platform }} -p:Configuration=${{parameters.configuration }}'
verbosityRestore: Detailed
verbosityPack: Detailed
retryCountOnTaskFailure: 1
@@ -116,7 +116,7 @@ steps:
command: custom
projects: build.proj
custom: msbuild
- arguments: '-t:RunFunctionalTests -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }} -p:platform=${{parameters.platform }} -p:Configuration=${{parameters.configuration }}'
+ arguments: '-t:RunFunctionalTests -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} -p:platform=${{parameters.platform }} -p:Configuration=${{parameters.configuration }}'
verbosityRestore: Detailed
verbosityPack: Detailed
retryCountOnTaskFailure: 1
@@ -128,7 +128,7 @@ steps:
command: custom
projects: build.proj
custom: msbuild
- arguments: '-t:RunManualTests -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.nugetPackageVersion }} -p:platform=${{parameters.platform }} -p:Configuration=${{parameters.configuration }}'
+ arguments: '-t:RunManualTests -p:TF=${{parameters.targetFramework }} -p:TestSet=${{parameters.testSet }} -p:ReferenceType=${{parameters.referenceType }} -p:TestMicrosoftDataSqlClientVersion=${{parameters.mdsPackageVersion }} -p:platform=${{parameters.platform }} -p:Configuration=${{parameters.configuration }}'
verbosityRestore: Detailed
verbosityPack: Detailed
retryCountOnTaskFailure: 2
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..f7bf252ebe 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,10 +11,6 @@ parameters:
- name: downloadedNugetPath # path to the downloaded nuget files
type: string
- - name: nugetPackageVersion
- type: string
- default: $(NugetPackageVersion)
-
steps:
- powershell: |
# Get a list of package sources available
@@ -34,7 +30,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")
@@ -45,39 +41,3 @@ steps:
# Display the content of the NuGet.config file
Get-Content -Path "NuGet.config"
displayName: 'Read NuGet.config [debug]'
-
-- task: DotNetCoreCLI@2
- displayName: 'Restore NuGets'
- inputs:
- command: 'custom'
- custom: 'msbuild'
- arguments: 'build.proj -t:restore'
- feedsToUse: 'select'
-
-- powershell: |
- $Doc = [xml](Get-Content "./Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj")
- $parent_xpath = '/Project/ItemGroup/ProjectReference'
- $node = $Doc.SelectSingleNode($parent_xpath)
- $parentNode = $node.ParentNode
- while($node -ne $null) {
- $node.ParentNode.RemoveChild($node)
- $node = $Doc.SelectSingleNode($parent_xpath)
- }
-
- $parent_xpath = '/Project/ItemGroup/PackageReference[@Include="Microsoft.Data.SqlClient"]'
- $node = $Doc.SelectSingleNode($parent_xpath)
-
- if($node -eq $null){
- $packagerefnode = $doc.createelement("packagereference")
- $value = $doc.selectsinglenode('/project/itemgroup/projectreference')
- $attrinclude = $doc.createattribute("include")
- $attrinclude.value = "microsoft.data.sqlclient"
- $packagerefnode.attributes.append($attrinclude)
- $parentNode.AppendChild($packageRefNode)
- }
-
- $currentFolder = Get-Location
- $filePath = Join-Path $currentFolder "Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj"
- $Doc.Save($filePath)
- workingDirectory: 'src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider'
- displayName: 'Update AKV Project Ref to Package Ref (.NET Framework/Core)'
diff --git a/eng/pipelines/dotnet-sqlclient-ci-core.yml b/eng/pipelines/dotnet-sqlclient-ci-core.yml
index 353122828b..e9b979a1f5 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-core.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-core.yml
@@ -58,9 +58,12 @@ parameters:
type: object
default: [net462, net8.0]
-- name: buildType
- displayName: 'Build Type'
- default: Project
+# The way we will reference sibling projects in the .csproj files:
+# Project - use references.
+# Package - use references to NuGet packages in the
+# packages/ directory.
+- name: referenceType
+ displayName: 'Reference Type'
values:
- Project
- Package
@@ -89,20 +92,46 @@ parameters:
variables:
- template: libraries/ci-build-variables.yml@self
- - name: artifactName
- value: Artifacts
+ - name: abstractionsArtifactName
+ value: Abstractions.Artifact
+
+ - name: mdsArtifactName
+ value: MDS.Artifact
- name: defaultHostedPoolName
value: 'Azure Pipelines'
stages:
- - stage: build_nugets
- displayName: 'Build NuGet Packages'
+
+ # Build the Abstractions package, and publish it to the pipeline artifacts
+ # under the name specified by the 'abstractionsArtifactName' variable.
+ - template: stages/build-abstractions-package-ci-stage.yml@self
+ parameters:
+ buildConfiguration: Release
+ packageVersion: $(abstractionsPackageVersion)
+ buildNumber: $(buildNumber)
+ artifactName: $(abstractionsArtifactName)
+ ${{if eq(parameters.debug, 'true')}}:
+ verbosity: diagnostic
+
+ # Build MDS and its NuGet packages.
+ - stage: build_mds_package
+ displayName: 'Build MDS Package'
+
+ # When building MDS via packages, we must depend on the Abstractions
+ # package.
+ ${{ if eq(parameters.referenceType, 'Package') }}:
+ dependsOn:
+ - build_abstractions_package_stage
+
jobs:
- template: common/templates/jobs/ci-build-nugets-job.yml@self
parameters:
+ referenceType: ${{ parameters.referenceType }}
configuration: ${{ parameters.buildConfiguration }}
- artifactName: $(artifactName)
+ abstractionsPackageVersion: $(abstractionsPackageVersion)
+ abstractionsArtifactName: $(abstractionsArtifactName)
+ mdsArtifactName: $(mdsArtifactName)
${{if ne(parameters.SNIVersion, '')}}:
prebuildSteps:
- template: common/templates/steps/override-sni-version.yml@self
@@ -114,40 +143,42 @@ stages:
- template: stages/stress-tests-ci-stage.yml@self
parameters:
buildConfiguration: ${{ parameters.buildConfiguration }}
- dependsOn: [build_nugets]
+ dependsOn: [build_mds_packages_job]
pipelineArtifactName: $(artifactName)
- mdsPackageVersion: $(NugetPackageVersion)
+ mdsPackageVersion: $(mdsPackageVersion)
${{ if eq(parameters.debug, 'true') }}:
verbosity: 'detailed'
- template: common/templates/stages/ci-run-tests-stage.yml@self
parameters:
debug: ${{ parameters.debug }}
- buildType: ${{ parameters.buildType }}
+ referenceType: ${{ parameters.referenceType }}
testsTimeout: ${{ parameters.testsTimeout }}
- ${{ if eq(parameters.buildType, 'Package') }}:
- dependsOn: build_nugets
-
- ${{if ne(parameters.SNIVersion, '')}}:
- prebuildSteps: # steps to run prior to building and running tests on each job
+ abstractionsArtifactName: $(abstractionsArtifactName)
+ abstractionsPackageVersion: $(abstractionsPackageVersion)
+ mdsArtifactName: $(mdsArtifactName)
+ mdsPackageVersion: $(mdsPackageVersion)
+
+ # When testing MDS via packages, we must depend on the Abstractions and
+ # MDS packages.
+ ${{ if eq(parameters.referenceType, 'Package') }}:
+ dependsOn:
+ - build_abstractions_package_stage
+ - build_nugets
+
+ prebuildSteps: # steps to run prior to building and running tests on each job
+ - ${{if ne(parameters.SNIVersion, '')}}:
- template: common/templates/steps/override-sni-version.yml@self
parameters:
SNIVersion: ${{parameters.SNIVersion}}
SNIValidationFeed: ${{parameters.SNIValidationFeed}}
- - template: common/templates/steps/ci-prebuild-step.yml@self
- parameters:
- debug: ${{ parameters.debug }}
- artifactName: $(artifactName)
- buildType: ${{ parameters.buildType }}
- ${{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)
- buildType: ${{ parameters.buildType }}
- ${{ if eq(parameters.buildType, 'Project') }}: # only run the code coverage job if the build type is project
+ - template: common/templates/steps/ci-prebuild-step.yml@self
+ parameters:
+ debug: ${{ parameters.debug }}
+ referenceType: ${{ parameters.referenceType }}
+
+ ${{ if eq(parameters.referenceType, 'Project') }}: # only run the code coverage job if the build type is project
postTestJobs: # jobs to run after the tests are done
- template: common/templates/jobs/ci-code-coverage-job.yml@self
parameters:
@@ -354,9 +385,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
@@ -383,9 +413,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
@@ -393,37 +422,6 @@ stages:
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
- ${{ 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 }}
@@ -469,9 +467,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
@@ -479,7 +476,65 @@ stages:
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
- ${{ if eq(variables['system.pullRequest.isFork'], 'False') }}: # only run enclave jobs if the password is available
+ # Self hosted SQL Server on Mac
+ mac_sql_22:
+ pool: $(defaultHostedPoolName)
+ hostedPool: true
+ images:
+ MacOSLatest_Sql22: macos-latest
+ TargetFrameworks: ${{parameters.targetFrameworksLinux }}
+ netcoreVersionTestUtils: ${{parameters.netcoreVersionTestUtils }}
+ buildPlatforms: [AnyCPU]
+ testSets: ${{parameters.testSets }}
+ useManagedSNI: [true]
+ codeCovTargetFrameworks: ${{parameters.codeCovTargetFrameworks }}
+ configSqlFor: local
+ operatingSystem: Mac
+ configProperties:
+ # config.json properties
+ TCPConnectionString: $(SQL_TCP_CONN_STRING)
+ NPConnectionString: $(SQL_NP_CONN_STRING)
+ SupportsIntegratedSecurity: false
+ 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:
@@ -507,26 +562,3 @@ stages:
UserManagedIdentityClientId: $(UserManagedIdentityClientId)
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
-
- # Self hosted SQL Server on Mac
- mac_sql_22:
- pool: $(defaultHostedPoolName)
- hostedPool: true
- images:
- MacOSLatest_Sql22: macos-latest
- TargetFrameworks: ${{parameters.targetFrameworksLinux }}
- netcoreVersionTestUtils: ${{parameters.netcoreVersionTestUtils }}
- buildPlatforms: [AnyCPU]
- testSets: ${{parameters.testSets }}
- useManagedSNI: [true]
- codeCovTargetFrameworks: ${{parameters.codeCovTargetFrameworks }}
- configSqlFor: local
- operatingSystem: Mac
- configProperties:
- # config.json properties
- TCPConnectionString: $(SQL_TCP_CONN_STRING)
- NPConnectionString: $(SQL_NP_CONN_STRING)
- SupportsIntegratedSecurity: false
- ManagedIdentitySupported: false
- 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 336bd97ab5..6eafba83cf 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml
@@ -74,13 +74,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
-
- name: buildConfiguration
displayName: 'Build Configuration'
default: Release
@@ -109,7 +102,7 @@ extends:
testSets: ${{ parameters.testSets }}
useManagedSNI: ${{ parameters.useManagedSNI }}
codeCovTargetFrameworks: ${{ parameters.codeCovTargetFrameworks }}
- buildType: ${{ parameters.buildType }}
+ referenceType: Package
buildConfiguration: ${{ parameters.buildConfiguration }}
enableStressTests: ${{ parameters.enableStressTests }}
testsTimeout: ${{ parameters.testsTimeout }}
diff --git a/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml b/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
index 38325d38ca..6169893061 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
@@ -66,13 +66,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
-
- name: buildConfiguration
displayName: 'Build Configuration'
default: Release
@@ -101,7 +94,7 @@ extends:
testSets: ${{ parameters.testSets }}
useManagedSNI: ${{ parameters.useManagedSNI }}
codeCovTargetFrameworks: ${{ parameters.codeCovTargetFrameworks }}
- buildType: ${{ parameters.buildType }}
+ referenceType: Project
buildConfiguration: ${{ parameters.buildConfiguration }}
enableStressTests: ${{ parameters.enableStressTests }}
testsTimeout: ${{ parameters.testsTimeout }}
diff --git a/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml b/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml
index b494a87426..ca49e3d402 100644
--- a/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml
+++ b/eng/pipelines/dotnet-sqlclient-signing-pipeline.yml
@@ -114,7 +114,7 @@ extends:
sbom:
enabled: ${{ not(parameters['isPreview']) }}
packageName: Microsoft.Data.SqlClient
- packageVersion: $(NugetPackageVersion)
+ packageVersion: $(mdsPackageVersion)
policheck:
enabled: ${{ not(parameters['isPreview']) }}
break: true # always break the build on policheck issues. You can disable it by setting to 'false'
diff --git a/eng/pipelines/jobs/build-akv-official-job.yml b/eng/pipelines/jobs/build-akv-official-job.yml
index a4374b773b..cbed1e2cbc 100644
--- a/eng/pipelines/jobs/build-akv-official-job.yml
+++ b/eng/pipelines/jobs/build-akv-official-job.yml
@@ -5,6 +5,9 @@
#################################################################################
parameters:
+ - name: akvPackageVersion
+ type: string
+
- name: apiScanDllPath
type: string
@@ -17,12 +20,6 @@ parameters:
- name: buildConfiguration
type: string
- - name: nugetPackageVersion
- type: string
-
- - name: mdsPackageVersion
- type: string
-
- name: publishSymbols
type: boolean
@@ -90,7 +87,7 @@ jobs:
parameters:
assemblyFileVersion: '${{ parameters.assemblyFileVersion }}'
buildConfiguration: '${{ parameters.buildConfiguration }}'
- mdsPackageVersion: '${{ parameters.mdsPackageVersion }}'
+ akvPackageVersion: '${{ parameters.akvPackageVersion }}'
- ${{ each targetFramework in parameters.targetFrameworks }}:
- template: ../steps/compound-extract-akv-apiscan-files-step.yml
@@ -104,7 +101,7 @@ jobs:
- template: ../steps/roslyn-analyzers-akv-step.yml@self
parameters:
buildConfiguration: '${{ parameters.buildConfiguration }}'
- mdsPackageVersion: '${{ parameters.mdsPackageVersion }}'
+ akvPackageVersion: '${{ parameters.akvPackageVersion }}'
- template: ../steps/compound-esrp-code-signing-step.yml@self
parameters:
@@ -120,7 +117,7 @@ jobs:
parameters:
buildConfiguration: '${{ parameters.buildConfiguration }}'
generateSymbolsPackage: true # Always generate symbols, even if they are not published
- packageVersion: '${{ parameters.nugetPackageVersion }}'
+ packageVersion: '${{ parameters.akvPackageVersion }}'
nuspecPath: '$(REPO_ROOT)/tools/specs/add-ons/$(PACKAGE_NAME).nuspec'
outputDirectory: '$(ARTIFACT_PATH)'
referenceType: 'Package'
@@ -138,7 +135,7 @@ jobs:
- ${{ if parameters.publishSymbols }}:
- template: ../steps/compound-publish-symbols-step.yml@self
parameters:
- artifactName: 'akv_symbols_$(System.TeamProject)_$(Build.Repository.Name)_$(Build.SourceBranchName)_${{ parameters.nugetPackageVersion }}_$(System.TimelineId)'
+ artifactName: 'akv_symbols_$(System.TeamProject)_$(Build.Repository.Name)_$(Build.SourceBranchName)_${{ parameters.akvPackageVersion }}_$(System.TimelineId)'
azureSubscription: '${{ parameters.symbolsAzureSubscription }}'
publishProjectName: '${{ parameters.symbolsPublishProjectName }}'
packageName: '$(PACKAGE_NAME)'
@@ -151,4 +148,4 @@ jobs:
Windows_NT/${{ parameters.buildConfiguration }}.AnyCPU/AzureKeyVaultProvider/**/$(PACKAGE_NAME).pdb
AnyOS/${{ parameters.buildConfiguration }}.AnyCPU/AzureKeyVaultProvider/**/$(PACKAGE_NAME).pdb
uploadAccount: '${{ parameters.symbolsUploadAccount }}'
- version: '${{ parameters.nugetPackageVersion }}'
+ version: '${{ parameters.akvPackageVersion }}'
diff --git a/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml b/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
new file mode 100644
index 0000000000..d7a6807474
--- /dev/null
+++ b/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
@@ -0,0 +1,143 @@
+################################################################################
+# 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 job packs the Abstractions package into NuGet and symbols packages and
+# publishes them as a named pipeline artifact.
+#
+# This template defines a job named 'pack_abstractions_package_job' that can be
+# depended on by downstream jobs.
+
+parameters:
+
+ # The name to apply to the published pipeline artifact.
+ - name: artifactName
+ type: string
+ default: Abstractions.Artifact
+
+ # The type of build to test (Release or Debug)
+ - name: buildConfiguration
+ type: string
+ values:
+ - Release
+ - Debug
+
+ # The list of upstream jobs to depend on.
+ - name: dependsOn
+ type: object
+ default: []
+
+ # The verbosity level for the dotnet CLI commands.
+ - name: verbosity
+ type: string
+ default: normal
+ values:
+ - quiet
+ - minimal
+ - normal
+ - detailed
+ - diagnostic
+
+jobs:
+
+ - job: pack_abstractions_package_job
+ displayName: 'Pack Abstractions Package'
+
+ dependsOn: ${{ parameters.dependsOn }}
+
+ pool:
+ name: Azure Pipelines
+ vmImage: ubuntu-latest
+
+ variables:
+
+ # The Abstractions solution file to use for all dotnet CLI commands.
+ - name: solution
+ value: src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
+
+ # The directory where the NuGet packages will be staged before being
+ # published as pipeline artifacts.
+ - name: dotnetPackagesDir
+ value: $(Build.StagingDirectory)/dotnetPackages
+
+ # dotnet CLI arguments common to all commands.
+ - name: commonArguments
+ value: >-
+ --verbosity ${{ parameters.verbosity }}
+
+ # dotnet CLI arguments for build/test/pack commands
+ - name: buildArguments
+ value: >-
+ $(commonArguments)
+ --configuration ${{ parameters.buildConfiguration }}
+
+ # 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 stress tests solution 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: ''
+
+ steps:
+
+ # Install the .NET 9.0 SDK.
+ - task: UseDotNet@2
+ displayName: Install .NET 9.0 SDK
+ inputs:
+ packageType: sdk
+ version: 9.x
+
+ # We use the 'custom' command because the DotNetCoreCLI@2 task doesn't
+ # support all of our argument combinations for the different build steps.
+
+ # Restore the solution.
+ - task: DotNetCoreCLI@2
+ displayName: Restore Solution
+ inputs:
+ command: custom
+ custom: restore
+ projects: $(solution)
+ arguments: $(commonArguments)
+
+ # Build the solution.
+ - task: DotNetCoreCLI@2
+ displayName: Build Solution
+ inputs:
+ command: custom
+ custom: build
+ projects: $(solution)
+ arguments: $(buildArguments) --no-restore
+
+ # Create the NuGet packages.
+ - task: DotNetCoreCLI@2
+ displayName: Create NuGet Package
+ inputs:
+ command: custom
+ custom: pack
+ projects: $(solution)
+ arguments: $(buildArguments) --no-build -o $(dotnetPackagesDir)
+
+ # Publish the NuGet packages as a named pipeline artifact.
+ - task: PublishPipelineArtifact@1
+ displayName: Publish Pipeline Artifact
+ inputs:
+ targetPath: $(dotnetPackagesDir)
+ artifactName: ${{ parameters.artifactName }}
+ publishLocation: pipeline
diff --git a/eng/pipelines/jobs/stress-tests-ci-job.yml b/eng/pipelines/jobs/stress-tests-ci-job.yml
index 2e01470fe5..cc2913c367 100644
--- a/eng/pipelines/jobs/stress-tests-ci-job.yml
+++ b/eng/pipelines/jobs/stress-tests-ci-job.yml
@@ -4,7 +4,7 @@
# file in the project root for more information.
################################################################################
-# This stage builds and runs stress tests against an MDS NuGet package available
+# This job builds and runs stress tests against an MDS NuGet package available
# as a pipeline artifact.
#
# The stress tests are located here:
diff --git a/eng/pipelines/jobs/test-abstractions-package-ci-job.yml b/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
new file mode 100644
index 0000000000..a2b25966d4
--- /dev/null
+++ b/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
@@ -0,0 +1,174 @@
+################################################################################
+# 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 job builds the Abstractions package and runs its tests for a set of .NET
+# runtimes.
+#
+# This template defines a job named 'test_abstractions_package_job_'
+# that can be depended on by downstream jobs.
+
+parameters:
+
+ # The type of build to test (Release or Debug)
+ - name: buildConfiguration
+ type: string
+ values:
+ - Release
+ - Debug
+
+ # The prefix to prepend to the job's display name:
+ #
+ # [] Run Stress Tests
+ #
+ - name: displayNamePrefix
+ type: string
+
+ # The suffix to append to the job name.
+ - name: jobNameSuffix
+ type: string
+
+ # The list of .NET Framework runtimes to test against.
+ - name: netFrameworkRuntimes
+ type: object
+ default: []
+
+ # The list of .NET runtimes to test against.
+ - name: netRuntimes
+ type: object
+ default: []
+
+ # The name of the Azure Pipelines pool to use.
+ - name: poolName
+ type: string
+
+ # The verbosity level for the dotnet CLI commands.
+ - name: verbosity
+ type: string
+ default: normal
+ values:
+ - quiet
+ - minimal
+ - normal
+ - detailed
+ - diagnostic
+
+ # The pool VM image to use.
+ - name: vmImage
+ type: string
+
+jobs:
+
+ - job: test_abstractions_package_job_${{ parameters.jobNameSuffix }}
+ displayName: '[${{ parameters.displayNamePrefix }}] Test Abstractions Package'
+ pool:
+ name: ${{ parameters.poolName }}
+
+ # Images provided by Azure Pipelines must be selected using 'vmImage'.
+ ${{ if eq(parameters.poolName, 'Azure Pipelines') }}:
+ vmImage: ${{ parameters.vmImage }}
+ # Images provided by 1ES must be selected using a demand.
+ ${{ else }}:
+ demands:
+ - imageOverride -equals ${{ parameters.vmImage }}
+
+ variables:
+
+ # The Abstractions solution file to use for all dotnet CLI commands.
+ - name: solution
+ value: src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
+
+ # dotnet CLI arguments common to all commands.
+ - name: commonArguments
+ value: >-
+ --verbosity ${{ parameters.verbosity }}
+
+ # dotnet CLI arguments for build/test/pack commands
+ - name: buildArguments
+ value: >-
+ $(commonArguments)
+ --configuration ${{ parameters.buildConfiguration }}
+
+ # 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 stress tests solution 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: ''
+
+ steps:
+
+ # Install the .NET 9.0 SDK.
+ - task: UseDotNet@2
+ displayName: Install .NET 9.0 SDK
+ inputs:
+ packageType: sdk
+ version: 9.x
+
+ # Install the .NET 8.0 runtime.
+ - task: UseDotNet@2
+ displayName: Install .NET 8.0 Runtime
+ inputs:
+ packageType: runtime
+ version: 8.x
+
+ # The Windows agent images include a suitable .NET Framework runtime, so
+ # we don't have to install one explicitly.
+
+ # We use the 'custom' command because the DotNetCoreCLI@2 task doesn't
+ # support all of our argument combinations for the different build steps.
+
+ # Restore the solution.
+ - task: DotNetCoreCLI@2
+ displayName: Restore Solution
+ inputs:
+ command: custom
+ custom: restore
+ projects: $(solution)
+ arguments: $(commonArguments)
+
+ # Build the solution.
+ - task: DotNetCoreCLI@2
+ displayName: Build Solution
+ inputs:
+ command: custom
+ custom: build
+ projects: $(solution)
+ arguments: $(buildArguments) --no-restore
+
+ # Run the tests for each .NET runtime.
+ - ${{ each runtime in parameters.netRuntimes }}:
+ - task: DotNetCoreCLI@2
+ displayName: Test [${{ runtime }}]
+ inputs:
+ command: custom
+ custom: test
+ projects: $(solution)
+ arguments: $(buildArguments) --no-build -f ${{ runtime }}
+
+ # Run the tests for each .NET Framework runtime.
+ - ${{ each runtime in parameters.netFrameworkRuntimes }}:
+ - task: DotNetCoreCLI@2
+ displayName: Test [${{ runtime }}]
+ inputs:
+ command: custom
+ custom: test
+ projects: $(solution)
+ arguments: $(buildArguments) --no-build -f ${{ runtime }}
diff --git a/eng/pipelines/libraries/ci-build-variables.yml b/eng/pipelines/libraries/ci-build-variables.yml
index 122281e083..ac39665b62 100644
--- a/eng/pipelines/libraries/ci-build-variables.yml
+++ b/eng/pipelines/libraries/ci-build-variables.yml
@@ -15,7 +15,9 @@ variables:
value: 'net8.0'
- name: SQLTarget
value: 'localhost'
- - name: NugetPackageVersion
+ - name: akvPackageVersion
+ value: 1.0.0.$(buildNumber)
+ - name: mdsPackageVersion
value: $(Major).$(Minor)$(Patch)-pull.1$(buildnumber)
- name: skipComponentGovernanceDetection
value: true
diff --git a/eng/pipelines/libraries/common-variables.yml b/eng/pipelines/libraries/common-variables.yml
index 8fc6aec755..b7df898497 100644
--- a/eng/pipelines/libraries/common-variables.yml
+++ b/eng/pipelines/libraries/common-variables.yml
@@ -40,9 +40,9 @@ variables:
- name: Revision
value: '1'
- - name: NugetPackageVersion
+ - name: mdsPackageVersion
value: $(Major).$(Minor).$(Patch)
- - name: PreviewNugetPackageVersion
+ - name: previewMdsPackageVersion
value: $(Major).$(Minor).$(Patch)$(Preview)$(Revision).$(Build.BuildNumber)
- name: AssemblyFileVersion
value: '$(Major).$(Minor)$(Patch).$(Build.BuildNumber)'
diff --git a/eng/pipelines/libraries/mds-validation-variables.yml b/eng/pipelines/libraries/mds-validation-variables.yml
index d7723a059f..93dc0804ff 100644
--- a/eng/pipelines/libraries/mds-validation-variables.yml
+++ b/eng/pipelines/libraries/mds-validation-variables.yml
@@ -13,7 +13,7 @@ variables:
- name: extractedNugetRootPath
value: $(Build.SourcesDirectory)\$(TempFolderName)\Microsoft.Data.SqlClient
- name: extractedNugetPath
- value: $(extractedNugetRootPath).$(NugetPackageVersion)
+ value: $(extractedNugetRootPath).$(mdsPackageVersion)
- name: expectedFolderNames
value: lib,ref,runtimes
- name: expectedDotnetVersions
diff --git a/eng/pipelines/stages/build-abstractions-package-ci-stage.yml b/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
new file mode 100644
index 0000000000..8e71ffad66
--- /dev/null
+++ b/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
@@ -0,0 +1,124 @@
+################################################################################
+# 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 Abstractions package, runs tests, and publishes the
+# resulting NuGet packages as pipeline artifacts.
+#
+# The NuGet packages have the following properties:
+#
+# Name: Microsoft.Data.SqlClient.Extensions.Abstractions Version:
+# .
+#
+# Where and are the values of the
+# 'packageVersion' and 'buildNumber' parameters, respectively.
+#
+# The following NuGet packages are published:
+#
+# Microsoft.Data.SqlClient.Extensions.Abstractions..nupkg
+# Microsoft.Data.SqlClient.Extensions.Abstractions..snupkg (symbols)
+#
+# The packages are published to pipeline artifacts with the name specified by
+# the 'artifactName' parameter.
+#
+# This template defines a stage named 'build_abstractions_package_stage' that
+# can be depended on by downstream stages.
+
+parameters:
+
+ # The name of the pipeline artifact to publish.
+ - name: artifactName
+ type: string
+ default: Abstractions.Artifact
+
+ # The type of build to produce (Release or Debug)
+ - name: buildConfiguration
+ type: string
+ default: Release
+ values:
+ - Release
+ - Debug
+
+ # The build number of the pipeline.
+ - name: buildNumber
+ type: string
+ default: $(Build.BuildNumber)
+
+ # The version (Major.Minor.Patch) to apply to the package.
+ - name: packageVersion
+ type: string
+ default: ''
+
+ # The verbosity level for the dotnet CLI commands.
+ - name: verbosity
+ type: string
+ default: normal
+ values:
+ - quiet
+ - minimal
+ - normal
+ - detailed
+ - diagnostic
+
+stages:
+
+ - stage: build_abstractions_package_stage
+ displayName: Build Abstractions Package
+
+ jobs:
+
+ # ------------------------------------------------------------------------
+ # Build and test on Linux.
+
+ - template: ../jobs/test-abstractions-package-ci-job.yml@self
+ parameters:
+ jobNameSuffix: linux
+ displayNamePrefix: Linux
+ poolName: Azure Pipelines
+ vmImage: ubuntu-latest
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ netRuntimes: [net8.0, net9.0]
+ netFrameworkRuntimes: []
+
+ # ------------------------------------------------------------------------
+ # Build and test on Windows
+
+ - template: ../jobs/test-abstractions-package-ci-job.yml@self
+ parameters:
+ jobNameSuffix: windows
+ displayNamePrefix: Win
+ poolName: Azure Pipelines
+ vmImage: windows-latest
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ netRuntimes: [net8.0, net9.0]
+ netFrameworkRuntimes: [net462, net47, net471, net472, net48, net481]
+
+ # ------------------------------------------------------------------------
+ # Build and test on macOS.
+
+ - template: ../jobs/test-abstractions-package-ci-job.yml
+ parameters:
+ jobNameSuffix: macos
+ displayNamePrefix: macOS
+ poolName: Azure Pipelines
+ vmImage: macos-latest
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ netRuntimes: [net8.0, net9.0]
+ netFrameworkRuntimes: []
+
+ # ------------------------------------------------------------------------
+ # Create and publish the NuGet package.
+
+ - template: ../jobs/pack-abstractions-package-ci-job.yml@self
+ parameters:
+ artifactName: ${{ parameters.artifactName }}
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ verbosity: ${{ parameters.verbosity }}
+ dependsOn:
+ # We depend on all of the test jobs to ensure the tests pass before
+ # producing the NuGet package.
+ - test_abstractions_package_job_linux
+ - test_abstractions_package_job_windows
+ - test_abstractions_package_job_macos
diff --git a/eng/pipelines/steps/compound-build-akv-step.yml b/eng/pipelines/steps/compound-build-akv-step.yml
index 906dcfaf72..a547604a2c 100644
--- a/eng/pipelines/steps/compound-build-akv-step.yml
+++ b/eng/pipelines/steps/compound-build-akv-step.yml
@@ -7,16 +7,16 @@
# @TODO: This can probably be made generic and pass in the command lines for msbuild
# BUT, they should be kept separate by now as we rebuild build.proj in parallel, we won't
# affect >1 project at a time.
-# @TODO: NugetPackageVersion should not be used for MDS package version
+# @TODO: mdsPackageVersion should not be used for MDS package version
parameters:
- - name: assemblyFileVersion
+ - name: akvPackageVersion
type: string
- - name: buildConfiguration
+ - name: assemblyFileVersion
type: string
- - name: mdsPackageVersion
+ - name: buildConfiguration
type: string
steps:
@@ -46,7 +46,7 @@ steps:
msbuildArguments: >-
-t:BuildAkv
-p:AssemblyFileVersion=${{ parameters.assemblyFileVersion }}
- -p:NugetPackageVersion=${{ parameters.mdsPackageVersion }}
+ -p:AkvPackageVersion=${{ parameters.akvPackageVersion }}
-p:ReferenceType=Package
-p:SigningKeyPath=$(Agent.TempDirectory)/netfxKeypair.snk
diff --git a/eng/pipelines/steps/roslyn-analyzers-akv-step.yml b/eng/pipelines/steps/roslyn-analyzers-akv-step.yml
index 0e05177d5a..c7acc84088 100644
--- a/eng/pipelines/steps/roslyn-analyzers-akv-step.yml
+++ b/eng/pipelines/steps/roslyn-analyzers-akv-step.yml
@@ -9,10 +9,10 @@
# affect >1 project at a time.
parameters:
- - name: buildConfiguration
+ - name: akvPackageVersion
type: string
- - name: mdsPackageVersion
+ - name: buildConfiguration
type: string
steps:
@@ -25,7 +25,7 @@ steps:
$(REPO_ROOT)/build.proj
-t:BuildAkv
-p:Configuration=${{ parameters.buildConfiguration }}
- -p:NugetPackageVersion=${{ parameters.mdsPackageVersion }}
+ -p:AkvPackageVersion=${{ parameters.akvPackageVersion }}
-p:ReferenceType=Package
msBuildVersion: 17.0
setupCommandLinePicker: vs2022
diff --git a/eng/pipelines/variables/akv-official-variables.yml b/eng/pipelines/variables/akv-official-variables.yml
index aaf8de7c5e..b22044548d 100644
--- a/eng/pipelines/variables/akv-official-variables.yml
+++ b/eng/pipelines/variables/akv-official-variables.yml
@@ -37,7 +37,5 @@ variables:
# Compound Variables ---------------------------------------------------
- name: assemblyFileVersion
value: '${{ variables.versionMajor }}.${{ variables.versionMinor }}${{ variables.versionPatch }}.$(Build.BuildNumber)'
- - name: nugetPackageVersion
+ - name: akvPackageVersion
value: '${{ variables.versionMajor }}.${{ variables.versionMinor }}.${{ variables.versionPatch }}${{ variables.versionPreview }}'
-
-
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 4c210df737..69143965a9 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 6ceddccd37..6cf7a6bc93 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -7,6 +7,13 @@
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
new file mode 100644
index 0000000000..9632efff88
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/Abstractions.slnx
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/README.md b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/README.md
new file mode 100644
index 0000000000..d2a24b898c
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/README.md
@@ -0,0 +1,285 @@
+# MDS Azure Extension Design
+
+## 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` extension package:
+
+- Create a new `Abstractions` 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 `AzureKeyVaultProvider` (AKV) implementation into the new
+ `Azure` extension package.
+
+This will reduce the main MDS package dependency tree along with a moderate
+package size reduction.
+
+## Motivation
+
+Issue: [#1108](https://github.com/dotnet/SqlClient/issues/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` extension
+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.
+
+The following dependencies will be removed from the main MDS package:
+
+- `Azure.Identity`
+ - `Azure.Core` (transitive)
+ - `Microsoft.Identity.Client` (transitive)
+- `Microsoft.IdentityModel.JsonWebTokens`
+ - `Microsoft.IdentityModel.Tokens` (transitive)
+ - `Microsoft.IdentityModel.Logging` (transitive)
+- `Microsoft.IdentityModel.Protocols.OpenIdConnect`
+ - `Microsoft.IdentityModel.Protocols` (transitive)
+
+The following dependencies will be removed from the AKV Provider package:
+
+- `Azure.Core`
+- `Azure.Security.KeyVault.Keys`
+
+## Package Architecture
+
+```mermaid
+classDiagram
+class MDS
+class MDS.Extensions.Abstractions
+class MDS.Extensions.Azure
+class AKV Provider
+
+MDS --> MDS.Extensions.Abstractions
+MDS ..> MDS.Extensions.Azure
+MDS ..> AKV Provider
+MDS.Extensions.Azure --> MDS.Extensions.Abstractions
+AKV Provider --> MDS.Extensions.Azure
+
+MDS: Depend on MDS.Extensions.Abstractions
+MDS: Load Azure or AKV assembly
+MDS.Extensions.Abstractions: Azure Authentication Types
+MDS.Extensions.Abstractions: Azure Attestation Types
+MDS.Extensions.Abstractions: Azure Key Vault Types
+MDS.Extensions.Azure: Depend on MDS.Extensions.Abstractions
+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 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 `Abstractions` 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 `Abstractions` 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
+
+
+
+```
+
+Calls to MDS APIs that require Azure features will throw an exception, since
+no Azure feature implementation is present.
+
+### With MDS Azure Features
+
+Applications that wish to use MDS-supplied Azure features will need to include
+the new `Azure` extension package as a direct dependency alongside the main MDS
+package:
+
+```xml
+
+
+
+
+```
+
+MDS will automatically detect the `Azure` extension assemblies and load them.
+
+### 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, 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: _**New API will be exposed.**_
+- 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 independently. This provides
+flexibility to update APIs and implementations for packages as needed, avoiding
+unnecessary version bumps and releases. The initial release of these packages
+will have the following versions:
+
+|Package|Version|Comment|
+|-|-|-|
+|`Microsoft.Data.SqlClient.Extensions.Abstractions`|1.0.0|First version of this package.|
+|`Microsoft.Data.SqlClient`|7.0.0|Major version bump due to breaking changes described in this document.|
+|`Microsoft.Data.SqlClient.Extensions.Azure`|1.0.0|First version of this package.|
+|`Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider`|7.0.0|_**Deprecated.**_|
+
+Going forward, each package will be versioned appropriately based on the nature
+of the changes included with subsequent releases.
+
+**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`
+extension package.
+
+## Intradependence
+
+The main MDS package and the new `Azure` package will depend on the
+`Abstractions` package. When APIs are added, modified, or removed from the
+`Abstractions` package, corresponding changes will be made to the dependent
+packages as well. Those dependent packages will then take a strict dependency
+on the appropriate `Abstractions` package version. This ensures that only
+compatible extensions package versions can co-exist with the main MDS package.
+
+For example, imagine that a new extensible conenction pooling feature is added
+to MDS. The `Abstractions` package would be updated to include any new pooling
+APIs, the main MDS package would be updated to accept extensible pooling, and
+the new pooling implementation would be included in a new `ConnectionPooling`
+extension package. The versions of these packages would look something like
+this:
+
+|Package|Version|
+|-|-|
+|`Microsoft.Data.SqlClient.Extensions.Abstractions`|1.1.0|
+|`Microsoft.Data.SqlClient`|7.1.0|
+|`Microsoft.Data.SqlClient.Extensions.ConnectionPooling`|1.0.0|
+
+Both the main MDS package and the new `ConnectionPooling` package would depend
+on `Abstractions` v1.1.0.
+
+An application wishing to use the new `ConnectionPooling` v1.0.0 package must
+also update the main MDS package to v7.1.0. The applictaion would not be able
+to use `ConnectionPooling` v1.0.0 and MDS v7.0.0.
+
+## Backwards Compatibility
+
+There are several backwards compatibility scenarios to consider for applications
+that rely on MDS Azure features currently implemented in the main MDS package
+and the AKV 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
+latest versions of MDS packages.
+
+### Apps using MDS Azure Authentication
+
+Applications currently using the MDS-supplied Azure Authentication features will
+need to add a dependency on 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.
+
+### Apps using MDS Azure Attestation
+
+Applications currently using the MDS-supplied Azure Attestation features will
+need to add a dependency on the `Azure` extension package to their project
+alongside the main MDS package:
+
+```xml
+
+
+
+
+```
+
+All Azure Attestation namespaces and types will remain the same, so this should
+be the only change necessary for applications.
+
+### Apps using AKV Provider
+
+Applications currently using the MDS-supplied AKV provider will have two options
+when upgrading to MDS v7.0.0. Both 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` extension package:
+
+```xml
+
+
+
+
+```
+
+The `Azure` extension 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` extension assembly and automatically load it.
+
+#### Use AKV Provider v7.0.0
+
+This is a temporary solution. The AKV provider v7.0.0 will be marked as
+deprecated and removed entirely at some point in the future. The applictaion
+would remain dependent on the AKV provider, but must update to the v7.0.0
+package. Previous AKV package versions do not support main MDS package versions
+beyond the v6.x range.
+
+```xml
+
+
+
+
+```
+
+This AKV Provider v7.0.0 package will be empty and simply depend on the `Azure`
+extension package to transitively provide the Azure Key Vault features.
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/doc/Sample.xml b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/doc/Sample.xml
new file mode 100644
index 0000000000..8d5f5c44d5
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/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/Abstractions/src/Abstractions.csproj b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
new file mode 100644
index 0000000000..8844458f1b
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+ 1
+
+
+ $(AbstractionsPackageMajorVersion).0.0
+
+
+ $(AbstractionsPackageVersion).$(BuildNumber)
+
+
+ $(AbstractionsPackageMajorVersion).0.0.0
+
+
+
+
+ netstandard2.0
+
+
+
+
+ enable
+ enable
+
+
+
+
+ Microsoft.Data.SqlClient.Extensions.Abstractions
+
+ $(AbstractionsPackageVersion)
+ $(AbstractionsPackageAssemblyVersion)
+ $(PackageVersion)
+ $(AssemblyFileVersion)
+
+ Microsoft.Data.SqlClient.Extensions.Abstractions
+
+
+
+
+ <_Parameter1>true
+
+
+
+
+
+
+
+
+
+
+
+
+ $(PackagesDir)
+ true
+ snupkg
+
+
+ $(OriginalAllowedOutputExtensions)
+
+ Microsoft Corporation
+ Microsoft Corporation
+ Microsoft.Data.SqlClient Extensions Abstractions
+ https://github.com/dotnet/SqlClient
+ MIT
+ dotnet.png
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Sample.cs b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Sample.cs
new file mode 100644
index 0000000000..bf22119436
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Sample.cs
@@ -0,0 +1,20 @@
+namespace Microsoft.Data.SqlClient.Extensions.Abstractions;
+
+///
+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/Abstractions/test/Abstractions.Test.csproj b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
new file mode 100644
index 0000000000..118b215737
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
@@ -0,0 +1,26 @@
+
+
+
+ net462;net47;net471;net472;net48;net481;net8.0;net9.0
+ enable
+ enable
+ false
+ true
+ Microsoft.Data.SqlClient.Extensions.Abstractions.Test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/SampleTest.cs b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/SampleTest.cs
new file mode 100644
index 0000000000..ab8e9da052
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/SampleTest.cs
@@ -0,0 +1,19 @@
+namespace Microsoft.Data.SqlClient.Extensions.Abstractions.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..2b8e583a8d 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
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
@@ -303,6 +304,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Data.SqlClient.Un
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Microsoft.Data.SqlClient\tests\Common\Common.csproj", "{67128EC0-30F5-6A98-448B-55F88A1DE707}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.SqlClient.Extensions", "Microsoft.Data.SqlClient.Extensions", "{19F1F1E5-3013-7660-661A-2A15F7D606C1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Abstractions", "Abstractions", "{556B486E-F9B0-7EA9-6A25-DA560C312761}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{210228A5-979A-DE06-EE1F-B35C65E1583C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abstractions", "Microsoft.Data.SqlClient.Extensions\Abstractions\src\Abstractions.csproj", "{B21E7C94-D805-427E-928A-8DE8EA2F08CC}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{59667E4C-0BD2-9F48-FB50-9E55DD8B1011}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abstractions.Test", "Microsoft.Data.SqlClient.Extensions\Abstractions\test\Abstractions.Test.csproj", "{04ACBF75-CFF2-41AB-B652-776BC0533490}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -571,6 +584,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
+ {B21E7C94-D805-427E-928A-8DE8EA2F08CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B21E7C94-D805-427E-928A-8DE8EA2F08CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B21E7C94-D805-427E-928A-8DE8EA2F08CC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B21E7C94-D805-427E-928A-8DE8EA2F08CC}.Debug|x64.Build.0 = Debug|Any CPU
+ {B21E7C94-D805-427E-928A-8DE8EA2F08CC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B21E7C94-D805-427E-928A-8DE8EA2F08CC}.Debug|x86.Build.0 = Debug|Any CPU
+ {B21E7C94-D805-427E-928A-8DE8EA2F08CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B21E7C94-D805-427E-928A-8DE8EA2F08CC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B21E7C94-D805-427E-928A-8DE8EA2F08CC}.Release|x64.ActiveCfg = Release|Any CPU
+ {B21E7C94-D805-427E-928A-8DE8EA2F08CC}.Release|x64.Build.0 = Release|Any CPU
+ {B21E7C94-D805-427E-928A-8DE8EA2F08CC}.Release|x86.ActiveCfg = Release|Any CPU
+ {B21E7C94-D805-427E-928A-8DE8EA2F08CC}.Release|x86.Build.0 = Release|Any CPU
+ {04ACBF75-CFF2-41AB-B652-776BC0533490}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {04ACBF75-CFF2-41AB-B652-776BC0533490}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {04ACBF75-CFF2-41AB-B652-776BC0533490}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {04ACBF75-CFF2-41AB-B652-776BC0533490}.Debug|x64.Build.0 = Debug|Any CPU
+ {04ACBF75-CFF2-41AB-B652-776BC0533490}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {04ACBF75-CFF2-41AB-B652-776BC0533490}.Debug|x86.Build.0 = Debug|Any CPU
+ {04ACBF75-CFF2-41AB-B652-776BC0533490}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {04ACBF75-CFF2-41AB-B652-776BC0533490}.Release|Any CPU.Build.0 = Release|Any CPU
+ {04ACBF75-CFF2-41AB-B652-776BC0533490}.Release|x64.ActiveCfg = Release|Any CPU
+ {04ACBF75-CFF2-41AB-B652-776BC0533490}.Release|x64.Build.0 = Release|Any CPU
+ {04ACBF75-CFF2-41AB-B652-776BC0533490}.Release|x86.ActiveCfg = Release|Any CPU
+ {04ACBF75-CFF2-41AB-B652-776BC0533490}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -621,6 +658,11 @@ 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}
+ {556B486E-F9B0-7EA9-6A25-DA560C312761} = {19F1F1E5-3013-7660-661A-2A15F7D606C1}
+ {210228A5-979A-DE06-EE1F-B35C65E1583C} = {556B486E-F9B0-7EA9-6A25-DA560C312761}
+ {B21E7C94-D805-427E-928A-8DE8EA2F08CC} = {210228A5-979A-DE06-EE1F-B35C65E1583C}
+ {59667E4C-0BD2-9F48-FB50-9E55DD8B1011} = {556B486E-F9B0-7EA9-6A25-DA560C312761}
+ {04ACBF75-CFF2-41AB-B652-776BC0533490} = {59667E4C-0BD2-9F48-FB50-9E55DD8B1011}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {01D48116-37A2-4D33-B9EC-94793C702431}
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 0944a4aea0..4b658f409a 100644
--- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj
@@ -46,7 +46,20 @@
-
+
+
+
+
+
+
+
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 50b04819ba..19951ebc96 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
@@ -1067,6 +1067,19 @@
+
+
+
+
+
+
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 380a2aa746..f73b8682a0 100644
--- a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj
@@ -49,5 +49,19 @@
+
+
+
+
+
+
+
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 17eeb3a472..a378ef5f51 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
@@ -1040,6 +1040,20 @@
+
+
+
+
+
+
+
diff --git a/tools/props/Versions.props b/tools/props/Versions.props
index ad42c4964a..e37e4c7fb1 100644
--- a/tools/props/Versions.props
+++ b/tools/props/Versions.props
@@ -1,29 +1,40 @@
-
+
+
+
- 7.0.0
0
+
+
+
+
+ 7.0.0
+
+ $(MdsVersionDefault).$(BuildNumber)-dev
+
+
$(MdsVersionDefault).$(BuildNumber)
-
+
+
7.0.0.0
$(AssemblyFileVersion)
- $(MdsVersionDefault)-dev
- $(NugetPackageVersion)
+ $(MdsPackageVersion)
+
+
@@ -33,8 +44,10 @@
1.0.0-dev
$(SqlServerPackageVersion)
+
+
- $(NugetPackageVersion)
+ $(AkvPackageVersion)
- $(NugetPackageVersion)
+ $(MdsPackageVersion)
diff --git a/tools/specs/Microsoft.Data.SqlClient.nuspec b/tools/specs/Microsoft.Data.SqlClient.nuspec
index 67d0078279..204f6b110b 100644
--- a/tools/specs/Microsoft.Data.SqlClient.nuspec
+++ b/tools/specs/Microsoft.Data.SqlClient.nuspec
@@ -32,6 +32,7 @@
+
@@ -48,6 +49,7 @@
+
@@ -62,6 +64,7 @@
+
@@ -76,6 +79,7 @@
+
diff --git a/tools/targets/GenerateNugetPackage.targets b/tools/targets/GenerateNugetPackage.targets
index 4c8cea4159..7b674ebfdb 100644
--- a/tools/targets/GenerateNugetPackage.targets
+++ b/tools/targets/GenerateNugetPackage.targets
@@ -1,10 +1,10 @@
-
+
- $(NugetPackageVersion)-debug
+ $(MdsPackageVersion)-debug
-
+
@@ -12,7 +12,7 @@
-
+
diff --git a/tools/targets/add-ons/GenerateAKVProviderNugetPackage.targets b/tools/targets/add-ons/GenerateAKVProviderNugetPackage.targets
index 78da74bf32..aa50a32463 100644
--- a/tools/targets/add-ons/GenerateAKVProviderNugetPackage.targets
+++ b/tools/targets/add-ons/GenerateAKVProviderNugetPackage.targets
@@ -2,11 +2,11 @@
- $(NugetPackageVersion)-debug
+ $(AkvPackageVersion)-debug
-
+
-
+
From 50c52c177144792347d5043d137eacdc12b42a3c Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Tue, 23 Sep 2025 07:53:34 -0300
Subject: [PATCH 30/30] User Story 37654: Create Abstractions package
- Fixed duplicate parameters from git merge.
---
.../common/templates/stages/ci-run-tests-stage.yml | 7 -------
1 file changed, 7 deletions(-)
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 a44f01837a..46318f8e06 100644
--- a/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
+++ b/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
@@ -42,13 +42,6 @@ parameters:
- name: testConfigurations
type: object
- - name: prebuildSteps
- type: stepList
- default: []
-
- - name: testConfigurations
- type: object
-
# The timeout, in minutes, for each test job.
- name: testsTimeout
type: string