From 4cc21a6edff4da2a683b3e1bab70130ce65d5fa5 Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Wed, 17 Jun 2026 13:02:17 -0300
Subject: [PATCH 01/12] pipeline: extract download-assembly-signing-key
template and wire signing through CI
- Create reusable eng/pipelines/common/steps/download-assembly-signing-key.yml
template with isTest parameter for driver vs test key download
- Migrate all pack jobs to use the template (Abstractions, Azure, Logging,
SqlClient, OneBranch)
- Add explicit signingKeyPath parameter to ci-project-build-step (replaces
implicit ##vso[task.setvariable] mechanism)
- Thread isInternalBuild through stages to pack and test jobs
- Add testSigningKeyPath to run-all-tests-step and ci-run-tests-job
- Add isInternalBuild + signing support to test-abstractions-package-ci-job
and test-azure-package-ci-job templates
- Remove @TODO comments about signing gap in stage files
---
.../ci/package/sqlclient-package.yml | 12 ++--
.../steps/download-assembly-signing-key.yml | 39 ++++++++++++
.../templates/jobs/ci-build-nugets-job.yml | 15 +++++
.../templates/jobs/ci-run-tests-job.yml | 20 ++++++
.../templates/stages/ci-run-tests-stage.yml | 7 +++
.../templates/steps/ci-project-build-step.yml | 9 +++
.../templates/steps/run-all-tests-step.yml | 48 ++++++++++++++
eng/pipelines/dotnet-sqlclient-ci-core.yml | 11 ++++
...qlclient-ci-package-reference-pipeline.yml | 1 +
...qlclient-ci-project-reference-pipeline.yml | 1 +
.../jobs/pack-abstractions-package-ci-job.yml | 63 +++++++++++--------
.../jobs/pack-azure-package-ci-job.yml | 63 +++++++++++--------
.../jobs/pack-logging-package-ci-job.yml | 24 ++++++-
.../jobs/test-abstractions-package-ci-job.yml | 25 +++++++-
.../jobs/test-azure-package-ci-job.yml | 25 +++++++-
.../onebranch/steps/build-buildproj-step.yml | 10 +--
.../build-abstractions-package-ci-stage.yml | 9 +++
.../stages/build-azure-package-ci-stage.yml | 11 ++++
.../build-sqlclient-package-ci-stage.yml | 6 ++
19 files changed, 331 insertions(+), 68 deletions(-)
create mode 100644 eng/pipelines/common/steps/download-assembly-signing-key.yml
diff --git a/eng/pipelines/ci/package/sqlclient-package.yml b/eng/pipelines/ci/package/sqlclient-package.yml
index e194e2abef..72c65b364e 100644
--- a/eng/pipelines/ci/package/sqlclient-package.yml
+++ b/eng/pipelines/ci/package/sqlclient-package.yml
@@ -89,10 +89,10 @@ variables:
value: ${{ eq(variables['System.TeamProject'], 'ADO.Net') }}
# Signing key argument passed to build.proj. On internal builds this references the secure file
- # downloaded by DownloadSecureFile@1; on public builds it expands to empty.
+ # downloaded by download-assembly-signing-key.yml; on public builds it expands to empty.
- name: signingKeyArg
${{ if eq(variables.isInternalBuild, true) }}:
- value: '-p:SigningKeyPath="$(keyFile.secureFilePath)"'
+ value: '-p:SigningKeyPath="$(driverKeyFile.secureFilePath)"'
${{ else }}:
value: ''
@@ -133,13 +133,9 @@ jobs:
Write-Host 'Done.'
displayName: Clean packages/ directory
- # On internal builds, download the strong-name signing key.
+ # On internal builds, download the assembly signing key.
- ${{ if eq(variables.isInternalBuild, true) }}:
- - task: DownloadSecureFile@1
- displayName: Download Signing Key
- inputs:
- secureFile: netfxKeypair.snk
- name: keyFile
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
# Run the Pack target via build.proj.
- task: DotNetCoreCLI@2
diff --git a/eng/pipelines/common/steps/download-assembly-signing-key.yml b/eng/pipelines/common/steps/download-assembly-signing-key.yml
new file mode 100644
index 0000000000..b7c415f74d
--- /dev/null
+++ b/eng/pipelines/common/steps/download-assembly-signing-key.yml
@@ -0,0 +1,39 @@
+################################################################################
+# 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.
+################################################################################
+
+# Downloads a signing key from ADO secure files.
+#
+# When isTest is false, downloads the driver signing key and exports it as 'driverKeyFile'. When
+# isTest is true, downloads the test signing key and exports it as 'testKeyFile'.
+#
+# Downstream steps reference the path via:
+#
+# $(driverKeyFile.secureFilePath) or
+# $(testKeyFile.secureFilePath)
+
+parameters:
+
+ # When false, download the driver signing key.
+ # When true, download the test signing key.
+ - name: isTest
+ type: boolean
+ default: false
+
+steps:
+
+ - ${{ if eq(parameters.isTest, false) }}:
+ - task: DownloadSecureFile@1
+ displayName: Download Driver Signing Key
+ inputs:
+ secureFile: netfxKeypair.snk
+ name: driverKeyFile
+
+ - ${{ if eq(parameters.isTest, true) }}:
+ - task: DownloadSecureFile@1
+ displayName: Download Test Signing Key
+ inputs:
+ secureFile: sqlclient-test-key.snk
+ name: testKeyFile
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 aa6a1c50c5..130f314beb 100644
--- a/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
@@ -87,6 +87,11 @@ parameters:
type: string
default: SqlServer.Artifacts
+ # True when building on the internal ADO.Net project.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
jobs:
- job: build_mds_akv_packages_job
displayName: Build MDS & AKV Packages
@@ -137,6 +142,10 @@ jobs:
# Restore dotnet CLI tools (e.g. pwsh, apicompat) before building.
- template: /eng/pipelines/common/steps/restore-dotnet-tools.yml@self
+ # Download the assembly signing key for internal builds.
+ - ${{ if eq(parameters.isInternalBuild, true) }}:
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
+
# When we're performing a Debug build, we still want to try _compiling_ the
# code in Release mode to ensure downstream pipelines don't encounter
# compilation errors. We won't use the Release artifacts for anything else
@@ -148,6 +157,8 @@ jobs:
buildConfiguration: Release
referenceType: Project
build: all
+ ${{ if eq(parameters.isInternalBuild, true) }}:
+ signingKeyPath: $(driverKeyFile.secureFilePath)
- template: /eng/pipelines/common/templates/steps/ci-project-build-step.yml@self
parameters:
@@ -159,6 +170,8 @@ jobs:
abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}
+ ${{ if eq(parameters.isInternalBuild, true) }}:
+ signingKeyPath: $(driverKeyFile.secureFilePath)
- task: DotNetCoreCLI@2
displayName: 'Create MDS NuGet Package'
@@ -206,6 +219,8 @@ jobs:
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
akvPackageVersion: ${{ parameters.akvPackageVersion }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}
+ ${{ if eq(parameters.isInternalBuild, true) }}:
+ signingKeyPath: $(driverKeyFile.secureFilePath)
- task: DotNetCoreCLI@2
displayName: 'Create AKV Provider 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 1b1ea7a2e7..df508c9522 100644
--- a/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
@@ -160,6 +160,11 @@ parameters:
- name: saPassword
type: string
+ # True when building on the internal ADO.Net project.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
jobs:
- job: ${{ format('{0}', coalesce(parameters.jobDisplayName, parameters.image, 'unknown_image')) }}
@@ -223,6 +228,13 @@ jobs:
# Restore dotnet CLI tools (e.g. pwsh, apicompat) before building.
- template: /eng/pipelines/common/steps/restore-dotnet-tools.yml@self
+ # Download the assembly signing keys for internal builds.
+ - ${{ if eq(parameters.isInternalBuild, true) }}:
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
+ parameters:
+ isTest: true
+
- ${{ if ne(parameters.prebuildSteps, '') }}:
- ${{ parameters.prebuildSteps }} # extra steps to run before the build like downloading sni and the required configuration
@@ -232,6 +244,8 @@ jobs:
build: allNoDocs
buildConfiguration: ${{ parameters.buildConfiguration }}
referenceType: Project
+ ${{ if eq(parameters.isInternalBuild, true) }}:
+ signingKeyPath: $(driverKeyFile.secureFilePath)
- ${{ if ne(parameters.configProperties, '{}') }}:
- template: /eng/pipelines/common/templates/steps/update-config-file-step.yml@self # update config.jsonc file
@@ -378,6 +392,9 @@ jobs:
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}
+ ${{ if eq(parameters.isInternalBuild, true) }}:
+ signingKeyPath: $(driverKeyFile.secureFilePath)
+ testSigningKeyPath: $(testKeyFile.secureFilePath)
- ${{ if and(eq(parameters.enableX86Test, true), eq(parameters.operatingSystem, 'Windows')) }}:
- template: /eng/pipelines/common/templates/steps/run-all-tests-step.yml@self
@@ -394,6 +411,9 @@ jobs:
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}
+ ${{ if eq(parameters.isInternalBuild, true) }}:
+ signingKeyPath: $(driverKeyFile.secureFilePath)
+ testSigningKeyPath: $(testKeyFile.secureFilePath)
- template: /eng/pipelines/common/templates/steps/publish-test-results-step.yml@self
parameters:
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 86ddc0ca45..86c86f7aec 100644
--- a/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
+++ b/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
@@ -88,6 +88,11 @@ parameters:
- name: testJobTimeout
type: number
+ # True when building on the internal ADO.Net project.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
stages:
- ${{ each config in parameters.testConfigurations }}:
- ${{ each image in config.value.images }}:
@@ -124,6 +129,7 @@ stages:
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
mdsArtifactsName: ${{ parameters.mdsArtifactsName }}
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
sqlServerArtifactsName: ${{ parameters.sqlServerArtifactsName }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}
prebuildSteps: ${{ parameters.prebuildSteps }}
@@ -162,6 +168,7 @@ stages:
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
mdsArtifactsName: ${{ parameters.mdsArtifactsName }}
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
sqlServerArtifactsName: ${{ parameters.sqlServerArtifactsName }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}
prebuildSteps: ${{ parameters.prebuildSteps }}
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 e5fa6d4424..a4b980f46e 100644
--- a/eng/pipelines/common/templates/steps/ci-project-build-step.yml
+++ b/eng/pipelines/common/templates/steps/ci-project-build-step.yml
@@ -73,6 +73,13 @@ parameters:
type: string
default: $(sqlServerPackageVersion)
+ # Path to the assembly signing key file. When non-empty, passed as -p:SigningKeyPath="" to the
+ # build. The calling job is responsible for downloading the key (via
+ # download-assembly-signing-key.yml).
+ - name: signingKeyPath
+ type: string
+ default: ''
+
steps:
# Build MDS
- ${{ if or(eq(parameters.build, 'MDS'), eq(parameters.build, 'all'), eq(parameters.build, 'allNoDocs')) }}:
@@ -91,6 +98,7 @@ steps:
-p:PackageVersionLogging=${{ parameters.loggingPackageVersion }}
-p:PackageVersionSqlClient=${{ parameters.mdsPackageVersion }}
-p:PackageVersionSqlServer=${{ parameters.sqlServerPackageVersion }}
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
# Build AKV Provider
- ${{ if or(eq(parameters.build, 'AkvProvider'), eq(parameters.build, 'all'), eq(parameters.build, 'allNoDocs')) }}:
@@ -110,3 +118,4 @@ steps:
-p:PackageVersionLogging=${{ parameters.loggingPackageVersion }}
-p:PackageVersionSqlClient=${{ parameters.mdsPackageVersion }}
-p:PackageVersionSqlServer=${{ parameters.sqlServerPackageVersion }}
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
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 e41c7d22b2..02c22087b4 100644
--- a/eng/pipelines/common/templates/steps/run-all-tests-step.yml
+++ b/eng/pipelines/common/templates/steps/run-all-tests-step.yml
@@ -72,6 +72,18 @@ parameters:
type: number
default: 2
+ # Path to the assembly signing key file. When non-empty, passed to build.proj so that the
+ # test-filter logic can include category=signed tests.
+ - name: signingKeyPath
+ type: string
+ default: ''
+
+ # Path to the test assembly signing key file. When non-empty, passed to build.proj so that test
+ # assemblies are signed and can satisfy InternalsVisibleTo grants from signed source assemblies.
+ - name: testSigningKeyPath
+ type: string
+ default: ''
+
steps:
- ${{ if parameters.debug }}:
- powershell: 'dotnet sdk check'
@@ -94,6 +106,8 @@ steps:
-p:PackageVersionSqlClient=${{ parameters.mdsPackageVersion }}
-p:PackageVersionSqlServer=${{ parameters.sqlServerPackageVersion }}
-p:TestResultsFolderPath=TestResults
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
${{ else }}: # x86
arguments: >-
-t:TestSqlClientUnit
@@ -104,6 +118,8 @@ steps:
-p:PackageVersionSqlServer=${{ parameters.sqlServerPackageVersion }}
-p:DotnetPath=${{ parameters.dotnetx86RootPath }}
-p:TestResultsFolderPath=TestResults
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
- task: DotNetCoreCLI@2
displayName: 'Run Flaky Unit Tests ${{parameters.msbuildArchitecture }}'
@@ -122,6 +138,8 @@ steps:
-p:TestFilters="category=flaky"
-p:TestResultsFolderPath=TestResults
-p:TestCodeCoverage=false
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
${{ else }}: # x86
arguments: >-
-t:TestSqlClientUnit
@@ -134,6 +152,8 @@ steps:
-p:TestFilters="category=flaky"
-p:TestResultsFolderPath=TestResults
-p:TestCodeCoverage=false
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
continueOnError: true
- task: DotNetCoreCLI@2
@@ -153,6 +173,8 @@ steps:
-p:PackageVersionSqlClient=${{ parameters.mdsPackageVersion }}
-p:PackageVersionSqlServer=${{ parameters.sqlServerPackageVersion }}
-p:TestResultsFolderPath=TestResults
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
${{ else }}: # x86
arguments: >-
-t:TestSqlClientFunctional
@@ -165,6 +187,8 @@ steps:
-p:PackageVersionSqlServer=${{ parameters.sqlServerPackageVersion }}
-p:DotnetPath=${{ parameters.dotnetx86RootPath }}
-p:TestResultsFolderPath=TestResults
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
- task: DotNetCoreCLI@2
displayName: 'Run Flaky Functional Tests ${{parameters.msbuildArchitecture }}'
@@ -185,6 +209,8 @@ steps:
-p:TestFilters="category=flaky"
-p:TestResultsFolderPath=TestResults
-p:TestCodeCoverage=false
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
${{ else }}: # x86
arguments: >-
-t:TestSqlClientFunctional
@@ -199,6 +225,8 @@ steps:
-p:TestFilters="category=flaky"
-p:TestResultsFolderPath=TestResults
-p:TestCodeCoverage=false
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
continueOnError: true
- task: DotNetCoreCLI@2
@@ -219,6 +247,8 @@ steps:
-p:PackageVersionSqlClient=${{ parameters.mdsPackageVersion }}
-p:PackageVersionSqlServer=${{ parameters.sqlServerPackageVersion }}
-p:TestResultsFolderPath=TestResults
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
${{ else }}: # x86
arguments: >-
-t:TestSqlClientManual
@@ -232,6 +262,8 @@ steps:
-p:PackageVersionSqlServer=${{ parameters.sqlServerPackageVersion }}
-p:DotnetPath=${{ parameters.dotnetx86RootPath }}
-p:TestResultsFolderPath=TestResults
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
retryCountOnTaskFailure: ${{parameters.retryCountOnManualTests }}
- task: DotNetCoreCLI@2
@@ -254,6 +286,8 @@ steps:
-p:TestFilters="category=flaky"
-p:TestResultsFolderPath=TestResults
-p:TestCodeCoverage=false
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
${{ else }}: # x86
arguments: >-
-t:TestSqlClientManual
@@ -269,6 +303,8 @@ steps:
-p:TestFilters="category=flaky"
-p:TestResultsFolderPath=TestResults
-p:TestCodeCoverage=false
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
continueOnError: true
- ${{ else }}: # Linux or macOS
@@ -286,6 +322,8 @@ steps:
-p:PackageVersionSqlClient=${{ parameters.mdsPackageVersion }}
-p:PackageVersionSqlServer=${{ parameters.sqlServerPackageVersion }}
-p:TestResultsFolderPath=TestResults
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
- task: DotNetCoreCLI@2
displayName: 'Run Flaky Unit Tests'
@@ -303,6 +341,8 @@ steps:
-p:TestFilters="category=flaky"
-p:TestResultsFolderPath=TestResults
-p:TestCodeCoverage=false
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
continueOnError: true
- task: DotNetCoreCLI@2
@@ -321,6 +361,8 @@ steps:
-p:PackageVersionSqlClient=${{ parameters.mdsPackageVersion }}
-p:PackageVersionSqlServer=${{ parameters.sqlServerPackageVersion }}
-p:TestResultsFolderPath=TestResults
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
- task: DotNetCoreCLI@2
displayName: 'Run Flaky Functional Tests'
@@ -340,6 +382,8 @@ steps:
-p:TestFilters="category=flaky"
-p:TestResultsFolderPath=TestResults
-p:TestCodeCoverage=false
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
continueOnError: true
- task: DotNetCoreCLI@2
displayName: 'Run Manual Tests'
@@ -358,6 +402,8 @@ steps:
-p:PackageVersionSqlClient=${{ parameters.mdsPackageVersion }}
-p:PackageVersionSqlServer=${{ parameters.sqlServerPackageVersion }}
-p:TestResultsFolderPath=TestResults
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
retryCountOnTaskFailure: ${{parameters.retryCountOnManualTests }}
- task: DotNetCoreCLI@2
@@ -379,4 +425,6 @@ steps:
-p:TestFilters="category=flaky"
-p:TestResultsFolderPath=TestResults
-p:TestCodeCoverage=false
+ -p:SigningKeyPath="${{ parameters.signingKeyPath }}"
+ -p:TestSigningKeyPath="${{ parameters.testSigningKeyPath }}"
continueOnError: true
diff --git a/eng/pipelines/dotnet-sqlclient-ci-core.yml b/eng/pipelines/dotnet-sqlclient-ci-core.yml
index 9ee7c7132d..5fdc25ee0e 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-core.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-core.yml
@@ -104,6 +104,12 @@ parameters:
- detailed
- diagnostic
+ # True when building on the internal ADO.Net project. Internal builds may perform additional or
+ # different steps, such as assembly signing.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
variables:
- template: /eng/pipelines/libraries/ci-build-variables.yml@self
@@ -150,6 +156,7 @@ stages:
buildConfiguration: ${{ parameters.buildConfiguration }}
debug: ${{ parameters.debug }}
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
# Build the Abstractions package, and publish it to the pipeline artifacts
# under the given artifact name.
@@ -167,6 +174,7 @@ stages:
loggingArtifactsName: $(loggingArtifactsName)
loggingPackageVersion: $(loggingPackageVersion)
referenceType: ${{ parameters.referenceType }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
# When building Abstractions via packages, we must depend on the Logging
# package.
${{ if eq(parameters.referenceType, 'Package') }}:
@@ -188,6 +196,7 @@ stages:
mdsPackageVersion: $(mdsPackageVersion)
akvPackageVersion: $(akvPackageVersion)
referenceType: ${{ parameters.referenceType }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
sqlServerArtifactsName: $(sqlServerArtifactsName)
sqlServerPackageVersion: $(sqlServerPackageVersion)
SNIVersion: ${{ parameters.SNIVersion }}
@@ -220,6 +229,7 @@ stages:
- build_sqlserver_package_stage
- build_sqlclient_package_stage
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
loggingArtifactsName: $(loggingArtifactsName)
loggingPackageVersion: $(loggingPackageVersion)
mdsArtifactsName: $(mdsArtifactsName)
@@ -251,6 +261,7 @@ stages:
loggingPackageVersion: $(loggingPackageVersion)
mdsArtifactsName: $(mdsArtifactsName)
mdsPackageVersion: $(mdsPackageVersion)
+ isInternalBuild: ${{ parameters.isInternalBuild }}
sqlServerArtifactsName: $(sqlServerArtifactsName)
sqlServerPackageVersion: $(sqlServerPackageVersion)
testJobTimeout: ${{ parameters.testJobTimeout }}
diff --git a/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml b/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml
index 98cac1bcdd..c510dc2c6b 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml
@@ -174,3 +174,4 @@ extends:
testJobTimeout: ${{ parameters.testJobTimeout }}
testSets: ${{ parameters.testSets }}
useManagedSNI: ${{ parameters.useManagedSNI }}
+ isInternalBuild: ${{ eq(variables['System.TeamProject'], 'ADO.Net') }}
diff --git a/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml b/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
index 7068c9693c..29f2660f0f 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
@@ -174,3 +174,4 @@ extends:
testJobTimeout: ${{ parameters.testJobTimeout }}
testSets: ${{ parameters.testSets }}
useManagedSNI: ${{ parameters.useManagedSNI }}
+ isInternalBuild: ${{ eq(variables['System.TeamProject'], 'ADO.Net') }}
diff --git a/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml b/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
index d077aa2115..b75900f1bc 100644
--- a/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
+++ b/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
@@ -77,6 +77,11 @@ parameters:
# Reference sibling packages as C# projects.
- Project
+ # True when building on the internal ADO.Net project.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
jobs:
- job: pack_abstractions_package_job
@@ -119,6 +124,26 @@ jobs:
- name: Configuration
value: ''
+ # Build properties passed to dotnet pack. Composed from a base set plus
+ # optional suffixes for Package-mode dependencies and assembly signing.
+ - name: baseBuildProperties
+ value: AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }};AbstractionsAssemblyFileVersion=${{ parameters.abstractionsAssemblyFileVersion }}
+
+ - name: packageModeProperties
+ ${{ if eq(parameters.referenceType, 'Package') }}:
+ value: ReferenceType=Package;LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
+ ${{ else }}:
+ value: ''
+
+ - name: signingProperties
+ ${{ if eq(parameters.isInternalBuild, true) }}:
+ value: SigningKeyPath=$(driverKeyFile.secureFilePath)
+ ${{ else }}:
+ value: ''
+
+ - name: buildProperties
+ value: $(baseBuildProperties);$(packageModeProperties);$(signingProperties)
+
steps:
# Emit environment variables if debug is enabled.
@@ -140,32 +165,20 @@ jobs:
parameters:
debug: ${{ parameters.debug }}
+ # Download the assembly signing key for internal builds.
+ - ${{ if eq(parameters.isInternalBuild, true) }}:
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
+
# Create the NuGet packages.
- #
- # When referenceType is Package, we must pass ReferenceType and the
- # dependency version so that Directory.Packages.props applies version
- # ranges to sibling package dependencies.
- - ${{ if eq(parameters.referenceType, 'Package') }}:
- - task: DotNetCoreCLI@2
- displayName: Create NuGet Package
- inputs:
- command: pack
- packagesToPack: $(project)
- configurationToPack: ${{ parameters.buildConfiguration }}
- packDirectory: $(dotnetPackagesDir)
- verbosityToPack: ${{ parameters.dotnetVerbosity }}
- buildProperties: AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }};AbstractionsAssemblyFileVersion=${{ parameters.abstractionsAssemblyFileVersion }};ReferenceType=Package;LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-
- - ${{ else }}:
- - task: DotNetCoreCLI@2
- displayName: Create NuGet Package
- inputs:
- command: pack
- packagesToPack: $(project)
- configurationToPack: ${{ parameters.buildConfiguration }}
- packDirectory: $(dotnetPackagesDir)
- verbosityToPack: ${{ parameters.dotnetVerbosity }}
- buildProperties: AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }};AbstractionsAssemblyFileVersion=${{ parameters.abstractionsAssemblyFileVersion }}
+ - task: DotNetCoreCLI@2
+ displayName: Create NuGet Package
+ inputs:
+ command: pack
+ packagesToPack: $(project)
+ configurationToPack: ${{ parameters.buildConfiguration }}
+ packDirectory: $(dotnetPackagesDir)
+ verbosityToPack: ${{ parameters.dotnetVerbosity }}
+ buildProperties: $(buildProperties)
# Publish the NuGet packages as a named pipeline artifact.
- task: PublishPipelineArtifact@1
diff --git a/eng/pipelines/jobs/pack-azure-package-ci-job.yml b/eng/pipelines/jobs/pack-azure-package-ci-job.yml
index 12567fec14..81def77c44 100644
--- a/eng/pipelines/jobs/pack-azure-package-ci-job.yml
+++ b/eng/pipelines/jobs/pack-azure-package-ci-job.yml
@@ -89,6 +89,11 @@ parameters:
# Reference sibling packages as C# projects.
- Project
+ # True when building on the internal ADO.Net project.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
jobs:
- job: pack_azure_package_job
@@ -131,6 +136,26 @@ jobs:
- name: Configuration
value: ''
+ # Build properties passed to dotnet pack. Composed from a base set plus
+ # optional suffixes for Package-mode dependencies and assembly signing.
+ - name: baseBuildProperties
+ value: AzurePackageVersion=${{ parameters.azurePackageVersion }};AzureAssemblyFileVersion=${{ parameters.azureAssemblyFileVersion }}
+
+ - name: packageModeProperties
+ ${{ if eq(parameters.referenceType, 'Package') }}:
+ value: ReferenceType=Package;LoggingPackageVersion=${{ parameters.loggingPackageVersion }};AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ ${{ else }}:
+ value: ''
+
+ - name: signingProperties
+ ${{ if eq(parameters.isInternalBuild, true) }}:
+ value: SigningKeyPath=$(driverKeyFile.secureFilePath)
+ ${{ else }}:
+ value: ''
+
+ - name: buildProperties
+ value: $(baseBuildProperties);$(packageModeProperties);$(signingProperties)
+
steps:
# Emit environment variables if debug is enabled.
@@ -157,32 +182,20 @@ jobs:
parameters:
debug: ${{ parameters.debug }}
+ # Download the assembly signing key for internal builds.
+ - ${{ if eq(parameters.isInternalBuild, true) }}:
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
+
# Create the NuGet packages.
- #
- # When referenceType is Package, we must pass ReferenceType and the
- # dependency versions so that Directory.Packages.props applies version
- # ranges to sibling package dependencies.
- - ${{ if eq(parameters.referenceType, 'Package') }}:
- - task: DotNetCoreCLI@2
- displayName: Create NuGet Package
- inputs:
- command: pack
- packagesToPack: $(project)
- configurationToPack: ${{ parameters.buildConfiguration }}
- packDirectory: $(dotnetPackagesDir)
- verbosityToPack: ${{ parameters.dotnetVerbosity }}
- buildProperties: AzurePackageVersion=${{ parameters.azurePackageVersion }};AzureAssemblyFileVersion=${{ parameters.azureAssemblyFileVersion }};ReferenceType=Package;LoggingPackageVersion=${{ parameters.loggingPackageVersion }};AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
-
- - ${{ else }}:
- - task: DotNetCoreCLI@2
- displayName: Create NuGet Package
- inputs:
- command: pack
- packagesToPack: $(project)
- configurationToPack: ${{ parameters.buildConfiguration }}
- packDirectory: $(dotnetPackagesDir)
- verbosityToPack: ${{ parameters.dotnetVerbosity }}
- buildProperties: AzurePackageVersion=${{ parameters.azurePackageVersion }};AzureAssemblyFileVersion=${{ parameters.azureAssemblyFileVersion }}
+ - task: DotNetCoreCLI@2
+ displayName: Create NuGet Package
+ inputs:
+ command: pack
+ packagesToPack: $(project)
+ configurationToPack: ${{ parameters.buildConfiguration }}
+ packDirectory: $(dotnetPackagesDir)
+ verbosityToPack: ${{ parameters.dotnetVerbosity }}
+ buildProperties: $(buildProperties)
# Publish the NuGet packages as a named pipeline artifact.
- task: PublishPipelineArtifact@1
diff --git a/eng/pipelines/jobs/pack-logging-package-ci-job.yml b/eng/pipelines/jobs/pack-logging-package-ci-job.yml
index f2a42699e0..f42b18cebe 100644
--- a/eng/pipelines/jobs/pack-logging-package-ci-job.yml
+++ b/eng/pipelines/jobs/pack-logging-package-ci-job.yml
@@ -53,6 +53,11 @@ parameters:
- detailed
- diagnostic
+ # True when building on the internal ADO.Net project.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
jobs:
- job: pack_logging_package_job
@@ -86,6 +91,19 @@ jobs:
- name: Configuration
value: ''
+ # Build properties passed to dotnet pack.
+ - name: baseBuildProperties
+ value: LoggingPackageVersion=${{ parameters.loggingPackageVersion }};LoggingAssemblyFileVersion=${{ parameters.loggingAssemblyFileVersion }}
+
+ - name: signingProperties
+ ${{ if eq(parameters.isInternalBuild, true) }}:
+ value: SigningKeyPath=$(driverKeyFile.secureFilePath)
+ ${{ else }}:
+ value: ''
+
+ - name: buildProperties
+ value: $(baseBuildProperties);$(signingProperties)
+
steps:
# Emit environment variables if debug is enabled.
@@ -98,6 +116,10 @@ jobs:
parameters:
debug: ${{ parameters.debug }}
+ # Download the assembly signing key for internal builds.
+ - ${{ if eq(parameters.isInternalBuild, true) }}:
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
+
# Create the NuGet packages.
- task: DotNetCoreCLI@2
displayName: Create NuGet Package
@@ -107,7 +129,7 @@ jobs:
configurationToPack: ${{ parameters.buildConfiguration }}
packDirectory: $(dotnetPackagesDir)
verbosityToPack: ${{ parameters.dotnetVerbosity }}
- buildProperties: LoggingPackageVersion=${{ parameters.loggingPackageVersion }};LoggingAssemblyFileVersion=${{ parameters.loggingAssemblyFileVersion }}
+ buildProperties: $(buildProperties)
# Publish the NuGet packages as a named pipeline artifact.
- task: PublishPipelineArtifact@1
diff --git a/eng/pipelines/jobs/test-abstractions-package-ci-job.yml b/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
index 83366b52a9..d4deed9f65 100644
--- a/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
+++ b/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
@@ -61,6 +61,12 @@ parameters:
- name: poolName
type: string
+ # True when building on the internal ADO.Net project. When set, assemblies
+ # are signed with the driver key and tests are signed with the test key.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
# The pool VM image to use.
- name: vmImage
type: string
@@ -94,6 +100,16 @@ jobs:
-p:Configuration=${{ parameters.buildConfiguration }}
--verbosity ${{ parameters.dotnetVerbosity }}
+ # Signing arguments — only set for internal builds.
+ - ${{ if eq(parameters.isInternalBuild, true) }}:
+ - name: signingArguments
+ value: >-
+ -p:SigningKeyPath=$(driverKeyFile.secureFilePath)
+ -p:TestSigningKeyPath=$(testKeyFile.secureFilePath)
+ - ${{ else }}:
+ - name: signingArguments
+ value: ''
+
# 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
@@ -121,6 +137,13 @@ jobs:
- pwsh: 'Get-ChildItem Env: | Sort-Object Name'
displayName: '[Debug] Print Environment Variables'
+ # Download the assembly signing keys for internal builds.
+ - ${{ if eq(parameters.isInternalBuild, true) }}:
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
+ parameters:
+ isTest: true
+
# Install the .NET SDK and Runtimes.
- template: /eng/pipelines/common/steps/install-dotnet.yml@self
parameters:
@@ -136,7 +159,7 @@ jobs:
inputs:
command: build
projects: $(project)
- arguments: $(buildArguments)
+ arguments: $(buildArguments) $(signingArguments)
# Run the tests for each .NET runtime.
- ${{ each runtime in parameters.netRuntimes }}:
diff --git a/eng/pipelines/jobs/test-azure-package-ci-job.yml b/eng/pipelines/jobs/test-azure-package-ci-job.yml
index eb9e36152a..457a3765c4 100644
--- a/eng/pipelines/jobs/test-azure-package-ci-job.yml
+++ b/eng/pipelines/jobs/test-azure-package-ci-job.yml
@@ -69,6 +69,12 @@ parameters:
- detailed
- diagnostic
+ # True when building on the internal ADO.Net project. When set, assemblies
+ # are signed with the driver key and tests are signed with the test key.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
# The suffix to append to the job name.
- name: jobNameSuffix
type: string
@@ -179,6 +185,16 @@ jobs:
-p:SqlClientPackageVersion=${{ parameters.mdsPackageVersion }}
-p:SqlServerPackageVersion=${{ parameters.sqlServerPackageVersion }}
+ # Signing arguments — only set for internal builds.
+ - ${{ if eq(parameters.isInternalBuild, true) }}:
+ - name: signingArguments
+ value: >-
+ -p:SigningKeyPath=$(driverKeyFile.secureFilePath)
+ -p:TestSigningKeyPath=$(testKeyFile.secureFilePath)
+ - ${{ else }}:
+ - name: signingArguments
+ value: ''
+
# 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
@@ -206,6 +222,13 @@ jobs:
- pwsh: 'Get-ChildItem Env: | Sort-Object Name'
displayName: '[Debug] Print Environment Variables'
+ # Download the assembly signing keys for internal builds.
+ - ${{ if eq(parameters.isInternalBuild, true) }}:
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
+ parameters:
+ isTest: true
+
# We have a few extra steps for Package reference builds.
- ${{ if eq(parameters.referenceType, 'Package') }}:
@@ -289,7 +312,7 @@ jobs:
inputs:
command: build
projects: $(project)
- arguments: $(buildArguments)
+ arguments: $(buildArguments) $(signingArguments)
# List the DLLs in the output directory for debugging purposes.
- ${{ if eq(parameters.debug, true) }}:
diff --git a/eng/pipelines/onebranch/steps/build-buildproj-step.yml b/eng/pipelines/onebranch/steps/build-buildproj-step.yml
index 2a5730c848..4b18be369b 100644
--- a/eng/pipelines/onebranch/steps/build-buildproj-step.yml
+++ b/eng/pipelines/onebranch/steps/build-buildproj-step.yml
@@ -44,12 +44,8 @@ parameters:
type: string
steps:
- # Download the strong name signing key from secure file storage
- - task: DownloadSecureFile@1
- displayName: 'Download Signing Key'
- inputs:
- secureFile: 'netfxKeypair.snk'
- name: keyFile
+ # Download the assembly signing key from secure file storage.
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
- task: DotNetCoreCLI@2
displayName: 'build.proj - Build${{ parameters.packageShortName }}'
@@ -61,7 +57,7 @@ steps:
-p:Configuration=${{ parameters.buildConfiguration }}
-p:ReferenceType=Package
-p:SkipDependencyPack=true
- -p:SigningKeyPath="$(keyFile.secureFilePath)"
+ -p:SigningKeyPath="$(driverKeyFile.secureFilePath)"
-p:BuildNumber="$(Build.BuildNumber)"
-p:PackageVersion${{ parameters.packageShortName }}="${{ parameters.packageVersion }}"
${{ parameters.dependencyArguments }}
diff --git a/eng/pipelines/stages/build-abstractions-package-ci-stage.yml b/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
index 8579b79caf..f251d7d9c6 100644
--- a/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
+++ b/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
@@ -91,6 +91,11 @@ parameters:
# Reference sibling packages as C# projects.
- Project
+ # True when building on the internal ADO.Net project.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
stages:
- stage: build_abstractions_package_stage
@@ -112,6 +117,7 @@ stages:
debug: ${{ parameters.debug }}
displayNamePrefix: Linux
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
jobNameSuffix: linux
netFrameworkRuntimes: []
netRuntimes: [net8.0, net9.0, net10.0]
@@ -127,6 +133,7 @@ stages:
debug: ${{ parameters.debug }}
displayNamePrefix: Win
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
jobNameSuffix: windows
netFrameworkRuntimes: [net462]
netRuntimes: [net8.0, net9.0, net10.0]
@@ -142,6 +149,7 @@ stages:
debug: ${{ parameters.debug }}
displayNamePrefix: macOS
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
jobNameSuffix: macos
netFrameworkRuntimes: []
netRuntimes: [net8.0, net9.0, net10.0]
@@ -168,3 +176,4 @@ stages:
loggingArtifactsName: ${{ parameters.loggingArtifactsName }}
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
referenceType: ${{ parameters.referenceType }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
diff --git a/eng/pipelines/stages/build-azure-package-ci-stage.yml b/eng/pipelines/stages/build-azure-package-ci-stage.yml
index b3cf9073d5..396314125c 100644
--- a/eng/pipelines/stages/build-azure-package-ci-stage.yml
+++ b/eng/pipelines/stages/build-azure-package-ci-stage.yml
@@ -152,6 +152,11 @@ parameters:
# Reference sibling packages as C# projects.
- Project
+ # True when building on the internal ADO.Net project.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
stages:
- stage: build_azure_package_stage
@@ -180,6 +185,7 @@ stages:
debug: ${{ parameters.debug }}
displayNamePrefix: Linux
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
jobNameSuffix: linux
loggingArtifactsName: ${{ parameters.loggingArtifactsName }}
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
@@ -202,6 +208,7 @@ stages:
debug: ${{ parameters.debug }}
displayNamePrefix: Linux Integration
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
jobNameSuffix: linux_integration
loggingArtifactsName: ${{ parameters.loggingArtifactsName }}
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
@@ -233,6 +240,7 @@ stages:
debug: ${{ parameters.debug }}
displayNamePrefix: Win
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
jobNameSuffix: windows
loggingArtifactsName: ${{ parameters.loggingArtifactsName }}
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
@@ -255,6 +263,7 @@ stages:
debug: ${{ parameters.debug }}
displayNamePrefix: Win Integration
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
jobNameSuffix: windows_integration
loggingArtifactsName: ${{ parameters.loggingArtifactsName }}
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
@@ -295,6 +304,7 @@ stages:
debug: ${{ parameters.debug }}
displayNamePrefix: macOS
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
jobNameSuffix: macos
loggingArtifactsName: ${{ parameters.loggingArtifactsName }}
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
@@ -331,6 +341,7 @@ stages:
- test_azure_package_job_windows_integration
- test_azure_package_job_macos
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
loggingArtifactsName: ${{ parameters.loggingArtifactsName }}
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
referenceType: ${{ parameters.referenceType }}
diff --git a/eng/pipelines/stages/build-sqlclient-package-ci-stage.yml b/eng/pipelines/stages/build-sqlclient-package-ci-stage.yml
index 858f1c8500..aa62f2122e 100644
--- a/eng/pipelines/stages/build-sqlclient-package-ci-stage.yml
+++ b/eng/pipelines/stages/build-sqlclient-package-ci-stage.yml
@@ -85,6 +85,11 @@ parameters:
type: string
default: ''
+ # True when building on the internal ADO.Net project.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
stages:
- stage: build_sqlclient_package_stage
@@ -109,6 +114,7 @@ stages:
akvPackageVersion: ${{ parameters.akvPackageVersion }}
sqlServerArtifactsName: ${{ parameters.sqlServerArtifactsName }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
${{ if ne(parameters.SNIVersion, '') }}:
prebuildSteps:
- template: /eng/pipelines/common/templates/steps/override-sni-version.yml@self
From 37d6dfa30023cc2ef2e850fc21e8f47e0db7557c Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Wed, 17 Jun 2026 13:03:15 -0300
Subject: [PATCH 02/12] src: add conditional signed IVT and TestSigningKeyPath
to extension projects
- Add STRONG_NAME_SIGNING conditional compilation to
SqlAuthenticationProvider.Internal.cs
- Add dual IVT blocks to Abstractions, Logging, and Azure source projects:
unsigned (SigningKeyPath='') and signed+Package mode (with test public key)
- Add TestSigningKeyPath signing support to Abstractions.Test, Azure.Test,
and Logging.Test csproj files
- Add SigningKeyPath, TestSigningKeyPath, and ReferenceType arguments to
TestAbstractions, TestLogging, and TestAzure targets in build.proj
---
build.proj | 46 +++++++++++--
.../Abstractions/src/Abstractions.csproj | 17 +++++
.../src/SqlAuthenticationProvider.Internal.cs | 67 ++++++++++++++++---
.../test/Abstractions.Test.csproj | 7 ++
.../Azure/src/Azure.csproj | 12 ++++
.../Azure/test/Azure.Test.csproj | 7 ++
.../Logging/src/Logging.csproj | 12 ++++
7 files changed, 151 insertions(+), 17 deletions(-)
diff --git a/build.proj b/build.proj
index 4ff29a08df..ac08aeaaee 100644
--- a/build.proj
+++ b/build.proj
@@ -394,7 +394,7 @@
environments. Please consider running project specific test targets or specific test sets
within the project.
-->
-
+
@@ -887,10 +887,6 @@
-
AbstractionsTests-$(OS)
$(LogFilePrefix)-$(TestFramework)
@@ -901,6 +897,12 @@
$(TestCodeCoverageArgument)
$(TestFiltersArgument)
$(TestFrameworkArgument)
+ $(SigningKeyPathArgument)
+ $(TestSigningKeyPathArgument)
+
+
+ $(ReferenceTypeArgument)
+ $(PackageVersionLoggingArgument)
--results-directory "$(TestResultsFolderPath)"
--logger:"trx;LogFilePrefix=$(LogFilePrefix)"
@@ -999,8 +1001,8 @@
$(TestCodeCoverageArgument)
$(TestFiltersArgument)
$(TestFrameworkArgument)
- --results-directory "$(TestResultsFolderPath)"
- --logger:"trx;LogFilePrefix=$(LogFilePrefix)"
+ $(SigningKeyPathArgument)
+ $(TestSigningKeyPathArgument)
$(ReferenceTypeArgument)
@@ -1008,6 +1010,8 @@
$(PackageVersionLoggingArgument)
$(PackageVersionSqlClientArgument)
$(PackageVersionSqlServerArgument)
+ --results-directory "$(TestResultsFolderPath)"
+ --logger:"trx;LogFilePrefix=$(LogFilePrefix)"
$([System.Text.RegularExpressions.Regex]::Replace($(DotnetCommand), "\s+", " "))
@@ -1022,6 +1026,7 @@
$(RepoRoot)src/Microsoft.Data.SqlClient.Internal/Logging/src/
$(LoggingSrcRoot)Logging.csproj
+ $(RepoRoot)src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj
$(RepoRoot)artifacts/Microsoft.Data.SqlClient.Internal.Logging/$(Configuration)/
@@ -1079,6 +1084,33 @@
SkipUnchangedFiles="true" />
+
+
+
+ LoggingTests-$(OS)
+ $(LogFilePrefix)-$(TestFramework)
+
+
+ "$(DotnetPath)dotnet" test "$(LoggingTestProjectPath)"
+ -p:Configuration=$(Configuration)
+ $(TestBlameArgument)
+ $(TestCodeCoverageArgument)
+ $(TestFiltersArgument)
+ $(TestFrameworkArgument)
+ $(SigningKeyPathArgument)
+ $(TestSigningKeyPathArgument)
+ $(ReferenceTypeArgument)
+ --results-directory "$(TestResultsFolderPath)"
+ --logger:"trx;LogFilePrefix=$(LogFilePrefix)"
+
+
+ $([System.Text.RegularExpressions.Regex]::Replace($(DotnetCommand), "\s+", " "))
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
index 0a9d29aa1e..0957180637 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
@@ -34,10 +34,22 @@
+
+
+
+
+
+
+
$(RepoRoot)artifacts/
@@ -79,6 +91,11 @@
Condition="'$(ReferenceType)' == 'Package'" />
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/SqlAuthenticationProvider.Internal.cs b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/SqlAuthenticationProvider.Internal.cs
index e0adf34e49..da56722718 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/SqlAuthenticationProvider.Internal.cs
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/SqlAuthenticationProvider.Internal.cs
@@ -23,6 +23,14 @@ public abstract partial class SqlAuthenticationProvider
///
private static class Internal
{
+ ///
+ /// The expected public key token of the SqlClient assembly, used to avoid loading imposter
+ /// assemblies. This is the same token used by all assemblies in this repository when
+ /// strong-name signed.
+ ///
+ private static readonly byte[] _sqlClientPublicKeyToken =
+ [ 0x23, 0xec, 0x7f, 0xc2, 0xd6, 0xea, 0xa4, 0xa5 ];
+
///
/// Our handle to the reflected GetProvider() method.
///
@@ -40,30 +48,69 @@ static Internal()
{
const string assemblyName = "Microsoft.Data.SqlClient";
- // If the MDS package is present, load its
+ // If the SqlClient assembly is present, load its
// SqlAuthenticationProviderManager class and get/set methods.
try
{
- // Try to load the MDS assembly.
+ // Try to load the SqlClient assembly.
+
+ #if STRONG_NAME_SIGNING
+
+ // When strong-name signing is enabled, build a fully-qualified AssemblyName that
+ // includes the expected public key token.
+ Log($"Attempting to load SqlClient assembly={assemblyName} with " +
+ "expected public key token=" +
+ BitConverter.ToString(_sqlClientPublicKeyToken).Replace("-", ""));
+
+ var qualifiedName = new AssemblyName(assemblyName);
+ qualifiedName.SetPublicKeyToken(_sqlClientPublicKeyToken);
+
+ // The .NET Framework runtime enforces the token during binding, causing Load() to
+ // throw if it doesn't match. The .NET (Core) runtime ignores the token, so we
+ // verify it ourselves below.
+ var assembly = Assembly.Load(qualifiedName);
+
+ // Defense-in-depth: verify the public key token after loading. This is necessary
+ // on .NET Core where the runtime does not enforce the token. It is harmless on .NET
+ // Framework.
+ if (assembly is not null)
+ {
+ byte[]? actualToken = assembly.GetName().GetPublicKeyToken();
+
+ if (actualToken is null ||
+ !actualToken.AsSpan().SequenceEqual(_sqlClientPublicKeyToken))
+ {
+ Log($"SqlClient assembly={assembly.GetName()} has an " +
+ "unexpected public key token; " +
+ "Get/SetProvider() will not function");
+ return;
+ }
+ }
+
+ #else
+
+ // Strong-name signing is disabled, so we cannot verify the public key token.
+ Log($"Loading SqlClient assembly={assemblyName} without strong name " +
+ "verification; ensure this assembly is from a trusted source");
+
var assembly = Assembly.Load(assemblyName);
+ #endif
+
if (assembly is null)
{
- Log($"MDS assembly={assemblyName} not found; " +
+ Log($"SqlClient assembly={assemblyName} not found; " +
"Get/SetProvider() will not function");
return;
}
- // TODO(https://sqlclientdrivers.visualstudio.com/ADO.Net/_workitems/edit/39845):
- // Verify the assembly is signed by us?
-
// Look for the manager class.
const string className = "Microsoft.Data.SqlClient.SqlAuthenticationProviderManager";
var manager = assembly.GetType(className);
if (manager is null)
{
- Log($"MDS auth manager manager class={className} not found; " +
+ Log($"SqlClient auth manager class={className} not found; " +
"Get/SetProvider() will not function");
return;
}
@@ -75,7 +122,7 @@ static Internal()
if (_getProvider is null)
{
- Log($"MDS GetProvider() method not found; " +
+ Log($"SqlClient GetProvider() method not found; " +
"GetProvider() will not function");
}
@@ -85,7 +132,7 @@ static Internal()
if (_setProvider is null)
{
- Log($"MDS SetProvider() method not found; " +
+ Log($"SqlClient SetProvider() method not found; " +
"SetProvider() will not function");
}
}
@@ -97,7 +144,7 @@ or BadImageFormatException
or FileLoadException
or FileNotFoundException)
{
- Log($"MDS assembly={assemblyName} not found or not usable; " +
+ Log($"SqlClient assembly={assemblyName} not found or not usable; " +
$"Get/SetProvider() will not function: {ex} ");
}
// Any other exceptions are fatal.
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
index 427a7aaf9f..0fe52f0327 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
@@ -8,6 +8,13 @@
true
+
+
+
+ true
+ $(TestSigningKeyPath)
+
+
enable
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Azure/src/Azure.csproj b/src/Microsoft.Data.SqlClient.Extensions/Azure/src/Azure.csproj
index dddf5673f9..796fc2767a 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Azure/src/Azure.csproj
+++ b/src/Microsoft.Data.SqlClient.Extensions/Azure/src/Azure.csproj
@@ -34,10 +34,22 @@
+
+
+
+
+
+
+
$(RepoRoot)artifacts/
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Azure/test/Azure.Test.csproj b/src/Microsoft.Data.SqlClient.Extensions/Azure/test/Azure.Test.csproj
index 1c020c2ae4..f34f247ea1 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Azure/test/Azure.Test.csproj
+++ b/src/Microsoft.Data.SqlClient.Extensions/Azure/test/Azure.Test.csproj
@@ -8,6 +8,13 @@
true
+
+
+
+ true
+ $(TestSigningKeyPath)
+
+
net8.0;net9.0;net10.0
diff --git a/src/Microsoft.Data.SqlClient.Internal/Logging/src/Logging.csproj b/src/Microsoft.Data.SqlClient.Internal/Logging/src/Logging.csproj
index d1c3e0fc5c..71d267f211 100644
--- a/src/Microsoft.Data.SqlClient.Internal/Logging/src/Logging.csproj
+++ b/src/Microsoft.Data.SqlClient.Internal/Logging/src/Logging.csproj
@@ -36,10 +36,22 @@
+
+
+
+
+
+
+
$(RepoRoot)artifacts/
From 28efdb5133c10dd46c96600ee569f426c8e3f90d Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Wed, 17 Jun 2026 13:03:36 -0300
Subject: [PATCH 03/12] test: add Logging.Test project and CI pipeline coverage
- Create Logging.Test.csproj targeting net462/net8.0/net9.0/net10.0
- Add SqlClientEventSourceTest verifying the singleton instance
- Create test-logging-package-ci-job.yml template with signing support
- Add Linux/Windows/macOS test jobs to build-logging-package-ci-stage
- Add project to solution file
---
.../jobs/test-logging-package-ci-job.yml | 210 ++++++++++++++++++
.../stages/build-logging-package-ci-stage.yml | 59 ++++-
.../Logging/test/Directory.Packages.props | 10 +
.../Logging/test/Logging.Test.csproj | 51 +++++
.../Logging/test/SqlClientEventSourceTest.cs | 14 ++
src/Microsoft.Data.SqlClient.slnx | 1 +
6 files changed, 341 insertions(+), 4 deletions(-)
create mode 100644 eng/pipelines/jobs/test-logging-package-ci-job.yml
create mode 100644 src/Microsoft.Data.SqlClient.Internal/Logging/test/Directory.Packages.props
create mode 100644 src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj
create mode 100644 src/Microsoft.Data.SqlClient.Internal/Logging/test/SqlClientEventSourceTest.cs
diff --git a/eng/pipelines/jobs/test-logging-package-ci-job.yml b/eng/pipelines/jobs/test-logging-package-ci-job.yml
new file mode 100644
index 0000000000..3678b99edf
--- /dev/null
+++ b/eng/pipelines/jobs/test-logging-package-ci-job.yml
@@ -0,0 +1,210 @@
+################################################################################
+# 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 Logging package and runs its tests for a set of .NET
+# runtimes.
+#
+# This template defines a job named
+# 'test_logging_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
+
+ # True to emit debug information and steps.
+ - name: debug
+ type: boolean
+ default: false
+
+ # The prefix to prepend to the job's display name:
+ #
+ # [] Test Logging Package
+ #
+ - name: displayNamePrefix
+ type: string
+
+ # The verbosity level for the dotnet CLI commands.
+ - name: dotnetVerbosity
+ type: string
+ default: normal
+ values:
+ - quiet
+ - minimal
+ - normal
+ - detailed
+ - diagnostic
+
+ # True when building on the internal ADO.Net project. When set, assemblies
+ # are signed with the driver key and tests are signed with the test key.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
+ # 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 pool VM image to use.
+ - name: vmImage
+ type: string
+
+jobs:
+
+ - job: test_logging_package_job_${{ parameters.jobNameSuffix }}
+ displayName: '[${{ parameters.displayNamePrefix }}] Test Logging 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 Logging test project file to use for all dotnet CLI commands.
+ #
+ # Building this project implicitly builds the Logging project.
+ - name: project
+ value: src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj
+
+ # dotnet CLI arguments for build/test/pack commands
+ - name: buildArguments
+ value: >-
+ -p:Configuration=${{ parameters.buildConfiguration }}
+ --verbosity ${{ parameters.dotnetVerbosity }}
+
+ # Signing arguments — only set for internal builds.
+ - ${{ if eq(parameters.isInternalBuild, true) }}:
+ - name: signingArguments
+ value: >-
+ -p:SigningKeyPath=$(driverKeyFile.secureFilePath)
+ -p:TestSigningKeyPath=$(testKeyFile.secureFilePath)
+ - ${{ else }}:
+ - name: signingArguments
+ value: ''
+
+ # 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.
+ #
+ # 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:
+
+ # Emit environment variables if debug is enabled.
+ - ${{ if eq(parameters.debug, true) }}:
+ - pwsh: 'Get-ChildItem Env: | Sort-Object Name'
+ displayName: '[Debug] Print Environment Variables'
+
+ # Download the assembly signing keys for internal builds.
+ - ${{ if eq(parameters.isInternalBuild, true) }}:
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
+ parameters:
+ isTest: true
+
+ # Install the .NET SDK and Runtimes.
+ - template: /eng/pipelines/common/steps/install-dotnet.yml@self
+ parameters:
+ debug: ${{ parameters.debug }}
+ runtimes: [8.x, 9.x]
+
+ # The Windows agent images include a suitable .NET Framework runtime, so
+ # we don't have to install one explicitly.
+
+ # Build the project.
+ - task: DotNetCoreCLI@2
+ displayName: Build Project
+ inputs:
+ command: build
+ projects: $(project)
+ arguments: $(buildArguments) $(signingArguments)
+
+ # Run the tests for each .NET runtime.
+ - ${{ each runtime in parameters.netRuntimes }}:
+ - task: DotNetCoreCLI@2
+ displayName: Test [${{ runtime }}]
+ inputs:
+ command: test
+ projects: $(project)
+ arguments: >-
+ $(buildArguments)
+ --no-build
+ -f ${{ runtime }}
+ --filter "category != failing & category != flaky & category != interactive"
+
+ - task: DotNetCoreCLI@2
+ displayName: Test Flaky [${{ runtime }}]
+ inputs:
+ command: test
+ projects: $(project)
+ arguments: >-
+ $(buildArguments)
+ --no-build
+ -f ${{ runtime }}
+ --filter "category = flaky"
+
+ # Run the tests for each .NET Framework runtime.
+ - ${{ each runtime in parameters.netFrameworkRuntimes }}:
+ - task: DotNetCoreCLI@2
+ displayName: Test [${{ runtime }}]
+ inputs:
+ command: test
+ projects: $(project)
+ arguments: >-
+ $(buildArguments)
+ --no-build
+ -f ${{ runtime }}
+ --filter "category != failing & category != flaky & category != interactive"
+
+ - task: DotNetCoreCLI@2
+ displayName: Test Flaky [${{ runtime }}]
+ inputs:
+ command: test
+ projects: $(project)
+ arguments: >-
+ $(buildArguments)
+ --no-build
+ -f ${{ runtime }}
+ --filter "category = flaky"
diff --git a/eng/pipelines/stages/build-logging-package-ci-stage.yml b/eng/pipelines/stages/build-logging-package-ci-stage.yml
index 6b5f22feeb..d25954d35e 100644
--- a/eng/pipelines/stages/build-logging-package-ci-stage.yml
+++ b/eng/pipelines/stages/build-logging-package-ci-stage.yml
@@ -67,6 +67,11 @@ parameters:
- detailed
- diagnostic
+ # True when building on the internal ADO.Net project.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
stages:
- stage: build_logging_package_stage
@@ -79,11 +84,56 @@ stages:
jobs:
+ # ------------------------------------------------------------------------
+ # Build and test on Linux.
+
+ - template: /eng/pipelines/jobs/test-logging-package-ci-job.yml@self
+ parameters:
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ debug: ${{ parameters.debug }}
+ displayNamePrefix: Linux
+ dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
+ jobNameSuffix: linux
+ netFrameworkRuntimes: []
+ netRuntimes: [net8.0, net9.0, net10.0]
+ poolName: Azure Pipelines
+ vmImage: ubuntu-latest
+
+ # ------------------------------------------------------------------------
+ # Build and test on Windows.
+
+ - template: /eng/pipelines/jobs/test-logging-package-ci-job.yml@self
+ parameters:
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ debug: ${{ parameters.debug }}
+ displayNamePrefix: Win
+ dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
+ jobNameSuffix: windows
+ netFrameworkRuntimes: [net462]
+ netRuntimes: [net8.0, net9.0, net10.0]
+ poolName: Azure Pipelines
+ vmImage: windows-latest
+
+ # ------------------------------------------------------------------------
+ # Build and test on macOS.
+
+ - template: /eng/pipelines/jobs/test-logging-package-ci-job.yml@self
+ parameters:
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ debug: ${{ parameters.debug }}
+ displayNamePrefix: macOS
+ dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
+ jobNameSuffix: macos
+ netFrameworkRuntimes: []
+ netRuntimes: [net8.0, net9.0, net10.0]
+ poolName: Azure Pipelines
+ vmImage: macos-latest
+
+ # ------------------------------------------------------------------------
# Create and publish the NuGet package.
- # Note: No test jobs because the Logging project does not have a test
- # project yet. When a test project is added, test jobs should be added
- # here (mirroring the Abstractions stage pattern) and the pack job should
- # depend on them.
- template: /eng/pipelines/jobs/pack-logging-package-ci-job.yml@self
parameters:
@@ -93,3 +143,4 @@ stages:
buildConfiguration: ${{ parameters.buildConfiguration }}
debug: ${{ parameters.debug }}
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
diff --git a/src/Microsoft.Data.SqlClient.Internal/Logging/test/Directory.Packages.props b/src/Microsoft.Data.SqlClient.Internal/Logging/test/Directory.Packages.props
new file mode 100644
index 0000000000..f3593ec1ba
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Internal/Logging/test/Directory.Packages.props
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj b/src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj
new file mode 100644
index 0000000000..58f6feae31
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj
@@ -0,0 +1,51 @@
+
+
+
+ Microsoft.Data.SqlClient.Internal.Logging.Test
+ net462;net8.0;net9.0;net10.0
+
+ false
+ true
+
+
+
+
+
+ true
+ $(TestSigningKeyPath)
+
+
+
+
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+ xunit.runner.json
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Internal/Logging/test/SqlClientEventSourceTest.cs b/src/Microsoft.Data.SqlClient.Internal/Logging/test/SqlClientEventSourceTest.cs
new file mode 100644
index 0000000000..ea3e4fabed
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Internal/Logging/test/SqlClientEventSourceTest.cs
@@ -0,0 +1,14 @@
+// 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.
+
+namespace Microsoft.Data.SqlClient.Internal.Logging.Test;
+
+public class SqlClientEventSourceTest
+{
+ [Fact]
+ public void SqlClientEventSource_Log_IsNotNull()
+ {
+ Assert.NotNull(SqlClientEventSource.Log);
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient.slnx b/src/Microsoft.Data.SqlClient.slnx
index a578a82db6..d6a615e39f 100644
--- a/src/Microsoft.Data.SqlClient.slnx
+++ b/src/Microsoft.Data.SqlClient.slnx
@@ -146,6 +146,7 @@
+
From 788979795bbc14f78abee258c41a691edcefa048 Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Wed, 17 Jun 2026 13:46:34 -0300
Subject: [PATCH 04/12] Renamed STRONG_NAME_SIGNING to ASSEMBLY_SIGNING, and
all similar terminology.
---
build.proj | 6 +++---
eng/pipelines/ci/package/sqlclient-package.yml | 2 +-
.../onebranch/jobs/validate-signed-package-job.yml | 4 ++--
.../onebranch/steps/build-buildproj-step.yml | 2 +-
src/Directory.Build.props | 6 +++---
...nt.AlwaysEncrypted.AzureKeyVaultProvider.csproj | 2 +-
.../Abstractions/src/Abstractions.csproj | 2 +-
.../src/SqlAuthenticationProvider.Internal.cs | 14 +++++++-------
.../Abstractions/test/Abstractions.Test.csproj | 2 +-
.../Azure/src/Azure.csproj | 2 +-
.../Azure/test/Azure.Test.csproj | 2 +-
.../Logging/src/Logging.csproj | 2 +-
.../Logging/test/Logging.Test.csproj | 2 +-
.../notsupported/Microsoft.Data.SqlClient.csproj | 2 +-
.../ref/Microsoft.Data.SqlClient.csproj | 2 +-
.../src/Microsoft.Data.SqlClient.csproj | 2 +-
.../SqlClient/SqlAuthenticationProviderManager.cs | 6 +++---
.../Microsoft.Data.SqlClient.TestCommon.csproj | 2 +-
.../tests/FunctionalTests/SqlDataRecordTest.cs | 2 +-
.../ManualTests/SQL/UdtTest/SqlServerTypesTest.cs | 8 ++++----
.../Microsoft.Data.SqlClient.UnitTests.csproj | 2 +-
.../Microsoft.Data.SqlClient.TestUtilities.csproj | 2 +-
.../Microsoft.SqlServer.Server.csproj | 2 +-
23 files changed, 39 insertions(+), 39 deletions(-)
diff --git a/build.proj b/build.proj
index ac08aeaaee..5bdfb44e2e 100644
--- a/build.proj
+++ b/build.proj
@@ -247,8 +247,8 @@
$(TestFilters)&category!=signed
diff --git a/eng/pipelines/ci/package/sqlclient-package.yml b/eng/pipelines/ci/package/sqlclient-package.yml
index 72c65b364e..244993c23d 100644
--- a/eng/pipelines/ci/package/sqlclient-package.yml
+++ b/eng/pipelines/ci/package/sqlclient-package.yml
@@ -11,7 +11,7 @@
# - On pushes to GitHub main and ADO internal/main (batched)
# - Nightly at 00:00 UTC on both branches
#
-# On internal/main the strong-name signing key is downloaded and used to sign assemblies during the
+# On internal/main the assembly signing key is downloaded and used to sign assemblies during the
# build.
#
# GOTCHA: This pipeline definition is triggered by GitHub _and_ ADO CI. We distinguish the two via
diff --git a/eng/pipelines/onebranch/jobs/validate-signed-package-job.yml b/eng/pipelines/onebranch/jobs/validate-signed-package-job.yml
index afa5aa5918..03f511af9b 100644
--- a/eng/pipelines/onebranch/jobs/validate-signed-package-job.yml
+++ b/eng/pipelines/onebranch/jobs/validate-signed-package-job.yml
@@ -157,8 +157,8 @@ jobs:
$nugetPackageInstallPath = "${{ variables.nugetPackageInstallPath }}"
echo "nugetPackageInstallPath= $nugetPackageInstallPath"
- # Verify strong name signing #####################################
- echo "> 1. Verifying strong name signing of DLLs ..."
+ # Verify assembly signing #####################################
+ echo "> 1. Verifying assembly signing of DLLs ..."
# @TODO: This path seems brittle to VS upgrades, can we make it more flexible?
$snPath = "C:\Program Files (x86)\Microsoft SDKs\Windows\*\bin\NETFX 4.8.1 Tools\sn.exe"
diff --git a/eng/pipelines/onebranch/steps/build-buildproj-step.yml b/eng/pipelines/onebranch/steps/build-buildproj-step.yml
index 4b18be369b..dcb66f6f15 100644
--- a/eng/pipelines/onebranch/steps/build-buildproj-step.yml
+++ b/eng/pipelines/onebranch/steps/build-buildproj-step.yml
@@ -7,7 +7,7 @@
# This collection of steps to build a project via the build.proj. This will execute the "Build*"
# target in build.proj, where * is the packageShortName provided in the parameters.
#
-# Note: This differs from the pr/ci build-buildproj-step.yml in that it always strong-name signs
+# Note: This differs from the pr/ci build-buildproj-step.yml in that it always signs
# the assemblies, it only builds in package reference mode, and as such allows for version
# parameters to be provided.
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index b3e0663fd3..7982e8f785 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -106,15 +106,15 @@
low
-
+
-
+
true
$(SigningKeyPath)
- $(DefineConstants);STRONG_NAME_SIGNING
+ $(DefineConstants);ASSEMBLY_SIGNING
diff --git a/src/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider/src/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj b/src/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider/src/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj
index 203aabd1f5..9604565837 100644
--- a/src/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider/src/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj
+++ b/src/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider/src/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj
@@ -22,7 +22,7 @@
$(AkvProviderPackageVersion)
-
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
index 0957180637..9eac7f6ecf 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
@@ -32,7 +32,7 @@
$(AbstractionsPackageVersion)
-
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/SqlAuthenticationProvider.Internal.cs b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/SqlAuthenticationProvider.Internal.cs
index da56722718..7a801e607a 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/SqlAuthenticationProvider.Internal.cs
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/SqlAuthenticationProvider.Internal.cs
@@ -25,8 +25,8 @@ private static class Internal
{
///
/// The expected public key token of the SqlClient assembly, used to avoid loading imposter
- /// assemblies. This is the same token used by all assemblies in this repository when
- /// strong-name signed.
+ /// assemblies. This is the public key token of the assembly signing key used for all of
+ /// our driver assemblies.
///
private static readonly byte[] _sqlClientPublicKeyToken =
[ 0x23, 0xec, 0x7f, 0xc2, 0xd6, 0xea, 0xa4, 0xa5 ];
@@ -54,9 +54,9 @@ static Internal()
{
// Try to load the SqlClient assembly.
- #if STRONG_NAME_SIGNING
+ #if ASSEMBLY_SIGNING
- // When strong-name signing is enabled, build a fully-qualified AssemblyName that
+ // When assembly signing is enabled, build a fully-qualified AssemblyName that
// includes the expected public key token.
Log($"Attempting to load SqlClient assembly={assemblyName} with " +
"expected public key token=" +
@@ -89,9 +89,9 @@ static Internal()
#else
- // Strong-name signing is disabled, so we cannot verify the public key token.
- Log($"Loading SqlClient assembly={assemblyName} without strong name " +
- "verification; ensure this assembly is from a trusted source");
+ // Assembly signing is disabled, so we cannot verify the public key token.
+ Log($"Loading SqlClient assembly={assemblyName} without assembly verification; " +
+ "ensure this assembly is from a trusted source");
var assembly = Assembly.Load(assemblyName);
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
index 0fe52f0327..24b8905322 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
@@ -8,7 +8,7 @@
true
-
+
true
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Azure/src/Azure.csproj b/src/Microsoft.Data.SqlClient.Extensions/Azure/src/Azure.csproj
index 796fc2767a..02d3733ffb 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Azure/src/Azure.csproj
+++ b/src/Microsoft.Data.SqlClient.Extensions/Azure/src/Azure.csproj
@@ -32,7 +32,7 @@
$(AzurePackageVersion)
-
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Azure/test/Azure.Test.csproj b/src/Microsoft.Data.SqlClient.Extensions/Azure/test/Azure.Test.csproj
index f34f247ea1..818a223f21 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Azure/test/Azure.Test.csproj
+++ b/src/Microsoft.Data.SqlClient.Extensions/Azure/test/Azure.Test.csproj
@@ -8,7 +8,7 @@
true
-
+
true
diff --git a/src/Microsoft.Data.SqlClient.Internal/Logging/src/Logging.csproj b/src/Microsoft.Data.SqlClient.Internal/Logging/src/Logging.csproj
index 71d267f211..bc7502d517 100644
--- a/src/Microsoft.Data.SqlClient.Internal/Logging/src/Logging.csproj
+++ b/src/Microsoft.Data.SqlClient.Internal/Logging/src/Logging.csproj
@@ -34,7 +34,7 @@
$(LoggingPackageVersion)
-
+
diff --git a/src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj b/src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj
index 58f6feae31..2993bcd22c 100644
--- a/src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj
+++ b/src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj
@@ -8,7 +8,7 @@
true
-
+
true
diff --git a/src/Microsoft.Data.SqlClient/notsupported/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/notsupported/Microsoft.Data.SqlClient.csproj
index a9474613e6..d1c65d6add 100644
--- a/src/Microsoft.Data.SqlClient/notsupported/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/notsupported/Microsoft.Data.SqlClient.csproj
@@ -83,7 +83,7 @@
$(SqlClientPackageVersion)
-
+
diff --git a/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.csproj
index 43aca3f1c1..7976d967fb 100644
--- a/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.csproj
@@ -28,7 +28,7 @@
-
+
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj
index 06eaf9e914..71e9c80215 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj
@@ -60,7 +60,7 @@
$(SqlClientPackageVersion)
-
+
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.cs
index 653063b68e..a3851e096f 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.cs
@@ -61,9 +61,9 @@ static SqlAuthenticationProviderManager()
try
{
// Try to load our Azure extension.
- #if STRONG_NAME_SIGNING
+ #if ASSEMBLY_SIGNING
- // When strong-name signing is enabled, build a fully-qualified AssemblyName
+ // When assembly signing is enabled, build a fully-qualified AssemblyName
// that includes the expected public key token.
SqlClientEventSource.Log.TryTraceEvent(
@@ -109,7 +109,7 @@ static SqlAuthenticationProviderManager()
SqlClientEventSource.Log.TryTraceEvent(
nameof(SqlAuthenticationProviderManager) +
$": Attempting to load Azure extension assembly={azureAssemblyName} without " +
- "strong name verification; ensure this assembly is from a trusted source");
+ "assembly verification; ensure this assembly is from a trusted source");
var assembly = Assembly.Load(azureAssemblyName);
diff --git a/src/Microsoft.Data.SqlClient/tests/Common/Microsoft.Data.SqlClient.TestCommon.csproj b/src/Microsoft.Data.SqlClient/tests/Common/Microsoft.Data.SqlClient.TestCommon.csproj
index 67c5250748..aac951b190 100644
--- a/src/Microsoft.Data.SqlClient/tests/Common/Microsoft.Data.SqlClient.TestCommon.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/Common/Microsoft.Data.SqlClient.TestCommon.csproj
@@ -14,7 +14,7 @@
false
-
+
true
diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlDataRecordTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlDataRecordTest.cs
index b051f2cc26..6c31e23bd3 100644
--- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlDataRecordTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlDataRecordTest.cs
@@ -334,7 +334,7 @@ public void GetChar_ThrowsNotSupported()
[Theory]
#if NETFRAMEWORK
- [Trait("Category", "signed")] // Requires strong-name signed Microsoft.SqlServer.Server
+ [Trait("Category", "signed")] // Requires a signed Microsoft.SqlServer.Server assembly
#endif
[MemberData(
nameof(GetUdtTypeTestData.Get),
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/SqlServerTypesTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/SqlServerTypesTest.cs
index 712d1ec2c6..911f2fbc58 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/SqlServerTypesTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/UdtTest/SqlServerTypesTest.cs
@@ -37,7 +37,7 @@ public static class SqlServerTypesTest
// Synapse: Parse error at line: 1, column: 48: Incorrect syntax near 'hierarchyid'.
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
#if NETFRAMEWORK
- [Trait("Category", "signed")] // Requires strong-name signed Microsoft.SqlServer.Server
+ [Trait("Category", "signed")] // Requires a signed Microsoft.SqlServer.Server assembly
#endif
public static void GetSchemaTableTest()
{
@@ -66,7 +66,7 @@ public static void GetSchemaTableTest()
// Synapse: Parse error at line: 1, column: 48: Incorrect syntax near 'hierarchyid'.
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
#if NETFRAMEWORK
- [Trait("Category", "signed")] // Requires strong-name signed Microsoft.SqlServer.Server
+ [Trait("Category", "signed")] // Requires a signed Microsoft.SqlServer.Server assembly
#endif
public static void GetValueTest()
{
@@ -227,7 +227,7 @@ void ActAndAssert(int index, string expectedHexString)
// Synapse: Parse error at line: 1, column: 41: Incorrect syntax near 'hierarchyid'.
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
#if NETFRAMEWORK
- [Trait("Category", "signed")] // Requires strong-name signed Microsoft.SqlServer.Server
+ [Trait("Category", "signed")] // Requires a signed Microsoft.SqlServer.Server assembly
#endif
public static void TestUdtSchemaMetadata()
{
@@ -384,7 +384,7 @@ private static string GetUdtName(Type udtClrType)
// Synapse: Parse error at line: 1, column: 8: Incorrect syntax near 'geometry'.
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
#if NETFRAMEWORK
- [Trait("Category", "signed")] // Requires strong-name signed Microsoft.SqlServer.Server
+ [Trait("Category", "signed")] // Requires a signed Microsoft.SqlServer.Server assembly
#endif
public static void TestSqlServerTypesInsertAndRead()
{
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj
index e09e49c967..cd95155822 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj
@@ -36,7 +36,7 @@
-
+
true
diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Microsoft.Data.SqlClient.TestUtilities.csproj b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Microsoft.Data.SqlClient.TestUtilities.csproj
index 05444fd022..3d4f6c41d7 100644
--- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Microsoft.Data.SqlClient.TestUtilities.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Microsoft.Data.SqlClient.TestUtilities.csproj
@@ -3,7 +3,7 @@
netstandard2.0
-
+
true
diff --git a/src/Microsoft.SqlServer.Server/Microsoft.SqlServer.Server.csproj b/src/Microsoft.SqlServer.Server/Microsoft.SqlServer.Server.csproj
index a995fa13b9..6769c42328 100644
--- a/src/Microsoft.SqlServer.Server/Microsoft.SqlServer.Server.csproj
+++ b/src/Microsoft.SqlServer.Server/Microsoft.SqlServer.Server.csproj
@@ -16,7 +16,7 @@
$(SqlServerPackageVersion)
-
+
From 659d1eca4976bc825d4d3d380d7356997864774f Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Wed, 17 Jun 2026 14:01:25 -0300
Subject: [PATCH 05/12] fix: address PR #4369 review feedback
- Logging.Test.csproj: make net462 TFM conditional on Windows (matches
Azure.Test.csproj pattern)
- Rename buildArguments variable to dotnetBuildOpts in all three test job
pipelines to avoid implicit .NET CLI argument injection via
BUILDARGUMENTS environment variable
- Add SqlClientEventSource_Log_IsSingleton test asserting singleton
identity
---
.../jobs/test-abstractions-package-ci-job.yml | 12 ++++++------
eng/pipelines/jobs/test-azure-package-ci-job.yml | 12 ++++++------
eng/pipelines/jobs/test-logging-package-ci-job.yml | 12 ++++++------
.../Logging/test/Logging.Test.csproj | 8 +++++++-
.../Logging/test/SqlClientEventSourceTest.cs | 6 ++++++
5 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/eng/pipelines/jobs/test-abstractions-package-ci-job.yml b/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
index d4deed9f65..880ea1d7f4 100644
--- a/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
+++ b/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
@@ -95,7 +95,7 @@ jobs:
value: src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
# dotnet CLI arguments for build/test/pack commands
- - name: buildArguments
+ - name: dotnetBuildOpts
value: >-
-p:Configuration=${{ parameters.buildConfiguration }}
--verbosity ${{ parameters.dotnetVerbosity }}
@@ -159,7 +159,7 @@ jobs:
inputs:
command: build
projects: $(project)
- arguments: $(buildArguments) $(signingArguments)
+ arguments: $(dotnetBuildOpts) $(signingArguments)
# Run the tests for each .NET runtime.
- ${{ each runtime in parameters.netRuntimes }}:
@@ -169,7 +169,7 @@ jobs:
command: test
projects: $(project)
arguments: >-
- $(buildArguments)
+ $(dotnetBuildOpts)
--no-build
-f ${{ runtime }}
--filter "category != failing & category != flaky & category != interactive"
@@ -180,7 +180,7 @@ jobs:
command: test
projects: $(project)
arguments: >-
- $(buildArguments)
+ $(dotnetBuildOpts)
--no-build
-f ${{ runtime }}
--filter "category = flaky"
@@ -193,7 +193,7 @@ jobs:
command: test
projects: $(project)
arguments: >-
- $(buildArguments)
+ $(dotnetBuildOpts)
--no-build
-f ${{ runtime }}
--filter "category != failing & category != flaky & category != interactive"
@@ -204,7 +204,7 @@ jobs:
command: test
projects: $(project)
arguments: >-
- $(buildArguments)
+ $(dotnetBuildOpts)
--no-build
-f ${{ runtime }}
--filter "category = flaky"
diff --git a/eng/pipelines/jobs/test-azure-package-ci-job.yml b/eng/pipelines/jobs/test-azure-package-ci-job.yml
index 457a3765c4..f1983eab91 100644
--- a/eng/pipelines/jobs/test-azure-package-ci-job.yml
+++ b/eng/pipelines/jobs/test-azure-package-ci-job.yml
@@ -175,7 +175,7 @@ jobs:
value: src/Microsoft.Data.SqlClient.Extensions/Azure/test/Azure.Test.csproj
# dotnet CLI arguments for build/test/pack commands.
- - name: buildArguments
+ - name: dotnetBuildOpts
value: >-
-p:Configuration=${{ parameters.buildConfiguration }}
--verbosity ${{ parameters.dotnetVerbosity }}
@@ -312,7 +312,7 @@ jobs:
inputs:
command: build
projects: $(project)
- arguments: $(buildArguments) $(signingArguments)
+ arguments: $(dotnetBuildOpts) $(signingArguments)
# List the DLLs in the output directory for debugging purposes.
- ${{ if eq(parameters.debug, true) }}:
@@ -347,7 +347,7 @@ jobs:
command: test
projects: $(project)
arguments: >-
- $(buildArguments)
+ $(dotnetBuildOpts)
--no-build
-f ${{ runtime }}
--filter "category != failing & category != flaky & category != interactive"
@@ -365,7 +365,7 @@ jobs:
command: test
projects: $(project)
arguments: >-
- $(buildArguments)
+ $(dotnetBuildOpts)
--no-build
-f ${{ runtime }}
--filter "category = flaky"
@@ -385,7 +385,7 @@ jobs:
command: test
projects: $(project)
arguments: >-
- $(buildArguments)
+ $(dotnetBuildOpts)
--no-build
-f ${{ runtime }}
--filter "category != failing & category != flaky & category != interactive"
@@ -403,7 +403,7 @@ jobs:
command: test
projects: $(project)
arguments: >-
- $(buildArguments)
+ $(dotnetBuildOpts)
--no-build
-f ${{ runtime }}
--filter "category = flaky"
diff --git a/eng/pipelines/jobs/test-logging-package-ci-job.yml b/eng/pipelines/jobs/test-logging-package-ci-job.yml
index 3678b99edf..6e035e33d6 100644
--- a/eng/pipelines/jobs/test-logging-package-ci-job.yml
+++ b/eng/pipelines/jobs/test-logging-package-ci-job.yml
@@ -95,7 +95,7 @@ jobs:
value: src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj
# dotnet CLI arguments for build/test/pack commands
- - name: buildArguments
+ - name: dotnetBuildOpts
value: >-
-p:Configuration=${{ parameters.buildConfiguration }}
--verbosity ${{ parameters.dotnetVerbosity }}
@@ -159,7 +159,7 @@ jobs:
inputs:
command: build
projects: $(project)
- arguments: $(buildArguments) $(signingArguments)
+ arguments: $(dotnetBuildOpts) $(signingArguments)
# Run the tests for each .NET runtime.
- ${{ each runtime in parameters.netRuntimes }}:
@@ -169,7 +169,7 @@ jobs:
command: test
projects: $(project)
arguments: >-
- $(buildArguments)
+ $(dotnetBuildOpts)
--no-build
-f ${{ runtime }}
--filter "category != failing & category != flaky & category != interactive"
@@ -180,7 +180,7 @@ jobs:
command: test
projects: $(project)
arguments: >-
- $(buildArguments)
+ $(dotnetBuildOpts)
--no-build
-f ${{ runtime }}
--filter "category = flaky"
@@ -193,7 +193,7 @@ jobs:
command: test
projects: $(project)
arguments: >-
- $(buildArguments)
+ $(dotnetBuildOpts)
--no-build
-f ${{ runtime }}
--filter "category != failing & category != flaky & category != interactive"
@@ -204,7 +204,7 @@ jobs:
command: test
projects: $(project)
arguments: >-
- $(buildArguments)
+ $(dotnetBuildOpts)
--no-build
-f ${{ runtime }}
--filter "category = flaky"
diff --git a/src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj b/src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj
index 2993bcd22c..be3ca85785 100644
--- a/src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj
+++ b/src/Microsoft.Data.SqlClient.Internal/Logging/test/Logging.Test.csproj
@@ -2,7 +2,13 @@
Microsoft.Data.SqlClient.Internal.Logging.Test
- net462;net8.0;net9.0;net10.0
+ net8.0;net9.0;net10.0
+
+
+ $(TargetFrameworks);net462
false
true
diff --git a/src/Microsoft.Data.SqlClient.Internal/Logging/test/SqlClientEventSourceTest.cs b/src/Microsoft.Data.SqlClient.Internal/Logging/test/SqlClientEventSourceTest.cs
index ea3e4fabed..d46896672f 100644
--- a/src/Microsoft.Data.SqlClient.Internal/Logging/test/SqlClientEventSourceTest.cs
+++ b/src/Microsoft.Data.SqlClient.Internal/Logging/test/SqlClientEventSourceTest.cs
@@ -11,4 +11,10 @@ public void SqlClientEventSource_Log_IsNotNull()
{
Assert.NotNull(SqlClientEventSource.Log);
}
+
+ [Fact]
+ public void SqlClientEventSource_Log_IsSingleton()
+ {
+ Assert.Same(SqlClientEventSource.Log, SqlClientEventSource.Log);
+ }
}
From 60edf88bdb39cd0ead18d3e3205ece6c8f676b58 Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Wed, 17 Jun 2026 14:36:25 -0300
Subject: [PATCH 06/12] fix: use compile-time branches for pack buildProperties
to avoid MSB1005
When optional variables (packageModeProperties, signingProperties) are
empty, concatenating them with hardcoded semicolons produces trailing
';;' that MSBuild rejects with MSB1005. Replace runtime concatenation
with compile-time ${{ if }} branches so only non-empty segments appear.
---
.../jobs/pack-abstractions-package-ci-job.yml | 25 +++++++++----------
.../jobs/pack-azure-package-ci-job.yml | 25 +++++++++----------
.../jobs/pack-logging-package-ci-job.yml | 13 +++++-----
3 files changed, 31 insertions(+), 32 deletions(-)
diff --git a/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml b/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
index b75900f1bc..7f7506c431 100644
--- a/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
+++ b/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
@@ -129,20 +129,19 @@ jobs:
- name: baseBuildProperties
value: AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }};AbstractionsAssemblyFileVersion=${{ parameters.abstractionsAssemblyFileVersion }}
- - name: packageModeProperties
- ${{ if eq(parameters.referenceType, 'Package') }}:
- value: ReferenceType=Package;LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
- ${{ else }}:
- value: ''
-
- - name: signingProperties
- ${{ if eq(parameters.isInternalBuild, true) }}:
- value: SigningKeyPath=$(driverKeyFile.secureFilePath)
- ${{ else }}:
- value: ''
-
+ # NOTE: We use compile-time ${{ if }} branches rather than concatenating
+ # separate variables (e.g. "$(base);$(optional);$(signing)") because
+ # when the optional variables are empty the semicolons remain, producing
+ # a trailing ";;" that MSBuild rejects with MSB1005.
- name: buildProperties
- value: $(baseBuildProperties);$(packageModeProperties);$(signingProperties)
+ ${{ if and(eq(parameters.referenceType, 'Package'), eq(parameters.isInternalBuild, true)) }}:
+ value: $(baseBuildProperties);ReferenceType=Package;LoggingPackageVersion=${{ parameters.loggingPackageVersion }};SigningKeyPath=$(driverKeyFile.secureFilePath)
+ ${{ elseif eq(parameters.referenceType, 'Package') }}:
+ value: $(baseBuildProperties);ReferenceType=Package;LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
+ ${{ elseif eq(parameters.isInternalBuild, true) }}:
+ value: $(baseBuildProperties);SigningKeyPath=$(driverKeyFile.secureFilePath)
+ ${{ else }}:
+ value: $(baseBuildProperties)
steps:
diff --git a/eng/pipelines/jobs/pack-azure-package-ci-job.yml b/eng/pipelines/jobs/pack-azure-package-ci-job.yml
index 81def77c44..d26a0f4e33 100644
--- a/eng/pipelines/jobs/pack-azure-package-ci-job.yml
+++ b/eng/pipelines/jobs/pack-azure-package-ci-job.yml
@@ -141,20 +141,19 @@ jobs:
- name: baseBuildProperties
value: AzurePackageVersion=${{ parameters.azurePackageVersion }};AzureAssemblyFileVersion=${{ parameters.azureAssemblyFileVersion }}
- - name: packageModeProperties
- ${{ if eq(parameters.referenceType, 'Package') }}:
- value: ReferenceType=Package;LoggingPackageVersion=${{ parameters.loggingPackageVersion }};AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
- ${{ else }}:
- value: ''
-
- - name: signingProperties
- ${{ if eq(parameters.isInternalBuild, true) }}:
- value: SigningKeyPath=$(driverKeyFile.secureFilePath)
- ${{ else }}:
- value: ''
-
+ # NOTE: We use compile-time ${{ if }} branches rather than concatenating
+ # separate variables (e.g. "$(base);$(optional);$(signing)") because
+ # when the optional variables are empty the semicolons remain, producing
+ # a trailing ";;" that MSBuild rejects with MSB1005.
- name: buildProperties
- value: $(baseBuildProperties);$(packageModeProperties);$(signingProperties)
+ ${{ if and(eq(parameters.referenceType, 'Package'), eq(parameters.isInternalBuild, true)) }}:
+ value: $(baseBuildProperties);ReferenceType=Package;LoggingPackageVersion=${{ parameters.loggingPackageVersion }};AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }};SigningKeyPath=$(driverKeyFile.secureFilePath)
+ ${{ elseif eq(parameters.referenceType, 'Package') }}:
+ value: $(baseBuildProperties);ReferenceType=Package;LoggingPackageVersion=${{ parameters.loggingPackageVersion }};AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ ${{ elseif eq(parameters.isInternalBuild, true) }}:
+ value: $(baseBuildProperties);SigningKeyPath=$(driverKeyFile.secureFilePath)
+ ${{ else }}:
+ value: $(baseBuildProperties)
steps:
diff --git a/eng/pipelines/jobs/pack-logging-package-ci-job.yml b/eng/pipelines/jobs/pack-logging-package-ci-job.yml
index f42b18cebe..3598ce009d 100644
--- a/eng/pipelines/jobs/pack-logging-package-ci-job.yml
+++ b/eng/pipelines/jobs/pack-logging-package-ci-job.yml
@@ -95,14 +95,15 @@ jobs:
- name: baseBuildProperties
value: LoggingPackageVersion=${{ parameters.loggingPackageVersion }};LoggingAssemblyFileVersion=${{ parameters.loggingAssemblyFileVersion }}
- - name: signingProperties
+ # NOTE: We use compile-time ${{ if }} branches rather than concatenating
+ # separate variables (e.g. "$(base);$(signing)") because when the
+ # optional variable is empty the semicolons remain, producing a trailing
+ # ";;" that MSBuild rejects with MSB1005.
+ - name: buildProperties
${{ if eq(parameters.isInternalBuild, true) }}:
- value: SigningKeyPath=$(driverKeyFile.secureFilePath)
+ value: $(baseBuildProperties);SigningKeyPath=$(driverKeyFile.secureFilePath)
${{ else }}:
- value: ''
-
- - name: buildProperties
- value: $(baseBuildProperties);$(signingProperties)
+ value: $(baseBuildProperties)
steps:
From a49e8461b6358f9b0af2a9eda62bda12e966be95 Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Thu, 18 Jun 2026 10:42:38 -0300
Subject: [PATCH 07/12] Pass SigningKeyPathArgument to test targets and
normalize DotnetCommand sections
Add to TestSqlClientFunctional, TestSqlClientManual,
and TestSqlClientUnit targets so the driver is strong-name signed when rebuilt
during dotnet test on net462.
Normalize all 20 DotnetCommand blocks to follow the BuildSqlClientNotSupported
pattern: blank line after command+project, consistent section headers
(Build arguments, Versioning arguments, Test arguments, Reference Type
Arguments, Pack arguments), and SigningKeyPathArgument in the Build section.
---
build.proj | 107 +++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 84 insertions(+), 23 deletions(-)
diff --git a/build.proj b/build.proj
index 5bdfb44e2e..91c8729f23 100644
--- a/build.proj
+++ b/build.proj
@@ -452,6 +452,8 @@
"$(DotnetPath)dotnet" build "$(SqlClientNotSupportedProjectPath)"
+
+
-p:Configuration=$(Configuration)
-p:GenApiPath="@(GenApiArtifactPath->'%(FullPath)')"
$(SigningKeyPathArgument)
@@ -483,6 +485,8 @@
"$(DotnetPath)dotnet" build $(SqlClientRefProjectPath)
+
+
-p:Configuration=$(Configuration)
$(SigningKeyPathArgument)
@@ -491,7 +495,7 @@
$(BuildSuffixArgument)
$(PackageVersionSqlClientArgument)
-
+
$(ReferenceTypeArgument)
$(PackageVersionAbstractionsArgument)
$(PackageVersionSqlServerArgument)
@@ -512,6 +516,8 @@
"$(DotnetPath)dotnet" build $(SqlClientProjectPath)
+
+
-p:Configuration=$(Configuration)
-p:TargetOs=Unix
$(SigningKeyPathArgument)
@@ -543,11 +549,13 @@
"$(DotnetPath)dotnet" build $(SqlClientProjectPath)
+
+
-p:Configuration=$(Configuration)
-p:TargetOs=Windows_NT
$(SigningKeyPathArgument)
-
+
$(BuildNumberArgument)
$(BuildSuffixArgument)
$(PackageVersionSqlClientArgument)
@@ -586,6 +594,8 @@
"$(DotnetPath)dotnet" pack "$(SqlClientProjectPath)"
+
+
-p:Configuration=$(Configuration)
$(PackBuildArgument)
$(SigningKeyPathArgument)
@@ -601,7 +611,7 @@
$(PackageVersionLoggingArgument)
$(PackageVersionSqlServerArgument)
-
+
-p:PackageOutputPath="$(SqlClientPackageArtifactRoot)"
@@ -635,7 +645,12 @@
"$(DotnetPath)dotnet" test "$(SqlClientFunctionalTestProjectPath)"
+
+
-p:Configuration=$(Configuration)
+ $(SigningKeyPathArgument)
+
+
$(TestBlameArgument)
$(TestCodeCoverageArgument)
$(TestFiltersArgument)
@@ -680,7 +695,12 @@
"$(DotnetPath)dotnet" test "$(SqlClientManualTestProjectPath)"
+
+
-p:Configuration=$(Configuration)
+ $(SigningKeyPathArgument)
+
+
$(TestBlameArgument)
$(TestCodeCoverageArgument)
$(ManualTestFiltersArgument)
@@ -710,17 +730,24 @@
"$(DotnetPath)dotnet" test "$(SqlClientUnitTestProjectPath)"
+
+
-p:Configuration=$(Configuration)
+ $(SigningKeyPathArgument)
+ $(TestSigningKeyPathArgument)
+
+
$(TestBlameArgument)
$(TestCodeCoverageArgument)
$(TestFiltersArgument)
$(TestFrameworkArgument)
+ --results-directory "$(TestResultsFolderPath)"
+ --logger:"trx;LogFilePrefix=$(LogFilePrefix)"
+
+
$(ReferenceTypeArgument)
- $(TestSigningKeyPathArgument)
$(PackageVersionSqlClientArgument)
$(PackageVersionSqlServerArgument)
- --results-directory "$(TestResultsFolderPath)"
- --logger:"trx;LogFilePrefix=$(LogFilePrefix)"
@@ -746,15 +773,17 @@
"$(DotnetPath)dotnet" build "$(AkvProviderProjectPath)"
+
+
-p:Configuration=$(Configuration)
$(SigningKeyPathArgument)
-
+
$(BuildNumberArgument)
$(BuildSuffixArgument)
$(PackageVersionAkvProviderArgument)
-
+
$(ReferenceTypeArgument)
$(PackageVersionAbstractionsArgument)
$(PackageVersionLoggingArgument)
@@ -774,6 +803,8 @@
"$(DotnetPath)dotnet" pack "$(AkvProviderProjectPath)"
+
+
-p:Configuration=$(Configuration)
$(PackBuildArgument)
$(SigningKeyPathArgument)
@@ -827,6 +858,8 @@
"$(DotnetPath)dotnet" build "$(AbstractionsProjectPath)"
+
+
-p:Configuration=$(Configuration)
$(SigningKeyPathArgument)
@@ -852,6 +885,8 @@
"$(DotnetPath)dotnet" pack "$(AbstractionsProjectPath)"
+
+
-p:Configuration=$(Configuration)
$(PackBuildArgument)
$(SigningKeyPathArgument)
@@ -892,19 +927,23 @@
"$(DotnetPath)dotnet" test "$(AbstractionsTestProjectPath)"
+
+
-p:Configuration=$(Configuration)
+ $(SigningKeyPathArgument)
+ $(TestSigningKeyPathArgument)
+
+
$(TestBlameArgument)
$(TestCodeCoverageArgument)
$(TestFiltersArgument)
$(TestFrameworkArgument)
- $(SigningKeyPathArgument)
- $(TestSigningKeyPathArgument)
+ --results-directory "$(TestResultsFolderPath)"
+ --logger:"trx;LogFilePrefix=$(LogFilePrefix)"
-
+
$(ReferenceTypeArgument)
$(PackageVersionLoggingArgument)
- --results-directory "$(TestResultsFolderPath)"
- --logger:"trx;LogFilePrefix=$(LogFilePrefix)"
$([System.Text.RegularExpressions.Regex]::Replace($(DotnetCommand), "\s+", " "))
@@ -931,6 +970,8 @@
"$(DotnetPath)dotnet" build "$(AzureProjectPath)"
+
+
-p:Configuration=$(Configuration)
$(SigningKeyPathArgument)
@@ -939,7 +980,7 @@
$(BuildSuffixArgument)
$(PackageVersionAzureArgument)
-
+
$(ReferenceTypeArgument)
$(PackageVersionLoggingArgument)
@@ -956,6 +997,8 @@
"$(DotnetPath)dotnet" pack "$(AzureProjectPath)"
+
+
-p:Configuration=$(Configuration)
$(PackBuildArgument)
$(SigningKeyPathArgument)
@@ -996,22 +1039,26 @@
"$(DotnetPath)dotnet" test "$(AzureTestProjectPath)"
+
+
-p:Configuration=$(Configuration)
+ $(SigningKeyPathArgument)
+ $(TestSigningKeyPathArgument)
+
+
$(TestBlameArgument)
$(TestCodeCoverageArgument)
$(TestFiltersArgument)
$(TestFrameworkArgument)
- $(SigningKeyPathArgument)
- $(TestSigningKeyPathArgument)
+ --results-directory "$(TestResultsFolderPath)"
+ --logger:"trx;LogFilePrefix=$(LogFilePrefix)"
-
+
$(ReferenceTypeArgument)
$(PackageVersionAbstractionsArgument)
$(PackageVersionLoggingArgument)
$(PackageVersionSqlClientArgument)
$(PackageVersionSqlServerArgument)
- --results-directory "$(TestResultsFolderPath)"
- --logger:"trx;LogFilePrefix=$(LogFilePrefix)"
$([System.Text.RegularExpressions.Regex]::Replace($(DotnetCommand), "\s+", " "))
@@ -1035,6 +1082,8 @@
"$(DotnetPath)dotnet" build $(LoggingProjectPath)
+
+
-p:Configuration=$(Configuration)
$(SigningKeyPathArgument)
@@ -1056,6 +1105,8 @@
"$(DotnetPath)dotnet" pack $(LoggingProjectPath)
+
+
-p:Configuration=$(Configuration)
$(PackBuildArgument)
$(SigningKeyPathArgument)
@@ -1092,16 +1143,22 @@
"$(DotnetPath)dotnet" test "$(LoggingTestProjectPath)"
+
+
-p:Configuration=$(Configuration)
+ $(SigningKeyPathArgument)
+ $(TestSigningKeyPathArgument)
+
+
$(TestBlameArgument)
$(TestCodeCoverageArgument)
$(TestFiltersArgument)
$(TestFrameworkArgument)
- $(SigningKeyPathArgument)
- $(TestSigningKeyPathArgument)
- $(ReferenceTypeArgument)
--results-directory "$(TestResultsFolderPath)"
--logger:"trx;LogFilePrefix=$(LogFilePrefix)"
+
+
+ $(ReferenceTypeArgument)
$([System.Text.RegularExpressions.Regex]::Replace($(DotnetCommand), "\s+", " "))
@@ -1124,10 +1181,12 @@
"$(DotnetPath)dotnet" build $(SqlServerProjectPath)
+
+
-p:Configuration=$(Configuration)
$(SigningKeyPathArgument)
-
+
$(BuildNumberArgument)
$(BuildSuffixArgument)
$(PackageVersionSqlServerArgument)
@@ -1145,6 +1204,8 @@
"$(DotnetPath)dotnet" pack $(SqlServerProjectPath)
+
+
-p:Configuration=$(Configuration)
$(PackBuildArgument)
$(SigningKeyPathArgument)
From 84d437a790732ae9f11c7234ec394d121bd4421e Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Thu, 18 Jun 2026 14:15:55 -0300
Subject: [PATCH 08/12] Disable signing for Project-mode pipeline; add signing
to SqlServer.Server pack
- ci-run-tests-job.yml: Remove signingKeyPath from Project-mode build step;
gate test step signing keys on referenceType != Project
- ci-build-nugets-job.yml: Remove signingKeyPath from hardcoded Project build;
gate other build steps on referenceType != Project
- pack-sqlserver-package-ci-job.yml: Add isInternalBuild parameter, download
signing key, and pass SigningKeyPath via buildProperties for internal builds
- build-sqlserver-package-ci-stage.yml: Accept and forward isInternalBuild
- dotnet-sqlclient-ci-core.yml: Pass isInternalBuild to SqlServer stage
Project mode now builds and tests unsigned, avoiding InternalsVisibleTo
conflicts (CS0122). Package mode retains signing for strong-name compliance
on net462. SqlServer.Server packages are now signed in internal builds,
fixing FileLoadException in Package-mode net462 tests.
---
.../templates/jobs/ci-build-nugets-job.yml | 6 ++----
.../templates/jobs/ci-run-tests-job.yml | 6 ++----
eng/pipelines/dotnet-sqlclient-ci-core.yml | 1 +
.../jobs/pack-sqlserver-package-ci-job.yml | 19 ++++++++++++++++++-
.../build-sqlserver-package-ci-stage.yml | 6 ++++++
5 files changed, 29 insertions(+), 9 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 130f314beb..ec0f18a5ea 100644
--- a/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
@@ -157,8 +157,6 @@ jobs:
buildConfiguration: Release
referenceType: Project
build: all
- ${{ if eq(parameters.isInternalBuild, true) }}:
- signingKeyPath: $(driverKeyFile.secureFilePath)
- template: /eng/pipelines/common/templates/steps/ci-project-build-step.yml@self
parameters:
@@ -170,7 +168,7 @@ jobs:
abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}
- ${{ if eq(parameters.isInternalBuild, true) }}:
+ ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
signingKeyPath: $(driverKeyFile.secureFilePath)
- task: DotNetCoreCLI@2
@@ -219,7 +217,7 @@ jobs:
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
akvPackageVersion: ${{ parameters.akvPackageVersion }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}
- ${{ if eq(parameters.isInternalBuild, true) }}:
+ ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
signingKeyPath: $(driverKeyFile.secureFilePath)
- task: DotNetCoreCLI@2
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 df508c9522..705c5133ad 100644
--- a/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
@@ -244,8 +244,6 @@ jobs:
build: allNoDocs
buildConfiguration: ${{ parameters.buildConfiguration }}
referenceType: Project
- ${{ if eq(parameters.isInternalBuild, true) }}:
- signingKeyPath: $(driverKeyFile.secureFilePath)
- ${{ if ne(parameters.configProperties, '{}') }}:
- template: /eng/pipelines/common/templates/steps/update-config-file-step.yml@self # update config.jsonc file
@@ -392,7 +390,7 @@ jobs:
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}
- ${{ if eq(parameters.isInternalBuild, true) }}:
+ ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
signingKeyPath: $(driverKeyFile.secureFilePath)
testSigningKeyPath: $(testKeyFile.secureFilePath)
@@ -411,7 +409,7 @@ jobs:
loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}
- ${{ if eq(parameters.isInternalBuild, true) }}:
+ ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
signingKeyPath: $(driverKeyFile.secureFilePath)
testSigningKeyPath: $(testKeyFile.secureFilePath)
diff --git a/eng/pipelines/dotnet-sqlclient-ci-core.yml b/eng/pipelines/dotnet-sqlclient-ci-core.yml
index 5fdc25ee0e..500d2a76e9 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-core.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-core.yml
@@ -144,6 +144,7 @@ stages:
buildConfiguration: ${{ parameters.buildConfiguration }}
debug: ${{ parameters.debug }}
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
# Build the Logging package, and publish it to the pipeline artifacts
# under the given artifact name. This runs in parallel with the Secrets
diff --git a/eng/pipelines/jobs/pack-sqlserver-package-ci-job.yml b/eng/pipelines/jobs/pack-sqlserver-package-ci-job.yml
index 6b19e8c154..a5b840cb79 100644
--- a/eng/pipelines/jobs/pack-sqlserver-package-ci-job.yml
+++ b/eng/pipelines/jobs/pack-sqlserver-package-ci-job.yml
@@ -49,6 +49,11 @@ parameters:
- detailed
- diagnostic
+ # True when building on the internal ADO.Net project.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
jobs:
- job: pack_sqlserver_package_job
@@ -82,6 +87,14 @@ jobs:
- name: Configuration
value: ''
+ # Build properties passed to dotnet pack. Composed from a base set plus
+ # optional signing key path for internal builds.
+ - name: buildProperties
+ ${{ if eq(parameters.isInternalBuild, true) }}:
+ value: SqlServerPackageVersion=${{ parameters.sqlServerPackageVersion }};SigningKeyPath=$(driverKeyFile.secureFilePath)
+ ${{ else }}:
+ value: SqlServerPackageVersion=${{ parameters.sqlServerPackageVersion }}
+
steps:
# Emit environment variables if debug is enabled.
@@ -94,6 +107,10 @@ jobs:
parameters:
debug: ${{ parameters.debug }}
+ # Download the assembly signing key for internal builds.
+ - ${{ if eq(parameters.isInternalBuild, true) }}:
+ - template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
+
# Create the NuGet packages.
- task: DotNetCoreCLI@2
displayName: Create NuGet Package
@@ -103,7 +120,7 @@ jobs:
configurationToPack: ${{ parameters.buildConfiguration }}
packDirectory: $(dotnetPackagesDir)
verbosityToPack: ${{ parameters.dotnetVerbosity }}
- buildProperties: SqlServerPackageVersion=${{ parameters.sqlServerPackageVersion }}
+ buildProperties: $(buildProperties)
- task: PublishPipelineArtifact@1
displayName: Publish Pipeline Artifact
diff --git a/eng/pipelines/stages/build-sqlserver-package-ci-stage.yml b/eng/pipelines/stages/build-sqlserver-package-ci-stage.yml
index 1711725373..bebff7c44b 100644
--- a/eng/pipelines/stages/build-sqlserver-package-ci-stage.yml
+++ b/eng/pipelines/stages/build-sqlserver-package-ci-stage.yml
@@ -63,6 +63,11 @@ parameters:
- detailed
- diagnostic
+ # True when building on the internal ADO.Net project.
+ - name: isInternalBuild
+ type: boolean
+ default: false
+
stages:
- stage: build_sqlserver_package_stage
@@ -81,3 +86,4 @@ stages:
sqlServerArtifactsName: ${{ parameters.sqlServerArtifactsName }}
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
+ isInternalBuild: ${{ parameters.isInternalBuild }}
From 44ae0f7b0b4221c60a90400e88603e7a88792b68 Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Thu, 18 Jun 2026 22:02:53 -0300
Subject: [PATCH 09/12] Disable signing for leaf packages in Project-mode
pipeline
Gate assembly signing in Abstractions, Logging, and SqlServer.Server pack
jobs on ne(referenceType, 'Project') so that Project-mode builds produce
unsigned assemblies consistently across all packages.
- pack-abstractions-package-ci-job.yml: remove Project+internal signing
branch, gate key download on Package mode
- pack-logging-package-ci-job.yml: add referenceType parameter, gate
buildProperties and key download
- pack-sqlserver-package-ci-job.yml: add referenceType parameter, gate
buildProperties and key download
- build-logging-package-ci-stage.yml: add referenceType parameter,
forward to pack job
- build-sqlserver-package-ci-stage.yml: add referenceType parameter,
forward to pack job
- dotnet-sqlclient-ci-core.yml: pass referenceType to Logging and
SqlServer stage invocations
---
eng/pipelines/dotnet-sqlclient-ci-core.yml | 2 ++
.../jobs/pack-abstractions-package-ci-job.yml | 6 ++----
.../jobs/pack-logging-package-ci-job.yml | 14 +++++++++++---
.../jobs/pack-sqlserver-package-ci-job.yml | 16 ++++++++++++----
.../stages/build-logging-package-ci-stage.yml | 9 +++++++++
.../stages/build-sqlserver-package-ci-stage.yml | 9 +++++++++
6 files changed, 45 insertions(+), 11 deletions(-)
diff --git a/eng/pipelines/dotnet-sqlclient-ci-core.yml b/eng/pipelines/dotnet-sqlclient-ci-core.yml
index 500d2a76e9..2df5d62e1e 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-core.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-core.yml
@@ -145,6 +145,7 @@ stages:
debug: ${{ parameters.debug }}
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
isInternalBuild: ${{ parameters.isInternalBuild }}
+ referenceType: ${{ parameters.referenceType }}
# Build the Logging package, and publish it to the pipeline artifacts
# under the given artifact name. This runs in parallel with the Secrets
@@ -158,6 +159,7 @@ stages:
debug: ${{ parameters.debug }}
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
isInternalBuild: ${{ parameters.isInternalBuild }}
+ referenceType: ${{ parameters.referenceType }}
# Build the Abstractions package, and publish it to the pipeline artifacts
# under the given artifact name.
diff --git a/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml b/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
index 7f7506c431..37b16769b4 100644
--- a/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
+++ b/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
@@ -138,8 +138,6 @@ jobs:
value: $(baseBuildProperties);ReferenceType=Package;LoggingPackageVersion=${{ parameters.loggingPackageVersion }};SigningKeyPath=$(driverKeyFile.secureFilePath)
${{ elseif eq(parameters.referenceType, 'Package') }}:
value: $(baseBuildProperties);ReferenceType=Package;LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
- ${{ elseif eq(parameters.isInternalBuild, true) }}:
- value: $(baseBuildProperties);SigningKeyPath=$(driverKeyFile.secureFilePath)
${{ else }}:
value: $(baseBuildProperties)
@@ -164,8 +162,8 @@ jobs:
parameters:
debug: ${{ parameters.debug }}
- # Download the assembly signing key for internal builds.
- - ${{ if eq(parameters.isInternalBuild, true) }}:
+ # Download the assembly signing key for internal Package-mode builds.
+ - ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
- template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
# Create the NuGet packages.
diff --git a/eng/pipelines/jobs/pack-logging-package-ci-job.yml b/eng/pipelines/jobs/pack-logging-package-ci-job.yml
index 3598ce009d..5248bf0853 100644
--- a/eng/pipelines/jobs/pack-logging-package-ci-job.yml
+++ b/eng/pipelines/jobs/pack-logging-package-ci-job.yml
@@ -53,6 +53,14 @@ parameters:
- detailed
- diagnostic
+ # The C# project reference type to use when building and packing the packages.
+ - name: referenceType
+ type: string
+ default: Project
+ values:
+ - Package
+ - Project
+
# True when building on the internal ADO.Net project.
- name: isInternalBuild
type: boolean
@@ -100,7 +108,7 @@ jobs:
# optional variable is empty the semicolons remain, producing a trailing
# ";;" that MSBuild rejects with MSB1005.
- name: buildProperties
- ${{ if eq(parameters.isInternalBuild, true) }}:
+ ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
value: $(baseBuildProperties);SigningKeyPath=$(driverKeyFile.secureFilePath)
${{ else }}:
value: $(baseBuildProperties)
@@ -117,8 +125,8 @@ jobs:
parameters:
debug: ${{ parameters.debug }}
- # Download the assembly signing key for internal builds.
- - ${{ if eq(parameters.isInternalBuild, true) }}:
+ # Download the assembly signing key for internal Package-mode builds.
+ - ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
- template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
# Create the NuGet packages.
diff --git a/eng/pipelines/jobs/pack-sqlserver-package-ci-job.yml b/eng/pipelines/jobs/pack-sqlserver-package-ci-job.yml
index a5b840cb79..8684d474ac 100644
--- a/eng/pipelines/jobs/pack-sqlserver-package-ci-job.yml
+++ b/eng/pipelines/jobs/pack-sqlserver-package-ci-job.yml
@@ -49,6 +49,14 @@ parameters:
- detailed
- diagnostic
+ # The C# project reference type to use when building and packing the packages.
+ - name: referenceType
+ type: string
+ default: Project
+ values:
+ - Package
+ - Project
+
# True when building on the internal ADO.Net project.
- name: isInternalBuild
type: boolean
@@ -88,9 +96,9 @@ jobs:
value: ''
# Build properties passed to dotnet pack. Composed from a base set plus
- # optional signing key path for internal builds.
+ # optional signing key path for internal Package-mode builds.
- name: buildProperties
- ${{ if eq(parameters.isInternalBuild, true) }}:
+ ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
value: SqlServerPackageVersion=${{ parameters.sqlServerPackageVersion }};SigningKeyPath=$(driverKeyFile.secureFilePath)
${{ else }}:
value: SqlServerPackageVersion=${{ parameters.sqlServerPackageVersion }}
@@ -107,8 +115,8 @@ jobs:
parameters:
debug: ${{ parameters.debug }}
- # Download the assembly signing key for internal builds.
- - ${{ if eq(parameters.isInternalBuild, true) }}:
+ # Download the assembly signing key for internal Package-mode builds.
+ - ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
- template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
# Create the NuGet packages.
diff --git a/eng/pipelines/stages/build-logging-package-ci-stage.yml b/eng/pipelines/stages/build-logging-package-ci-stage.yml
index d25954d35e..bfdbe84ff2 100644
--- a/eng/pipelines/stages/build-logging-package-ci-stage.yml
+++ b/eng/pipelines/stages/build-logging-package-ci-stage.yml
@@ -72,6 +72,14 @@ parameters:
type: boolean
default: false
+ # The C# project reference type to use when building and packing the packages.
+ - name: referenceType
+ type: string
+ default: Project
+ values:
+ - Package
+ - Project
+
stages:
- stage: build_logging_package_stage
@@ -144,3 +152,4 @@ stages:
debug: ${{ parameters.debug }}
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
isInternalBuild: ${{ parameters.isInternalBuild }}
+ referenceType: ${{ parameters.referenceType }}
diff --git a/eng/pipelines/stages/build-sqlserver-package-ci-stage.yml b/eng/pipelines/stages/build-sqlserver-package-ci-stage.yml
index bebff7c44b..e08fbba531 100644
--- a/eng/pipelines/stages/build-sqlserver-package-ci-stage.yml
+++ b/eng/pipelines/stages/build-sqlserver-package-ci-stage.yml
@@ -68,6 +68,14 @@ parameters:
type: boolean
default: false
+ # The C# project reference type to use when building and packing the packages.
+ - name: referenceType
+ type: string
+ default: Project
+ values:
+ - Package
+ - Project
+
stages:
- stage: build_sqlserver_package_stage
@@ -87,3 +95,4 @@ stages:
sqlServerPackageVersion: ${{ parameters.sqlServerPackageVersion }}
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
isInternalBuild: ${{ parameters.isInternalBuild }}
+ referenceType: ${{ parameters.referenceType }}
From 8668069dee87543f5f9a08ef26955be3e3b88d61 Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Fri, 19 Jun 2026 08:05:54 -0300
Subject: [PATCH 10/12] Disable signing for Azure Extensions pack job in
Project mode
Same fix as the other leaf packages: remove the Project+internal signing
branch from buildProperties and gate the key download step on
ne(referenceType, 'Project').
---
eng/pipelines/jobs/pack-azure-package-ci-job.yml | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/eng/pipelines/jobs/pack-azure-package-ci-job.yml b/eng/pipelines/jobs/pack-azure-package-ci-job.yml
index d26a0f4e33..e1ddd7da76 100644
--- a/eng/pipelines/jobs/pack-azure-package-ci-job.yml
+++ b/eng/pipelines/jobs/pack-azure-package-ci-job.yml
@@ -150,8 +150,6 @@ jobs:
value: $(baseBuildProperties);ReferenceType=Package;LoggingPackageVersion=${{ parameters.loggingPackageVersion }};AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }};SigningKeyPath=$(driverKeyFile.secureFilePath)
${{ elseif eq(parameters.referenceType, 'Package') }}:
value: $(baseBuildProperties);ReferenceType=Package;LoggingPackageVersion=${{ parameters.loggingPackageVersion }};AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
- ${{ elseif eq(parameters.isInternalBuild, true) }}:
- value: $(baseBuildProperties);SigningKeyPath=$(driverKeyFile.secureFilePath)
${{ else }}:
value: $(baseBuildProperties)
@@ -181,8 +179,8 @@ jobs:
parameters:
debug: ${{ parameters.debug }}
- # Download the assembly signing key for internal builds.
- - ${{ if eq(parameters.isInternalBuild, true) }}:
+ # Download the assembly signing key for internal Package-mode builds.
+ - ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
- template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
# Create the NuGet packages.
From 5b5ff12169d98454a45c0be8bc2af6e26dff59cf Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Fri, 19 Jun 2026 08:13:42 -0300
Subject: [PATCH 11/12] Gate test job signing on referenceType for leaf
packages
Logging, Abstractions, and Azure test jobs were signing unconditionally
when isInternalBuild=true, causing Project-mode tests to run signed.
- test-logging-package-ci-job.yml: add referenceType param, gate signing
- test-abstractions-package-ci-job.yml: add referenceType param, gate signing
- test-azure-package-ci-job.yml: gate signing (already had referenceType)
- build-logging-package-ci-stage.yml: pass referenceType to test jobs
- build-abstractions-package-ci-stage.yml: pass referenceType to test jobs
---
.../jobs/test-abstractions-package-ci-job.yml | 16 ++++++++++++----
eng/pipelines/jobs/test-azure-package-ci-job.yml | 8 ++++----
.../jobs/test-logging-package-ci-job.yml | 16 ++++++++++++----
.../build-abstractions-package-ci-stage.yml | 3 +++
.../stages/build-logging-package-ci-stage.yml | 3 +++
5 files changed, 34 insertions(+), 12 deletions(-)
diff --git a/eng/pipelines/jobs/test-abstractions-package-ci-job.yml b/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
index 880ea1d7f4..ceb176274a 100644
--- a/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
+++ b/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
@@ -67,6 +67,14 @@ parameters:
type: boolean
default: false
+ # The C# project reference type to use when building.
+ - name: referenceType
+ type: string
+ default: Project
+ values:
+ - Package
+ - Project
+
# The pool VM image to use.
- name: vmImage
type: string
@@ -100,8 +108,8 @@ jobs:
-p:Configuration=${{ parameters.buildConfiguration }}
--verbosity ${{ parameters.dotnetVerbosity }}
- # Signing arguments — only set for internal builds.
- - ${{ if eq(parameters.isInternalBuild, true) }}:
+ # Signing arguments — only set for internal Package-mode builds.
+ - ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
- name: signingArguments
value: >-
-p:SigningKeyPath=$(driverKeyFile.secureFilePath)
@@ -137,8 +145,8 @@ jobs:
- pwsh: 'Get-ChildItem Env: | Sort-Object Name'
displayName: '[Debug] Print Environment Variables'
- # Download the assembly signing keys for internal builds.
- - ${{ if eq(parameters.isInternalBuild, true) }}:
+ # Download the assembly signing keys for internal Package-mode builds.
+ - ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
- template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
- template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
parameters:
diff --git a/eng/pipelines/jobs/test-azure-package-ci-job.yml b/eng/pipelines/jobs/test-azure-package-ci-job.yml
index f1983eab91..3570d72114 100644
--- a/eng/pipelines/jobs/test-azure-package-ci-job.yml
+++ b/eng/pipelines/jobs/test-azure-package-ci-job.yml
@@ -185,8 +185,8 @@ jobs:
-p:SqlClientPackageVersion=${{ parameters.mdsPackageVersion }}
-p:SqlServerPackageVersion=${{ parameters.sqlServerPackageVersion }}
- # Signing arguments — only set for internal builds.
- - ${{ if eq(parameters.isInternalBuild, true) }}:
+ # Signing arguments — only set for internal Package-mode builds.
+ - ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
- name: signingArguments
value: >-
-p:SigningKeyPath=$(driverKeyFile.secureFilePath)
@@ -222,8 +222,8 @@ jobs:
- pwsh: 'Get-ChildItem Env: | Sort-Object Name'
displayName: '[Debug] Print Environment Variables'
- # Download the assembly signing keys for internal builds.
- - ${{ if eq(parameters.isInternalBuild, true) }}:
+ # Download the assembly signing keys for internal Package-mode builds.
+ - ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
- template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
- template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
parameters:
diff --git a/eng/pipelines/jobs/test-logging-package-ci-job.yml b/eng/pipelines/jobs/test-logging-package-ci-job.yml
index 6e035e33d6..fde3e44c7e 100644
--- a/eng/pipelines/jobs/test-logging-package-ci-job.yml
+++ b/eng/pipelines/jobs/test-logging-package-ci-job.yml
@@ -71,6 +71,14 @@ parameters:
- name: vmImage
type: string
+ # The C# project reference type to use when building.
+ - name: referenceType
+ type: string
+ default: Project
+ values:
+ - Package
+ - Project
+
jobs:
- job: test_logging_package_job_${{ parameters.jobNameSuffix }}
@@ -100,8 +108,8 @@ jobs:
-p:Configuration=${{ parameters.buildConfiguration }}
--verbosity ${{ parameters.dotnetVerbosity }}
- # Signing arguments — only set for internal builds.
- - ${{ if eq(parameters.isInternalBuild, true) }}:
+ # Signing arguments — only set for internal Package-mode builds.
+ - ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
- name: signingArguments
value: >-
-p:SigningKeyPath=$(driverKeyFile.secureFilePath)
@@ -137,8 +145,8 @@ jobs:
- pwsh: 'Get-ChildItem Env: | Sort-Object Name'
displayName: '[Debug] Print Environment Variables'
- # Download the assembly signing keys for internal builds.
- - ${{ if eq(parameters.isInternalBuild, true) }}:
+ # Download the assembly signing keys for internal Package-mode builds.
+ - ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
- template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
- template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
parameters:
diff --git a/eng/pipelines/stages/build-abstractions-package-ci-stage.yml b/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
index f251d7d9c6..82a4efd6a4 100644
--- a/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
+++ b/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
@@ -122,6 +122,7 @@ stages:
netFrameworkRuntimes: []
netRuntimes: [net8.0, net9.0, net10.0]
poolName: Azure Pipelines
+ referenceType: ${{ parameters.referenceType }}
vmImage: ubuntu-latest
# ------------------------------------------------------------------------
@@ -138,6 +139,7 @@ stages:
netFrameworkRuntimes: [net462]
netRuntimes: [net8.0, net9.0, net10.0]
poolName: Azure Pipelines
+ referenceType: ${{ parameters.referenceType }}
vmImage: windows-latest
# ------------------------------------------------------------------------
@@ -154,6 +156,7 @@ stages:
netFrameworkRuntimes: []
netRuntimes: [net8.0, net9.0, net10.0]
poolName: Azure Pipelines
+ referenceType: ${{ parameters.referenceType }}
vmImage: macos-latest
# ------------------------------------------------------------------------
diff --git a/eng/pipelines/stages/build-logging-package-ci-stage.yml b/eng/pipelines/stages/build-logging-package-ci-stage.yml
index bfdbe84ff2..4a0ee11a8f 100644
--- a/eng/pipelines/stages/build-logging-package-ci-stage.yml
+++ b/eng/pipelines/stages/build-logging-package-ci-stage.yml
@@ -106,6 +106,7 @@ stages:
netFrameworkRuntimes: []
netRuntimes: [net8.0, net9.0, net10.0]
poolName: Azure Pipelines
+ referenceType: ${{ parameters.referenceType }}
vmImage: ubuntu-latest
# ------------------------------------------------------------------------
@@ -122,6 +123,7 @@ stages:
netFrameworkRuntimes: [net462]
netRuntimes: [net8.0, net9.0, net10.0]
poolName: Azure Pipelines
+ referenceType: ${{ parameters.referenceType }}
vmImage: windows-latest
# ------------------------------------------------------------------------
@@ -138,6 +140,7 @@ stages:
netFrameworkRuntimes: []
netRuntimes: [net8.0, net9.0, net10.0]
poolName: Azure Pipelines
+ referenceType: ${{ parameters.referenceType }}
vmImage: macos-latest
# ------------------------------------------------------------------------
From 240ea7e573ecc8a16807ee66456bb38820794da8 Mon Sep 17 00:00:00 2001
From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com>
Date: Fri, 19 Jun 2026 09:47:34 -0300
Subject: [PATCH 12/12] Address PR #4369 review feedback
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Replace static _sqlClientPublicKeyToken field with local variable
inside #if ASSEMBLY_SIGNING block to eliminate CS0414 warning
- Align Abstractions.Test.csproj TFM pattern with sibling test projects
(conditional net462 on Windows only)
- Standardize terminology: 'assembly verification' → 'strong-name
identity verification', 'assembly signing' → 'strong-name signing'
- Gate key download steps in ci-run-tests-job and ci-build-nugets-job
on ne(referenceType, 'Project') to skip unnecessary downloads
---
.../templates/jobs/ci-build-nugets-job.yml | 4 ++--
.../templates/jobs/ci-run-tests-job.yml | 4 ++--
.../jobs/validate-signed-package-job.yml | 4 ++--
.../src/SqlAuthenticationProvider.Internal.cs | 24 +++++++++----------
.../test/Abstractions.Test.csproj | 9 ++++++-
.../SqlAuthenticationProviderManager.cs | 2 +-
6 files changed, 26 insertions(+), 21 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 ec0f18a5ea..50d017f459 100644
--- a/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
@@ -142,8 +142,8 @@ jobs:
# Restore dotnet CLI tools (e.g. pwsh, apicompat) before building.
- template: /eng/pipelines/common/steps/restore-dotnet-tools.yml@self
- # Download the assembly signing key for internal builds.
- - ${{ if eq(parameters.isInternalBuild, true) }}:
+ # Download the assembly signing key for internal Package-mode builds.
+ - ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
- template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
# When we're performing a Debug build, we still want to try _compiling_ the
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 705c5133ad..1bbaef213a 100644
--- a/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
@@ -228,8 +228,8 @@ jobs:
# Restore dotnet CLI tools (e.g. pwsh, apicompat) before building.
- template: /eng/pipelines/common/steps/restore-dotnet-tools.yml@self
- # Download the assembly signing keys for internal builds.
- - ${{ if eq(parameters.isInternalBuild, true) }}:
+ # Download the assembly signing keys for internal Package-mode builds.
+ - ${{ if and(eq(parameters.isInternalBuild, true), ne(parameters.referenceType, 'Project')) }}:
- template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
- template: /eng/pipelines/common/steps/download-assembly-signing-key.yml@self
parameters:
diff --git a/eng/pipelines/onebranch/jobs/validate-signed-package-job.yml b/eng/pipelines/onebranch/jobs/validate-signed-package-job.yml
index 03f511af9b..0769e2093c 100644
--- a/eng/pipelines/onebranch/jobs/validate-signed-package-job.yml
+++ b/eng/pipelines/onebranch/jobs/validate-signed-package-job.yml
@@ -157,8 +157,8 @@ jobs:
$nugetPackageInstallPath = "${{ variables.nugetPackageInstallPath }}"
echo "nugetPackageInstallPath= $nugetPackageInstallPath"
- # Verify assembly signing #####################################
- echo "> 1. Verifying assembly signing of DLLs ..."
+ # Verify strong-name signing ###################################
+ echo "> 1. Verifying strong-name signing of DLLs ..."
# @TODO: This path seems brittle to VS upgrades, can we make it more flexible?
$snPath = "C:\Program Files (x86)\Microsoft SDKs\Windows\*\bin\NETFX 4.8.1 Tools\sn.exe"
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/SqlAuthenticationProvider.Internal.cs b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/SqlAuthenticationProvider.Internal.cs
index 7a801e607a..dd7cc33e6e 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/SqlAuthenticationProvider.Internal.cs
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/SqlAuthenticationProvider.Internal.cs
@@ -23,14 +23,6 @@ public abstract partial class SqlAuthenticationProvider
///
private static class Internal
{
- ///
- /// The expected public key token of the SqlClient assembly, used to avoid loading imposter
- /// assemblies. This is the public key token of the assembly signing key used for all of
- /// our driver assemblies.
- ///
- private static readonly byte[] _sqlClientPublicKeyToken =
- [ 0x23, 0xec, 0x7f, 0xc2, 0xd6, 0xea, 0xa4, 0xa5 ];
-
///
/// Our handle to the reflected GetProvider() method.
///
@@ -56,14 +48,20 @@ static Internal()
#if ASSEMBLY_SIGNING
+ // The expected public key token of the SqlClient assembly, used to avoid invoking
+ // APIs from imposter assemblies. This is the public key token of the assembly
+ // signing key used for all of our driver assemblies.
+ byte[] expectedPublicKeyToken =
+ [ 0x23, 0xec, 0x7f, 0xc2, 0xd6, 0xea, 0xa4, 0xa5 ];
+
// When assembly signing is enabled, build a fully-qualified AssemblyName that
// includes the expected public key token.
Log($"Attempting to load SqlClient assembly={assemblyName} with " +
"expected public key token=" +
- BitConverter.ToString(_sqlClientPublicKeyToken).Replace("-", ""));
+ BitConverter.ToString(expectedPublicKeyToken).Replace("-", ""));
var qualifiedName = new AssemblyName(assemblyName);
- qualifiedName.SetPublicKeyToken(_sqlClientPublicKeyToken);
+ qualifiedName.SetPublicKeyToken(expectedPublicKeyToken);
// The .NET Framework runtime enforces the token during binding, causing Load() to
// throw if it doesn't match. The .NET (Core) runtime ignores the token, so we
@@ -78,7 +76,7 @@ static Internal()
byte[]? actualToken = assembly.GetName().GetPublicKeyToken();
if (actualToken is null ||
- !actualToken.AsSpan().SequenceEqual(_sqlClientPublicKeyToken))
+ !actualToken.AsSpan().SequenceEqual(expectedPublicKeyToken))
{
Log($"SqlClient assembly={assembly.GetName()} has an " +
"unexpected public key token; " +
@@ -90,8 +88,8 @@ static Internal()
#else
// Assembly signing is disabled, so we cannot verify the public key token.
- Log($"Loading SqlClient assembly={assemblyName} without assembly verification; " +
- "ensure this assembly is from a trusted source");
+ Log($"Loading SqlClient assembly={assemblyName} without strong-name identity " +
+ "verification; ensure this assembly is from a trusted source");
var assembly = Assembly.Load(assemblyName);
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
index 24b8905322..7ab085560e 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
@@ -2,7 +2,14 @@
Microsoft.Data.SqlClient.Extensions.Abstractions.Test
- net462;net8.0;net9.0;net10.0
+ net8.0;net9.0;net10.0
+
+
+ $(TargetFrameworks);net462
false
true
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.cs
index a3851e096f..e73a533245 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAuthenticationProviderManager.cs
@@ -109,7 +109,7 @@ static SqlAuthenticationProviderManager()
SqlClientEventSource.Log.TryTraceEvent(
nameof(SqlAuthenticationProviderManager) +
$": Attempting to load Azure extension assembly={azureAssemblyName} without " +
- "assembly verification; ensure this assembly is from a trusted source");
+ "strong-name identity verification; ensure this assembly is from a trusted source");
var assembly = Assembly.Load(azureAssemblyName);