diff --git a/.editorconfig b/.editorconfig index 19e2a3c9be..0543e5fd6e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -159,7 +159,7 @@ dotnet_diagnostic.xUnit1031.severity=none dotnet_diagnostic.xUnit1030.severity=none # Xml files -[*.{xml,csproj,stylecop,resx,ruleset,props,targets,config,nuspec}] +[*.{xml,slnx,proj,csproj,stylecop,resx,ruleset,props,targets,config,nuspec}] indent_size = 2 # Shell scripts diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index efeb747cad..7984813fb1 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.| +|`BuildAbstractions`|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,12 +50,11 @@ 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 msbuild -t:BuildTestsNetFx -p:TF=net462 msbuild -t:BuildTestsNetCore msbuild -t:RunTests @@ -59,28 +63,25 @@ 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: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 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:BuildTestsNetFx -p:TF=net462 +msbuild -t:BuildTestsNetCore +msbuild -t:RunTests -p:DotnetPath=C:\net8-win-x86\ ``` ### Running Manual Tests @@ -119,15 +120,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 +151,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 +194,39 @@ 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 -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 +245,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 +288,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..3e762e7fe9 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,11 +1,30 @@  + + - + + + + + + + + diff --git a/build.proj b/build.proj index 0443bbcf4e..28b9a99eb4 100644 --- a/build.proj +++ b/build.proj @@ -2,8 +2,9 @@ - - + + + @@ -29,7 +30,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 +87,96 @@ - - - + + + - - + + + + + + + AbstractionsPackageVersion=$(AbstractionsPackageVersion) + + + + + $(AbstractionsProperties);AbstractionsAssemblyFileVersion=$(AbstractionsAssemblyFileVersion) + + + + + + + + + + + + + + + + + + + + - + - + - + - + @@ -122,7 +189,10 @@ - + @@ -139,27 +209,37 @@ - + - + + - + - - + + @@ -168,7 +248,9 @@ - + @@ -177,12 +259,18 @@ - + - + @@ -191,7 +279,10 @@ - + @@ -346,14 +437,14 @@ - + - - - - - - + + + + + + @@ -388,7 +479,10 @@ - + @@ -398,7 +492,9 @@ - + @@ -408,7 +504,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 91eb864337..21539540df 100644 --- a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml +++ b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml @@ -51,6 +51,7 @@ jobs: - template: ../steps/generate-nuget-package-step.yml@self parameters: OutputDirectory: $(artifactDirectory) + properties: 'AbstractionsPackageVersion=$(abstractionsPackageVersion)' - 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 cb3790262c..5642d5be47 100644 --- a/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml +++ b/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml @@ -58,6 +58,7 @@ jobs: nuspecPath: 'tools/specs/Microsoft.Data.SqlClient.nuspec' OutputDirectory: $(packagePath) generateSymbolsPackage: false + properties: 'AbstractionsPackageVersion=$(abstractionsPackageVersion)' displayName: 'Generate NuGet package M.D.SqlClient' - template: ../steps/generate-nuget-package-step.yml@self @@ -67,6 +68,7 @@ jobs: nuspecPath: 'tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec' OutputDirectory: $(packagePath) generateSymbolsPackage: false + properties: 'MdsPackageVersion=$(mdsPackageVersion)' installNuget: false displayName: 'Generate NuGet package AKV Provider' 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..8a8fd00f6f 100644 --- a/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml +++ b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml @@ -32,11 +32,11 @@ parameters: type: boolean default: true - - name: referenceType - default: project - values: - - project - - package + # Semi-colon separated properties to pass to nuget via the -properties + # argument. + - name: properties + type: string + default: '' steps: - ${{ if parameters.installNuget }}: @@ -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.NugetPackageVersion}} -OutputDirectory ${{parameters.OutputDirectory}} -properties "COMMITID=$(CommitHead);Configuration=${{parameters.Configuration}};${{parameters.properties}}"' ${{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.NugetPackageVersion}} -OutputDirectory ${{parameters.OutputDirectory}} -properties "COMMITID=$(CommitHead);Configuration=${{parameters.Configuration}};${{parameters.properties}}"' diff --git a/eng/pipelines/libraries/ci-build-variables.yml b/eng/pipelines/libraries/ci-build-variables.yml index 122281e083..d3ae6fcbc3 100644 --- a/eng/pipelines/libraries/ci-build-variables.yml +++ b/eng/pipelines/libraries/ci-build-variables.yml @@ -23,3 +23,13 @@ variables: value: false - name: packagePath value: '$(Build.SourcesDirectory)/packages' + + # TODO(ADO-38703): Remove these when the other pipeline changes arrive. + - name: baseBuildNumber + value: $[ split(variables['Build.BuildNumber'], '.')[0] ] + - name: abstractionsPackageVersion + value: 1.0.0.$(baseBuildNumber) + - name: mdsPackageVersion + value: $(NugetPackageVersion) + - name: akvPackageVersion + value: $(NugetPackageVersion) diff --git a/eng/pipelines/libraries/common-variables.yml b/eng/pipelines/libraries/common-variables.yml index 8fc6aec755..3e3cb15559 100644 --- a/eng/pipelines/libraries/common-variables.yml +++ b/eng/pipelines/libraries/common-variables.yml @@ -34,7 +34,7 @@ variables: - name: Patch value: '0' - # Update this for preview releases. + # Update this for preview releases. - name: Preview value: '-preview' - name: Revision @@ -48,3 +48,13 @@ variables: value: '$(Major).$(Minor)$(Patch).$(Build.BuildNumber)' - name: nuspecPath value: '$(REPOROOT)/tools/specs/Microsoft.Data.SqlClient.nuspec' + + # TODO(ADO-38703): Remove these when the other pipeline changes arrive. + - name: baseBuildNumber + value: $[ split(variables['Build.BuildNumber'], '.')[0] ] + - name: abstractionsPackageVersion + value: 1.0.0.$(baseBuildNumber) + - name: mdsPackageVersion + value: $(NugetPackageVersion) + - name: akvPackageVersion + value: $(NugetPackageVersion) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 4c210df737..86f3529cbb 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -20,7 +20,6 @@ > msbuild -p:configuration=Release --> Project - $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)')) diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 6ceddccd37..e8e590d8f6 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -7,6 +7,13 @@ + + + + + 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..fbb8bfb738 --- /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 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 application 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..485a3de83a --- /dev/null +++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj @@ -0,0 +1,71 @@ + + + + + + + + netstandard2.0 + + + + + enable + enable + + + + + Microsoft.Data.SqlClient.Extensions.Abstractions + Microsoft.Data.SqlClient.Extensions.Abstractions + + + $(_DefaultMajorVersion).0.0.0 + + $(AbstractionsAssemblyFileVersion) + $(AbstractionsAssemblyFileVersion) + $(AbstractionsPackageVersion) + + + + + <_Parameter1>true + + + + + + + + + $(AssemblyName) + $(AbstractionsPackageVersion) + $(PackagesDir) + true + snupkg + + 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/AbstractionsVersions.props b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/AbstractionsVersions.props new file mode 100644 index 0000000000..29ff5899af --- /dev/null +++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/AbstractionsVersions.props @@ -0,0 +1,70 @@ + + + + + + + + + + + + + <_DefaultMajorVersion>1 + + + <_OurPackageVersion Condition="'$(AbstractionsPackageVersion)' != ''">$(AbstractionsPackageVersion) + <_OurPackageVersion Condition="'$(AbstractionsPackageVersion)' == ''">$(_DefaultMajorVersion).0.0.$(BuildNumber)-dev + + + + <_OurAssemblyFileVersion Condition="'$(AbstractionsAssemblyFileVersion)' != ''">$(AbstractionsAssemblyFileVersion) + + <_OurAssemblyFileVersion Condition="'$(AbstractionsAssemblyFileVersion)' == '' and '$(AbstractionsPackageVersion)' != ''">$(AbstractionsPackageVersion.Split('-')[0]) + + <_OurAssemblyFileVersion Condition="'$(AbstractionsAssemblyFileVersion)' == '' and '$(AbstractionsPackageVersion)' == ''">$(_DefaultMajorVersion).0.0.$(BuildNumber) + + + $(_OurPackageVersion) + $(_OurAssemblyFileVersion) + + + + 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/add-ons/Directory.Build.props b/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props index 7776439adc..dfeb60b38c 100644 --- a/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props +++ b/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props @@ -9,7 +9,6 @@ true true Project - $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb true $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFramework)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)')) 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..f4fa41bf45 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,23 @@ - + + + + + + + + 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 926ebf3580..9f46d448b3 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -1072,6 +1072,22 @@ + + + + + + + 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..e8dbcf7070 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,22 @@ + + + + + + + + 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 41a3fe3f68..250308d053 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -1045,6 +1045,23 @@ + + + + + + + + diff --git a/tools/props/Versions.props b/tools/props/Versions.props index ad42c4964a..7a3ba3cc9a 100644 --- a/tools/props/Versions.props +++ b/tools/props/Versions.props @@ -1,29 +1,12 @@ - + + + - 7.0.0 0 - - - $(MdsVersionDefault).$(BuildNumber) - - 7.0.0.0 - - $(AssemblyFileVersion) - $(MdsVersionDefault)-dev - $(NugetPackageVersion) + + @@ -33,8 +16,47 @@ 1.0.0-dev $(SqlServerPackageVersion) + + + + + + + 7.0.0 + + $(MdsVersionDefault).$(BuildNumber)-dev + + + + + $(MdsVersionDefault).$(BuildNumber) + + + 7.0.0.0 + + $(AssemblyFileVersion) + + + $(MdsPackageVersion) + + + - $(NugetPackageVersion) + 7.0.0 + $(AkvVersionDefault).$(BuildNumber)-dev - $(NugetPackageVersion) + $(MdsPackageVersion) diff --git a/tools/specs/Microsoft.Data.SqlClient.nuspec b/tools/specs/Microsoft.Data.SqlClient.nuspec index 67d0078279..17f23723cb 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/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec b/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec index 079a902953..92cbc480dd 100644 --- a/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec +++ b/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec @@ -25,13 +25,13 @@ Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyStoreProvider.SqlColumnEncrypti sqlclient microsoft.data.sqlclient azurekeyvaultprovider akvprovider alwaysencrypted - + - + @@ -46,22 +46,22 @@ Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyStoreProvider.SqlColumnEncrypti - - - - - + + + + + - - - + + + - - - + + + - + + + + + + + + + diff --git a/tools/targets/GenerateNugetPackage.targets b/tools/targets/GenerateNugetPackage.targets deleted file mode 100644 index 4c8cea4159..0000000000 --- a/tools/targets/GenerateNugetPackage.targets +++ /dev/null @@ -1,31 +0,0 @@ - - - - - $(NugetPackageVersion)-debug - - - - - - - - - - - - - $(SqlServerPackageVersion)-debug - - - - - - - - - - - diff --git a/tools/targets/GenerateSqlServerPackage.targets b/tools/targets/GenerateSqlServerPackage.targets new file mode 100644 index 0000000000..ea6655dcee --- /dev/null +++ b/tools/targets/GenerateSqlServerPackage.targets @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/tools/targets/add-ons/GenerateAKVProviderNugetPackage.targets b/tools/targets/add-ons/GenerateAKVProviderNugetPackage.targets deleted file mode 100644 index 78da74bf32..0000000000 --- a/tools/targets/add-ons/GenerateAKVProviderNugetPackage.targets +++ /dev/null @@ -1,12 +0,0 @@ - - - - - $(NugetPackageVersion)-debug - - - - - - diff --git a/tools/targets/add-ons/GenerateAkvPackage.targets b/tools/targets/add-ons/GenerateAkvPackage.targets new file mode 100644 index 0000000000..fd822442a2 --- /dev/null +++ b/tools/targets/add-ons/GenerateAkvPackage.targets @@ -0,0 +1,13 @@ + + + + + + + + + + + +