From 9c13cb9f17a09ff9627b0027e8dd968189db094a Mon Sep 17 00:00:00 2001 From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com> Date: Fri, 21 Aug 2026 11:34:33 -0300 Subject: [PATCH] Add assembly signing for Microsoft.Data.SqlClient.Extensions.Azure Sign the Azure package and its test assembly on internal Package-mode builds. Azure references Abstractions and Logging, both of which are signed earlier in this stack, so the reference closure is complete. - Thread isInternalBuild from the CI core into the Azure stage, pack job and test jobs, downloading the driver and test signing keys as needed. - Add a signed InternalsVisibleTo grant for the Azure test assembly, which needs internal access for the WAM broker tests, and sign that assembly when a test key is supplied. - Thread signing arguments into the build.proj TestAzure target. - Rename the test job's buildArguments variable to dotnetBuildOpts; Azure Pipelines exposes variables as environment variables and the dotnet CLI injects BUILDARGUMENTS into dotnet build. --- build.proj | 8 +++- eng/pipelines/dotnet-sqlclient-ci-core.yml | 1 + .../jobs/pack-azure-package-ci-job.yml | 24 +++++++++++- .../jobs/test-azure-package-ci-job.yml | 39 +++++++++++++++---- .../stages/build-azure-package-ci-stage.yml | 11 ++++++ .../Azure/src/Azure.csproj | 12 ++++++ .../Azure/test/Azure.Test.csproj | 8 +++- 7 files changed, 93 insertions(+), 10 deletions(-) diff --git a/build.proj b/build.proj index b0d04a4ebb..4620161a97 100644 --- a/build.proj +++ b/build.proj @@ -1015,7 +1015,13 @@ "$(DotnetPath)dotnet" test "$(AzureTestProjectPath)" + + -p:Configuration=$(Configuration) + $(SigningKeyPathArgument) + $(TestSigningKeyPathArgument) + + $(TestBlameArgument) $(TestCodeCoverageArgument) $(TestFiltersArgument) @@ -1023,7 +1029,7 @@ --results-directory "$(TestResultsFolderPath)" --logger:"trx;LogFilePrefix=$(LogFilePrefix)" - + $(ReferenceTypeArgument) $(PackageVersionSqlClientArgument) $(PackageVersionSqlServerArgument) diff --git a/eng/pipelines/dotnet-sqlclient-ci-core.yml b/eng/pipelines/dotnet-sqlclient-ci-core.yml index bfaa8b4620..5d59d9d005 100644 --- a/eng/pipelines/dotnet-sqlclient-ci-core.yml +++ b/eng/pipelines/dotnet-sqlclient-ci-core.yml @@ -221,6 +221,7 @@ stages: azureArtifactsName: $(azureArtifactsName) buildConfiguration: ${{ parameters.buildConfiguration }} debug: ${{ parameters.debug }} + isInternalBuild: ${{ parameters.isInternalBuild }} # When building via packages, we must depend on the Abstractions, Logging, # SqlServer, and MDS packages. ${{ if eq(parameters.referenceType, 'Package') }}: diff --git a/eng/pipelines/jobs/pack-azure-package-ci-job.yml b/eng/pipelines/jobs/pack-azure-package-ci-job.yml index 38eaf58fe9..6a7226cccd 100644 --- a/eng/pipelines/jobs/pack-azure-package-ci-job.yml +++ b/eng/pipelines/jobs/pack-azure-package-ci-job.yml @@ -73,6 +73,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 @@ -141,12 +146,29 @@ jobs: parameters: debug: ${{ parameters.debug }} + # 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. # # 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') }}: + - ${{ if and(eq(parameters.referenceType, 'Package'), eq(parameters.isInternalBuild, true)) }}: + - task: DotNetCoreCLI@2 + displayName: Create NuGet Package + inputs: + command: pack + packagesToPack: $(project) + configurationToPack: ${{ parameters.buildConfiguration }} + packDirectory: $(dotnetPackagesDir) + verbosityToPack: ${{ parameters.dotnetVerbosity }} + # BuildNumber supplies the revision component of FileVersion; without + # it the assembly is stamped Major.Minor.Patch.0 (see Project branch). + buildProperties: SqlClientPackageVersion=${{ parameters.packageVersion }};ReferenceType=Package;BuildNumber=$(Build.BuildNumber);SigningKeyPath=$(driverKeyFile.secureFilePath) + + - ${{ elseif eq(parameters.referenceType, 'Package') }}: - task: DotNetCoreCLI@2 displayName: Create NuGet Package inputs: diff --git a/eng/pipelines/jobs/test-azure-package-ci-job.yml b/eng/pipelines/jobs/test-azure-package-ci-job.yml index 104401b585..51f9be2f07 100644 --- a/eng/pipelines/jobs/test-azure-package-ci-job.yml +++ b/eng/pipelines/jobs/test-azure-package-ci-job.yml @@ -127,6 +127,12 @@ parameters: type: boolean default: false + # 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 @@ -154,8 +160,10 @@ jobs: - name: project value: src/Microsoft.Data.SqlClient.Extensions/Azure/test/Azure.Test.csproj - # dotnet CLI arguments for build/test/pack commands. - - name: buildArguments + # dotnet CLI arguments for build/test commands. + # + # Not named 'buildArguments': dotnet injects $BUILDARGUMENTS into 'dotnet build'. + - name: dotnetBuildOpts value: >- -p:Configuration=${{ parameters.buildConfiguration }} --verbosity ${{ parameters.dotnetVerbosity }} @@ -163,6 +171,16 @@ jobs: -p:SqlClientPackageVersion=${{ parameters.packageVersion }} -p:SqlServerPackageVersion=${{ parameters.sqlServerPackageVersion }} + # 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) + -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 @@ -232,6 +250,13 @@ jobs: debug: ${{ parameters.debug }} runtimes: [8.x, 9.x] + # 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: + isTest: true + # The Windows agent images include a suitable .NET Framework runtime, so # we don't have to install one explicitly. @@ -273,7 +298,7 @@ jobs: inputs: command: build projects: $(project) - arguments: $(buildArguments) + arguments: $(dotnetBuildOpts) $(signingArguments) # List the DLLs in the output directory for debugging purposes. - ${{ if eq(parameters.debug, true) }}: @@ -308,7 +333,7 @@ jobs: command: test projects: $(project) arguments: >- - $(buildArguments) + $(dotnetBuildOpts) --no-build -f ${{ runtime }} --filter "category != failing & category != flaky & category != interactive" @@ -326,7 +351,7 @@ jobs: command: test projects: $(project) arguments: >- - $(buildArguments) + $(dotnetBuildOpts) --no-build -f ${{ runtime }} --filter "category = flaky" @@ -346,7 +371,7 @@ jobs: command: test projects: $(project) arguments: >- - $(buildArguments) + $(dotnetBuildOpts) --no-build -f ${{ runtime }} --filter "category != failing & category != flaky & category != interactive" @@ -364,7 +389,7 @@ jobs: command: test projects: $(project) arguments: >- - $(buildArguments) + $(dotnetBuildOpts) --no-build -f ${{ runtime }} --filter "category = flaky" diff --git a/eng/pipelines/stages/build-azure-package-ci-stage.yml b/eng/pipelines/stages/build-azure-package-ci-stage.yml index 0713030b76..1dbc61ca3e 100644 --- a/eng/pipelines/stages/build-azure-package-ci-stage.yml +++ b/eng/pipelines/stages/build-azure-package-ci-stage.yml @@ -118,6 +118,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 @@ -153,6 +158,7 @@ stages: displayNamePrefix: Linux dotnetVerbosity: ${{ parameters.dotnetVerbosity }} jobNameSuffix: linux + isInternalBuild: ${{ parameters.isInternalBuild }} loggingArtifactsName: ${{ parameters.loggingArtifactsName }} mdsArtifactsName: ${{ parameters.mdsArtifactsName }} sqlServerArtifactsName: ${{ parameters.sqlServerArtifactsName }} @@ -173,6 +179,7 @@ stages: displayNamePrefix: Linux Integration dotnetVerbosity: ${{ parameters.dotnetVerbosity }} jobNameSuffix: linux_integration + isInternalBuild: ${{ parameters.isInternalBuild }} loggingArtifactsName: ${{ parameters.loggingArtifactsName }} mdsArtifactsName: ${{ parameters.mdsArtifactsName }} sqlServerArtifactsName: ${{ parameters.sqlServerArtifactsName }} @@ -202,6 +209,7 @@ stages: displayNamePrefix: Win dotnetVerbosity: ${{ parameters.dotnetVerbosity }} jobNameSuffix: windows + isInternalBuild: ${{ parameters.isInternalBuild }} loggingArtifactsName: ${{ parameters.loggingArtifactsName }} mdsArtifactsName: ${{ parameters.mdsArtifactsName }} sqlServerArtifactsName: ${{ parameters.sqlServerArtifactsName }} @@ -222,6 +230,7 @@ stages: displayNamePrefix: Win Integration dotnetVerbosity: ${{ parameters.dotnetVerbosity }} jobNameSuffix: windows_integration + isInternalBuild: ${{ parameters.isInternalBuild }} loggingArtifactsName: ${{ parameters.loggingArtifactsName }} mdsArtifactsName: ${{ parameters.mdsArtifactsName }} sqlServerArtifactsName: ${{ parameters.sqlServerArtifactsName }} @@ -260,6 +269,7 @@ stages: displayNamePrefix: macOS dotnetVerbosity: ${{ parameters.dotnetVerbosity }} jobNameSuffix: macos + isInternalBuild: ${{ parameters.isInternalBuild }} loggingArtifactsName: ${{ parameters.loggingArtifactsName }} mdsArtifactsName: ${{ parameters.mdsArtifactsName }} sqlServerArtifactsName: ${{ parameters.sqlServerArtifactsName }} @@ -293,3 +303,4 @@ stages: dotnetVerbosity: ${{ parameters.dotnetVerbosity }} loggingArtifactsName: ${{ parameters.loggingArtifactsName }} referenceType: ${{ parameters.referenceType }} + isInternalBuild: ${{ parameters.isInternalBuild }} diff --git a/src/Microsoft.Data.SqlClient.Extensions/Azure/src/Azure.csproj b/src/Microsoft.Data.SqlClient.Extensions/Azure/src/Azure.csproj index da0a4cb4c7..8734cc2ccb 100644 --- a/src/Microsoft.Data.SqlClient.Extensions/Azure/src/Azure.csproj +++ b/src/Microsoft.Data.SqlClient.Extensions/Azure/src/Azure.csproj @@ -33,10 +33,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 5d6780414b..54fa4f9b56 100644 --- a/src/Microsoft.Data.SqlClient.Extensions/Azure/test/Azure.Test.csproj +++ b/src/Microsoft.Data.SqlClient.Extensions/Azure/test/Azure.Test.csproj @@ -19,12 +19,18 @@ $(TargetFrameworks);net462 + + + + true + $(TestSigningKeyPath) + + enable enable -