diff --git a/.github/instructions/ado-pipelines.instructions.md b/.github/instructions/ado-pipelines.instructions.md
index 9cc5d316c6..82b8046dee 100644
--- a/.github/instructions/ado-pipelines.instructions.md
+++ b/.github/instructions/ado-pipelines.instructions.md
@@ -74,7 +74,7 @@ Optional pipeline for long-running stress and endurance testing. Enabled via `en
## Build Stages
1. **build_abstractions_package_stage**: Build and pack abstractions
-2. **build_mds_akv_packages_stage**: Build main driver and AKV packages
+2. **build_sqlclient_package_stage**: Build main driver and AKV packages
3. **build_azure_package_stage**: Build Azure extensions package
4. **stress_tests_stage**: Optional stress testing
5. **run_tests_stage**: Execute all test suites
diff --git a/.github/instructions/onebranch-pipeline-design.instructions.md b/.github/instructions/onebranch-pipeline-design.instructions.md
new file mode 100644
index 0000000000..e7efab6be1
--- /dev/null
+++ b/.github/instructions/onebranch-pipeline-design.instructions.md
@@ -0,0 +1,521 @@
+---
+applyTo: "eng/pipelines/**/*.yml"
+---
+# Multi-Product Azure DevOps Pipeline in dotnet/sqlclient — Design Specification
+
+## 1. Overview
+
+This document describes the design of the unified Azure DevOps YAML pipeline that builds, signs, packages, and optionally releases six NuGet packages with interdependencies. The pipeline uses **stages** and **jobs** to maximize parallelism while respecting dependency order. It comprises five stages: three build stages, a validation stage, and an on-demand release stage.
+
+Two pipeline variants exist from the same stage/job structure:
+
+| Pipeline | Template | Trigger | Purpose |
+|----------|----------|---------|---------|
+| `dotnet-sqlclient-official-pipeline.yml` | `OneBranch.Official.CrossPlat.yml` | CI + scheduled | Production-signed builds |
+| `dotnet-sqlclient-non-official-pipeline.yml` | `OneBranch.NonOfficial.CrossPlat.yml` | Manual only | Validation / test builds (release in dry-run mode) |
+
+Both pipelines use the **OneBranch (1ES) governed template** infrastructure and share identical stage definitions, job templates, and variable chains.
+
+---
+
+## 2. Products and Dependencies
+
+| # | Package | Dependencies |
+|---|---------|-------------|
+| 1 | `Microsoft.SqlServer.Server` | — |
+| 2 | `Microsoft.Data.SqlClient.Extensions.Logging` | — |
+| 3 | `Microsoft.Data.SqlClient.Extensions.Abstractions` | — |
+| 4 | `Microsoft.Data.SqlClient` | `Extensions.Logging`, `Extensions.Abstractions` |
+| 5 | `Microsoft.Data.SqlClient.Extensions.Azure` | `Extensions.Abstractions` |
+| 6 | `Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider` | `SqlClient`, `Extensions.Logging` |
+
+---
+
+## 3. Pipeline Flow — Sequence Diagram
+
+```mermaid
+sequenceDiagram
+ participant T as Trigger / User
+ participant P as Pipeline Orchestrator
+ participant B1a as Job: Build Extensions.Logging
+ participant B1b as Job: Build Extensions.Abstractions
+ participant B1c as Job: Build SqlServer.Server
+ participant B2a as Job: Build SqlClient
+ participant B2b as Job: Build Extensions.Azure
+ participant V as Job: Validate MDS Package
+ participant B3 as Job: Build AKV Provider
+ participant R as Stage: Release
+
+ Note over T,R: ══════ BUILD & SIGN PHASE ══════
+
+ T->>P: Pipeline triggered (CI / Scheduled / Manual)
+
+ Note over P: Stage 1 — build_independent (parallel, no deps)
+
+ par Stage 1 jobs (parallel)
+ P->>B1a: Build DLLs → ESRP sign DLLs → Pack → ESRP sign NuGet (Logging)
+ B1a-->>P: ✅ Signed .nupkg
+ and
+ P->>B1b: Build DLLs → ESRP sign DLLs → Pack → ESRP sign NuGet (Abstractions)
+ B1b-->>P: ✅ Signed .nupkg
+ and
+ P->>B1c: Build + ESRP sign + pack SqlServer.Server
+ B1c-->>P: ✅ Signed .nupkg
+ end
+
+ Note over P: Stage 2 — buildMDS (dependsOn: build_independent)
+
+ par Stage 2 jobs (parallel)
+ P->>B2a: Build + ESRP sign + pack SqlClient
+ Note right of B2a: Downloads: Extensions.Logging,
Extensions.Abstractions artifacts
+ B2a-->>P: ✅ Signed .nupkg + .snupkg
+ and
+ P->>B2b: Build DLLs → ESRP sign DLLs → Pack → ESRP sign NuGet (Azure)
+ Note right of B2b: Downloads:
Extensions.Abstractions artifact
+ B2b-->>P: ✅ Signed .nupkg
+ end
+
+ Note over P: Validation + Stage 3 (both dependsOn: buildMDS, run in parallel)
+
+ par Validation and Stage 3 (parallel)
+ P->>V: Validate signed MDS package
+ V-->>P: ✅ Package validation passed
+ and
+ P->>B3: Build + ESRP sign + pack AKV Provider
+ Note right of B3: Downloads: SqlClient,
Extensions.Logging artifacts
+ B3-->>P: ✅ Signed .nupkg
+ end
+
+ Note over T,R: ══════ RELEASE PHASE (on-demand) ══════
+
+ alt At least one release parameter is true
+ P->>R: Stage: release (dependsOn: conditional on build stages)
+ Note right of R: ADO Environment Approval
(NuGet-Production environment)
+ R-->>P: ✅ Approved
+ Note right of R: Publish selected packages
via NuGetCommand@2
+ R-->>P: ✅ Published to NuGet
+ else No release parameters set
+ Note over P: Release stage skipped
+ end
+
+ Note over T,R: Pipeline complete 🎉
+```
+
+---
+
+## 4. Stage Design
+
+### 4.1 Build Phase
+
+The build phase runs automatically on every CI trigger, scheduled run, or manual queue. It is divided into three build stages plus a validation stage, based on the dependency graph.
+
+#### Stage 1 — `build_independent`: Independent Packages (no dependencies)
+
+| Job Template | Package | Build Target | Condition |
+|--------------|---------|--------------|-----------|
+| `build-signed-csproj-package-job.yml` | `Microsoft.Data.SqlClient.Extensions.Logging` | `BuildLogging` / `PackLogging` | `buildAKVProvider OR buildSqlClient` |
+| `build-signed-csproj-package-job.yml` | `Microsoft.Data.SqlClient.Extensions.Abstractions` | `BuildAbstractions` / `PackAbstractions` | `buildSqlClient` |
+| `build-signed-csproj-package-job.yml` | `Microsoft.SqlServer.Server` | `PackSqlServer` | `buildSqlServerServer` |
+
+- **`dependsOn`**: none
+- **Parallelism**: Jobs run in parallel (depending on which are enabled)
+- **Conditional builds**: Each job is wrapped with compile-time `${{ if }}` conditionals based on build parameters
+- csproj-based jobs (`build-signed-csproj-package-job.yml`) perform: **Build DLLs → ESRP DLL signing → NuGet pack (NoBuild=true) → ESRP NuGet signing** → publish artifact
+
+#### Stage 2 — `buildMDS`: Core Packages (depend on Stage 1)
+
+| Job Template | Package | Build Target | Artifact Dependencies |
+|--------------|---------|--------------|----------------------|
+| `build-signed-package-job.yml` | `Microsoft.Data.SqlClient` | *(nuspec-based)* | `Extensions.Logging`, `Extensions.Abstractions` |
+| `build-signed-csproj-package-job.yml` | `Microsoft.Data.SqlClient.Extensions.Azure` | `BuildAzure` / `PackAzure` | `Extensions.Abstractions` |
+
+- **Stage condition**: `buildSqlClient = true` (entire stage is excluded when false)
+- **`dependsOn`**: `build_independent`
+- **Parallelism**: Both jobs run in parallel
+- The MDS (SqlClient) job also publishes symbol packages (`.snupkg`) when `publishSymbols` is true
+- All jobs configure APIScan with job-level `ob_sdl_apiscan_*` variables targeting package-specific folders
+
+#### Stage 3 — `build_addons`: Add-on Packages (depend on Stage 2)
+
+| Job Template | Package | Artifact Dependencies |
+|--------------|---------|----------------------|
+| `build-akv-official-job.yml` | `Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider` | `SqlClient`, `Extensions.Logging` |
+
+- **Stage condition**: `buildAKVProvider AND buildSqlClient` (both must be true)
+- **`dependsOn`**: `buildMDS`
+- Downloads `Microsoft.Data.SqlClient.nupkg` (from Stage 2) and `Microsoft.Data.SqlClient.Extensions.Logging.nupkg` (from Stage 1) pipeline artifacts
+- Uses separate ESRP signing credentials (`Signing`-prefixed variables from `esrp-variables-v2` group)
+
+### 4.2 Validation Stage — `mds_package_validation`
+
+Validates the signed MDS (SqlClient) package after Stage 2 completes.
+
+- **Stage condition**: `buildSqlClient = true`
+- **`dependsOn`**: `buildMDS`
+- Runs in parallel with Stage 3 (`build_addons`)
+- Uses `validate-signed-package-job.yml` template
+- Downloads the `drop_buildMDS_build_signed_package` artifact and validates against `CurrentNetFxVersion` (default: `net462`)
+
+### 4.3 Release Phase — `release`
+
+The release stage is gated and only executes on demand when at least one release parameter is set to `true` at queue time.
+
+- **`dependsOn`**: Conditional based on which build stages are enabled:
+ - `build_independent` (always)
+ - `buildMDS`, `mds_package_validation` (when `buildSqlClient = true`)
+ - `build_addons` (when `buildAKVProvider AND buildSqlClient`)
+- **Gate**: ADO Environment approvals (official pipeline only):
+ - Official: `NuGet-Production` environment with configured approvals
+ - Non-Official: `NuGet-DryRun` environment (no approvals, validation only)
+- **Package selection**: Controlled by 6 runtime boolean parameters (see Section 5.2)
+- **Stage condition**: The entire stage is skipped unless at least one release parameter is `true`:
+ ```yaml
+ - ${{ if or(parameters.releaseSqlServerServer, parameters.releaseLogging, ...) }}:
+ - stage: release
+ ```
+- **Publish jobs**: Each package has a conditional publish job that is included at compile time only when its parameter is `true`:
+ ```yaml
+ - ${{ if eq(parameters.releaseXxx, true) }}:
+ - template: /eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml@self
+ ```
+- **Environment variables**: Stage sets `ob_release_usedeploymentjob: true` for OneBranch integration:
+ - Official: `ob_release_environment: 'NuGet-Production'`
+ - Non-Official: `ob_release_environment: 'NuGet-DryRun'`
+
+#### Artifact → Publish Job Mapping
+
+| Package | Artifact Name | Publish Job |
+|---------|---------------|-------------|
+| `Microsoft.SqlServer.Server` | `drop_build_independent_build_signed_sqlserver_package` | `publish_SqlServer_Server` |
+| `Microsoft.Data.SqlClient.Extensions.Logging` | `drop_build_independent_build_signed_Logging_package` | `publish_Logging` |
+| `Microsoft.Data.SqlClient.Extensions.Abstractions` | `drop_build_independent_build_signed_Abstractions_package` | `publish_Abstractions` |
+| `Microsoft.Data.SqlClient` | `drop_buildMDS_build_signed_package` | `publish_SqlClient` |
+| `Microsoft.Data.SqlClient.Extensions.Azure` | `drop_buildMDS_build_signed_Azure_package` | `publish_Extensions_Azure` |
+| `Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider` | `drop_build_addons_buildSignedAkvPackage` | `publish_AKVProvider` |
+
+Each publish job uses the reusable `publish-nuget-package-job.yml` template, which downloads the artifact and pushes `.nupkg`/`.snupkg` files via `NuGetCommand@2` with an external feed service connection.
+
+#### Dry-Run Mode
+
+Two ADO environments control release behavior:
+
+| Environment | Pipeline | Behavior |
+|------------|----------|----------|
+| `NuGet-DryRun` | Non-Official | Validation only — packages are never pushed |
+| `NuGet-Production` | Official | Real releases with approval gate |
+
+**Non-official pipeline**: Always runs in dry-run mode. There is no `releaseDryRun` parameter — `dryRun: true` is hardcoded in every publish job. This prevents accidental publication from validation builds.
+
+**Official pipeline**: Exposes a `releaseDryRun` parameter (default: `true` for safety). When enabled, the template downloads artifacts and lists the `.nupkg`/`.snupkg` files that *would* be published but skips the actual `NuGetCommand@2` push. Set `releaseDryRun: false` to perform real pushes after final validation.
+
+---
+
+## 5. Runtime Parameters
+
+### 5.1 Build Parameters
+
+The pipeline exposes the following parameters at queue time:
+
+```yaml
+parameters:
+ - name: debug
+ displayName: 'Enable debug output'
+ type: boolean
+ default: false
+
+ - name: publishSymbols
+ displayName: 'Publish symbols'
+ type: boolean
+ default: false
+
+ - name: CurrentNetFxVersion
+ displayName: 'Lowest supported .NET Framework version (MDS validation)'
+ type: string
+ default: 'net462'
+
+ - name: isPreview
+ displayName: 'Is this a preview build?'
+ type: boolean
+ default: false
+
+ - name: testJobTimeout
+ displayName: 'Test job timeout (in minutes)'
+ type: number
+ default: 60
+
+ # Build parameters — control which packages to build
+ - name: buildSqlServerServer
+ displayName: 'Build Microsoft.SqlServer.Server'
+ type: boolean
+ default: true
+
+ - name: buildSqlClient
+ displayName: 'Build Microsoft.Data.SqlClient and Extensions'
+ type: boolean
+ default: true
+
+ - name: buildAKVProvider
+ displayName: 'Build Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider'
+ type: boolean
+ default: true
+```
+
+The `isPreview` parameter controls version resolution — when `true`, each package uses its preview version (e.g., `loggingPackagePreviewVersion`) instead of the GA version (e.g., `loggingPackageVersion`). All versions are defined in the centralized `libraries/common-variables.yml`.
+
+The build parameters enable selective package building:
+- `buildSqlServerServer` — controls SqlServer.Server build job
+- `buildSqlClient` — controls MDS, Extensions.Azure, Abstractions, Logging (when AKV is disabled), and validation stages
+- `buildAKVProvider` — controls AKV Provider build (also requires `buildSqlClient=true`) and Logging (when SqlClient is disabled)
+
+When set to `false`, the respective jobs/stages are excluded at compile-time using `${{ if }}` conditionals. This allows faster pipeline runs when only certain packages need to be built.
+
+### 5.2 Release Parameters
+
+Six boolean parameters control selective package release. All default to `false` so the release stage is skipped on normal CI/scheduled builds:
+
+```yaml
+parameters:
+ - name: releaseSqlServerServer
+ displayName: 'Release Microsoft.SqlServer.Server'
+ type: boolean
+ default: false
+
+ - name: releaseLogging
+ displayName: 'Release Microsoft.Data.SqlClient.Extensions.Logging'
+ type: boolean
+ default: false
+
+ - name: releaseAbstractions
+ displayName: 'Release Microsoft.Data.SqlClient.Extensions.Abstractions'
+ type: boolean
+ default: false
+
+ - name: releaseSqlClient
+ displayName: 'Release Microsoft.Data.SqlClient'
+ type: boolean
+ default: false
+
+ - name: releaseExtAzure
+ displayName: 'Release Microsoft.Data.SqlClient.Extensions.Azure'
+ type: boolean
+ default: false
+
+ - name: releaseAKVProvider
+ displayName: 'Release Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider'
+ type: boolean
+ default: false
+```
+
+#### Dry-Run Parameter (Official Pipeline Only)
+
+The **official pipeline** includes a `releaseDryRun` parameter that defaults to `true` for safety:
+
+```yaml
+ - name: releaseDryRun
+ displayName: 'Release Dry Run (do not push to NuGet)'
+ type: boolean
+ default: true # safety default — must explicitly disable for real releases
+```
+
+When `releaseDryRun: true`, publish jobs download artifacts and list packages but skip actual NuGet push. Set to `false` for production releases.
+
+> **Note**: The non-official pipeline does **not** expose this parameter — dry-run mode is hardcoded and cannot be disabled.
+
+---
+
+## 6. Variable & Version Management
+
+### 6.1 Variable Chain
+
+Variables are defined in a layered template chain. All variable groups live inside the templates — none are declared inline at the pipeline level:
+
+```
+dotnet-sqlclient-official-pipeline.yml
+ └─ libraries/variables.yml
+ └─ libraries/build-variables.yml
+ ├─ group: 'Release Variables'
+ ├─ group: 'Symbols publishing' ← SymbolsPublishServer, SymbolsPublishTokenUri, etc.
+ └─ libraries/common-variables.yml
+ ├─ group: 'ESRP Federated Creds (AME)' ← ESRP signing credentials
+ ├─ SymbolServer / SymbolTokenUri aliases ← mapped from Symbols publishing group
+ └─ all package versions, paths, build variables
+```
+
+### 6.2 Package Version Variables
+
+All package versions are centralized in `libraries/common-variables.yml`:
+
+| Package | GA Version Var | Preview Version Var | Assembly Version Var |
+|---------|---------------|--------------------|--------------------|
+| Logging | `loggingPackageVersion` | `loggingPackagePreviewVersion` | `loggingAssemblyFileVersion` |
+| Abstractions | `abstractionsPackageVersion` | `abstractionsPackagePreviewVersion` | `abstractionsAssemblyFileVersion` |
+| SqlServer.Server | `sqlServerPackageVersion` | `sqlServerPackagePreviewVersion` | `sqlServerAssemblyFileVersion` |
+| SqlClient (MDS) | `mdsPackageVersion` | `previewMdsPackageVersion` | `mdsAssemblyFileVersion` |
+| Extensions.Azure | `azurePackageVersion` | `azurePackagePreviewVersion` | `azureAssemblyFileVersion` |
+| AKV Provider | `akvPackageVersion` | `akvPackagePreviewVersion` | `akvAssemblyFileVersion` |
+
+The pipeline resolves `effective*Version` variables at compile time based on the `isPreview` parameter.
+
+### 6.3 Release & Symbol Variables
+
+| Variable | Defined In | Purpose |
+|----------|-----------|---------|
+| `NuGetServiceConnection` | `libraries/common-variables.yml` | External NuGet service connection name for `NuGetCommand@2` push |
+| `SymbolServer` | `libraries/common-variables.yml` (alias) | Alias for `$(SymbolsPublishServer)` — used by MDS `publish-symbols-step.yml` |
+| `SymbolTokenUri` | `libraries/common-variables.yml` (alias) | Alias for `$(SymbolsPublishTokenUri)` — used by MDS `publish-symbols-step.yml` |
+
+### 6.4 Variable Groups
+
+| Group | Included In | Purpose |
+|-------|------------|---------|
+| `Release Variables` | `build-variables.yml` | Release-specific configuration |
+| `Symbols publishing` | `build-variables.yml` | Symbol publishing credentials (`SymbolsAzureSubscription`, `SymbolsPublishServer`, `SymbolsPublishTokenUri`, `SymbolsUploadAccount`, `SymbolsPublishProjectName`) |
+| `ESRP Federated Creds (AME)` | `common-variables.yml` | Federated identity for ESRP signing (`ESRPConnectedServiceName`, `ESRPClientId`, `AppRegistrationClientId`, `AppRegistrationTenantId`, `AuthAKVName`, `AuthSignCertName`) |
+
+---
+
+## 7. Code Signing (ESRP)
+
+All packages are signed using **ESRP (Enterprise Security Release Pipeline)** with federated identity authentication.
+
+### Signing Flow (per job)
+
+#### csproj-based Extension Packages (Logging, Abstractions, Azure)
+1. **Build DLLs only** — `build.proj` target (e.g., `BuildLogging`) compiles assemblies without creating NuGet packages
+2. **ESRP DLL signing** — Assemblies are signed with Authenticode certificates via ESRP
+3. **NuGet pack** — `build.proj` pack target (e.g., `PackLogging`) creates `.nupkg` from signed DLLs using `NoBuild=true`
+4. **ESRP NuGet signing** — The `.nupkg` files are signed with NuGet certificates via ESRP
+
+This workflow ensures the NuGet package contains **signed DLLs** rather than signing the NuGet package around unsigned assemblies.
+
+#### nuspec-based Packages (SqlServer.Server, SqlClient, AKV Provider)
+1. **Build + pack** — MSBuild creates both assemblies and NuGet packages
+2. **ESRP DLL signing** — Assemblies are signed with Authenticode certificates via ESRP
+3. **ESRP NuGet signing** — The `.nupkg` files are signed with NuGet certificates via ESRP
+
+### Credential Model
+
+- Extension packages (Logging, Abstractions, Azure, SqlServer.Server, SqlClient) use the primary ESRP credentials from the `ESRP Federated Creds (AME)` variable group (loaded via `common-variables.yml`)
+- AKV Provider uses separate `Signing`-prefixed credential parameters that are passed explicitly to the `build-akv-official-job.yml` template
+- All credentials are sourced from Azure Key Vault and federated identity — no secrets stored in pipeline YAML
+
+---
+
+## 8. SDL & Compliance (OneBranch)
+
+Both pipelines use **OneBranch governed templates** for 1ES compliance. The SDL configuration differs between Official and Non-Official:
+
+| SDL Tool | Official | Non-Official | Purpose |
+|----------|----------|--------------|---------|
+| **TSA** | ✅ `enabled: true` | ❌ `enabled: false` | Uploads SDL results to TSA for downstream analysis |
+| **ApiScan** | ✅ `enabled: true`, `break: true` | ✅ `enabled: true`, `break: true` | Scans APIs for compliance issues |
+| **CodeQL** | ✅ (non-preview) | ✅ (non-preview) | Static analysis for security vulnerabilities |
+| **SBOM** | ✅ (non-preview) | ✅ (non-preview) | Software Bill of Materials generation |
+| **Policheck** | ✅ `break: true` | ✅ `break: true` | Scans for policy-violating content |
+| **BinSkim** | ✅ (async, non-preview) | ✅ (async, non-preview) | Binary security analysis |
+| **CredScan** | ✅ (async, non-preview) | ✅ (async, non-preview) | Credential leak detection |
+| **Roslyn** | ✅ (async, non-preview) | ✅ (async, non-preview) | Roslyn-based security analyzers |
+| **Armory** | ✅ `break: true` | ✅ `break: true` | Additional security scanning |
+
+### APIScan Configuration
+
+APIScan is configured at **both pipeline level and job level**:
+
+**Pipeline-level** (`globalSdl:apiscan:`): Sets default configuration inherited by all jobs. This is configured for MDS (Microsoft.Data.SqlClient) as the primary product.
+
+**Job-level** (`ob_sdl_apiscan_*` variables): Each build job overrides the pipeline defaults with package-specific settings:
+
+| Variable | Purpose |
+|----------|---------|
+| `ob_sdl_apiscan_enabled` | Enable/disable APIScan for this job (`true`) |
+| `ob_sdl_apiscan_softwareFolder` | Path to signed DLLs for scanning |
+| `ob_sdl_apiscan_symbolsFolder` | Path to PDBs for scanning |
+| `ob_sdl_apiscan_softwarename` | Package name (e.g., `Microsoft.Data.SqlClient.Extensions.Logging`) |
+| `ob_sdl_apiscan_versionNumber` | Assembly file version |
+
+Each job copies its signed DLLs and PDBs to a package-specific folder under `$(Build.SourcesDirectory)/apiScan//` after ESRP DLL signing, ensuring APIScan analyzes the correct signed binaries for each package.
+
+> **PRC Compliance**: The Official pipeline hardcodes `OneBranch.Official.CrossPlat.yml` (not parameterized) to satisfy Production Readiness Check static verification requirements.
+
+---
+
+## 9. Artifact Strategy
+
+- Each build job publishes its output as a **pipeline artifact** managed by OneBranch's `ob_outputDirectory` convention.
+- Artifact names follow the OneBranch auto-generated pattern: `drop__` (e.g., `drop_buildMDS_build_signed_package`).
+- Downstream stages use `DownloadPipelineArtifact@2` to pull required packages into a local directory.
+- A local NuGet source is configured at build time pointing to the downloaded artifacts directory so `dotnet restore` resolves internal dependencies.
+
+---
+
+## 10. Trigger Configuration
+
+### Official Pipeline (`dotnet-sqlclient-official-pipeline.yml`)
+
+```yaml
+trigger:
+ branches:
+ include:
+ - internal/main
+ paths:
+ include:
+ - .azuredevops
+ - .config
+ - doc
+ - eng/pipelines
+ - src
+ - tools
+ - azurepipelines-coverage.yml
+ - build.proj
+ - NuGet.config
+
+schedules:
+ - cron: '30 4 * * Mon' # Weekly Sunday 9:30 PM (UTC-7)
+ branches: { include: [internal/main] }
+ always: true
+ - cron: '30 3 * * Mon-Fri' # Weekday 8:30 PM (UTC-7)
+ branches: { include: [internal/main] }
+```
+
+- **CI trigger**: Runs on pushes to `internal/main` when relevant paths change
+- **Scheduled**: Weekly full build (Sundays) + weekday builds (Mon–Fri)
+- **No PR trigger**: Official pipeline should not run on PRs (separate PR pipelines exist)
+
+### Non-Official Pipeline (`dotnet-sqlclient-non-official-pipeline.yml`)
+
+```yaml
+trigger: none
+pr: none
+```
+
+- **Manual only**: Queued on-demand for validation/test builds
+
+---
+
+## 11. Infrastructure
+
+| Concern | Implementation |
+|---------|---------------|
+| **Pipeline template** | OneBranch governed templates (`OneBranch.Pipelines/GovernedTemplates`) |
+| **Build agents** | OneBranch-managed Windows containers (`WindowsHostVersion: 1ESWindows2022`) |
+| **.NET SDK** | Pinned via `global.json` (with `useGlobalJson: true` in install steps) |
+| **Code signing** | ESRP v2 with federated identity (Azure Key Vault backed) |
+| **Symbol publishing** | Optional, controlled by `publishSymbols` parameter; uses `Symbols publishing` variable group (aliases `SymbolServer`/`SymbolTokenUri` defined in `common-variables.yml`) |
+
+---
+
+## 12. Key Design Decisions
+
+1. **Single pipeline, multiple stages** — avoids managing 6 separate pipelines while keeping clear separation of concerns.
+2. **Official + Non-Official variants** — hardcoded OneBranch templates (no parameterized `oneBranchType`) for PRC compliance; Non-Official variant allows manual validation builds.
+3. **Parallel jobs within stages** — minimizes total wall-clock time; only waits where dependencies demand it.
+4. **Pipeline artifacts over Universal Packages** — faster, ephemeral, scoped to the run; appropriate for build-time dependency resolution.
+5. **ESRP-based code signing** — all DLLs and NuGet packages are signed in-pipeline using ESRP with federated identity; no secrets in YAML.
+6. **Centralized version management** — all 6 package versions (GA + preview) defined once in `libraries/common-variables.yml`; `isPreview` toggle selects the active set.
+7. **Dependency-aware stage ordering** — ensures packages are always built after their dependencies, guaranteeing consistent, reproducible builds.
+8. **Validation in parallel with Stage 3** — MDS package validation runs alongside AKV Provider build (both depend on Stage 2), reducing total pipeline duration.
+9. **Selective on-demand release** — 6 boolean parameters control which packages are published; the release stage is entirely skipped when none are selected, keeping normal CI builds unaffected.
+10. **ADO Environment approval gate** — two environments: `NuGet-Production` (official, with configured approvals) and `NuGet-DryRun` (non-official, validation only). Both use `ob_release_environment` for OneBranch integration.
+11. **Compile-time conditional publish jobs** — `${{ if eq(parameters.releaseXxx, true) }}` template expansion ensures unselected publish jobs are excluded entirely from the pipeline run (not just skipped at runtime).
+12. **Mandatory dry-run for non-official** — the non-official variant hardcodes `dryRun: true` (no parameter), preventing accidental publication. The official variant defaults `releaseDryRun: true` for safety but allows override for actual releases.
+13. **Selective build parameters** — `buildSqlClient`, `buildSqlServerServer`, and `buildAKVProvider` allow building subsets of packages, with dependency-aware conditionals ensuring Logging builds when either SqlClient or AKV is needed.
diff --git a/.github/prompts/update-build-pipelines.prompt.md b/.github/prompts/update-build-pipelines.prompt.md
index 1b4310e1bf..617cf39901 100644
--- a/.github/prompts/update-build-pipelines.prompt.md
+++ b/.github/prompts/update-build-pipelines.prompt.md
@@ -40,7 +40,7 @@ Follow this workflow step-by-step:
- Modify YAML files following the existing patterns and indentation style.
- When adding new stages, follow the existing stage ordering:
1. `build_abstractions_package_stage`
- 2. `build_mds_akv_packages_stage`
+ 2. `build_sqlclient_package_stage`
3. `build_azure_package_stage`
4. `stress_tests_stage` (optional)
5. `run_tests_stage`
diff --git a/.vscode/mcp.json b/.vscode/mcp.json
index 89a091dc1a..c43fda18b6 100644
--- a/.vscode/mcp.json
+++ b/.vscode/mcp.json
@@ -28,4 +28,4 @@
]
}
}
-}
\ No newline at end of file
+}
diff --git a/AGENTS.md b/AGENTS.md
index b8e951063c..56d7555c99 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -22,6 +22,7 @@ The `.github/instructions/` directory contains comprehensive guides:
| [architecture.instructions.md](.github/instructions/architecture.instructions.md) | Project structure, unified project model |
| [tds-protocol.instructions.md](.github/instructions/tds-protocol.instructions.md) | TDS protocol, packet handling |
| [ado-pipelines.instructions.md](.github/instructions/ado-pipelines.instructions.md) | Azure DevOps CI/CD pipelines |
+| [onebranch-pipeline-design.instructions.md](.github/instructions/onebranch-pipeline-design.instructions.md) | OneBranch multi-product pipeline design spec |
| [testing.instructions.md](.github/instructions/testing.instructions.md) | Test framework, running tests |
| [connection-pooling.instructions.md](.github/instructions/connection-pooling.instructions.md) | Connection pool internals |
| [api-design.instructions.md](.github/instructions/api-design.instructions.md) | Public API design principles |
diff --git a/Directory.Packages.props b/Directory.Packages.props
index e4953215a7..f6a9f24815 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -7,6 +7,8 @@
+
+
+ Include="Microsoft.Data.SqlClient.Extensions.Logging"
+ Version="$(LoggingPackageVersion)" />
+
@@ -74,7 +79,12 @@
-
+
+
+
+
+
+
@@ -84,7 +94,14 @@
-
+
+
+
+
+
+
+
+
@@ -112,13 +129,6 @@
-
-
-
-
-
-
-
diff --git a/build.proj b/build.proj
index 7911924363..94d8e4c877 100644
--- a/build.proj
+++ b/build.proj
@@ -2,7 +2,6 @@
-
@@ -29,7 +28,6 @@
true
Configuration=$(Configuration);ReferenceType=$(ReferenceType);
- $(CommonProperties);AssemblyVersion=$(SqlServerAssemblyVersion);AssemblyFileVersion=$(SqlServerAssemblyFileVersion);Version=$(SqlServerPackageVersion);
$(CommonProperties);AssemblyFileVersion=$(AssemblyFileVersion);TargetsWindows=$(TargetsWindows);TargetsUnix=$(TargetsUnix);
$(ProjectProperties);BuildForRelease=false;TargetNetCoreVersion=$(TargetNetCoreVersion);TargetNetFxVersion=$(TargetNetFxVersion)
TestResults
@@ -74,9 +72,10 @@
-
+
+
@@ -95,9 +94,41 @@
-
-
-
+
+
+
+
+
+ $(CommonProperties)
+
+
+ $(SqlServerProperties);SqlServerPackageVersion=$(SqlServerPackageVersion)
+
+
+
+ $(SqlServerProperties);SqlServerAssemblyFileVersion=$(SqlServerAssemblyFileVersion)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -138,8 +169,58 @@
+ Targets="Build"
+ Properties="$(CI);$(AbstractionsProperties)" />
+
+
+
+
+
+
+
+
+ $(CommonProperties)
+
+
+
+ $(LoggingProperties);LoggingPackageVersion=$(LoggingPackageVersion)
+
+
+
+
+ $(LoggingProperties);LoggingAssemblyFileVersion=$(LoggingAssemblyFileVersion)
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -180,20 +261,23 @@
+ Targets="Build"
+ Properties="$(CI);$(AzureProperties)" />
-
-
-
+
+
-
+
+
-
+
@@ -205,28 +289,15 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
diff --git a/eng/pipelines/abstractions/onebranch/non-official-pipeline.yml b/eng/pipelines/abstractions/onebranch/non-official-pipeline.yml
deleted file mode 100644
index aac9eddc36..0000000000
--- a/eng/pipelines/abstractions/onebranch/non-official-pipeline.yml
+++ /dev/null
@@ -1,55 +0,0 @@
-#################################################################################
-# Licensed to the .NET Foundation under one or more agreements. #
-# The .NET Foundation licenses this file to you under the MIT license. #
-# See the LICENSE file in the project root for more information. #
-#################################################################################
-
-# Stub for Abstractions package non-official builds.
-
-pr: none
-trigger: none
-
-# Parameters visible in the Azure DevOps UI.
-parameters:
-
- # We build in Release mode by default.
- - name: buildConfiguration
- displayName: Build configuration
- type: string
- values:
- - Debug
- - Release
- default: Release
-
- # True to enable debug steps and logging.
- - name: debug
- displayName: Enable debug steps and logging
- type: boolean
- default: false
-
- # The verbosity level for the dotnet CLI commands.
- - name: dotnetVerbosity
- type: string
- default: normal
- values:
- - quiet
- - minimal
- - normal
- - detailed
- - diagnostic
-
- # True to publish symbols after a successful build.
- - name: publishSymbols
- displayName: Publish symbols
- type: boolean
- default: false
-
-stages:
- - stage: stub_stage
- displayName: Stub Stage
- jobs:
- - job: stub_job
- displayName: Stub Job
- steps:
- - script: echo "This is a stub pipeline for non-official builds of the Abstractions package."
- displayName: Stub Step
diff --git a/eng/pipelines/abstractions/onebranch/official-pipeline.yml b/eng/pipelines/abstractions/onebranch/official-pipeline.yml
deleted file mode 100644
index e6e1c4785f..0000000000
--- a/eng/pipelines/abstractions/onebranch/official-pipeline.yml
+++ /dev/null
@@ -1,55 +0,0 @@
-#################################################################################
-# Licensed to the .NET Foundation under one or more agreements. #
-# The .NET Foundation licenses this file to you under the MIT license. #
-# See the LICENSE file in the project root for more information. #
-#################################################################################
-
-# Stub for Abstractions package official builds.
-
-pr: none
-trigger: none
-
-# Parameters visible in the Azure DevOps UI.
-parameters:
-
- # We build in Release mode by default.
- - name: buildConfiguration
- displayName: Build configuration
- type: string
- values:
- - Debug
- - Release
- default: Release
-
- # True to enable debug steps and logging.
- - name: debug
- displayName: Enable debug steps and logging
- type: boolean
- default: false
-
- # The verbosity level for the dotnet CLI commands.
- - name: dotnetVerbosity
- type: string
- default: normal
- values:
- - quiet
- - minimal
- - normal
- - detailed
- - diagnostic
-
- # True to publish symbols after a successful build.
- - name: publishSymbols
- displayName: Publish symbols
- type: boolean
- default: false
-
-stages:
- - stage: stub_stage
- displayName: Stub Stage
- jobs:
- - job: stub_job
- displayName: Stub Job
- steps:
- - script: echo "This is a stub pipeline for official builds of the Abstractions package."
- displayName: Stub Step
diff --git a/eng/pipelines/akv-non-official-pipeline.yml b/eng/pipelines/akv-non-official-pipeline.yml
deleted file mode 100644
index 40f93fc33a..0000000000
--- a/eng/pipelines/akv-non-official-pipeline.yml
+++ /dev/null
@@ -1,137 +0,0 @@
-#################################################################################
-# Licensed to the .NET Foundation under one or more agreements. #
-# The .NET Foundation licenses this file to you under the MIT license. #
-# See the LICENSE file in the project root for more information. #
-#################################################################################
-
-name: $(Year:YY)$(DayOfYear)$(Rev:.r)
-
-parameters:
- - name: buildConfiguration
- displayName: 'Build configuration'
- type: 'string'
- values:
- - 'Release'
- - 'Debug'
- default: 'Release'
-
- - name: publishSymbols
- displayName: 'Publish symbols'
- type: 'boolean'
- default: false
-
- - name: runSdlTasks
- displayName: 'Run SDL Tasks'
- type: 'boolean'
- default: true
-
-variables:
- - template: /eng/pipelines/variables/common-variables.yml@self
- - template: /eng/pipelines/variables/onebranch-variables.yml@self
- - template: /eng/pipelines/variables/esrp-signing-variables.yml@self
- - template: /eng/pipelines/variables/akv-official-variables.yml@self
-
-resources:
- repositories:
- - repository: templates
- type: 'git'
- name: 'OneBranch.Pipelines/GovernedTemplates'
- ref: 'refs/heads/main'
-
-extends:
- template: 'v2/OneBranch.NonOfficial.CrossPlat.yml@templates'
-
- parameters:
- featureFlags:
- WindowsHostVersion:
- Version: '2022'
-
- globalSdl:
- # See https://aka.ms/obpipelines/sdl
-
- apiscan:
- enabled: ${{ parameters.runSdlTasks }}
- softwareFolder: '${{ variables.apiScanDllPath }}'
- softwareName: 'Microsoft.Data.SqlClient' # Note: This name is registered with ApiScan
- softwareVersionNum: '${{ variables.assemblyFileVersion }}'
- symbolsFolder: '${{ variables.apiScanPdbPath }}'
-
- armory:
- enabled: ${{ parameters.runSdlTasks }}
- break: true
-
- asyncSdl:
- # If this should be enabled, move supported tools under this item,
- # see https://aka.ms/obpipelines/asyncsdl
- enabled: false
-
- binskim:
- enabled: ${{ parameters.runSdlTasks }}
- break: true
-
- codeinspector:
- enabled: ${{ parameters.runSdlTasks }}
- logLevel: Error
-
- codeql:
- enabled: ${{ parameters.runSdlTasks }}
- sourceRoot: '$(REPO_ROOT)/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider'
- # Note, this can only be done if project doesn't depend on other projects. In
- # package reference mode, this is true, but if we ever enable project reference
- # builds, this will have to be removed.
-
- credscan:
- enabled: ${{ parameters.runSdlTasks }}
- suppressionsFile: '$(REPO_ROOT)/.config/CredScanSuppressions.json'
-
- eslint:
- enabled: false
-
- policheck:
- enabled: ${{ parameters.runSdlTasks }}
- break: true
- exclusionFile: '$(REPO_ROOT)/.config/PolicheckExclusions.xml'
-
- roslyn:
- enabled: ${{ parameters.runSdlTasks }}
- break: true
- # Requires RoslynAnalyzers task to be added somewhere in the build stage.
-
- publishLogs:
- enabled: ${{ parameters.runSdlTasks }}
-
- sbom:
- enabled: ${{ parameters.runSdlTasks }}
- packageName: 'Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider'
- packageVersion: ${{ variables.akvPackageVersion }}
-
- tsa:
- # OneBranch publishes all sdl results to TSA. If TSA is disabled all SDL tools will
- # be forced into 'break' build mode.
- enabled: false
- configFile: '$(REPO_ROOT)/.config/tsaoptions.json'
-
- stages:
- - stage: BuildAkv
- displayName: 'Build AKV'
- jobs:
- - template: /eng/pipelines/jobs/build-akv-official-job.yml@self
- parameters:
- akvAssemblyFileVersion: '${{ variables.assemblyFileVersion }}'
- akvPackageVersion: '${{ variables.akvPackageVersion }}'
- apiScanDllPath: '${{ variables.apiScanDllPath }}'
- apiScanPdbPath: '${{ variables.apiScanPdbPath }}'
- buildConfiguration: '${{ parameters.buildConfiguration }}'
- mdsPackageVersion: '${{ variables.mdsPackageVersion }}'
- publishSymbols: '${{ parameters.publishSymbols }}'
- signingAppRegistrationClientId: '$(SigningAppRegistrationClientId)'
- signingAppRegistrationTenantId: '$(SigningAppRegistrationTenantId)'
- signingAuthAkvName: '$(SigningAuthAkvName)'
- signingAuthSignCertName: '$(SigningAuthSignCertName)'
- signingEsrpClientId: '$(SigningEsrpClientId)'
- signingEsrpConnectedServiceName: '$(SigningEsrpConnectedServiceName)'
- symbolsAzureSubscription: '$(SymbolsAzureSubscription)'
- symbolsPublishProjectName: '$(SymbolsPublishProjectName)'
- symbolsPublishServer: '$(SymbolsPublishServer)'
- symbolsPublishTokenUri: '$(SymbolsPublishTokenUri)'
- symbolsUploadAccount: '$(SymbolsUploadAccount)'
diff --git a/eng/pipelines/akv-official-pipeline.yml b/eng/pipelines/akv-official-pipeline.yml
deleted file mode 100644
index dfc5189518..0000000000
--- a/eng/pipelines/akv-official-pipeline.yml
+++ /dev/null
@@ -1,139 +0,0 @@
-#################################################################################
-# Licensed to the .NET Foundation under one or more agreements. #
-# The .NET Foundation licenses this file to you under the MIT license. #
-# See the LICENSE file in the project root for more information. #
-#################################################################################
-
-name: $(Year:YY)$(DayOfYear)$(Rev:.r)
-
-# @TODO: Add triggers and schedules
-
-parameters:
- - name: buildConfiguration
- displayName: 'Build configuration'
- type: 'string'
- values:
- - 'Release'
- - 'Debug'
- default: 'Release'
-
- - name: publishSymbols
- displayName: 'Publish symbols'
- type: 'boolean'
- default: false
-
- - name: runSdlTasks
- displayName: 'Run SDL Tasks'
- type: 'boolean'
- default: true
-
-variables:
- - template: /eng/pipelines/variables/common-variables.yml@self
- - template: /eng/pipelines/variables/onebranch-variables.yml@self
- - template: /eng/pipelines/variables/esrp-signing-variables.yml@self
- - template: /eng/pipelines/variables/akv-official-variables.yml@self
-
-resources:
- repositories:
- - repository: templates
- type: 'git'
- name: 'OneBranch.Pipelines/GovernedTemplates'
- ref: 'refs/heads/main'
-
-extends:
- template: 'v2/OneBranch.Official.CrossPlat.yml@templates'
-
- parameters:
- featureFlags:
- WindowsHostVersion:
- Version: '2022'
-
- globalSdl:
- # See https://aka.ms/obpipelines/sdl
-
- apiscan:
- enabled: ${{ parameters.runSdlTasks }}
- softwareFolder: '${{ variables.apiScanDllPath }}'
- softwareName: 'Microsoft.Data.SqlClient' # Note: This name is registered with ApiScan
- softwareVersionNum: '${{ variables.assemblyFileVersion }}'
- symbolsFolder: '${{ variables.apiScanPdbPath }}'
-
- armory:
- enabled: ${{ parameters.runSdlTasks }}
- break: true
-
- asyncSdl:
- # If this should be enabled, move supported tools under this item,
- # see https://aka.ms/obpipelines/asyncsdl
- enabled: false
-
- binskim:
- enabled: ${{ parameters.runSdlTasks }}
- break: true
-
- codeinspector:
- enabled: ${{ parameters.runSdlTasks }}
- logLevel: Error
-
- codeql:
- enabled: ${{ parameters.runSdlTasks }}
- sourceRoot: '$(REPO_ROOT)/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider'
- # Note, this can only be done if project doesn't depend on other projects. In
- # package reference mode, this is true, but if we ever enable project reference
- # builds, this will have to be removed.
-
- credscan:
- enabled: ${{ parameters.runSdlTasks }}
- suppressionsFile: '$(REPO_ROOT)/.config/CredScanSuppressions.json'
-
- eslint:
- enabled: false
-
- policheck:
- enabled: ${{ parameters.runSdlTasks }}
- break: true
- exclusionFile: '$(REPO_ROOT)/.config/PolicheckExclusions.xml'
-
- roslyn:
- enabled: ${{ parameters.runSdlTasks }}
- break: true
- # Requires RoslynAnalyzers task to be added somewhere in the build stage.
-
- publishLogs:
- enabled: ${{ parameters.runSdlTasks }}
-
- sbom:
- enabled: ${{ parameters.runSdlTasks }}
- packageName: 'Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider'
- packageVersion: ${{ variables.akvPackageVersion }}
-
- tsa:
- # OneBranch publishes all sdl results to TSA. If TSA is disabled all SDL tools will
- # be forced into 'break' build mode.
- enabled: true
- configFile: '$(REPO_ROOT)/.config/tsaoptions.json'
-
- stages:
- - stage: BuildAkv
- displayName: 'Build AKV'
- jobs:
- - template: /eng/pipelines/jobs/build-akv-official-job.yml@self
- parameters:
- akvAssemblyFileVersion: '${{ variables.assemblyFileVersion }}'
- akvPackageVersion: '${{ variables.akvPackageVersion }}'
- apiScanDllPath: '${{ variables.apiScanDllPath }}'
- apiScanPdbPath: '${{ variables.apiScanPdbPath }}'
- buildConfiguration: '${{ parameters.buildConfiguration }}'
- mdsPackageVersion: '${{ variables.mdsPackageVersion }}'
- publishSymbols: '${{ parameters.publishSymbols }}'
- signingAppRegistrationClientId: '$(SigningAppRegistrationClientId)'
- signingAppRegistrationTenantId: '$(SigningAppRegistrationTenantId)'
- signingAuthAkvName: '$(SigningAuthAkvName)'
- signingAuthSignCertName: '$(SigningAuthSignCertName)'
- signingEsrpClientId: '$(SigningEsrpClientId)'
- signingEsrpConnectedServiceName: '$(SigningEsrpConnectedServiceName)'
- symbolsAzureSubscription: '$(SymbolsAzureSubscription)'
- symbolsPublishProjectName: '$(SymbolsPublishProjectName)'
- symbolsPublishServer: '$(SymbolsPublishServer)'
- symbolsPublishTokenUri: '$(SymbolsPublishTokenUri)'
- symbolsUploadAccount: '$(SymbolsUploadAccount)'
diff --git a/eng/pipelines/azure/onebranch/non-official-pipeline.yml b/eng/pipelines/azure/onebranch/non-official-pipeline.yml
deleted file mode 100644
index 53c83f8cbc..0000000000
--- a/eng/pipelines/azure/onebranch/non-official-pipeline.yml
+++ /dev/null
@@ -1,55 +0,0 @@
-#################################################################################
-# Licensed to the .NET Foundation under one or more agreements. #
-# The .NET Foundation licenses this file to you under the MIT license. #
-# See the LICENSE file in the project root for more information. #
-#################################################################################
-
-# Stub for Azure package non-official builds.
-
-pr: none
-trigger: none
-
-# Parameters visible in the Azure DevOps UI.
-parameters:
-
- # We build in Release mode by default.
- - name: buildConfiguration
- displayName: Build configuration
- type: string
- values:
- - Debug
- - Release
- default: Release
-
- # True to enable debug steps and logging.
- - name: debug
- displayName: Enable debug steps and logging
- type: boolean
- default: false
-
- # The verbosity level for the dotnet CLI commands.
- - name: dotnetVerbosity
- type: string
- default: normal
- values:
- - quiet
- - minimal
- - normal
- - detailed
- - diagnostic
-
- # True to publish symbols after a successful build.
- - name: publishSymbols
- displayName: Publish symbols
- type: boolean
- default: false
-
-stages:
- - stage: stub_stage
- displayName: Stub Stage
- jobs:
- - job: stub_job
- displayName: Stub Job
- steps:
- - script: echo "This is a stub pipeline for non-official builds of the Azure package."
- displayName: Stub Step
diff --git a/eng/pipelines/azure/onebranch/official-pipeline.yml b/eng/pipelines/azure/onebranch/official-pipeline.yml
deleted file mode 100644
index 31e0482a11..0000000000
--- a/eng/pipelines/azure/onebranch/official-pipeline.yml
+++ /dev/null
@@ -1,55 +0,0 @@
-#################################################################################
-# Licensed to the .NET Foundation under one or more agreements. #
-# The .NET Foundation licenses this file to you under the MIT license. #
-# See the LICENSE file in the project root for more information. #
-#################################################################################
-
-# Stub for Azure package official builds.
-
-pr: none
-trigger: none
-
-# Parameters visible in the Azure DevOps UI.
-parameters:
-
- # We build in Release mode by default.
- - name: buildConfiguration
- displayName: Build configuration
- type: string
- values:
- - Debug
- - Release
- default: Release
-
- # True to enable debug steps and logging.
- - name: debug
- displayName: Enable debug steps and logging
- type: boolean
- default: false
-
- # The verbosity level for the dotnet CLI commands.
- - name: dotnetVerbosity
- type: string
- default: normal
- values:
- - quiet
- - minimal
- - normal
- - detailed
- - diagnostic
-
- # True to publish symbols after a successful build.
- - name: publishSymbols
- displayName: Publish symbols
- type: boolean
- default: false
-
-stages:
- - stage: stub_stage
- displayName: Stub Stage
- jobs:
- - job: stub_job
- displayName: Stub Job
- steps:
- - script: echo "This is a stub pipeline for official builds of the Azure package."
- displayName: Stub Step
diff --git a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
index bf5ee07ebb..f2b42894fd 100644
--- a/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
+++ b/eng/pipelines/common/templates/jobs/build-signed-package-job.yml
@@ -3,34 +3,38 @@
# The .NET Foundation licenses this file to you under the MIT license. #
# See the LICENSE file in the project root for more information. #
#################################################################################
-parameters:
- - name: symbolsFolder
- type: string
- default: symbols
- - name: softwareFolder
- type: string
- default: software
+# This file is only included in MDS OneBranch Official pipelines.
+parameters:
+ # True to publish symbols to public and private feeds after the build completes.
- name: publishSymbols
type: boolean
+ # True if this is a preview build, which uses the preview version numbers from
+ # common-variables.yml.
- name: isPreview
type: boolean
jobs:
-- job: build_signed_package
- displayName: 'Build Signed MDS Package'
+- job: build_package_SqlClient
+ displayName: 'Build Microsoft.Data.SqlClient'
pool:
type: windows # read more about custom job pool types at https://aka.ms/obpipelines/yaml/jobs
variables:
- - template: /eng/pipelines/libraries/variables.yml@self
- - ${{ if parameters.isPreview }}:
- - name: abstractionsPackageVersion
- value: $(abstractionsPackagePreviewVersion)
- - name: mdsPackageVersion
- value: $(previewMdsPackageVersion)
+ ob_outputDirectory: $(PACK_OUTPUT)
+ # APIScan configuration for this Extension package
+ ob_sdl_apiscan_enabled: true
+ ob_sdl_apiscan_softwareFolder: $(Build.SourcesDirectory)/apiScan/SqlClient/dlls
+ ob_sdl_apiscan_symbolsFolder: $(Build.SourcesDirectory)/apiScan/SqlClient/pdbs
+ ob_sdl_apiscan_softwarename: Microsoft.Data.SqlClient
+ ob_sdl_apiscan_versionNumber: $(assemblyBuildNumber)
+
+ ${{ if parameters.isPreview }}:
+ abstractionsPackageVersion: $(abstractionsPackagePreviewVersion)
+ loggingPackageVersion: $(loggingPackagePreviewVersion)
+ mdsPackageVersion: $(previewMdsPackageVersion)
steps:
- script: SET
@@ -42,6 +46,21 @@ jobs:
name: GetBuildType
displayName: Get Build Type
+ # Download the Abstractions and Logging packages from the previous stage into
+ # packages/ so that they're available via the local NuGet feed when restoring MDS.
+ # MDS depends on both Extensions.Abstractions and Extensions.Logging.
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Abstractions Package
+ inputs:
+ artifactName: $(abstractionsArtifactsName)
+ targetPath: $(Build.SourcesDirectory)/packages
+
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Logging Package
+ inputs:
+ artifactName: $(loggingArtifactsName)
+ targetPath: $(Build.SourcesDirectory)/packages
+
# Install the .NET SDK.
- template: /eng/pipelines/steps/install-dotnet.yml@self
@@ -63,6 +82,8 @@ jobs:
# These variables are sourced from common-variables.yml.
abstractionsAssemblyFileVersion: $(abstractionsAssemblyFileVersion)
abstractionsPackageVersion: $(abstractionsPackageVersion)
+ loggingAssemblyFileVersion: $(loggingAssemblyFileVersion)
+ loggingPackageVersion: $(loggingPackageVersion)
mdsAssemblyFileVersion: $(mdsAssemblyFileVersion)
mdsPackageVersion: $(mdsPackageVersion)
@@ -74,21 +95,41 @@ jobs:
parameters:
buildConfiguration: Release
displayName: 'Create MDS NuGet Package'
+ generateSymbolsPackage: true
installNuget: false
nuspecPath: $(nuspecPath)
- outputDirectory: $(artifactDirectory)
+ outputDirectory: $(PACK_OUTPUT)
packageVersion: $(mdsPackageVersion)
- properties: 'AbstractionsPackageVersion=$(abstractionsPackageVersion)'
+ properties: 'AbstractionsPackageVersion=$(abstractionsPackageVersion);LoggingPackageVersion=$(loggingPackageVersion)'
referenceType: Package
- template: /eng/pipelines/common/templates/steps/esrp-code-signing-step.yml@self
parameters:
artifactType: pkg
- - template: /eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml@self
+ # Copy signed DLLs and PDBs to APIScan folders.
+ - task: CopyFiles@2
+ displayName: Copy DLLs for APIScan
+ inputs:
+ SourceFolder: $(BUILD_OUTPUT)/Package/bin
+ Contents: '**/Microsoft.Data.SqlClient*.dll'
+ TargetFolder: $(ob_sdl_apiscan_softwareFolder)
+ # We must preserve the folder structure since our C# projects may produce multiple
+ # identically named DLLs for different target frameworks (e.g. netstandard2.0, net5.0,
+ # etc.), and we need to keep those separate for APIScan to work correctly.
+ flattenFolders: false
+
+ - task: CopyFiles@2
+ displayName: Copy PDBs for APIScan
+ inputs:
+ SourceFolder: $(BUILD_OUTPUT)/Package/bin
+ Contents: '**/Microsoft.Data.SqlClient*.pdb'
+ TargetFolder: $(ob_sdl_apiscan_symbolsFolder)
+ flattenFolders: false
# Publish symbols to servers
- ${{ if eq(parameters.publishSymbols, true) }}:
- template: /eng/pipelines/common/templates/steps/publish-symbols-step.yml@self
parameters:
- symbolsArtifactName: mds_symbols_$(System.TeamProject)_$(Build.Repository.Name)_$(Build.SourceBranchName)_$(mdsPackageVersion)_$(System.TimelineId)
+ packageFullName: Microsoft.Data.SqlClient
+ packageVersion: $(mdsPackageVersion)
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 aa68e74b0e..9fb3620bf6 100644
--- a/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml
@@ -5,49 +5,71 @@
#################################################################################
parameters:
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
+ # The C# project reference type to use when building and packing the packages.
- name: referenceType
type: string
values:
+ # Reference sibling packages as NuGet packages.
- Package
+ # Reference sibling packages as C# projects.
- Project
+ # The name of Azure Pipelines pool to use.
- name: poolName
type: string
default: $(ci_var_defaultPoolName)
+ # The name of the Azure Pipelines image to use within the pool.
- name: imageOverride
type: string
default: ADO-MMS22-SQL19
+ # The name of the Abstractions pipeline artifact to download when referenceType is 'Package'.
- name: abstractionsArtifactsName
type: string
default: Abstractions.Artifacts
+ # The name of the Logging pipeline artifact to download when referenceType is 'Package'.
+ - name: loggingArtifactsName
+ type: string
+ default: Logging.Artifacts
+
+ # The name of the SqlClient pipeline artifact to publish.
- name: mdsArtifactsName
type: string
default: MDS.Artifacts
+ # The C# project platform to build (e.g. AnyCPU, x64, x86).
- name: platform
type: string
default: $(Platform)
+ # The C# build configuration to build (e.g. Debug or Release).
- name: buildConfiguration
type: string
values:
- Debug
- Release
+ # Pipeline steps to run before the build starts, if any.
- name: prebuildSteps
type: stepList
default: []
+ # The version of the Abstractions package to depend on when referenceType is 'Package'.
- name: abstractionsPackageVersion
type: string
+ # The version of the Logging package to depend on when referenceType is 'Package'.
+ - name: loggingPackageVersion
+ type: string
+
+ # The version to apply to the SqlClient package.
- name: mdsPackageVersion
type: string
@@ -75,7 +97,7 @@ jobs:
# configuration
- ${{ parameters.prebuildSteps }}
- # If we're testing in Package mode, then we must download the Abstractions package artifacts.
+ # If we're testing in Package mode, then we must download dependent package artifacts.
- ${{ if eq(parameters.referenceType, 'Package') }}:
- task: DownloadPipelineArtifact@2
displayName: Download Abstractions Package Artifacts
@@ -83,6 +105,12 @@ jobs:
artifactName: ${{ parameters.abstractionsArtifactsName }}
targetPath: $(packagePath)
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Logging Package Artifacts
+ inputs:
+ artifactName: ${{ parameters.loggingArtifactsName }}
+ targetPath: $(packagePath)
+
# Install the .NET SDK.
- template: /eng/pipelines/steps/install-dotnet.yml@self
@@ -97,6 +125,7 @@ jobs:
buildConfiguration: Release
referenceType: Project
build: all
+ assemblyBuildNumber: $(assemblyBuildNumber)
- template: /eng/pipelines/common/templates/steps/ci-project-build-step.yml@self
parameters:
@@ -105,8 +134,9 @@ jobs:
referenceType: ${{ parameters.referenceType }}
operatingSystem: Windows
build: MDS
+ assemblyBuildNumber: $(assemblyBuildNumber)
abstractionsPackageVersion: ${{parameters.abstractionsPackageVersion}}
- mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
+ loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
- template: /eng/pipelines/common/templates/steps/generate-nuget-package-step.yml@self
parameters:
@@ -116,7 +146,7 @@ jobs:
nuspecPath: 'tools/specs/Microsoft.Data.SqlClient.nuspec'
outputDirectory: $(packagePath)
packageVersion: ${{ parameters.mdsPackageVersion }}
- properties: 'AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}'
+ properties: 'AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }};LoggingPackageVersion=${{ parameters.loggingPackageVersion }}'
referenceType: ${{ parameters.referenceType }}
- template: /eng/pipelines/common/templates/steps/ci-project-build-step.yml@self
@@ -126,6 +156,7 @@ jobs:
referenceType: ${{ parameters.referenceType }}
operatingSystem: Windows
build: AKV
+ assemblyBuildNumber: $(assemblyBuildNumber)
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
- template: /eng/pipelines/common/templates/steps/generate-nuget-package-step.yml@self
diff --git a/eng/pipelines/common/templates/jobs/ci-code-coverage-job.yml b/eng/pipelines/common/templates/jobs/ci-code-coverage-job.yml
index 39ab0ed379..09c72e9719 100644
--- a/eng/pipelines/common/templates/jobs/ci-code-coverage-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-code-coverage-job.yml
@@ -10,7 +10,7 @@
parameters:
- # True to include debug steps.
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
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 444b44bb1e..04f63ca76b 100644
--- a/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
+++ b/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml
@@ -4,12 +4,23 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
+ # The name of the Abstractions pipeline artifact to download when referenceType is 'Package'.
- name: abstractionsArtifactsName
type: string
+ # The version of the Abstractions package to depend on when referenceType is 'Package'.
- name: abstractionsPackageVersion
type: string
+ # The name of the Logging pipeline artifact to download when referenceType is 'Package'.
+ - name: loggingArtifactsName
+ type: string
+ default: Logging.Artifacts
+
+ # The version of the Logging package to depend on when referenceType is 'Package'.
+ - name: loggingPackageVersion
+ type: string
+
# The configuration properties to set in the config file.
#
# GOTCHA: The following keys are used in template expressions and must be
@@ -26,45 +37,62 @@ parameters:
# SupportsFileStream
# SupportsIntegratedSecurity
# TracingEnabled
+ #
- name: configProperties
type: object
default: {} # - key: 'value'
+ # The type of SQL Server to configure.
- name: configSqlFor
- type: string # local, azure, or enclave
+ type: string
+ values:
+ - azure
+ - enclave
+ - local
default: local
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
+ # True to enable testing for the x64 architecture.
- name: enableX64Test
type: boolean
default: true
+ # True to enable testing for the x86 architecture.
- name: enableX86Test
type: boolean
default: false
+ # True if this job will run in a generic Azure Pipelines hosted pool; false to run in a custom 1ES
+ # pool.
- name: hostedPool
type: boolean
default: false
+ # The VM image to use, which must exist in the specified pool.
- name: image
type: string
+ # The display name for this job.
- name: jobDisplayName
type: string
+ # The name of the SqlClient pipeline artifacts to download.
- name: mdsArtifactsName
type: string
+ # The version of the SqlClient package to depend on when referenceType is 'Package'.
- name: mdsPackageVersion
type: string
+ # TODO: What is this for?
- name: netcoreVersionTestUtils
type: string
+ # The OS to build and run the tests for.
- name: operatingSystem
type: string
values:
@@ -73,28 +101,36 @@ parameters:
- Windows
default: Windows
+ # The C# build configuration to build (e.g. Debug or Release).
- name: buildConfiguration
type: string
values:
- Debug
- Release
+ # The name of the Azure Pipelines pool to use.
- name: poolName
type: string
+ # Steps to run before each build, if any.
- name: prebuildSteps
type: stepList
default: []
+ # The C# project reference type to use when building and packing the packages.
- name: referenceType
type: string
values:
- - Project
+ # Reference sibling packages as NuGet packages.
- Package
+ # Reference sibling packages as C# projects.
+ - Project
+ # The target framework to build and run tests for.
- name: targetFramework
type: string
+ # The test set to run.
- name: testSet
type: string
@@ -107,6 +143,7 @@ parameters:
type: boolean
default: false
+ # True to use managed SNI, where applicable.
- name: usemanagedSNI
type: boolean
default: false
@@ -145,6 +182,12 @@ jobs:
artifactName: ${{ parameters.abstractionsArtifactsName }}
targetPath: $(Build.SourcesDirectory)/packages
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Logging Package Artifacts
+ inputs:
+ artifactName: ${{ parameters.loggingArtifactsName }}
+ targetPath: $(Build.SourcesDirectory)/packages
+
- task: DownloadPipelineArtifact@2
displayName: Download MDS Package Artifacts
inputs:
@@ -172,6 +215,9 @@ jobs:
build: allNoDocs
buildConfiguration: ${{ parameters.buildConfiguration }}
referenceType: ${{ parameters.referenceType }}
+ assemblyBuildNumber: $(assemblyBuildNumber)
+ abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
+ loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
- ${{ if ne(parameters.configProperties, '{}') }}:
@@ -293,6 +339,7 @@ jobs:
testSet: ${{ parameters.testSet }}
operatingSystem: ${{ parameters.operatingSystem }}
abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
+ loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
- ${{ if and(eq(parameters.enableX86Test, true), eq(parameters.operatingSystem, 'Windows')) }}:
@@ -321,6 +368,7 @@ jobs:
dotnetx86RootPath: $(dotnetx86RootPath)
operatingSystem: ${{ parameters.operatingSystem }}
abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
+ loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
- template: /eng/pipelines/common/templates/steps/publish-test-results-step.yml@self
diff --git a/eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml b/eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml
new file mode 100644
index 0000000000..3d194cfb97
--- /dev/null
+++ b/eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml
@@ -0,0 +1,91 @@
+#################################################################################
+# 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. #
+#################################################################################
+
+# Reusable job template for publishing a signed NuGet package to a NuGet feed. Downloads the
+# pipeline artifact produced by a build job and pushes .nupkg and .snupkg files using
+# NuGetCommand@2.
+#
+# Uses a deployment job with ADO environment for approval gates.
+#
+# OneBranch Requirements:
+# - All deployment jobs must use releaseJob syntax per 1ES Pipeline Templates v2.
+# - Must declare inputs via templateContext since deploy lifecycle doesn't auto-download.
+# - See:
+# https://eng.ms/docs/products/onebranch/build/releasepipelines/releaseworkflows/deploymentjob
+
+parameters:
+ # Human-readable package name (used in display strings).
+ - name: packageDisplayName
+ type: string
+
+ # The pipeline artifact name to download (OneBranch naming: drop__).
+ - name: artifactName
+ type: string
+
+ # NuGet service connection name for authentication.
+ - name: nugetServiceConnection
+ type: string
+
+ # Indicates whether this is a production release (enables additional 1ES PT checks).
+ - name: isProduction
+ type: boolean
+ default: false
+
+ # Globbing pattern to match .nupkg and .snupkg files within the downloaded artifact.
+ - name: packagePattern
+ type: string
+ default: '**/*.nupkg;**/*.snupkg'
+
+ # When true, list packages that would be published without actually pushing. Use for non-official
+ # pipelines to validate the release stage without risk.
+ - name: dryRun
+ type: boolean
+ default: false
+
+# Read more: https://eng.ms/docs/products/onebranch/release/yamlreleasepipelines/pipelinebasics#what-is-a-onebranch-release-yaml-pipeline
+jobs:
+ - job: publish_${{ replace(parameters.packageDisplayName, '.', '_') }}
+ displayName: Publish ${{ parameters.packageDisplayName }}
+
+ # Template context inputs are used to pass parameters to the deployment job since it doesn't
+ # automatically download pipeline artifacts.
+ templateContext:
+ type: releaseJob
+ isProduction: ${{ parameters.isProduction }}
+ inputs:
+ - input: pipelineArtifact
+ artifactName: ${{ parameters.artifactName }}
+ targetPath: $(Pipeline.Workspace)/${{ parameters.artifactName }}
+
+ variables:
+ - name: ob_outputDirectory
+ value: $(Build.SourcesDirectory)/packages
+
+ pool:
+ type: release
+
+ steps:
+
+ # Artifacts are downloaded via templateContext.inputs per OneBranch requirements.
+
+ - ${{ if eq(parameters.dryRun, true) }}:
+ - pwsh: |
+ Write-Host "##[section]DRY RUN — the following packages may be published:"
+ $nupkgs = Get-ChildItem -Path "$(Pipeline.Workspace)/${{ parameters.artifactName }}" -Filter "*.nupkg" -Recurse -ErrorAction SilentlyContinue
+ $snupkgs = Get-ChildItem -Path "$(Pipeline.Workspace)/${{ parameters.artifactName }}" -Filter "*.snupkg" -Recurse -ErrorAction SilentlyContinue
+ if ($nupkgs) { $nupkgs | ForEach-Object { Write-Host $_.FullName } } else { Write-Host "(no .nupkg found)" }
+ if ($snupkgs) { $snupkgs | ForEach-Object { Write-Host $_.FullName } } else { Write-Host "(no .snupkg found)" }
+ Write-Host "##[warning]Dry run mode — no packages were pushed."
+ displayName: Dry Run — List ${{ parameters.packageDisplayName }} packages
+
+ - ${{ else }}:
+ - task: NuGetCommand@2
+ displayName: Push ${{ parameters.packageDisplayName }} to NuGet
+ inputs:
+ command: push
+ packagesToPush: $(Pipeline.Workspace)/${{ parameters.artifactName }}/${{ parameters.packagePattern }}
+ nuGetFeedType: external
+ publishFeedCredentials: ${{ parameters.nugetServiceConnection }}
diff --git a/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml b/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml
index 6d53bcd9b8..bdc26ac82a 100644
--- a/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml
+++ b/eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml
@@ -5,9 +5,11 @@
#################################################################################
parameters:
+ # The name of the pipeline artifacts to download prior to building the tests.
- name: artifactName
type: string
+ # True if this build is a preview.
- name: isPreview
type: boolean
diff --git a/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml b/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml
index 237d4798f6..eb9c633c3c 100644
--- a/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml
+++ b/eng/pipelines/common/templates/jobs/validate-signed-package-job.yml
@@ -5,9 +5,11 @@
#################################################################################
parameters:
+ # The name of the pipeline artifacts to download prior to building the tests.
- name: artifactName
type: string
+ # True if this build is a preview.
- name: isPreview
type: boolean
@@ -30,7 +32,7 @@ jobs:
- name: BuildType
# This variable is set in the build-signed-package-job.yml job. Any changes
# to the names of the stage, job, or variable must be reflected here.
- value: $[ stageDependencies.buildMDS.build_signed_package.outputs['GetBuildType.CDP_BUILD_TYPE_COPY'] ]
+ value: $[ stageDependencies.build_dependent.build_package_SqlClient.outputs['GetBuildType.CDP_BUILD_TYPE_COPY'] ]
- ${{ if parameters.isPreview }}:
- name: extractedNugetPath
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 bc1ea204c9..fd87d7d9ac 100644
--- a/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
+++ b/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml
@@ -7,47 +7,70 @@
# This stage depends on the secrets_stage.
parameters:
+ # The name of the Abstractions pipeline artifacts to download.
- name: abstractionsArtifactsName
type: string
+ # The version of the Abstractions package to depend on when referenceType is 'Package'.
- name: abstractionsPackageVersion
type: string
+ # Additional stages we depend on, if any.
- name: additionalDependsOn
type: object
default: []
+ # The C# build configuration to build (e.g. Debug or Release).
- name: buildConfiguration
type: string
values:
- Debug
- Release
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
+ # The name of the Logging pipeline artifacts to download.
+ - name: loggingArtifactsName
+ type: string
+ default: Logging.Artifacts
+
+ # The version of the Logging package to depend on when referenceType is 'Package'.
+ - name: loggingPackageVersion
+ type: string
+
+ # The name of the SqlClient pipeline artifacts to download.
- name: mdsArtifactsName
type: string
default: MDS.Artifacts
+ # The version of the SqlClient package to depend on when referenceType is 'Package'.
- name: mdsPackageVersion
type: string
+ # Jobs to run after the test jobs complete, if any.
- name: postTestJobs
type: jobList
default: []
+ # Steps to run before the build starts, if any.
- name: prebuildSteps
type: stepList
default: []
+ # The C# project reference type to use when building and packing the packages.
- name: referenceType
+ type: string
default: Project
values:
- - Project
+ # Reference sibling packages as NuGet packages.
- Package
+ # Reference sibling packages as C# projects.
+ - Project
+ # Each entry in this object will become a test stage.
- name: testConfigurations
type: object
@@ -87,6 +110,8 @@ stages:
configProperties: ${{ config.value.configProperties }}
abstractionsArtifactsName: ${{ parameters.abstractionsArtifactsName }}
abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
+ loggingArtifactsName: ${{ parameters.loggingArtifactsName }}
+ loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
mdsArtifactsName: ${{ parameters.mdsArtifactsName }}
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
prebuildSteps: ${{ parameters.prebuildSteps }}
@@ -121,6 +146,8 @@ stages:
useManagedSNI: ${{ useManagedSNI }}
abstractionsArtifactsName: ${{ parameters.abstractionsArtifactsName }}
abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
+ loggingArtifactsName: ${{ parameters.loggingArtifactsName }}
+ loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
mdsArtifactsName: ${{ parameters.mdsArtifactsName }}
mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
prebuildSteps: ${{ parameters.prebuildSteps }}
diff --git a/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml b/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml
index c6b8ed82d1..04a8490b0b 100644
--- a/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml
+++ b/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml
@@ -5,15 +5,27 @@
#################################################################################
parameters:
+ # The assembly file version to apply to the Abstractions package.
- name: abstractionsAssemblyFileVersion
type: string
+ # The version to apply to the Abstractions package.
- name: abstractionsPackageVersion
type: string
+ # The assembly file version to apply to the Logging package.
+ - name: loggingAssemblyFileVersion
+ type: string
+
+ # The version to apply to the Logging package.
+ - name: loggingPackageVersion
+ type: string
+
+ # The assembly file version to apply to the Mds package.
- name: mdsAssemblyFileVersion
type: string
+ # The version to apply to the Mds package.
- name: mdsPackageVersion
type: string
@@ -40,6 +52,7 @@ steps:
-p:SigningKeyPath=$(Agent.TempDirectory)\netfxKeypair.snk
-p:AssemblyFileVersion=${{ parameters.mdsAssemblyFileVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
- -p:AssemblyFileVersion=${{ parameters.mdsAssemblyFileVersion }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
-p:AbstractionsAssemblyFileVersion=${{ parameters.abstractionsAssemblyFileVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
+ -p:LoggingAssemblyFileVersion=${{ parameters.loggingAssemblyFileVersion }}
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 bb649d59f3..acc7d12d9f 100644
--- a/eng/pipelines/common/templates/steps/ci-project-build-step.yml
+++ b/eng/pipelines/common/templates/steps/ci-project-build-step.yml
@@ -8,21 +8,25 @@ parameters:
type: string
default: $(Platform)
+ # The C# build configuration to build (e.g. Debug or Release).
- name: buildConfiguration
type: string
values:
- Debug
- Release
+ # The C# project reference type to use when building and packing the packages.
- name: referenceType
type: string
values:
+ # Reference sibling packages as NuGet packages.
- Package
+ # Reference sibling packages as C# projects.
- Project
- name: buildNumber
type: string
- default: $(BuildNumber)
+ default: $(Build.BuildNumber)
- name: operatingSystem
type: string
@@ -42,15 +46,24 @@ parameters:
- all
- allNoDocs
- # Necessary to build MDS when referenceType is Package
+ # The build number suffix to apply to all assembly file versions built by this step.
+ - name: assemblyBuildNumber
+ type: string
+
+ # Necessary to build MDS when referenceType is Package. Ignored when referenceType is Project.
- name: abstractionsPackageVersion
type: string
- default: ''
+ default: $(abstractionsPackageVersion)
+
+ # Necessary to build MDS when referenceType is Package. Ignored when referenceType is Project.
+ - name: loggingPackageVersion
+ type: string
+ default: $(loggingPackageVersion)
- # Necessary to build AKV when referenceType is Package.
+ # Necessary to build AKV when referenceType is Package. Ignored when referenceType is Project.
- name: mdsPackageVersion
type: string
- default: ''
+ default: $(mdsPackageVersion)
steps:
- ${{ if or(eq(parameters.operatingSystem, 'Windows'), eq(parameters.operatingSystem, 'deferedToRuntime')) }}:
@@ -65,6 +78,7 @@ steps:
-t:restore
-p:ReferenceType=${{ parameters.referenceType }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
retryCountOnTaskFailure: 1
@@ -83,7 +97,9 @@ steps:
-p:GenerateNuget=false
-p:GenerateDocumentationFile=false
-p:BuildNumber=${{ parameters.buildNumber }}
+ -p:AssemblyBuildNumber=${{ parameters.assemblyBuildNumber }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
- ${{ if or(eq(parameters.build, 'MDS'), eq(parameters.build, 'all')) }}:
@@ -100,7 +116,9 @@ steps:
-p:ReferenceType=${{ parameters.referenceType }}
-p:GenerateNuget=false
-p:BuildNumber=${{ parameters.buildNumber }}
+ -p:AssemblyBuildNumber=${{ parameters.assemblyBuildNumber }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
- ${{ if or(eq(parameters.build, 'AKV'), eq(parameters.build, 'all'), eq(parameters.build, 'allNoDocs')) }}:
@@ -117,6 +135,7 @@ steps:
-p:ReferenceType=${{ parameters.referenceType }}
-p:GenerateNuget=false
-p:BuildNumber=${{ parameters.buildNumber }}
+ -p:AssemblyBuildNumber=${{ parameters.assemblyBuildNumber }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
- task: MSBuild@1
@@ -132,6 +151,7 @@ steps:
-p:ReferenceType=${{ parameters.referenceType }}
-p:GenerateNuget=false
-p:BuildNumber=${{ parameters.buildNumber }}
+ -p:AssemblyBuildNumber=${{ parameters.assemblyBuildNumber }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
- ${{ if or(eq(parameters.operatingSystem, 'Linux'), eq(parameters.operatingSystem, 'MacOS'), eq(parameters.operatingSystem, 'deferedToRuntime')) }}:
@@ -149,7 +169,10 @@ steps:
-p:GenerateNuget=false
-p:GenerateDocumentationFile=false
-p:Configuration=${{ parameters.buildConfiguration }}
+ -p:BuildNumber=${{ parameters.buildNumber }}
+ -p:AssemblyBuildNumber=${{ parameters.assemblyBuildNumber }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
verbosityRestore: Detailed
verbosityPack: Detailed
diff --git a/eng/pipelines/common/templates/steps/code-analyze-step.yml b/eng/pipelines/common/templates/steps/code-analyze-step.yml
index 3ee9b4e92e..a574c7886f 100644
--- a/eng/pipelines/common/templates/steps/code-analyze-step.yml
+++ b/eng/pipelines/common/templates/steps/code-analyze-step.yml
@@ -18,9 +18,10 @@
# affect >1 project at a time.
parameters:
+ # Source Root.
- name: sourceRoot
type: string
- default: $(REPOROOT)
+ default: $(REPO_ROOT)
steps:
- task: securedevelopmentteam.vss-secure-development-tools.build-task-roslynanalyzers.RoslynAnalyzers@3
diff --git a/eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml b/eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml
deleted file mode 100644
index 3c00b3883c..0000000000
--- a/eng/pipelines/common/templates/steps/copy-dlls-for-test-step.yml
+++ /dev/null
@@ -1,71 +0,0 @@
-#################################################################################
-# Licensed to the .NET Foundation under one or more agreements. #
-# The .NET Foundation licenses this file to you under the MIT license. #
-# See the LICENSE file in the project root for more information. #
-#################################################################################
-parameters:
- - name: symbolsFolder
- type: string
- default: symbols
-
- - name: softwareFolder
- type: string
- default: software
-
- - name: listOfTF
- type: object
- default:
- - net462
- - net8.0
- - net9.0
-
-steps:
-- powershell: |
- $software = '${{parameters.softwareFolder}}'
- $symbols = '${{parameters.symbolsFolder}}'
-
- md $software
- md $software\win
-
- md $symbols
- md $symbols\win
- displayName: 'Make base directories'
-
-- ${{ each targetFramework in parameters.listOfTF }}:
- - powershell: |
- $software = '${{parameters.softwareFolder}}'
- $tf = '${{ targetFramework }}'
- md $software\win\$tf
-
- if ($tf.StartsWith('net4'))
- {
- Copy-Item "artifacts\Package\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netfx\$tf\Microsoft.Data.SqlClient.dll" "$software\win\$tf" -recurse
- }
- else
- {
- Copy-Item "artifacts\Package\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\$tf\Microsoft.Data.SqlClient.dll" "$software\win\$tf" -recurse
- }
-
- $symbols = '${{parameters.symbolsFolder}}'
- md $symbols\win\$tf
-
- if ($tf.StartsWith('net4'))
- {
- Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netfx\$tf\Microsoft.Data.SqlClient.pdb" "$symbols\win\$tf" -recurse
- }
- else
- {
- Copy-Item "artifacts\Project\bin\Windows_NT\Release.AnyCPU\Microsoft.Data.SqlClient\netcore\$tf\Microsoft.Data.SqlClient.pdb" "$symbols\win\$tf" -recurse
- }
-
- Write-Host "Artifacts fetched for testing"
- Get-Location
- displayName: 'Prepare ${{ targetFramework }} Artifacts for Testing'
-
-- powershell: |
- $software = '${{parameters.softwareFolder}}'
- $symbols = '${{parameters.symbolsFolder}}'
-
- Get-ChildItem -recurse "$software\*.dll" | ForEach-Object VersionInfo | Format-List
- Get-ChildItem -recurse "$symbols\*.pdb" | ForEach-Object VersionInfo | Format-List
- displayName: 'List the prepared files'
diff --git a/eng/pipelines/common/templates/steps/esrp-code-signing-step.yml b/eng/pipelines/common/templates/steps/esrp-code-signing-step.yml
index b2f6261f32..b46a18cbae 100644
--- a/eng/pipelines/common/templates/steps/esrp-code-signing-step.yml
+++ b/eng/pipelines/common/templates/steps/esrp-code-signing-step.yml
@@ -11,11 +11,11 @@ parameters:
- name: sourceRoot
type: string
- default: $(REPOROOT)
-
+ default: $(REPO_ROOT)
+
- name: artifactDirectory
type: string
- default: $(artifactDirectory)
+ default: $(PACK_OUTPUT)
- name: ESRPConnectedServiceName
type: string
@@ -43,7 +43,8 @@ parameters:
steps:
- ${{ if eq(parameters.artifactType, 'dll') }}:
- - task: EsrpMalwareScanning@5
+ # See: https://aka.ms/esrp.scantask
+ - task: EsrpMalwareScanning@6
displayName: 'ESRP MalwareScanning'
inputs:
ConnectedServiceName: '${{parameters.ESRPConnectedServiceName }}'
@@ -55,7 +56,9 @@ steps:
Pattern: 'Microsoft.Data.SqlClient*.dll'
CleanupTempStorage: 1
VerboseLogin: 1
- - task: EsrpCodeSigning@5
+
+ # See: https://aka.ms/esrp.signtask
+ - task: EsrpCodeSigning@6
displayName: 'ESRP CodeSigning'
inputs:
ConnectedServiceName: '${{parameters.ESRPConnectedServiceName }}'
@@ -69,46 +72,47 @@ steps:
Pattern: 'Microsoft.Data.SqlClient*.dll'
signConfigType: inlineSignParams
inlineOperation: |
- [
- {
- "keyCode": "CP-230012",
- "operationSetCode": "SigntoolSign",
- "parameters": [
- {
- "parameterName": "OpusName",
- "parameterValue": "Microsoft Data SqlClient Data Provider for SQL Server"
- },
- {
- "parameterName": "OpusInfo",
- "parameterValue": "http://www.microsoft.com"
- },
- {
- "parameterName": "FileDigest",
- "parameterValue": "/fd \"SHA256\""
- },
- {
- "parameterName": "PageHash",
- "parameterValue": "/NPH"
- },
- {
- "parameterName": "TimeStamp",
- "parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
- }
- ],
- "toolName": "sign",
- "toolVersion": "1.0"
- },
- {
- "keyCode": "CP-230012",
- "operationSetCode": "SigntoolVerify",
- "parameters": [ ],
- "toolName": "sign",
- "toolVersion": "1.0"
- }
- ]
+ [
+ {
+ "keyCode": "CP-230012",
+ "operationSetCode": "SigntoolSign",
+ "parameters": [
+ {
+ "parameterName": "OpusName",
+ "parameterValue": "Microsoft Data SqlClient Data Provider for SQL Server"
+ },
+ {
+ "parameterName": "OpusInfo",
+ "parameterValue": "http://www.microsoft.com"
+ },
+ {
+ "parameterName": "FileDigest",
+ "parameterValue": "/fd \"SHA256\""
+ },
+ {
+ "parameterName": "PageHash",
+ "parameterValue": "/NPH"
+ },
+ {
+ "parameterName": "TimeStamp",
+ "parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
+ }
+ ],
+ "toolName": "sign",
+ "toolVersion": "1.0"
+ },
+ {
+ "keyCode": "CP-230012",
+ "operationSetCode": "SigntoolVerify",
+ "parameters": [ ],
+ "toolName": "sign",
+ "toolVersion": "1.0"
+ }
+ ]
- ${{ if eq(parameters.artifactType, 'pkg') }}:
- - task: EsrpMalwareScanning@5
+ # See: https://aka.ms/esrp.scantask
+ - task: EsrpMalwareScanning@6
displayName: 'ESRP MalwareScanning Nuget Package'
inputs:
ConnectedServiceName: '${{parameters.ESRPConnectedServiceName }}'
@@ -120,7 +124,9 @@ steps:
Pattern: '*.*nupkg'
CleanupTempStorage: 1
VerboseLogin: 1
- - task: EsrpCodeSigning@5
+
+ # See: https://aka.ms/esrp.signtask
+ - task: EsrpCodeSigning@6
displayName: 'ESRP CodeSigning Nuget Package'
inputs:
inputs:
@@ -135,19 +141,19 @@ steps:
Pattern: '*.*nupkg'
signConfigType: inlineSignParams
inlineOperation: |
- [
- {
- "keyCode": "CP-401405",
- "operationSetCode": "NuGetSign",
- "parameters": [ ],
- "toolName": "sign",
- "toolVersion": "1.0"
+ [
+ {
+ "keyCode": "CP-401405",
+ "operationSetCode": "NuGetSign",
+ "parameters": [ ],
+ "toolName": "sign",
+ "toolVersion": "1.0"
},
- {
- "keyCode": "CP-401405",
- "operationSetCode": "NuGetVerify",
- "parameters": [ ],
- "toolName": "sign",
- "toolVersion": "1.0"
- }
- ]
+ {
+ "keyCode": "CP-401405",
+ "operationSetCode": "NuGetVerify",
+ "parameters": [ ],
+ "toolName": "sign",
+ "toolVersion": "1.0"
+ }
+ ]
diff --git a/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml
index 8227a69ff6..6e51adeeb6 100644
--- a/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml
+++ b/eng/pipelines/common/templates/steps/generate-nuget-package-step.yml
@@ -14,6 +14,7 @@ parameters:
type: string
default: '$(Build.SourcesDirectory)/packages'
+ # The C# build configuration (e.g. Debug or Release) to use when building the NuGet package.
- name: buildConfiguration
type: string
default: Debug
@@ -31,14 +32,16 @@ parameters:
type: boolean
default: true
+ # The C# project reference type to use when building and packing the packages.
- name: referenceType
type: string
values:
+ # Reference sibling packages as NuGet packages.
- Package
+ # Reference sibling packages as C# projects.
- Project
- # Semi-colon separated properties to pass to nuget via the -properties
- # argument.
+ # Semi-colon separated properties to pass to nuget pack via the -properties argument.
- name: properties
type: string
default: ''
diff --git a/eng/pipelines/common/templates/steps/prepare-test-db-step.yml b/eng/pipelines/common/templates/steps/prepare-test-db-step.yml
index 250fab772a..981780fc58 100644
--- a/eng/pipelines/common/templates/steps/prepare-test-db-step.yml
+++ b/eng/pipelines/common/templates/steps/prepare-test-db-step.yml
@@ -7,7 +7,7 @@ parameters:
- name: databaseName
type: string
default: $(Database)
-
+
- name: targetFramework
type: string
default: net10.0
diff --git a/eng/pipelines/common/templates/steps/publish-symbols-step.yml b/eng/pipelines/common/templates/steps/publish-symbols-step.yml
index 894730ab03..a23dbf4556 100644
--- a/eng/pipelines/common/templates/steps/publish-symbols-step.yml
+++ b/eng/pipelines/common/templates/steps/publish-symbols-step.yml
@@ -6,25 +6,32 @@
# doc: https://www.osgwiki.com/wiki/Symbols_Publishing_Pipeline_to_SymWeb_and_MSDL #
####################################################################################
parameters:
- - name: SymAccount
+
+ # The full name of the package whose symbols are being published.
+ - name: packageFullName
type: string
- default: 'SqlClientDrivers'
- - name: symbolsVersion
+ # The version of the package whose symbols are being published.
+ - name: packageVersion
type: string
- default: '$(mdsPackageVersion)'
- - name: symbolServer
+ # Our symbols account name.
+ - name: symbolsAccount
type: string
- default: '$(SymbolServer)'
+ default: SqlClientDrivers
- - name: symbolTokenUri
+ # The symbols server to publish to.
+ - name: symbolServer
type: string
- default: '$(SymbolTokenUri)'
+ default: $(SymbolServer)
- - name: symbolsArtifactName
+ # The token URI for the symbol publishing service.
+ - name: symbolTokenUri
type: string
+ default: $(SymbolTokenUri)
+ # A pair of flags indicating whether to publish to the internal and public symbol servers. Both
+ # default to true.
- name: publishToServers
type: object
default:
@@ -32,23 +39,24 @@ parameters:
public: true
steps:
-- powershell: 'Write-Host "##vso[task.setvariable variable=ArtifactServices.Symbol.AccountName;]${{parameters.SymAccount}}"'
- displayName: 'Update Symbol.AccountName with ${{parameters.SymAccount}}'
+- pwsh: 'Write-Host "##vso[task.setvariable variable=ArtifactServices.Symbol.AccountName;]${{parameters.symbolsAccount}}"'
+ displayName: 'Set ArtifactServices.Symbol.AccountName to ${{parameters.symbolsAccount}}'
+
+- pwsh: 'Write-Host "##vso[task.setvariable variable=symbolsArtifactName;]${{ parameters.packageFullName }}_symbols_$(System.TeamProject)_$(Build.Repository.Name)_$(Build.SourceBranchName)_${{ parameters.packageVersion }}_$(System.TimelineId)"'
+ displayName: 'Set symbolsArtifactName variable'
- task: PublishSymbols@2
- displayName: 'Upload symbols to ${{parameters.SymAccount }} org'
+ displayName: 'Upload symbols to ${{parameters.symbolsAccount }} org'
inputs:
SymbolsFolder: '$(Build.SourcesDirectory)\artifacts\Package\bin'
- SearchPattern: |
- Windows_NT/Release.AnyCPU/**/Microsoft.Data.SqlClient.pdb
- Unix/Release.AnyCPU/**/Microsoft.Data.SqlClient.pdb
+ SearchPattern: '**/*.pdb'
IndexSources: false
SymbolServerType: TeamServices
SymbolsMaximumWaitTime: 60
SymbolExpirationInDays: 1825 # 5 years
- SymbolsProduct: Microsoft.Data.SqlClient
- SymbolsVersion: ${{parameters.symbolsVersion }}
- SymbolsArtifactName: ${{parameters.symbolsArtifactName }}
+ SymbolsProduct: ${{ parameters.packageFullName }}
+ SymbolsVersion: ${{ parameters.packageVersion }}
+ SymbolsArtifactName: $(symbolsArtifactName)
Pat: $(System.AccessToken)
- task: AzureCLI@2
@@ -61,7 +69,7 @@ steps:
$publishToInternalServer = "${{parameters.publishToServers.internal }}".ToLower()
$publishToPublicServer = "${{parameters.publishToServers.public }}".ToLower()
- echo "Publishing request name: ${{parameters.symbolsArtifactName }}"
+ echo "Publishing request name: $(symbolsArtifactName)"
echo "Publish to internal server: $publishToInternalServer"
echo "Publish to public server: $publishToPublicServer"
@@ -76,7 +84,7 @@ steps:
echo "> 1.Symbol publishing token acquired."
echo "Registering the request name ..."
- $requestName = "${{parameters.symbolsArtifactName }}"
+ $requestName = "$(symbolsArtifactName)"
$requestNameRegistrationBody = "{'requestName': '$requestName'}"
Invoke-RestMethod -Method POST -Uri "https://$symbolServer.trafficmanager.net/projects/$projectName/requests" -Headers @{ Authorization = "Bearer $symbolPublishingToken" } -ContentType "application/json" -Body $requestNameRegistrationBody
diff --git a/eng/pipelines/common/templates/steps/publish-test-results-step.yml b/eng/pipelines/common/templates/steps/publish-test-results-step.yml
index 7a0fb1ebc6..9cb356aa45 100644
--- a/eng/pipelines/common/templates/steps/publish-test-results-step.yml
+++ b/eng/pipelines/common/templates/steps/publish-test-results-step.yml
@@ -4,6 +4,7 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
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 eba906be63..b1d0261abc 100644
--- a/eng/pipelines/common/templates/steps/run-all-tests-step.yml
+++ b/eng/pipelines/common/templates/steps/run-all-tests-step.yml
@@ -8,6 +8,10 @@ parameters:
- name: abstractionsPackageVersion
type: string
+ - name: loggingPackageVersion
+ type: string
+
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
@@ -22,17 +26,22 @@ parameters:
type: string
default: $(Platform)
+ # The C# build configuration to build (e.g. Debug or Release).
- name: buildConfiguration
type: string
values:
- Debug
- Release
+ # The C# project reference type to use when building and packing the packages.
- name: referenceType
+ type: string
default: Package
values:
- - Project
+ # Reference sibling packages as NuGet packages.
- Package
+ # Reference sibling packages as C# projects.
+ - Project
- name: testSet
type: string
@@ -43,7 +52,8 @@ parameters:
- x64
- x86
- - name: dotnetx86RootPath # full path to the x86 dotnet root folder with trailing slash
+ # Full path to the x86 dotnet root folder with trailing slash.
+ - name: dotnetx86RootPath
type: string
default: ''
@@ -127,6 +137,7 @@ steps:
-p:TestSet=${{ parameters.testSet }}
-p:ReferenceType=${{ parameters.referenceType }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
${{ else }}: # x86
msbuildArguments: >-
@@ -135,6 +146,7 @@ steps:
-p:TestSet=${{ parameters.testSet }}
-p:ReferenceType=${{ parameters.referenceType }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
-p:DotnetPath=${{ parameters.dotnetx86RootPath }}
@@ -153,6 +165,7 @@ steps:
-p:TestSet=${{ parameters.testSet }}
-p:ReferenceType=${{ parameters.referenceType }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
-p:Filter="category=flaky"
-p:CollectCodeCoverage=false
@@ -163,6 +176,7 @@ steps:
-p:TestSet=${{ parameters.testSet }}
-p:ReferenceType=${{ parameters.referenceType }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
-p:DotnetPath=${{ parameters.dotnetx86RootPath }}
-p:Filter="category=flaky"
@@ -184,6 +198,7 @@ steps:
-p:TestSet=${{ parameters.testSet }}
-p:ReferenceType=${{ parameters.referenceType }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
${{ else }}: # x86
msbuildArguments: >-
@@ -192,6 +207,7 @@ steps:
-p:TestSet=${{ parameters.testSet }}
-p:ReferenceType=${{ parameters.referenceType }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
-p:DotnetPath=${{ parameters.dotnetx86RootPath }}
retryCountOnTaskFailure: ${{parameters.retryCountOnManualTests }}
@@ -211,6 +227,7 @@ steps:
-p:TestSet=${{ parameters.testSet }}
-p:ReferenceType=${{ parameters.referenceType }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
-p:Filter="category=flaky"
-p:CollectCodeCoverage=false
@@ -221,6 +238,7 @@ steps:
-p:TestSet=${{ parameters.testSet }}
-p:ReferenceType=${{ parameters.referenceType }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
-p:DotnetPath=${{ parameters.dotnetx86RootPath }}
-p:Filter="category=flaky"
@@ -241,6 +259,9 @@ steps:
-p:TF=${{ parameters.targetFramework }}
-p:TestSet=${{ parameters.testSet }}
-p:ReferenceType=${{ parameters.referenceType }}
+ -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
+ -p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
-p:Platform=${{ parameters.platform }}
-p:Configuration=${{ parameters.buildConfiguration }}
verbosityRestore: Detailed
@@ -258,6 +279,9 @@ steps:
-p:TF=${{ parameters.targetFramework }}
-p:TestSet=${{ parameters.testSet }}
-p:ReferenceType=${{ parameters.referenceType }}
+ -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
+ -p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
-p:Platform=${{ parameters.platform }}
-p:Configuration=${{ parameters.buildConfiguration }}
-p:Filter="category=flaky"
@@ -279,6 +303,7 @@ steps:
-p:TestSet=${{ parameters.testSet }}
-p:ReferenceType=${{ parameters.referenceType }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
-p:Platform=${{ parameters.platform }}
-p:Configuration=${{ parameters.buildConfiguration }}
@@ -298,6 +323,7 @@ steps:
-p:TestSet=${{ parameters.testSet }}
-p:ReferenceType=${{ parameters.referenceType }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
-p:Platform=${{ parameters.platform }}
-p:Configuration=${{ parameters.buildConfiguration }}
@@ -320,6 +346,7 @@ steps:
-p:TestSet=${{ parameters.testSet }}
-p:ReferenceType=${{ parameters.referenceType }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
-p:platform=${{ parameters.platform }}
-p:Configuration=${{ parameters.buildConfiguration }}
@@ -340,6 +367,7 @@ steps:
-p:TestSet=${{ parameters.testSet }}
-p:ReferenceType=${{ parameters.referenceType }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
-p:Platform=${{ parameters.platform }}
-p:Configuration=${{ parameters.buildConfiguration }}
diff --git a/eng/pipelines/common/templates/steps/update-config-file-step.yml b/eng/pipelines/common/templates/steps/update-config-file-step.yml
index fad1bc1636..b10abdc617 100644
--- a/eng/pipelines/common/templates/steps/update-config-file-step.yml
+++ b/eng/pipelines/common/templates/steps/update-config-file-step.yml
@@ -4,6 +4,7 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
diff --git a/eng/pipelines/dotnet-sqlclient-ci-core.yml b/eng/pipelines/dotnet-sqlclient-ci-core.yml
index ab6b5a9dd9..65fe3f5690 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-core.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-core.yml
@@ -4,6 +4,7 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
parameters:
+# True to emit debug information and steps.
- name: debug
type: boolean
default: false
@@ -58,14 +59,14 @@ parameters:
type: string
default: https://sqlclientdrivers.pkgs.visualstudio.com/ADO.Net/_packaging/SNIValidation/nuget/v3/index.json
-# The way we will reference sibling projects in the .csproj files:
-# Project - use references.
-# Package - use references to NuGet packages in the
-# packages/ directory.
+# The C# project reference type to use when building and packing the packages.
- name: referenceType
+ type: string
values:
- - Project
+ # Reference sibling packages as NuGet packages.
- Package
+ # Reference sibling packages as C# projects.
+ - Project
- name: buildConfiguration
type: string
@@ -111,6 +112,9 @@ variables:
- name: azureArtifactsName
value: Azure.Artifacts
+ - name: loggingArtifactsName
+ value: Logging.Artifacts
+
- name: mdsArtifactsName
value: MDS.Artifacts
@@ -126,38 +130,46 @@ stages:
- template: /eng/pipelines/stages/build-abstractions-package-ci-stage.yml@self
parameters:
abstractionsArtifactsName: $(abstractionsArtifactsName)
+ abstractionsAssemblyFileVersion: $(abstractionsAssemblyFileVersion)
abstractionsPackageVersion: $(abstractionsPackageVersion)
buildConfiguration: ${{ parameters.buildConfiguration }}
debug: ${{ parameters.debug }}
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
- # Build MDS and its NuGet packages.
- - stage: build_mds_akv_packages_stage
- displayName: 'Build MDS & AKV Packages'
-
- # When building MDS via packages, we must depend on the Abstractions
- # package.
- ${{ if eq(parameters.referenceType, 'Package') }}:
- dependsOn:
- - build_abstractions_package_stage
- ${{ else }}:
- dependsOn: []
+ # Build the Logging package, and publish it to the pipeline artifacts
+ # under the given artifact name. This runs in parallel with the Abstractions
+ # stage since neither depends on the other.
+ - template: /eng/pipelines/stages/build-logging-package-ci-stage.yml@self
+ parameters:
+ loggingArtifactsName: $(loggingArtifactsName)
+ loggingAssemblyFileVersion: $(loggingAssemblyFileVersion)
+ loggingPackageVersion: $(loggingPackageVersion)
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ debug: ${{ parameters.debug }}
+ dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
- jobs:
- - template: /eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml@self
- parameters:
- buildConfiguration: ${{ parameters.buildConfiguration }}
- referenceType: ${{ parameters.referenceType }}
- abstractionsPackageVersion: $(abstractionsPackageVersion)
- abstractionsArtifactsName: $(abstractionsArtifactsName)
- mdsPackageVersion: $(mdsPackageVersion)
- mdsArtifactsName: $(mdsArtifactsName)
- ${{if ne(parameters.SNIVersion, '')}}:
- prebuildSteps:
- - template: /eng/pipelines/common/templates/steps/override-sni-version.yml@self
- parameters:
- SNIVersion: ${{parameters.SNIVersion}}
- SNIValidationFeed: ${{parameters.SNIValidationFeed}}
+ # Build the SqlClienet package.
+ #
+ # For legacy reasons, this also builds the AKV package.
+ #
+ - template: /eng/pipelines/stages/build-sqlclient-package-ci-stage.yml@self
+ parameters:
+ abstractionsArtifactsName: $(abstractionsArtifactsName)
+ abstractionsPackageVersion: $(abstractionsPackageVersion)
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ loggingArtifactsName: $(loggingArtifactsName)
+ loggingPackageVersion: $(loggingPackageVersion)
+ mdsArtifactsName: $(mdsArtifactsName)
+ mdsPackageVersion: $(mdsPackageVersion)
+ referenceType: ${{ parameters.referenceType }}
+ SNIVersion: ${{ parameters.SNIVersion }}
+ SNIValidationFeed: ${{ parameters.SNIValidationFeed }}
+ # When building SqlClient via packages, we must depend on the Abstractions and Logging
+ # packages.
+ ${{ if eq(parameters.referenceType, 'Package') }}:
+ additionalDependsOn:
+ - build_abstractions_package_stage
+ - build_logging_package_stage
# Build the Azure package, and publish it to the pipeline artifacts under the
# given artifact name.
@@ -166,15 +178,17 @@ stages:
abstractionsArtifactsName: $(abstractionsArtifactsName)
abstractionsPackageVersion: $(abstractionsPackageVersion)
azureArtifactsName: $(azureArtifactsName)
+ azureAssemblyFileVersion: $(azureAssemblyFileVersion)
azurePackageVersion: $(azurePackageVersion)
buildConfiguration: ${{ parameters.buildConfiguration }}
debug: ${{ parameters.debug }}
- # When building via packages, we must depend on the Abstractions and MDS
- # packages.
+ # When building via packages, we must depend on the Abstractions, Logging,
+ # and MDS packages.
${{ if eq(parameters.referenceType, 'Package') }}:
additionalDependsOn:
- build_abstractions_package_stage
- - build_mds_akv_packages_stage
+ - build_logging_package_stage
+ - build_sqlclient_package_stage
dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
mdsArtifactsName: $(mdsArtifactsName)
mdsPackageVersion: $(mdsPackageVersion)
@@ -186,7 +200,7 @@ stages:
parameters:
buildConfiguration: ${{ parameters.buildConfiguration }}
additionalDependsOn:
- - build_mds_akv_packages_stage
+ - build_sqlclient_package_stage
- build_azure_package_stage
mdsArtifactsName: $(mdsArtifactsName)
mdsPackageVersion: $(mdsPackageVersion)
@@ -201,16 +215,19 @@ stages:
referenceType: ${{ parameters.referenceType }}
abstractionsArtifactsName: $(abstractionsArtifactsName)
abstractionsPackageVersion: $(abstractionsPackageVersion)
+ loggingArtifactsName: $(loggingArtifactsName)
+ loggingPackageVersion: $(loggingPackageVersion)
mdsArtifactsName: $(mdsArtifactsName)
mdsPackageVersion: $(mdsPackageVersion)
testJobTimeout: ${{ parameters.testJobTimeout }}
# When testing MDS via packages, we must depend on the Abstractions,
- # MDS, and Azure packages.
+ # Logging, MDS, and Azure packages.
${{ if eq(parameters.referenceType, 'Package') }}:
additionalDependsOn:
- build_abstractions_package_stage
- - build_mds_akv_packages_stage
+ - build_logging_package_stage
+ - build_sqlclient_package_stage
- build_azure_package_stage
# Steps to run prior to building and running tests on each job.
@@ -251,22 +268,24 @@ stages:
#
upload: ${{ or(eq(variables['Build.DefinitionName'], 'PR-SqlClient-Project'), eq(variables['Build.DefinitionName'], 'CI-SqlClient')) }}
-# test stages configurations
- # self hosted SQL Server on Windows
+ # Configuration of test jobs. Each entry in this object will become a test job, and the
+ # properties of each entry will be supplied as parameters to the test job template.
testConfigurations:
- windows_sql_19_x64: # configuration name
- pool: ${{parameters.defaultPoolName }} # pool name
- images: # list of images to run tests on
- Win22_Sql19: ADO-MMS22-SQL19 # stage display name: image name from the pool
- TargetFrameworks: ${{parameters.targetFrameworks }} #[net462, net8.0] # list of target frameworks to run
+
+ # Windows Server 22 with local SQL Server 2019, x64 build platform.
+ windows_sql_19_x64:
+ pool: ${{parameters.defaultPoolName }}
+ images:
+ Win22_Sql19: ADO-MMS22-SQL19
+ TargetFrameworks: ${{parameters.targetFrameworks }}
netcoreVersionTestUtils: ${{parameters.netcoreVersionTestUtils }}
buildPlatforms: ${{parameters.buildPlatforms }}
- testSets: ${{parameters.testSets }} # [1, 2, 3] # list of test sets to run
- useManagedSNI: ${{parameters.useManagedSNI }} # can be used for .NET Core only tests on Windows: [false, true], [false] or [true] values are allowed
- configSqlFor: local # setup Sql Server (local | azure | enclave)
- operatingSystem: Windows # operating system to run tests on (Windows | Linux | Mac)
+ testSets: ${{parameters.testSets }}
+ useManagedSNI: ${{parameters.useManagedSNI }}
+ configSqlFor: local
+ operatingSystem: Windows
+ # config.json properties
configProperties:
- # config.json properties
TCPConnectionString: $(SQL_TCP_CONN_STRING)
NPConnectionString: $(SQL_NP_CONN_STRING)
AzureKeyVaultUrl: $(AzureKeyVaultUrl)
@@ -277,36 +296,22 @@ stages:
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
AliasName: $(SQLAliasName)
- # extra config properties
SQLRootPath: $(SQL19RootPath)
enableLocalDB: true
- # instanceName: default: MSSQLSERVER
- # user: default: $(user)
- # saUser: default: $(saUser)
- # fileStreamDirectory: default: ''
- # x64AliasRegistryPath: default: $(x64AliasRegistryPath)
- # x86AliasRegistryPath: default: $(x86AliasRegistryPath)
- # SQLAliasName: default: $(SQLAliasName)
- # SQLAliasPort: default: $(SQLAliasPort)
- # databaseName: default: Northwind
- # localDbAppName: default: $(LocalDbAppName)
- # localDbSharedInstanceName: default: $(LocalDbSharedInstanceName)
- # skipSqlConfiguration: # skips the SQL configuration step
-
-
- windows_sql_19_x86: # configuration name
- pool: ${{parameters.defaultPoolName }} # pool name
- images: # list of images to run tests on
- Win22_Sql19_x86: ADO-MMS22-SQL19 # stage display name: image name from the pool
+
+ # Windows Server 22 with local SQL Server 2019, x86 build platform.
+ windows_sql_19_x86:
+ pool: ${{parameters.defaultPoolName }}
+ images:
+ Win22_Sql19_x86: ADO-MMS22-SQL19
TargetFrameworks: [net462, net8.0, net9.0]
netcoreVersionTestUtils: ${{parameters.netcoreVersionTestUtils }}
buildPlatforms: ${{parameters.buildPlatforms }}
- testSets: ${{parameters.testSets }} # [1, 2, 3] # list of test sets to run
- useManagedSNI: [false] # can be used for .NET Core only tests on Windows: [false, true], [false] or [true] values are allowed
- configSqlFor: local # setup Sql Server (local | azure | enclave)
- operatingSystem: Windows # operating system to run tests on (Windows | Linux | Mac)
+ testSets: ${{parameters.testSets }}
+ useManagedSNI: [false]
+ configSqlFor: local
+ operatingSystem: Windows
configProperties:
- # config.json properties
TCPConnectionString: $(SQL_TCP_CONN_STRING)
NPConnectionString: $(SQL_NP_CONN_STRING)
AzureKeyVaultUrl: $(AzureKeyVaultUrl)
@@ -317,24 +322,11 @@ stages:
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
AliasName: $(SQLAliasName)
- # extra config properties
x86TestTargetFrameworks: [net462, net8.0, net9.0]
SQLRootPath: $(SQL19RootPath)
enableLocalDB: true
- # instanceName: default: MSSQLSERVER
- # user: default: $(user)
- # saUser: default: $(saUser)
- # fileStreamDirectory: default: ''
- # x64AliasRegistryPath: default: $(x64AliasRegistryPath)
- # x86AliasRegistryPath: default: $(x86AliasRegistryPath)
- # SQLAliasName: default: $(SQLAliasName)
- # SQLAliasPort: default: $(SQLAliasPort)
- # databaseName: default: Northwind
- # localDbAppName: default: $(LocalDbAppName)
- # localDbSharedInstanceName: default: $(LocalDbSharedInstanceName)
- # skipSqlConfiguration: # skips the SQL configuration step
-
+ # Windows Server 22 with local SQL Server 2022, x64 build platform.
windows_sql_22_x64:
pool: ${{parameters.defaultPoolName }}
images:
@@ -347,7 +339,6 @@ stages:
configSqlFor: local
operatingSystem: Windows
configProperties:
- # config.json properties
TCPConnectionString: $(SQL_TCP_CONN_STRING)
NPConnectionString: $(SQL_NP_CONN_STRING)
AzureKeyVaultUrl: $(AzureKeyVaultUrl)
@@ -358,11 +349,10 @@ stages:
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
AliasName: $(SQLAliasName)
- # extra config properties
SQLRootPath: $(SQL22RootPath)
enableLocalDB: true
-
+ # Windows Server 22 with local SQL Server 2022, x86 build platform.
windows_sql_22_x86:
pool: ${{parameters.defaultPoolName }}
images:
@@ -375,7 +365,6 @@ stages:
configSqlFor: local
operatingSystem: Windows
configProperties:
- # config.json properties
TCPConnectionString: $(SQL_TCP_CONN_STRING)
NPConnectionString: $(SQL_NP_CONN_STRING)
AzureKeyVaultUrl: $(AzureKeyVaultUrl)
@@ -386,12 +375,11 @@ stages:
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
AliasName: $(SQLAliasName)
- # extra config properties
x86TestTargetFrameworks: [net462, net8.0, net9.0]
SQLRootPath: $(SQL22RootPath)
enableLocalDB: true
-
+ # Windows Server 22 with local SQL Server 2022 Named Instance, x64 build platform.
windows_sql_22_named_instance:
pool: ${{parameters.defaultPoolName }}
images:
@@ -404,16 +392,13 @@ stages:
configSqlFor: local
operatingSystem: Windows
configProperties:
- # config.json properties
TCPConnectionString: $(SQL_TCP_INSTANCE_CONN_STRING)
NPConnectionString: $(SQL_NP_INSTANCE_CONN_STRING)
SupportsIntegratedSecurity: true
- # extra config properties
SQLRootPath: $(SQL22RootPath)
instanceName: $(NamedInstance)
-
- # Azure SQL Server - Windows
+ # Windows Server 2022 and Windows 11, x64 build platform, with Azure SQL Server.
windows_azure_sql:
pool: ${{parameters.defaultPoolName }}
images:
@@ -427,7 +412,6 @@ stages:
configSqlFor: azure
operatingSystem: Windows
configProperties:
- # config.json properties
TCPConnectionString: $(AZURE_DB_TCP_CONN_STRING)
NPConnectionString: $(AZURE_DB_NP_CONN_STRING)
AADAuthorityURL: $(AADAuthorityURL)
@@ -445,6 +429,7 @@ stages:
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
+ # Windows 11 on ARM64 with Azure SQL Server.
windows_azure_arm64_sql:
pool: ADO-CI-PUBLIC-ARM64-1ES-EUS-POOL
images:
@@ -458,7 +443,6 @@ stages:
configSqlFor: azure
operatingSystem: Windows
configProperties:
- # config.json properties
TCPConnectionString: $(AZURE_DB_TCP_CONN_STRING_eastus)
NPConnectionString: $(AZURE_DB_NP_CONN_STRING_eastus)
AADAuthorityURL: $(AADAuthorityURL)
@@ -473,11 +457,11 @@ stages:
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
- # self hosted SQL Server on Linux
+ # Linux Ubuntu 20 and 22 with local SQL Server 2022, x64 build platform.
linux_ub20_22_sql_22:
pool: ${{parameters.defaultPoolName }}
images:
- Ubuntu20_Sql22: ADO-UB20-SQL22 # drop testing against UB20 image post April 2025
+ Ubuntu20_Sql22: ADO-UB20-SQL22
Ubuntu22_Sql22: ADO-UB22-SQL22
TargetFrameworks: ${{parameters.targetFrameworksUnix }}
netcoreVersionTestUtils: ${{parameters.netcoreVersionTestUtils }}
@@ -487,7 +471,6 @@ stages:
configSqlFor: local
operatingSystem: Linux
configProperties:
- # config.json properties
TCPConnectionString: $(SQL_TCP_CONN_STRING)
NPConnectionString: $(SQL_NP_CONN_STRING)
AzureKeyVaultUrl: $(AzureKeyVaultUrl)
@@ -498,7 +481,7 @@ stages:
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
AliasName: $(SQLAliasName)
- # Azure Sql Server - Linux
+ # Linux Ubuntu 22 with Azure SQL Server, x64 build platform.
linux_azure_sql:
pool: ${{parameters.defaultPoolName }}
images:
@@ -511,7 +494,6 @@ stages:
configSqlFor: azure
operatingSystem: Linux
configProperties:
- # config.json properties
TCPConnectionString: $(AZURE_DB_TCP_CONN_STRING)
NPConnectionString: $(AZURE_DB_NP_CONN_STRING)
AADAuthorityURL: $(AADAuthorityURL)
@@ -526,7 +508,7 @@ stages:
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
- # Self hosted SQL Server on Mac
+ # macOS with local SQL Server 2022, x64 build platform.
mac_sql_22:
pool: Azure Pipelines
hostedPool: true
@@ -540,7 +522,6 @@ stages:
configSqlFor: local
operatingSystem: Mac
configProperties:
- # config.json properties
TCPConnectionString: $(SQL_TCP_CONN_STRING)
NPConnectionString: $(SQL_NP_CONN_STRING)
SupportsIntegratedSecurity: false
@@ -553,6 +534,8 @@ stages:
# Only run these tests if explicitly enabled, and if we're not a forked repo (which won't
# have access to the necessary Library secrets).
${{ if and(eq(parameters.runAlwaysEncryptedTests, true), eq(variables['System.PullRequest.IsFork'], 'False')) }}:
+
+ # Windows Server 22 with remote Enclave-enabled SQL Server 2019, x64 build platform.
windows_enclave_sql:
pool: ADO-CI-AE-1ES-Pool
images:
@@ -565,7 +548,6 @@ stages:
configSqlFor: enclave
operatingSystem: Windows
configProperties:
- # config.json properties
TCPConnectionStringHGSVBS: $(SQL_TCP_CONN_STRING_HGSVBS)
TCPConnectionStringNoneVBS: $(SQL_TCP_CONN_STRING_NoneVBS)
TCPConnectionStringAASSGX: $(SQL_TCP_CONN_STRING_AASSGX)
@@ -581,6 +563,7 @@ stages:
LocalDbAppName: $(LocalDbAppName)
LocalDbSharedInstanceName: $(LocalDbSharedInstanceName)
+ # Linux Ubuntu 22 with remote Enclave-enabled SQL Server 2019, x64 build platform.
linux_enclave_sql:
pool: ADO-CI-AE-1ES-Pool
images:
@@ -593,7 +576,6 @@ stages:
configSqlFor: enclave
operatingSystem: Linux
configProperties:
- # config.json properties
TCPConnectionStringHGSVBS: $(SQL_TCP_CONN_STRING_HGSVBS)
TCPConnectionStringNoneVBS: $(SQL_TCP_CONN_STRING_NoneVBS)
TCPConnectionStringAASSGX: $(SQL_TCP_CONN_STRING_AASSGX)
diff --git a/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml b/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml
index b3e3a9c701..9bde8f7c88 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-package-reference-pipeline.yml
@@ -95,7 +95,7 @@ schedules:
# Pipeline parameters, visible in the Azure DevOps UI.
parameters:
- # The build configuration to use; defaults to Release.
+ # The C# build configuration to use; defaults to Release.
- name: buildConfiguration
displayName: Build Configuration
type: string
@@ -109,11 +109,13 @@ parameters:
type: object
default: [AnyCPU]
+ # True to emit debug information and steps.
- name: debug
displayName: Enable debug output
type: boolean
default: false
+ # True to run the stress tests stage.
- name: enableStressTests
displayName: Enable Stress Tests
type: boolean
diff --git a/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml b/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
index 1d5df2dabb..b7782c2162 100644
--- a/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
+++ b/eng/pipelines/dotnet-sqlclient-ci-project-reference-pipeline.yml
@@ -95,7 +95,7 @@ schedules:
# Pipeline parameters, visible in the Azure DevOps UI.
parameters:
- # The build configuration to use; defaults to Release.
+ # The C# build configuration to use; defaults to Release.
- name: buildConfiguration
displayName: Build Configuration
type: string
@@ -109,11 +109,13 @@ parameters:
type: object
default: [AnyCPU]
+ # True to emit debug information and steps.
- name: debug
displayName: Enable debug output
type: boolean
default: false
+ # True to run the stress tests stage.
- name: enableStressTests
displayName: Enable Stress Tests
type: boolean
diff --git a/eng/pipelines/dotnet-sqlclient-non-official-pipeline.yml b/eng/pipelines/dotnet-sqlclient-non-official-pipeline.yml
index 883e32e81e..2515677706 100644
--- a/eng/pipelines/dotnet-sqlclient-non-official-pipeline.yml
+++ b/eng/pipelines/dotnet-sqlclient-non-official-pipeline.yml
@@ -5,60 +5,98 @@
#################################################################################
name: $(Year:YY)$(DayOfYear)$(Rev:.r)
-trigger:
- branches:
- include:
-
- # This pipeline is intended to only run against the ADO.Net dotnet-sqlclient
- # repo.
- - internal/main
- paths:
- include:
- - .azuredevops
- - .config
- - doc
- - eng/pipelines
- - src
- - tools
- - azurepipelines-coverage.yml
- - build.proj
- - NuGet.config
-
-parameters: # parameters are shown up in ADO UI in a build queue time
-- name: 'debug'
- displayName: 'Enable debug output'
- type: boolean
- default: false
-
-- name: publishSymbols
- displayName: 'Publish symbols'
- type: boolean
- default: false
-
-- name: CurrentNetFxVersion
- displayName: 'Lowest supported .NET Framework version (MDS validation)'
- type: string
- default: 'net462'
-
-- name: isPreview
- displayName: 'Is this a preview build?'
- type: boolean
- default: false
-
-# The timeout, in minutes, for each test job.
-- name: testJobTimeout
- displayName: 'Test job timeout (in minutes)'
- type: number
- default: 60
+
+# No automated triggers; this pipeline must be run manually.
+pr: none
+trigger: none
+
+# These parameters are visible in the Azure DevOps pipeline UI when a new run is queued.
+parameters:
+ # True to enable debug information and steps.
+ - name: debug
+ displayName: Enable debug output
+ type: boolean
+ default: false
+
+ # True if this is a preview build.
+ - name: isPreview
+ displayName: Is this a preview build?
+ type: boolean
+ default: false
+
+ # True to publish symbols to private and public servers.
+ - name: publishSymbols
+ displayName: Publish symbols
+ type: boolean
+ default: false
+
+ # The timeout, in minutes, for each test job.
+ - name: testJobTimeout
+ displayName: Test job timeout (in minutes)
+ type: number
+ default: 60
+
+ # Build parameters — select which packages to build.
+
+ # Build the Microsoft.SqlServer.Server package.
+ - name: buildSqlServerServer
+ displayName: Build Microsoft.SqlServer.Server
+ type: boolean
+ default: true
+
+ # Build Microsoft.Data.SqlClient and Extensions packages.
+ - name: buildSqlClient
+ displayName: Build Microsoft.Data.SqlClient and Extensions
+ type: boolean
+ default: true
+
+ # Build the Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider package.
+ - name: buildAKVProvider
+ displayName: Build Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+ type: boolean
+ default: true
+
+ # Release parameters — select which packages to publish to NuGet.
+ # All default to false; toggle at queue time for on-demand selective release.
+
+ # Release the Microsoft.SqlServer.Server package.
+ - name: releaseSqlServerServer
+ displayName: Release Microsoft.SqlServer.Server
+ type: boolean
+ default: false
+
+ # Release the Microsoft.Data.SqlClient.Extensions.Logging package.
+ - name: releaseLogging
+ displayName: Release Microsoft.Data.SqlClient.Extensions.Logging
+ type: boolean
+ default: false
+
+ # Release the Microsoft.Data.SqlClient.Extensions.Abstractions package.
+ - name: releaseAbstractions
+ displayName: Release Microsoft.Data.SqlClient.Extensions.Abstractions
+ type: boolean
+ default: false
+
+ # Release the Microsoft.Data.SqlClient package.
+ - name: releaseSqlClient
+ displayName: Release Microsoft.Data.SqlClient
+ type: boolean
+ default: false
+
+ # Release the Microsoft.Data.SqlClient.Extensions.Azure package.
+ - name: releaseExtAzure
+ displayName: Release Microsoft.Data.SqlClient.Extensions.Azure
+ type: boolean
+ default: false
+
+ # Release the Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider package.
+ - name: releaseAKVProvider
+ displayName: Release Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+ type: boolean
+ default: false
variables:
- - template: /eng/pipelines/libraries/variables.yml@self
- - name: mdsArtifactName
- value: drop_buildMDS_build_signed_package
- - name: PublishSymbols
- value: ${{ parameters['publishSymbols'] }}
- - name: CurrentNetFxVersion
- value: ${{ parameters['CurrentNetFxVersion'] }}
+ - template: /eng/pipelines/libraries/onebranch-variables.yml@self
resources:
repositories:
@@ -68,77 +106,73 @@ resources:
ref: refs/heads/main
extends:
- template: v2/OneBranch.NonOfficial.CrossPlat.yml@templates # https://aka.ms/obpipelines/templates
+ # See: https://aka.ms/obpipelines/templates
+ template: /v2/OneBranch.NonOfficial.CrossPlat.yml@templates
parameters:
+ release:
+ # This indicates the pipeline category to deploy Box products. See:
+ # https://eng.ms/docs/products/onebranch/release/yamlreleasepipelines/deployboxproducts
+ category: NonAzure
featureFlags:
- # Suggested by MerlinBot (https://sqlclientdrivers.visualstudio.com/ADO.Net/_git/dotnet-sqlclient/pullrequest/4882)
EnableCDPxPAT: false
WindowsHostVersion: 1ESWindows2022
- globalSdl: # https://aka.ms/obpipelines/sdl
+ # See: https://aka.ms/obpipelines/sdl
+ globalSdl:
tsa:
- # The OneBranch template will set 'break' to false for the other SDL
- # tools when TSA is enabled. This allows TSA to gather the results
- # and publish them for downstream analysis.
+ # We disable TSA for non-official pipelines. This inhibits spurious TSA alerts and ADO
+ # task creation, since non-official builds are often done against development branches.
enabled: false
apiscan:
enabled: true
- softwareFolder: $(softwareFolder)
- symbolsFolder: $(symbolsFolder)
- softwarename: Microsoft.Data.SqlClient
- versionNumber: $(mdsAssemblyFileVersion)
+ break: false
+ # Other ApiScan options are set by the jobs via ob_sdl_apiscan_* variables.
codeql:
compiled:
- enabled: ${{ not(parameters['isPreview']) }}
+ enabled: true
sbom:
- enabled: ${{ not(parameters['isPreview']) }}
+ enabled: true
packageName: Microsoft.Data.SqlClient
packageVersion: $(mdsPackageVersion)
policheck:
- enabled: ${{ not(parameters['isPreview']) }}
- break: true # always break the build on policheck issues. You can disable it by setting to 'false'
- exclusionsFile: $(REPOROOT)\.config\PolicheckExclusions.xml
+ enabled: true
+ break: true
+ exclusionsFile: $(REPO_ROOT)\.config\PolicheckExclusions.xml
asyncSdl:
enabled: false
credscan:
- enabled: ${{ not(parameters['isPreview']) }}
- suppressionsFile: $(REPOROOT)/.config/CredScanSuppressions.json
+ enabled: true
+ suppressionsFile: $(REPO_ROOT)/.config/CredScanSuppressions.json
binskim:
- enabled: ${{ not(parameters['isPreview']) }}
+ enabled: true
armory:
- enabled: ${{ not(parameters['isPreview']) }}
+ enabled: true
break: true
- eslint: # TypeScript and JavaScript
+ eslint:
enabled: false
roslyn:
- enabled: ${{ not(parameters['isPreview']) }}
+ enabled: true
break: true
publishLogs:
- enabled: ${{ not(parameters['isPreview']) }}
- tsaOptionsPath: $(REPOROOT)\.config\tsaoptions.json
+ enabled: true
+ tsaOptionsPath: $(REPO_ROOT)\.config\tsaoptions.json
disableLegacyManifest: true
stages:
- - stage: buildMDS
- displayName: 'Build MDS'
- jobs:
- - template: /eng/pipelines/common/templates/jobs/build-signed-package-job.yml@self
- parameters:
- symbolsFolder: $(symbolsFolder)
- softwareFolder: $(softwareFolder)
- publishSymbols: ${{ parameters['publishSymbols'] }}
- isPreview: ${{ parameters['isPreview'] }}
-
- - stage: mds_package_validation
- displayName: 'MDS Package Validation'
- dependsOn: buildMDS
- jobs:
- - template: /eng/pipelines/common/templates/jobs/validate-signed-package-job.yml@self
+ - template: /eng/pipelines/stages/sqlclient-onebranch-stages.yml@self
parameters:
- artifactName: $(mdsArtifactName)
- isPreview: ${{ parameters['isPreview'] }}
-
-# Disabling as of 10/15/2025 due to OneBranch apparently disallowing MSBuild tasks in validation stages.
-# - template: /eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml@self
-# parameters:
-# artifactName: $(mdsArtifactName)
-# isPreview: ${{ parameters['isPreview'] }}
-# timeout: ${{ parameters.testJobTimeout }}
+ debug: ${{ parameters.debug }}
+ # This is not an official pipeline.
+ isOfficial: false
+ isPreview: ${{ parameters.isPreview }}
+ publishSymbols: ${{ parameters.publishSymbols }}
+ # Non-Official pipelines must always be a dry-run.
+ releaseDryRun: true
+ testJobTimeout: ${{ parameters.testJobTimeout }}
+ buildSqlServerServer: ${{ parameters.buildSqlServerServer }}
+ buildSqlClient: ${{ parameters.buildSqlClient }}
+ buildAKVProvider: ${{ parameters.buildAKVProvider }}
+ releaseSqlServerServer: ${{ parameters.releaseSqlServerServer }}
+ releaseLogging: ${{ parameters.releaseLogging }}
+ releaseAbstractions: ${{ parameters.releaseAbstractions }}
+ releaseSqlClient: ${{ parameters.releaseSqlClient }}
+ releaseExtAzure: ${{ parameters.releaseExtAzure }}
+ releaseAKVProvider: ${{ parameters.releaseAKVProvider }}
diff --git a/eng/pipelines/dotnet-sqlclient-official-pipeline.yml b/eng/pipelines/dotnet-sqlclient-official-pipeline.yml
index 96dee0ea15..45cecd6a02 100644
--- a/eng/pipelines/dotnet-sqlclient-official-pipeline.yml
+++ b/eng/pipelines/dotnet-sqlclient-official-pipeline.yml
@@ -5,74 +5,119 @@
#################################################################################
name: $(Year:YY)$(DayOfYear)$(Rev:.r)
+
+# No PR-based triggers.
+pr: none
+
+# We trigger runs on activity on the internal/main branch, but not on any other branches. This
+# pipeline is intended to only run against the ADO.Net dotnet-sqlclient repo.
trigger:
branches:
include:
+ - internal/main
- # This pipeline is intended to only run against the ADO.Net dotnet-sqlclient
- # repo.
- - internal/main
- paths:
- include:
- - .azuredevops
- - .config
- - doc
- - eng/pipelines
- - src
- - tools
- - azurepipelines-coverage.yml
- - build.proj
- - NuGet.config
-
+# We run this pipeline on a daily schedule.
schedules:
-- cron: '30 4 * * Mon'
- displayName: Weekly Sunday 9:30 PM (UTC - 7) Build
- branches:
- include:
- - internal/main
- always: true
+ - cron: "30 4 * * *"
+ displayName: Daily 04:30 UTC Build
+ branches:
+ include:
+ - internal/main
+ always: true
-- cron: '30 3 * * Mon-Fri'
- displayName: Mon-Fri 8:30 PM (UTC - 7) Build
- branches:
- include:
- - internal/main
-
-parameters: # parameters are shown up in ADO UI in a build queue time
-- name: 'debug'
- displayName: 'Enable debug output'
- type: boolean
- default: false
-
-- name: publishSymbols
- displayName: 'Publish symbols'
- type: boolean
- default: false
-
-- name: CurrentNetFxVersion
- displayName: 'Lowest supported .NET Framework version (MDS validation)'
- type: string
- default: 'net462'
-
-- name: isPreview
- displayName: 'Is this a preview build?'
- type: boolean
- default: false
-
-# The timeout, in minutes, for each test job.
-- name: testJobTimeout
- displayName: 'Test job timeout (in minutes)'
- type: number
- default: 60
+# These parameters are visible in the Azure DevOps pipeline UI when a new run is queued.
+parameters:
+ # True to enable debug information and steps.
+ - name: debug
+ displayName: Enable debug output
+ type: boolean
+ default: false
+
+ # True if this is a preview build.
+ - name: isPreview
+ displayName: Is this a preview build?
+ type: boolean
+ default: false
+
+ # True to publish symbols to private and public servers.
+ - name: publishSymbols
+ displayName: Publish symbols
+ type: boolean
+ default: false
+
+ # Release Dry Run (do not push to NuGet)
+ - name: releaseDryRun
+ displayName: Release Dry Run (do not push to NuGet)
+ type: boolean
+ default: true
+
+ # The timeout, in minutes, for each test job.
+ - name: testJobTimeout
+ displayName: Test job timeout (in minutes)
+ type: number
+ default: 60
+
+ # Build parameters — select which packages to build.
+
+ # Build the Microsoft.SqlServer.Server package.
+ - name: buildSqlServerServer
+ displayName: Build Microsoft.SqlServer.Server
+ type: boolean
+ default: true
+
+ # Build Microsoft.Data.SqlClient and Extensions packages.
+ - name: buildSqlClient
+ displayName: Build Microsoft.Data.SqlClient and Extensions
+ type: boolean
+ default: true
+
+ # Build the Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider package.
+ - name: buildAKVProvider
+ displayName: Build Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+ type: boolean
+ default: true
+
+ # Release parameters — select which packages to publish to NuGet.
+ # All default to false; toggle at queue time for on-demand selective release.
+
+ # Release the Microsoft.SqlServer.Server package.
+ - name: releaseSqlServerServer
+ displayName: Release Microsoft.SqlServer.Server
+ type: boolean
+ default: false
+
+ # Release the Microsoft.Data.SqlClient.Extensions.Logging package.
+ - name: releaseLogging
+ displayName: Release Microsoft.Data.SqlClient.Extensions.Logging
+ type: boolean
+ default: false
+
+ # Release the Microsoft.Data.SqlClient.Extensions.Abstractions package.
+ - name: releaseAbstractions
+ displayName: Release Microsoft.Data.SqlClient.Extensions.Abstractions
+ type: boolean
+ default: false
+
+ # Release the Microsoft.Data.SqlClient package.
+ - name: releaseSqlClient
+ displayName: Release Microsoft.Data.SqlClient
+ type: boolean
+ default: false
+
+ # Release the Microsoft.Data.SqlClient.Extensions.Azure package.
+ - name: releaseExtAzure
+ displayName: Release Microsoft.Data.SqlClient.Extensions.Azure
+ type: boolean
+ default: false
+
+ # Release the Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider package.
+ - name: releaseAKVProvider
+ displayName: Release Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+ type: boolean
+ default: false
variables:
- - template: /eng/pipelines/libraries/variables.yml@self
- - name: mdsArtifactName
- value: drop_buildMDS_build_signed_package
- - name: PublishSymbols
- value: ${{ parameters['publishSymbols'] }}
- - name: CurrentNetFxVersion
- value: ${{ parameters['CurrentNetFxVersion'] }}
+ - template: /eng/pipelines/libraries/onebranch-variables.yml@self
resources:
repositories:
@@ -82,77 +127,72 @@ resources:
ref: refs/heads/main
extends:
- template: v2/OneBranch.Official.CrossPlat.yml@templates # https://aka.ms/obpipelines/templates
+ # See: https://aka.ms/obpipelines/templates
+ template: /v2/OneBranch.Official.CrossPlat.yml@templates
parameters:
+ release:
+ # This indicates the pipeline category to deploy Box products. See:
+ # https://eng.ms/docs/products/onebranch/release/yamlreleasepipelines/deployboxproducts
+ category: NonAzure
featureFlags:
- # Suggested by MerlinBot (https://sqlclientdrivers.visualstudio.com/ADO.Net/_git/dotnet-sqlclient/pullrequest/4882)
EnableCDPxPAT: false
WindowsHostVersion: 1ESWindows2022
- globalSdl: # https://aka.ms/obpipelines/sdl
+ # See: https://aka.ms/obpipelines/sdl
+ globalSdl:
tsa:
- # The OneBranch template will set 'break' to false for the other SDL
- # tools when TSA is enabled. This allows TSA to gather the results
- # and publish them for downstream analysis.
+ # The OneBranch template will set 'break' to false for the other SDL tools when TSA is
+ # enabled. This allows TSA to gather the results and publish them for downstream analysis.
enabled: true
apiscan:
enabled: true
- softwareFolder: $(softwareFolder)
- symbolsFolder: $(symbolsFolder)
- softwarename: Microsoft.Data.SqlClient
- versionNumber: $(mdsAssemblyFileVersion)
+ break: true
+ # Other ApiScan options are set by the jobs via ob_sdl_apiscan_* variables.
codeql:
compiled:
- enabled: ${{ not(parameters['isPreview']) }}
+ enabled: true
sbom:
- enabled: ${{ not(parameters['isPreview']) }}
+ enabled: true
packageName: Microsoft.Data.SqlClient
packageVersion: $(mdsPackageVersion)
policheck:
- enabled: ${{ not(parameters['isPreview']) }}
- break: true # always break the build on policheck issues. You can disable it by setting to 'false'
- exclusionsFile: $(REPOROOT)\.config\PolicheckExclusions.xml
+ enabled: true
+ break: true
+ exclusionsFile: $(REPO_ROOT)\.config\PolicheckExclusions.xml
asyncSdl:
enabled: false
credscan:
- enabled: ${{ not(parameters['isPreview']) }}
- suppressionsFile: $(REPOROOT)/.config/CredScanSuppressions.json
+ enabled: true
+ suppressionsFile: $(REPO_ROOT)/.config/CredScanSuppressions.json
binskim:
- enabled: ${{ not(parameters['isPreview']) }}
+ enabled: true
armory:
- enabled: ${{ not(parameters['isPreview']) }}
+ enabled: true
break: true
- eslint: # TypeScript and JavaScript
+ eslint:
enabled: false
roslyn:
- enabled: ${{ not(parameters['isPreview']) }}
+ enabled: true
break: true
publishLogs:
- enabled: ${{ not(parameters['isPreview']) }}
- tsaOptionsPath: $(REPOROOT)\.config\tsaoptions.json
+ enabled: true
+ tsaOptionsPath: $(REPO_ROOT)\.config\tsaoptions.json
disableLegacyManifest: true
stages:
- - stage: buildMDS
- displayName: 'Build MDS'
- jobs:
- - template: /eng/pipelines/common/templates/jobs/build-signed-package-job.yml@self
- parameters:
- symbolsFolder: $(symbolsFolder)
- softwareFolder: $(softwareFolder)
- publishSymbols: ${{ parameters['publishSymbols'] }}
- isPreview: ${{ parameters['isPreview'] }}
-
- - stage: mds_package_validation
- displayName: 'MDS Package Validation'
- dependsOn: buildMDS
- jobs:
- - template: /eng/pipelines/common/templates/jobs/validate-signed-package-job.yml@self
+ - template: /eng/pipelines/stages/sqlclient-onebranch-stages.yml@self
parameters:
- artifactName: $(mdsArtifactName)
- isPreview: ${{ parameters['isPreview'] }}
-
-# Disabling as of 10/15/2025 due to OneBranch apparently disallowing MSBuild tasks in validation stages.
-# - template: /eng/pipelines/common/templates/jobs/run-tests-package-reference-job.yml@self
-# parameters:
-# artifactName: $(mdsArtifactName)
-# isPreview: ${{ parameters['isPreview'] }}
-# timeout: ${{ parameters.testJobTimeout }}
+ debug: ${{ parameters.debug }}
+ # This is an official pipeline.
+ isOfficial: true
+ isPreview: ${{ parameters.isPreview }}
+ publishSymbols: ${{ parameters.publishSymbols }}
+ releaseDryRun: ${{ parameters.releaseDryRun }}
+ testJobTimeout: ${{ parameters.testJobTimeout }}
+ buildSqlServerServer: ${{ parameters.buildSqlServerServer }}
+ buildSqlClient: ${{ parameters.buildSqlClient }}
+ buildAKVProvider: ${{ parameters.buildAKVProvider }}
+ releaseSqlServerServer: ${{ parameters.releaseSqlServerServer }}
+ releaseLogging: ${{ parameters.releaseLogging }}
+ releaseAbstractions: ${{ parameters.releaseAbstractions }}
+ releaseSqlClient: ${{ parameters.releaseSqlClient }}
+ releaseExtAzure: ${{ parameters.releaseExtAzure }}
+ releaseAKVProvider: ${{ parameters.releaseAKVProvider }}
diff --git a/eng/pipelines/jobs/build-akv-official-job.yml b/eng/pipelines/jobs/build-akv-official-job.yml
index c7ed0a7354..06b276990d 100644
--- a/eng/pipelines/jobs/build-akv-official-job.yml
+++ b/eng/pipelines/jobs/build-akv-official-job.yml
@@ -26,25 +26,31 @@ parameters:
- name: mdsPackageVersion
type: string
+ - name: loggingPackageVersion
+ type: string
+
+ - name: abstractionsPackageVersion
+ type: string
+
- name: publishSymbols
type: boolean
- - name: signingAppRegistrationClientId
+ - name: appRegistrationClientId
type: string
- - name: signingAppRegistrationTenantId
+ - name: appRegistrationTenantId
type: string
- - name: signingAuthAkvName
+ - name: authAkvName
type: string
- - name: signingAuthSignCertName
+ - name: authSignCertName
type: string
- - name: signingEsrpClientId
+ - name: esrpClientId
type: string
- - name: signingEsrpConnectedServiceName
+ - name: esrpConnectedServiceName
type: string
- name: symbolsAzureSubscription
@@ -63,9 +69,9 @@ parameters:
type: string
# @TODO: This should be determined from build output, or at a higher level
- - # Note: not intended to be passed in, is only used for copying files for ApiScan.
- # This is only defined as a parameter since ADO pipelines do not support array variables.
- name: targetFrameworks
+ # Note: not intended to be passed in, is only used for copying files for ApiScan.
+ # This is only defined as a parameter since ADO pipelines do not support array variables.
+ - name: targetFrameworks
type: object
default:
- net462
@@ -74,12 +80,18 @@ parameters:
jobs:
- job: buildSignedAkvPackage
- displayName: 'Build Signed AKV Package'
+ displayName: 'Build Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider'
pool:
type: windows
variables:
- ob_outputDirectory: '$(ARTIFACT_PATH)'
+ ob_outputDirectory: '$(PACK_OUTPUT)'
+ # APIScan configuration for AKV Provider
+ ob_sdl_apiscan_enabled: true
+ ob_sdl_apiscan_softwareFolder: '${{ parameters.apiScanDllPath }}'
+ ob_sdl_apiscan_symbolsFolder: '${{ parameters.apiScanPdbPath }}'
+ ob_sdl_apiscan_softwarename: 'Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider'
+ ob_sdl_apiscan_versionNumber: '${{ parameters.akvAssemblyFileVersion }}'
steps:
- template: /eng/pipelines/steps/script-output-environment-variables-step.yml@self
@@ -89,6 +101,21 @@ jobs:
$jsonParams | ConvertFrom-Json | Format-List
displayName: 'Output Job Parameters'
+ # Download SqlClient (MDS) and Logging packages from previous stages into
+ # packages/ so that they're available via the local NuGet feed when restoring.
+ # AKV Provider depends on both SqlClient and Extensions.Logging.
+ - task: DownloadPipelineArtifact@2
+ displayName: Download SqlClient Package
+ inputs:
+ artifactName: $(sqlClientArtifactsName)
+ targetPath: $(Build.SourcesDirectory)/packages
+
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Logging Package
+ inputs:
+ artifactName: $(loggingArtifactsName)
+ targetPath: $(Build.SourcesDirectory)/packages
+
# Install the .NET SDK.
- template: /eng/pipelines/steps/install-dotnet.yml@self
@@ -99,6 +126,8 @@ jobs:
akvPackageVersion: '${{ parameters.akvPackageVersion }}'
buildConfiguration: '${{ parameters.buildConfiguration }}'
mdsPackageVersion: '${{ parameters.mdsPackageVersion }}'
+ loggingPackageVersion: '${{ parameters.loggingPackageVersion }}'
+ abstractionsPackageVersion: '${{ parameters.abstractionsPackageVersion }}'
- template: /eng/pipelines/steps/compound-build-akv-step.yml@self
parameters:
@@ -106,6 +135,8 @@ jobs:
akvPackageVersion: '${{ parameters.akvPackageVersion }}'
buildConfiguration: '${{ parameters.buildConfiguration }}'
mdsPackageVersion: '${{ parameters.mdsPackageVersion }}'
+ loggingPackageVersion: '${{ parameters.loggingPackageVersion }}'
+ abstractionsPackageVersion: '${{ parameters.abstractionsPackageVersion }}'
- ${{ each targetFramework in parameters.targetFrameworks }}:
- template: /eng/pipelines/steps/compound-extract-akv-apiscan-files-step.yml@self
@@ -118,12 +149,12 @@ jobs:
- template: /eng/pipelines/steps/compound-esrp-dll-signing-step.yml@self
parameters:
- appRegistrationClientId: '${{ parameters.signingAppRegistrationClientId }}'
- appRegistrationTenantId: '${{ parameters.signingAppRegistrationTenantId }}'
- authAkvName: '${{ parameters.signingAuthAkvName }}'
- authSignCertName: '${{ parameters.signingAuthSignCertName }}'
- esrpClientId: '${{ parameters.signingEsrpClientId }}'
- esrpConnectedServiceName: '${{ parameters.signingEsrpConnectedServiceName }}'
+ appRegistrationClientId: '${{ parameters.appRegistrationClientId }}'
+ appRegistrationTenantId: '${{ parameters.appRegistrationTenantId }}'
+ authAkvName: '${{ parameters.authAkvName }}'
+ authSignCertName: '${{ parameters.authSignCertName }}'
+ esrpClientId: '${{ parameters.esrpClientId }}'
+ esrpConnectedServiceName: '${{ parameters.esrpConnectedServiceName }}'
pattern: 'Microsoft.Data.SqlClient.AlwaysEncrypted.*.dll'
- template: /eng/pipelines/steps/compound-nuget-pack-step.yml@self
@@ -132,18 +163,18 @@ jobs:
generateSymbolsPackage: true # Always generate symbols, even if they are not published
packageVersion: '${{ parameters.akvPackageVersion }}'
nuspecPath: '$(REPO_ROOT)/tools/specs/add-ons/$(PACKAGE_NAME).nuspec'
- outputDirectory: '$(ARTIFACT_PATH)'
+ outputDirectory: '$(PACK_OUTPUT)'
referenceType: Package
- properties: MdsPackageVersion=${{ parameters.mdsPackageVersion }}
+ properties: MdsPackageVersion=${{ parameters.mdsPackageVersion }};LoggingPackageVersion=${{ parameters.loggingPackageVersion }};AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
- template: /eng/pipelines/steps/compound-esrp-nuget-signing-step.yml@self
parameters:
- appRegistrationClientId: '${{ parameters.signingAppRegistrationClientId }}'
- appRegistrationTenantId: '${{ parameters.signingAppRegistrationTenantId }}'
- authAkvName: '${{ parameters.signingAuthAkvName }}'
- authSignCertName: '${{ parameters.signingAuthSignCertName }}'
- esrpClientId: '${{ parameters.signingEsrpClientId }}'
- esrpConnectedServiceName: '${{ parameters.signingEsrpConnectedServiceName }}'
+ appRegistrationClientId: '${{ parameters.appRegistrationClientId }}'
+ appRegistrationTenantId: '${{ parameters.appRegistrationTenantId }}'
+ authAkvName: '${{ parameters.authAkvName }}'
+ authSignCertName: '${{ parameters.authSignCertName }}'
+ esrpClientId: '${{ parameters.esrpClientId }}'
+ esrpConnectedServiceName: '${{ parameters.esrpConnectedServiceName }}'
- ${{ if parameters.publishSymbols }}:
- template: /eng/pipelines/steps/compound-publish-symbols-step.yml@self
diff --git a/eng/pipelines/jobs/build-signed-csproj-package-job.yml b/eng/pipelines/jobs/build-signed-csproj-package-job.yml
new file mode 100644
index 0000000000..1e120e7216
--- /dev/null
+++ b/eng/pipelines/jobs/build-signed-csproj-package-job.yml
@@ -0,0 +1,184 @@
+#################################################################################
+# 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. #
+#################################################################################
+
+# Generic job template for building and signing simple csproj-based packages, currently:
+#
+# - Abstractions
+# - Azure
+# - Logging
+# - SqlServer
+#
+# The job builds DLLs via build.proj, ESRP signs the DLLs, then creates NuGet packages from the
+# signed DLLs, and finally ESRP signs the NuGet packages.
+
+parameters:
+ # Short package name used in the job name, display strings, filesystem paths, and as a suffix for
+ # the default Build and Pack targets if those aren't specified.
+ - name: packageName
+ type: string
+ values:
+ - Abstractions
+ - Azure
+ - Logging
+ - SqlServer
+
+ # The full name of the package. This is used in the job name, and to form DLL and PDB filenames
+ # for APIScan.
+ - name: packageFullName
+ type: string
+
+ # The version of the package. This is used for symbol publishing. It is not used for the DLL or
+ # NuGet package versions since those are supplied via the versionProperties parameter.
+ - name: packageVersion
+ type: string
+
+ # The MSBuild build target in build.proj (e.g. BuildLogging). If not specified, defaults to
+ # Build.
+ - name: buildTarget
+ type: string
+ default: ''
+
+ # The MSBuild pack target in build.proj (e.g. PackLogging). If not specified, defaults to
+ # Pack.
+ - name: packTarget
+ type: string
+ default: ''
+
+ # The C# build configuration to build (e.g. Debug or Release).
+ - name: buildConfiguration
+ type: string
+ values:
+ - Debug
+ - Release
+ default: Release
+
+ # Additional MSBuild -p: arguments for version properties. These may include versions of
+ # packages this package depends on, or versions for this package itself.
+ - name: versionProperties
+ type: string
+ default: ''
+
+ # Assembly file version for APIScan (e.g. 1.0.0.12345).
+ - name: assemblyFileVersion
+ type: string
+
+ # True to publish symbols to private and public servers.
+ - name: publishSymbols
+ type: boolean
+
+ # Values required by ESRP tasks.
+ - name: esrpConnectedServiceName
+ type: string
+
+ - name: esrpClientId
+ type: string
+
+ - name: appRegistrationClientId
+ type: string
+
+ - name: appRegistrationTenantId
+ type: string
+
+ - name: authAkvName
+ type: string
+
+ - name: authSignCertName
+ type: string
+
+jobs:
+ - job: build_package_${{ parameters.packageName }}
+ displayName: Build ${{ parameters.packageFullName }}
+ pool:
+ type: windows
+
+ variables:
+ ob_outputDirectory: $(PACK_OUTPUT)
+ # APIScan configuration for this Extension package
+ ob_sdl_apiscan_enabled: true
+ ob_sdl_apiscan_softwareFolder: $(Build.SourcesDirectory)/apiScan/${{ parameters.packageName }}/dlls
+ ob_sdl_apiscan_symbolsFolder: $(Build.SourcesDirectory)/apiScan/${{ parameters.packageName }}/pdbs
+ ob_sdl_apiscan_softwarename: ${{ parameters.packageFullName }}
+ ob_sdl_apiscan_versionNumber: ${{ parameters.assemblyFileVersion }}
+
+ buildTarget: ${{ coalesce(parameters.buildTarget, format('Build{0}', parameters.packageName)) }}
+ packTarget: ${{ coalesce(parameters.packTarget, format('Pack{0}', parameters.packageName)) }}
+
+ steps:
+ - template: /eng/pipelines/steps/script-output-environment-variables-step.yml@self
+
+ # The Azure package depends on Abstractions. The other packages we build have no
+ # inter-package dependencies.
+ - ${{ if eq(parameters.packageName, 'Azure') }}:
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Abstractions Package
+ inputs:
+ artifactName: $(abstractionsArtifactsName)
+ targetPath: $(Build.SourcesDirectory)/packages
+
+ # Install the .NET SDK.
+ - template: /eng/pipelines/steps/install-dotnet.yml@self
+
+ # Build the package, producing DLLs only (no NuGet package yet).
+ - template: /eng/pipelines/steps/compound-build-csproj-step.yml@self
+ parameters:
+ buildTarget: $(buildTarget)
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ versionProperties: ${{ parameters.versionProperties }}
+
+ # ESRP sign the DLLs.
+ - template: /eng/pipelines/steps/compound-esrp-dll-signing-step.yml@self
+ parameters:
+ appRegistrationClientId: ${{ parameters.appRegistrationClientId }}
+ appRegistrationTenantId: ${{ parameters.appRegistrationTenantId }}
+ authAkvName: ${{ parameters.authAkvName }}
+ authSignCertName: ${{ parameters.authSignCertName }}
+ esrpClientId: ${{ parameters.esrpClientId }}
+ esrpConnectedServiceName: ${{ parameters.esrpConnectedServiceName }}
+ pattern: ${{ parameters.packageFullName }}.dll
+
+ # Copy signed DLLs and PDBs to APIScan folders.
+ - task: CopyFiles@2
+ displayName: Copy DLLs for APIScan
+ inputs:
+ SourceFolder: $(BUILD_OUTPUT)/Package/bin
+ Contents: '**/${{ parameters.packageFullName }}.dll'
+ TargetFolder: $(ob_sdl_apiscan_softwareFolder)
+ # We must preserve the folder structure since our C# projects may produce multiple
+ # identically named DLLs for different target frameworks (e.g. netstandard2.0, net5.0,
+ # etc.), and we need to keep those separate for APIScan to work correctly.
+ flattenFolders: false
+
+ - task: CopyFiles@2
+ displayName: Copy PDBs for APIScan
+ inputs:
+ SourceFolder: $(BUILD_OUTPUT)/Package/bin
+ Contents: '**/${{ parameters.packageFullName }}.pdb'
+ TargetFolder: $(ob_sdl_apiscan_symbolsFolder)
+ flattenFolders: false
+
+ # Pack the signed DLLs into NuGet package (NoBuild=true).
+ - template: /eng/pipelines/steps/compound-pack-csproj-step.yml@self
+ parameters:
+ packTarget: $(packTarget)
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ versionProperties: ${{ parameters.versionProperties }}
+
+ # ESRP sign the NuGet package.
+ - template: /eng/pipelines/steps/compound-esrp-nuget-signing-step.yml@self
+ parameters:
+ appRegistrationClientId: ${{ parameters.appRegistrationClientId }}
+ appRegistrationTenantId: ${{ parameters.appRegistrationTenantId }}
+ authAkvName: ${{ parameters.authAkvName }}
+ authSignCertName: ${{ parameters.authSignCertName }}
+ esrpClientId: ${{ parameters.esrpClientId }}
+ esrpConnectedServiceName: ${{ parameters.esrpConnectedServiceName }}
+
+ # Publish symbols to servers
+ - ${{ if eq(parameters.publishSymbols, true) }}:
+ - template: /eng/pipelines/common/templates/steps/publish-symbols-step.yml@self
+ parameters:
+ packageFullName: ${{ parameters.packageFullName }}
+ packageVersion: ${{ parameters.packageVersion }}
diff --git a/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml b/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
index cc993ce8a2..9db1c05696 100644
--- a/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
+++ b/eng/pipelines/jobs/pack-abstractions-package-ci-job.yml
@@ -17,6 +17,10 @@ parameters:
type: string
default: Abstractions.Artifact
+ # The assembly file version to stamp into the Abstractions DLLs.
+ - name: abstractionsAssemblyFileVersion
+ type: string
+
# The version to apply to the Abstractions NuGet package and its assemblies.
- name: abstractionsPackageVersion
type: string
@@ -28,11 +32,11 @@ parameters:
- Release
- Debug
- # True to enable extra debug steps and logging.
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
-
+
# The list of upstream jobs to depend on.
- name: dependsOn
type: object
@@ -71,18 +75,6 @@ jobs:
- name: dotnetPackagesDir
value: $(Build.StagingDirectory)/dotnetPackages
- # dotnet CLI arguments common to all commands.
- - name: commonArguments
- value: >-
- --verbosity ${{ parameters.dotnetVerbosity }}
-
- # dotnet CLI arguments for build/test/pack commands
- - name: buildArguments
- value: >-
- $(commonArguments)
- --configuration ${{ parameters.buildConfiguration }}
- -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
-
# 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
@@ -117,35 +109,16 @@ jobs:
parameters:
debug: ${{ parameters.debug }}
- # We use the 'custom' command because the DotNetCoreCLI@2 task doesn't
- # support all of our argument combinations for the different build steps.
-
- # Restore the project.
- - task: DotNetCoreCLI@2
- displayName: Restore Project
- inputs:
- command: custom
- custom: restore
- projects: $(project)
- arguments: $(commonArguments)
-
- # Build the project.
- - task: DotNetCoreCLI@2
- displayName: Build Project
- inputs:
- command: custom
- custom: build
- projects: $(project)
- arguments: $(buildArguments) --no-restore
-
# Create the NuGet packages.
- task: DotNetCoreCLI@2
displayName: Create NuGet Package
inputs:
- command: custom
- custom: pack
- projects: $(project)
- arguments: $(buildArguments) --no-build -o $(dotnetPackagesDir)
+ command: pack
+ packagesToPack: $(project)
+ configurationToPack: ${{ parameters.buildConfiguration }}
+ packDirectory: $(dotnetPackagesDir)
+ verbosityToPack: ${{ parameters.dotnetVerbosity }}
+ buildProperties: AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }};AbstractionsAssemblyFileVersion=${{ parameters.abstractionsAssemblyFileVersion }}
# 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 41e3317732..fc0e2a6b3d 100644
--- a/eng/pipelines/jobs/pack-azure-package-ci-job.yml
+++ b/eng/pipelines/jobs/pack-azure-package-ci-job.yml
@@ -30,6 +30,10 @@ parameters:
type: string
default: Azure.Artifacts
+ # The assembly file version to stamp into the Azure DLLs.
+ - name: azureAssemblyFileVersion
+ type: string
+
# The version to apply to the NuGet package and DLLs.
- name: azurePackageVersion
type: string
@@ -41,7 +45,7 @@ parameters:
- Release
- Debug
- # True to enable extra debug steps and logging.
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
@@ -62,16 +66,14 @@ parameters:
- detailed
- diagnostic
- # The reference type to use:
- #
- # Project - dependent projects are referenced directly.
- # Package - dependent projects are referenced via NuGet packages.
- #
+ # The C# project reference type to use when building and packing the packages.
- name: referenceType
type: string
values:
- - Package
- - Project
+ # Reference sibling packages as NuGet packages.
+ - Package
+ # Reference sibling packages as C# projects.
+ - Project
jobs:
@@ -95,20 +97,6 @@ jobs:
- name: dotnetPackagesDir
value: $(Build.StagingDirectory)/dotnetPackages
- # dotnet CLI arguments common to all commands.
- - name: commonArguments
- value: >-
- --verbosity ${{ parameters.dotnetVerbosity }}
- -p:ReferenceType=${{ parameters.referenceType }}
- -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
-
- # dotnet CLI arguments for build/test/pack commands
- - name: buildArguments
- value: >-
- $(commonArguments)
- --configuration ${{ parameters.buildConfiguration }}
- -p:AzurePackageVersion=${{ parameters.azurePackageVersion }}
-
# 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
@@ -151,35 +139,16 @@ jobs:
parameters:
debug: ${{ parameters.debug }}
- # We use the 'custom' command because the DotNetCoreCLI@2 task doesn't
- # support all of our argument combinations for the different build steps.
-
- # Restore the project.
- - task: DotNetCoreCLI@2
- displayName: Restore Project
- inputs:
- command: custom
- custom: restore
- projects: $(project)
- arguments: $(commonArguments)
-
- # Build the project.
- - task: DotNetCoreCLI@2
- displayName: Build Project
- inputs:
- command: custom
- custom: build
- projects: $(project)
- arguments: $(buildArguments) --no-restore
-
# Create the NuGet packages.
- task: DotNetCoreCLI@2
displayName: Create NuGet Package
inputs:
- command: custom
- custom: pack
- projects: $(project)
- arguments: $(buildArguments) --no-build -o $(dotnetPackagesDir)
+ command: pack
+ packagesToPack: $(project)
+ configurationToPack: ${{ parameters.buildConfiguration }}
+ packDirectory: $(dotnetPackagesDir)
+ verbosityToPack: ${{ parameters.dotnetVerbosity }}
+ buildProperties: AzurePackageVersion=${{ parameters.azurePackageVersion }};AzureAssemblyFileVersion=${{ parameters.azureAssemblyFileVersion }}
# 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
new file mode 100644
index 0000000000..4a1a225f8a
--- /dev/null
+++ b/eng/pipelines/jobs/pack-logging-package-ci-job.yml
@@ -0,0 +1,118 @@
+################################################################################
+# Licensed to the .NET Foundation under one or more agreements. The .NET
+# Foundation licenses this file to you under the MIT license. See the LICENSE
+# file in the project root for more information.
+################################################################################
+
+# This job packs the Logging package into NuGet and symbols packages and
+# publishes them as a named pipeline artifact.
+#
+# This template defines a job named 'pack_logging_package_job' that can be
+# depended on by downstream jobs.
+
+parameters:
+
+ # The name to apply to the published pipeline artifacts.
+ - name: loggingArtifactsName
+ type: string
+ default: Logging.Artifacts
+
+ # The assembly file version to stamp into the Logging DLLs.
+ - name: loggingAssemblyFileVersion
+ type: string
+
+ # The version to apply to the Logging NuGet package and its assemblies.
+ - name: loggingPackageVersion
+ type: string
+
+ # 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 list of upstream jobs to depend on.
+ - name: dependsOn
+ type: object
+ default: []
+
+ # The verbosity level for the dotnet CLI commands.
+ - name: dotnetVerbosity
+ type: string
+ default: normal
+ values:
+ - quiet
+ - minimal
+ - normal
+ - detailed
+ - diagnostic
+
+jobs:
+
+ - job: pack_logging_package_job
+ displayName: Pack Logging Package
+
+ dependsOn: ${{ parameters.dependsOn }}
+
+ pool:
+ name: Azure Pipelines
+ vmImage: ubuntu-latest
+
+ variables:
+
+ # The Logging project file to use for all dotnet CLI commands.
+ - name: project
+ value: src/Microsoft.Data.SqlClient.Extensions/Logging/src/Logging.csproj
+
+ # The directory where the NuGet packages will be staged before being
+ # published as pipeline artifacts.
+ - name: dotnetPackagesDir
+ value: $(Build.StagingDirectory)/dotnetPackages
+
+ # Explicitly unset the $PLATFORM environment variable that is set by the
+ # 'ADO Build properties' Library in the ADO SqlClientDrivers public project.
+ - 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'
+
+ # Install the .NET SDK.
+ - template: /eng/pipelines/steps/install-dotnet.yml@self
+ parameters:
+ debug: ${{ parameters.debug }}
+
+ # Create the NuGet packages.
+ - task: DotNetCoreCLI@2
+ displayName: Create NuGet Package
+ inputs:
+ command: pack
+ packagesToPack: $(project)
+ configurationToPack: ${{ parameters.buildConfiguration }}
+ packDirectory: $(dotnetPackagesDir)
+ verbosityToPack: ${{ parameters.dotnetVerbosity }}
+ buildProperties: LoggingPackageVersion=${{ parameters.loggingPackageVersion }};LoggingAssemblyFileVersion=${{ parameters.loggingAssemblyFileVersion }}
+
+ # Publish the NuGet packages as a named pipeline artifact.
+ - task: PublishPipelineArtifact@1
+ displayName: Publish Pipeline Artifact
+ inputs:
+ targetPath: $(dotnetPackagesDir)
+ artifactName: ${{ parameters.loggingArtifactsName }}
+ publishLocation: pipeline
diff --git a/eng/pipelines/jobs/test-abstractions-package-ci-job.yml b/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
index a5b9aabf32..25afd0afca 100644
--- a/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
+++ b/eng/pipelines/jobs/test-abstractions-package-ci-job.yml
@@ -20,7 +20,7 @@ parameters:
- Release
- Debug
- # True to enable extra debug steps and logging.
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
@@ -88,16 +88,11 @@ jobs:
- name: project
value: src/Microsoft.Data.SqlClient.Extensions/Abstractions/test/Abstractions.Test.csproj
- # dotnet CLI arguments common to all commands.
- - name: commonArguments
- value: >-
- --verbosity ${{ parameters.dotnetVerbosity }}
-
# dotnet CLI arguments for build/test/pack commands
- name: buildArguments
value: >-
- $(commonArguments)
--configuration ${{ parameters.buildConfiguration }}
+ --verbosity ${{ parameters.dotnetVerbosity }}
# Explicitly unset the $PLATFORM environment variable that is set by the
# 'ADO Build properties' Library in the ADO SqlClientDrivers public project.
@@ -137,34 +132,20 @@ jobs:
# The Windows agent images include a suitable .NET Framework runtime, so
# we don't have to install one explicitly.
- # We use the 'custom' command because the DotNetCoreCLI@2 task doesn't
- # support all of our argument combinations for the different build steps.
-
- # Restore the project.
- - task: DotNetCoreCLI@2
- displayName: Restore Project
- inputs:
- command: custom
- custom: restore
- projects: $(project)
- arguments: $(commonArguments)
-
# Build the project.
- task: DotNetCoreCLI@2
displayName: Build Project
inputs:
- command: custom
- custom: build
+ command: build
projects: $(project)
- arguments: $(buildArguments) --no-restore
+ arguments: $(buildArguments)
# Run the tests for each .NET runtime.
- ${{ each runtime in parameters.netRuntimes }}:
- task: DotNetCoreCLI@2
displayName: Test [${{ runtime }}]
inputs:
- command: custom
- custom: test
+ command: test
projects: $(project)
arguments: >-
$(buildArguments)
@@ -175,8 +156,7 @@ jobs:
- task: DotNetCoreCLI@2
displayName: Test Flaky [${{ runtime }}]
inputs:
- command: custom
- custom: test
+ command: test
projects: $(project)
arguments: >-
$(buildArguments)
@@ -189,8 +169,7 @@ jobs:
- task: DotNetCoreCLI@2
displayName: Test [${{ runtime }}]
inputs:
- command: custom
- custom: test
+ command: test
projects: $(project)
arguments: >-
$(buildArguments)
@@ -201,8 +180,7 @@ jobs:
- task: DotNetCoreCLI@2
displayName: Test Flaky [${{ runtime }}]
inputs:
- command: custom
- custom: test
+ command: test
projects: $(project)
arguments: >-
$(buildArguments)
diff --git a/eng/pipelines/jobs/test-azure-package-ci-job.yml b/eng/pipelines/jobs/test-azure-package-ci-job.yml
index 6948e5c81c..3289f1b54d 100644
--- a/eng/pipelines/jobs/test-azure-package-ci-job.yml
+++ b/eng/pipelines/jobs/test-azure-package-ci-job.yml
@@ -32,7 +32,7 @@ parameters:
- Release
- Debug
- # True to enable extra debug steps and logging.
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
@@ -86,16 +86,14 @@ parameters:
- name: poolName
type: string
- # The reference type to use:
- #
- # Project - dependent projects are referenced directly.
- # Package - dependent projects are referenced via NuGet packages.
- #
+ # The C# project reference type to use when building and packing the packages.
- name: referenceType
type: string
values:
- - Package
- - Project
+ # Reference sibling packages as NuGet packages.
+ - Package
+ # Reference sibling packages as C# projects.
+ - Project
# The SA password set by the sqlServerSetupSteps, if relevant.
- name: saPassword
@@ -141,20 +139,15 @@ jobs:
- name: project
value: src/Microsoft.Data.SqlClient.Extensions/Azure/test/Azure.Test.csproj
- # dotnet CLI arguments common to all commands.
- - name: commonArguments
+ # dotnet CLI arguments for build/test/pack commands.
+ - name: buildArguments
value: >-
+ --configuration ${{ parameters.buildConfiguration }}
--verbosity ${{ parameters.dotnetVerbosity }}
-p:ReferenceType=${{ parameters.referenceType }}
-p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
- # dotnet CLI arguments for build/test/pack commands.
- - name: buildArguments
- value: >-
- $(commonArguments)
- --configuration ${{ parameters.buildConfiguration }}
-
# Explicitly unset the $PLATFORM environment variable that is set by the
# 'ADO Build properties' Library in the ADO SqlClientDrivers public
# project. This is defined with a non-standard Platform of 'AnyCPU', and
@@ -244,26 +237,13 @@ jobs:
# Perform any local SQL Server setup.
- ${{ parameters.sqlServerSetupSteps }}
- # We use the 'custom' command because the DotNetCoreCLI@2 task doesn't
- # support all of our argument combinations for the different build steps.
-
- # Restore the project.
- - task: DotNetCoreCLI@2
- displayName: Restore Project
- inputs:
- command: custom
- custom: restore
- projects: $(project)
- arguments: $(commonArguments)
-
# Build the project.
- task: DotNetCoreCLI@2
displayName: Build Project
inputs:
- command: custom
- custom: build
+ command: build
projects: $(project)
- arguments: $(buildArguments) --no-restore
+ arguments: $(buildArguments)
# List the DLLs in the output directory for debugging purposes.
- ${{ if eq(parameters.debug, true) }}:
@@ -295,8 +275,7 @@ jobs:
#
# https://sqlclientdrivers.visualstudio.com/public/_settings/adminservices?resourceId=ec9623b2-829c-497f-ae1f-7461766f9a9c
connectedServiceName: dotnetMSI-managed-identity
- command: custom
- custom: test
+ command: test
projects: $(project)
arguments: >-
$(buildArguments)
@@ -314,8 +293,7 @@ jobs:
TEST_DEBUG_EMIT: 1
inputs:
connectedServiceName: dotnetMSI-managed-identity
- command: custom
- custom: test
+ command: test
projects: $(project)
arguments: >-
$(buildArguments)
@@ -335,8 +313,7 @@ jobs:
TEST_DEBUG_EMIT: 1
inputs:
connectedServiceName: dotnetMSI-managed-identity
- command: custom
- custom: test
+ command: test
projects: $(project)
arguments: >-
$(buildArguments)
@@ -354,8 +331,7 @@ jobs:
TEST_DEBUG_EMIT: 1
inputs:
connectedServiceName: dotnetMSI-managed-identity
- command: custom
- custom: test
+ command: test
projects: $(project)
arguments: >-
$(buildArguments)
diff --git a/eng/pipelines/libraries/build-variables.yml b/eng/pipelines/libraries/build-variables.yml
index 6bb5d224ee..6a267ac9fa 100644
--- a/eng/pipelines/libraries/build-variables.yml
+++ b/eng/pipelines/libraries/build-variables.yml
@@ -4,8 +4,18 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
-# This file is only included in MDS OneBranch Official pipelines.
+# Official build variable groups and shared variable templates.
+# Included transitively by onebranch-variables.yml in all OneBranch pipelines.
variables:
- group: Release Variables
+
+ # Symbols publishing credentials
+ - group: 'Symbols publishing'
+ # SymbolsAzureSubscription
+ # SymbolsPublishProjectName
+ # SymbolsPublishServer
+ # SymbolsPublishTokenUri
+ # SymbolsUploadAccount
+
- template: /eng/pipelines/libraries/common-variables.yml@self
diff --git a/eng/pipelines/libraries/ci-build-variables.yml b/eng/pipelines/libraries/ci-build-variables.yml
index f13c7154bc..6f93e5a292 100644
--- a/eng/pipelines/libraries/ci-build-variables.yml
+++ b/eng/pipelines/libraries/ci-build-variables.yml
@@ -5,27 +5,75 @@
#################################################################################
# This file is only included in PR and CI pipelines for the Abstractions, AKV,
-# Azure, and MDS projects.
+# Azure, Logging, and MDS projects.
variables:
- - group: 'ADO Build properties'
- - group: 'ADO Test Configuration Properties'
+ - group: ADO Build properties
+ - group: ADO Test Configuration Properties
- - name: buildNumber
- value: '$(Build.BuildNumber)'
- - name: SQLTarget
- value: 'localhost'
+ # C# assembly versions must be in the format: Major.Minor.Build.Revision, but
+ # $(Build.BuildNumber) has the format XXX.YY. Additionally, each version part
+ # must be a positive 16-bit integer less than 65535. Simply concatenating
+ # both parts of $(Build.BuildNumber) could produce values larger than 65534,
+ # so we must omit the second part entirely. Unfortunately, this may result
+ # in multiple subsequent pipline builds using the same C# assembly versions.
+ # The package versions will not be affected and will show the complete
+ # $(Build.BuildNumber) values.
+ - name: assemblyBuildNumber
+ value: $[ split(variables['Build.BuildNumber'], '.')[0] ]
+
+ # Abstractions library assembly file version
+ - name: abstractionsAssemblyFileVersion
+ value: 1.0.0.$(assemblyBuildNumber)
+
+ # Abstractions library NuGet package version
- name: abstractionsPackageVersion
- value: 1.0.0.$(buildNumber)-ci
+ value: 1.0.0.$(Build.BuildNumber)-ci
+
+ # AKV provider assembly file version
+ - name: akvAssemblyFileVersion
+ value: 7.0.0.$(assemblyBuildNumber)
+
+ # AKV provider NuGet package version
- name: akvPackageVersion
- value: 7.0.0.$(buildNumber)-ci
+ value: 7.0.0.$(Build.BuildNumber)-ci
+
+ # Azure library assembly file version
+ - name: azureAssemblyFileVersion
+ value: 1.0.0.$(assemblyBuildNumber)
+
+ # Azure library NuGet package version
- name: azurePackageVersion
- value: 1.0.0.$(buildNumber)-ci
+ value: 1.0.0.$(Build.BuildNumber)-ci
+
+ # Logging library assembly file version
+ - name: loggingAssemblyFileVersion
+ value: 1.0.0.$(assemblyBuildNumber)
+
+ # Logging library NuGet package version
+ - name: loggingPackageVersion
+ value: 1.0.0.$(Build.BuildNumber)-ci
+
+ # MDS library assembly file version
+ - name: mdsAssemblyFileVersion
+ value: 7.0.0.$(assemblyBuildNumber)
+
+ # MDS library NuGet package version
- name: mdsPackageVersion
- value: 7.0.0.$(buildNumber)-ci
- - name: skipComponentGovernanceDetection
- value: true
+ value: 7.0.0.$(Build.BuildNumber)-ci
+
+ # Output path for built NuGet packages
+ - name: packagePath
+ value: $(Build.SourcesDirectory)/packages
+
+ # Disable codesign validation injection for CI builds
- name: runCodesignValidationInjection
value: false
- - name: packagePath
- value: '$(Build.SourcesDirectory)/packages'
+
+ # Skip component governance detection for CI builds
+ - name: skipComponentGovernanceDetection
+ value: true
+
+ # SQL Server target host for testing
+ - name: SQLTarget
+ value: localhost
diff --git a/eng/pipelines/libraries/common-variables.yml b/eng/pipelines/libraries/common-variables.yml
index 1d241c1c05..4037feea25 100644
--- a/eng/pipelines/libraries/common-variables.yml
+++ b/eng/pipelines/libraries/common-variables.yml
@@ -4,8 +4,8 @@
# See the LICENSE file in the project root for more information. #
#################################################################################
-# This file is only included in Abstractions, Azure, and MDS OneBranch Official
-# pipelines.
+# Common variables shared across all OneBranch Official pipelines.
+# Included transitively by build-variables.yml -> onebranch-variables.yml.
variables:
- group: ESRP Federated Creds (AME)
@@ -18,14 +18,24 @@ variables:
- name: CommitHead
value: '' # the value will be extracted from the repo's head
- - name: REPOROOT
+
+ # Aliases required by compound step templates (compound-esrp-dll-signing-step,
+ # compound-esrp-nuget-signing-step, compound-nuget-pack-step, etc.).
+
+ # The root of our repo.
+ - name: REPO_ROOT
value: $(Build.SourcesDirectory)
- - name: softwareFolder
- value: $(REPOROOT)/software
- - name: symbolsFolder
- value: $(REPOROOT)/symbols
- - name: artifactDirectory
- value: '$(REPOROOT)/packages'
+
+ # This is where our C# projects place their build outputs (see Directory.Build.props
+ # ). We exclude the reference type here since Official pipelines always use
+ # Package mode.
+ - name: BUILD_OUTPUT
+ value: $(REPO_ROOT)/artifacts
+
+ # THis is where our C# projects place their NuGet package outputs (see Directory.Build.props
+ # ).
+ - name: PACK_OUTPUT
+ value: $(REPO_ROOT)/packages
# C# assembly versions must be in the format: Major.Minor.Build.Revision, but
# $(Build.BuildNumber) has the format XXX.YY. Additionally, each version part
@@ -76,7 +86,25 @@ variables:
# The path to the NuGet packaging specification file used to generate the MDS NuGet package.
- name: nuspecPath
- value: '$(REPOROOT)/tools/specs/Microsoft.Data.SqlClient.nuspec'
+ value: '$(REPO_ROOT)/tools/specs/Microsoft.Data.SqlClient.nuspec'
+
+ # ----------------------------------------------------------------------------
+ # Logging Package Versions
+ #
+ # These are version values that will be used by the official build. They
+ # should be updated after each release to reflect the next release's versions.
+
+ # The NuGet package version for GA releases (non-preview).
+ - name: loggingPackageVersion
+ value: '1.0.0'
+
+ # The NuGet package version for preview releases.
+ - name: loggingPackagePreviewVersion
+ value: 1.0.0-preview1.$(Build.BuildNumber)
+
+ # The AssemblyFileVersion for all assemblies in the Logging package.
+ - name: loggingAssemblyFileVersion
+ value: 1.0.0.$(assemblyBuildNumber)
# ----------------------------------------------------------------------------
# Azure Package Versions
@@ -95,3 +123,67 @@ variables:
# The AssemblyFileVersion for all assemblies in the Azure package.
- name: azureAssemblyFileVersion
value: 1.0.0.$(assemblyBuildNumber)
+
+ # ----------------------------------------------------------------------------
+ # SqlServer.Server Package Versions
+ #
+ # These are version values that will be used by the official build. They
+ # should be updated after each release to reflect the next release's versions.
+
+ # The NuGet package version for GA releases (non-preview).
+ - name: sqlServerPackageVersion
+ value: '1.0.0'
+
+ # The NuGet package version for preview releases.
+ - name: sqlServerPackagePreviewVersion
+ value: 1.0.0-preview1.$(Build.BuildNumber)
+
+ # The AssemblyFileVersion for all assemblies in the SqlServer.Server package.
+ - name: sqlServerAssemblyFileVersion
+ value: 1.0.0.$(assemblyBuildNumber)
+
+ # ----------------------------------------------------------------------------
+ # AKV Provider Package Versions
+ #
+ # These are version values that will be used by the official build. They
+ # should be updated after each release to reflect the next release's versions.
+
+ # The NuGet package version for GA releases (non-preview).
+ - name: akvPackageVersion
+ value: '7.0.0'
+
+ # The NuGet package version for preview releases.
+ - name: akvPackagePreviewVersion
+ value: 7.0.0-preview1.$(Build.BuildNumber)
+
+ # The AssemblyFileVersion for all assemblies in the AKV Provider package.
+ - name: akvAssemblyFileVersion
+ value: 7.0.0.$(assemblyBuildNumber)
+
+ # The MDS package version that AKV Provider depends on.
+ - name: akvMdsPackageVersion
+ value: '7.0.0-preview4.$(Build.BuildNumber)'
+
+ # The path to the NuGet packaging specification file for the AKV Provider.
+ - name: akvNuspecPath
+ value: '$(REPO_ROOT)/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec'
+
+ # ----------------------------------------------------------------------------
+ # MDS Symbols Publishing
+ #
+ # Alias variables for MDS publish-symbols-step.yml, which defaults to
+ # $(SymbolServer) and $(SymbolTokenUri). These map to the values provided
+ # by the akv-variables-v2 variable group.
+ - name: SymbolServer
+ value: $(SymbolsPublishServer)
+ - name: SymbolTokenUri
+ value: $(SymbolsPublishTokenUri)
+
+ # ----------------------------------------------------------------------------
+ # Release Variables
+ #
+ # NuGet service connection used by the release stage to push packages.
+ # This should match the name of an ADO service connection configured with
+ # NuGet.org credentials (API key or federated auth).
+ - name: NuGetServiceConnection
+ value: 'NuGet-Org-ServiceConnection'
diff --git a/eng/pipelines/libraries/onebranch-variables.yml b/eng/pipelines/libraries/onebranch-variables.yml
new file mode 100644
index 0000000000..dd52ca32dd
--- /dev/null
+++ b/eng/pipelines/libraries/onebranch-variables.yml
@@ -0,0 +1,55 @@
+#################################################################################
+# 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 file is only included in MDS OneBranch Official pipelines.
+
+variables:
+ - template: /eng/pipelines/libraries/build-variables.yml@self
+
+ # onebranch template variables
+ - name: ob_sdl_binskim_break
+ value: true # https://aka.ms/obpipelines/sdl
+ - name: Packaging.EnableSBOMSigning
+ value: true
+ - name: WindowsContainerImage
+ value: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest' # Docker image which is used to build the project https://aka.ms/obpipelines/containers
+
+ # OneBranch automatically publishes pipeline artifacts from all jobs. Use of the
+ # PublishPipelineArtifacts task is prohibited. All content in the ob_outputDirectory is
+ # published. The artifacts are named according to this pattern:
+ #
+ # drop__
+ #
+ # Downstream stages and jobs may download these artifacts via the DownloadPipelineArtifact task,
+ # but they must know the artifact name.
+ #
+ # Here we define the artifact names that our OneBranch pipelines produce to avoid hardcoding them
+ # throughout the pipeline files. If any of the stage or job names change, we only need to update
+ # the artifact names here.
+
+ # The Abstractions package artifacts.
+ - name: abstractionsArtifactsName
+ value: drop_build_independent_build_package_Abstractions
+
+ # The AKV package artifacts.
+ - name: akvArtifactsName
+ value: drop_build_dependent_build_package_AKV
+
+ # The Azure package artifacts.
+ - name: azureArtifactsName
+ value: drop_build_dependent_build_package_Azure
+
+ # The Logging package artifacts.
+ - name: loggingArtifactsName
+ value: drop_build_independent_build_package_Logging
+
+ # The SqlServer package artifacts.
+ - name: sqlServerArtifactsName
+ value: drop_build_independent_build_package_SqlServer
+
+ # The SqlClient package artifacts.
+ - name: sqlClientArtifactsName
+ value: drop_build_dependent_build_package_SqlClient
diff --git a/eng/pipelines/libraries/variables.yml b/eng/pipelines/libraries/variables.yml
deleted file mode 100644
index 63181ffd84..0000000000
--- a/eng/pipelines/libraries/variables.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-#################################################################################
-# Licensed to the .NET Foundation under one or more agreements. #
-# The .NET Foundation licenses this file to you under the MIT license. #
-# See the LICENSE file in the project root for more information. #
-#################################################################################
-
-# This file is only included in MDS OneBranch Official pipelines.
-
-variables:
- - template: /eng/pipelines/libraries/build-variables.yml@self
- # onebranch template variables
- - name: ob_outputDirectory
- value: '$(artifactDirectory)' # this directory is uploaded to pipeline artifacts, reddog and cloudvault. More info at https://aka.ms/obpipelines/artifacts
- - name: ob_sdl_binskim_break
- value: true # https://aka.ms/obpipelines/sdl
- - name: Packaging.EnableSBOMSigning
- value: true
- - name: WindowsContainerImage
- value: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest' # Docker image which is used to build the project https://aka.ms/obpipelines/containers
diff --git a/eng/pipelines/sqlclient-pr-package-ref-pipeline.yml b/eng/pipelines/sqlclient-pr-package-ref-pipeline.yml
index 5b5647d200..0955a6affa 100644
--- a/eng/pipelines/sqlclient-pr-package-ref-pipeline.yml
+++ b/eng/pipelines/sqlclient-pr-package-ref-pipeline.yml
@@ -52,7 +52,7 @@ trigger: none
# Pipeline parameters, visible in the Azure DevOps UI.
parameters:
- # The build configuration to use; defaults to Debug.
+ # The C# build configuration to use; defaults to Debug.
- name: buildConfiguration
displayName: Build Configuration
type: string
@@ -66,11 +66,13 @@ parameters:
type: object
default: [AnyCPU]
+ # True to emit debug information and steps.
- name: debug
displayName: Enable debug output
type: boolean
default: false
+ # True to run the stress tests stage.
- name: enableStressTests
displayName: Enable Stress Tests
type: boolean
diff --git a/eng/pipelines/sqlclient-pr-project-ref-pipeline.yml b/eng/pipelines/sqlclient-pr-project-ref-pipeline.yml
index aa990772be..bf971861b2 100644
--- a/eng/pipelines/sqlclient-pr-project-ref-pipeline.yml
+++ b/eng/pipelines/sqlclient-pr-project-ref-pipeline.yml
@@ -52,7 +52,7 @@ trigger: none
# Pipeline parameters, visible in the Azure DevOps UI.
parameters:
- # The build configuration to use; defaults to Debug.
+ # The C# build configuration to use; defaults to Debug.
- name: buildConfiguration
displayName: Build Configuration
type: string
@@ -66,11 +66,13 @@ parameters:
type: object
default: [AnyCPU]
+ # True to emit debug information and steps.
- name: debug
displayName: Enable debug output
type: boolean
default: false
+ # True to run the stress tests stage.
- name: enableStressTests
displayName: Enable Stress Tests
type: boolean
diff --git a/eng/pipelines/stages/build-abstractions-package-ci-stage.yml b/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
index 5ac36d7d6c..6aae1703b8 100644
--- a/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
+++ b/eng/pipelines/stages/build-abstractions-package-ci-stage.yml
@@ -30,10 +30,19 @@ parameters:
type: string
default: Abstractions.Artifacts
+ # The assembly file version to stamp into the DLLs.
+ - name: abstractionsAssemblyFileVersion
+ type: string
+
# The version to apply to the NuGet package and DLLs.
- name: abstractionsPackageVersion
type: string
+ # Additional stages we depend on, if any.
+ - name: additionalDependsOn
+ type: object
+ default: []
+
# The type of build to produce (Release or Debug)
- name: buildConfiguration
type: string
@@ -42,7 +51,7 @@ parameters:
- Release
- Debug
- # True to enable extra debug steps and logging.
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
@@ -63,6 +72,11 @@ stages:
- stage: build_abstractions_package_stage
displayName: Build Abstractions Package
+ dependsOn:
+ - secrets_stage
+ - ${{ each dep in parameters.additionalDependsOn }}:
+ - ${{ dep }}
+
jobs:
# ------------------------------------------------------------------------
@@ -116,6 +130,7 @@ stages:
- template: /eng/pipelines/jobs/pack-abstractions-package-ci-job.yml@self
parameters:
abstractionsArtifactsName: ${{ parameters.abstractionsArtifactsName }}
+ abstractionsAssemblyFileVersion: ${{ parameters.abstractionsAssemblyFileVersion }}
abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
buildConfiguration: ${{ parameters.buildConfiguration }}
debug: ${{ parameters.debug }}
diff --git a/eng/pipelines/stages/build-azure-package-ci-stage.yml b/eng/pipelines/stages/build-azure-package-ci-stage.yml
index c9f135f731..3b57ce8c3b 100644
--- a/eng/pipelines/stages/build-azure-package-ci-stage.yml
+++ b/eng/pipelines/stages/build-azure-package-ci-stage.yml
@@ -63,6 +63,10 @@ parameters:
type: string
default: Azure.Artifacts
+ # The assembly file version to stamp into the DLLs.
+ - name: azureAssemblyFileVersion
+ type: string
+
# The version to apply to the NuGet package and DLLs.
- name: azurePackageVersion
type: string
@@ -81,7 +85,7 @@ parameters:
- Release
- Debug
- # True to enable extra debug steps and logging.
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
@@ -110,16 +114,14 @@ parameters:
- name: mdsPackageVersion
type: string
- # The reference type to use:
- #
- # Project - dependent projects are referenced directly.
- # Package - dependent projects are referenced via NuGet packages.
- #
+ # The C# project reference type to use when building and packing the packages.
- name: referenceType
type: string
values:
- - Package
- - Project
+ # Reference sibling packages as NuGet packages.
+ - Package
+ # Reference sibling packages as C# projects.
+ - Project
stages:
@@ -267,6 +269,7 @@ stages:
abstractionsArtifactsName: ${{ parameters.abstractionsArtifactsName }}
abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
azureArtifactsName: ${{ parameters.azureArtifactsName }}
+ azureAssemblyFileVersion: ${{ parameters.azureAssemblyFileVersion }}
azurePackageVersion: ${{ parameters.azurePackageVersion }}
buildConfiguration: ${{ parameters.buildConfiguration }}
debug: ${{ parameters.debug }}
diff --git a/eng/pipelines/stages/build-logging-package-ci-stage.yml b/eng/pipelines/stages/build-logging-package-ci-stage.yml
new file mode 100644
index 0000000000..8ca9928bb7
--- /dev/null
+++ b/eng/pipelines/stages/build-logging-package-ci-stage.yml
@@ -0,0 +1,95 @@
+################################################################################
+# Licensed to the .NET Foundation under one or more agreements. The .NET
+# Foundation licenses this file to you under the MIT license. See the LICENSE
+# file in the project root for more information.
+################################################################################
+
+# This stage builds the Logging package and publishes the resulting NuGet
+# packages as pipeline artifacts.
+#
+# The NuGet packages have the following properties:
+#
+# Name: Microsoft.Data.SqlClient.Extensions.Logging
+# Version: (from parameter)
+#
+# The following NuGet packages are published:
+#
+# Microsoft.Data.SqlClient.Extensions.Logging..nupkg
+# Microsoft.Data.SqlClient.Extensions.Logging..snupkg (symbols)
+#
+# The packages are published to pipeline artifacts with the name specified by
+# the loggingArtifactsName parameter.
+#
+# This template defines a stage named 'build_logging_package_stage' that
+# can be depended on by downstream stages.
+
+parameters:
+
+ # Additional stages we depend on, if any.
+ - name: additionalDependsOn
+ type: object
+ default: []
+
+ # The name of the pipeline artifacts to publish.
+ - name: loggingArtifactsName
+ type: string
+ default: Logging.Artifacts
+
+ # The assembly file version to stamp into the DLLs.
+ - name: loggingAssemblyFileVersion
+ type: string
+
+ # The version to apply to the NuGet package and DLLs.
+ - name: loggingPackageVersion
+ type: string
+
+ # The type of build to produce (Release or Debug)
+ - name: buildConfiguration
+ type: string
+ default: Release
+ values:
+ - Release
+ - Debug
+
+ # True to emit debug information and steps.
+ - name: debug
+ type: boolean
+ default: false
+
+ # The verbosity level for the dotnet CLI commands.
+ - name: dotnetVerbosity
+ type: string
+ default: normal
+ values:
+ - quiet
+ - minimal
+ - normal
+ - detailed
+ - diagnostic
+
+stages:
+
+ - stage: build_logging_package_stage
+ displayName: Build Logging Package
+
+ dependsOn:
+ - secrets_stage
+ - ${{ each dep in parameters.additionalDependsOn }}:
+ - ${{ dep }}
+
+ jobs:
+
+ # 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:
+ loggingArtifactsName: ${{ parameters.loggingArtifactsName }}
+ loggingAssemblyFileVersion: ${{ parameters.loggingAssemblyFileVersion }}
+ loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ debug: ${{ parameters.debug }}
+ dotnetVerbosity: ${{ parameters.dotnetVerbosity }}
diff --git a/eng/pipelines/stages/build-sqlclient-package-ci-stage.yml b/eng/pipelines/stages/build-sqlclient-package-ci-stage.yml
new file mode 100644
index 0000000000..abea56f1cd
--- /dev/null
+++ b/eng/pipelines/stages/build-sqlclient-package-ci-stage.yml
@@ -0,0 +1,99 @@
+################################################################################
+# Licensed to the .NET Foundation under one or more agreements. The .NET
+# Foundation licenses this file to you under the MIT license. See the LICENSE
+# file in the project root for more information.
+################################################################################
+
+# This stage builds the SqlClient (MDS) package (and for legacy reasons, the AKV NuGet package as
+# well) and publishes them as pipeline artifacts.
+#
+# This template defines a stage named 'build_sqlclient_package_stage' that can be depended on by
+# downstream stages.
+
+parameters:
+
+ # The name of the Abstractions pipeline artifacts to download.
+ - name: abstractionsArtifactsName
+ type: string
+ default: Abstractions.Artifacts
+
+ # The Abstractions package version.
+ - name: abstractionsPackageVersion
+ type: string
+
+ # Additional stages we depend on, if any.
+ - name: additionalDependsOn
+ type: object
+ default: []
+
+ # Build Configuration.
+ - name: buildConfiguration
+ type: string
+ values:
+ - Debug
+ - Release
+
+ # The name of the Logging pipeline artifacts to download.
+ - name: loggingArtifactsName
+ type: string
+ default: Logging.Artifacts
+
+ # The Logging package version.
+ - name: loggingPackageVersion
+ type: string
+
+ # The name of the MDS pipeline artifacts to publish.
+ - name: mdsArtifactsName
+ type: string
+ default: MDS.Artifacts
+
+ # The MDS package version.
+ - name: mdsPackageVersion
+ type: string
+
+ # The C# project reference type to use when building and packing the packages.
+ - name: referenceType
+ type: string
+ values:
+ # Reference sibling packages as NuGet packages.
+ - Package
+ # Reference sibling packages as C# projects.
+ - Project
+
+ # SNI Version Override.
+ - name: SNIVersion
+ type: string
+ default: ''
+
+ # SNI Version Override NuGet Feed.
+ - name: SNIValidationFeed
+ type: string
+ default: ''
+
+stages:
+
+ - stage: build_sqlclient_package_stage
+ displayName: Build MDS & AKV Packages
+
+ dependsOn:
+ - secrets_stage
+ - ${{ each dep in parameters.additionalDependsOn }}:
+ - ${{ dep }}
+
+ jobs:
+ - template: /eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml@self
+ parameters:
+ buildConfiguration: ${{ parameters.buildConfiguration }}
+ referenceType: ${{ parameters.referenceType }}
+ abstractionsPackageVersion: ${{ parameters.abstractionsPackageVersion }}
+ abstractionsArtifactsName: ${{ parameters.abstractionsArtifactsName }}
+ loggingPackageVersion: ${{ parameters.loggingPackageVersion }}
+ loggingArtifactsName: ${{ parameters.loggingArtifactsName }}
+ mdsPackageVersion: ${{ parameters.mdsPackageVersion }}
+ mdsArtifactsName: ${{ parameters.mdsArtifactsName }}
+ ${{ if ne(parameters.SNIVersion, '') }}:
+ prebuildSteps:
+ - template: /eng/pipelines/common/templates/steps/override-sni-version.yml@self
+ parameters:
+ SNIVersion: ${{ parameters.SNIVersion }}
+ SNIValidationFeed: ${{ parameters.SNIValidationFeed }}
diff --git a/eng/pipelines/stages/generate-secrets-ci-stage.yml b/eng/pipelines/stages/generate-secrets-ci-stage.yml
index 507e18d279..26d7d3b925 100644
--- a/eng/pipelines/stages/generate-secrets-ci-stage.yml
+++ b/eng/pipelines/stages/generate-secrets-ci-stage.yml
@@ -26,7 +26,7 @@
#
parameters:
- # True to emit debugging steps and messages.
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
diff --git a/eng/pipelines/stages/sqlclient-onebranch-stages.yml b/eng/pipelines/stages/sqlclient-onebranch-stages.yml
new file mode 100644
index 0000000000..5b3b88e210
--- /dev/null
+++ b/eng/pipelines/stages/sqlclient-onebranch-stages.yml
@@ -0,0 +1,453 @@
+#################################################################################
+# 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. #
+#################################################################################
+#
+# Unified stages template for dotnet-sqlclient OneBranch pipelines.
+# Consumed by both the official and non-official pipeline definitions via:
+#
+# stages:
+# - template: /eng/pipelines/sqlclient-onebranch-stages.yml@self
+# parameters:
+# isOfficial: true # or false
+# ...
+#
+# The `isOfficial` flag controls release-stage behaviour:
+# - Official → Production environment, approval gate, dryRun parameter
+# - Non-Official → Test environment, dry-run always enforced
+#
+
+parameters:
+
+ # ── General parameters ─────────────────────────────────────────────────
+
+ # True to enable debug information and steps.
+ - name: debug
+ type: boolean
+
+ # True for a OneBranch Official pipeline, false for a Non-Official pipeline.
+ - name: isOfficial
+ type: boolean
+
+ # True if this is a preview build, which uses the preview version numbers from
+ # common-variables.yml.
+ - name: isPreview
+ type: boolean
+
+ # True to publish symbols to public and private servers.
+ - name: publishSymbols
+ type: boolean
+
+ # True for this to be a dry-run of the release portion of the pipeline. A dry run will ask
+ # for approvals and list the packages that would be released.
+ #
+ # When false, a release will actually push packages to NuGet.
+ #
+ - name: releaseDryRun
+ displayName: "Release Dry Run (do not push to NuGet)"
+ type: boolean
+ default: true
+
+ # The timeout, in minutes, for each test job.
+ - name: testJobTimeout
+ type: number
+
+ # ── Build parameters ───────────────────────────────────────────────────
+
+ - name: buildSqlServerServer
+ type: boolean
+
+ - name: buildSqlClient
+ type: boolean
+
+ - name: buildAKVProvider
+ type: boolean
+
+ # ── Release parameters ─────────────────────────────────────────────────
+
+ - name: releaseSqlServerServer
+ type: boolean
+
+ - name: releaseLogging
+ type: boolean
+
+ - name: releaseAbstractions
+ type: boolean
+
+ - name: releaseSqlClient
+ type: boolean
+
+ - name: releaseExtAzure
+ type: boolean
+
+ - name: releaseAKVProvider
+ type: boolean
+
+stages:
+ # ====================================================================
+ # Stage 1: Independent packages (no cross-package dependencies)
+ # Logging, Abstractions, and SqlServer.Server build in parallel.
+ # ====================================================================
+ - stage: build_independent
+ displayName: "Build Independent Packages"
+
+ variables:
+ # Resolved package versions: use preview versions when isPreview is true
+ - ${{ if parameters.isPreview }}:
+ - name: effectiveLoggingVersion
+ value: $(loggingPackagePreviewVersion)
+ - name: effectiveAbstractionsVersion
+ value: $(abstractionsPackagePreviewVersion)
+ - name: effectiveSqlServerVersion
+ value: $(sqlServerPackagePreviewVersion)
+ - ${{ else }}:
+ - name: effectiveLoggingVersion
+ value: $(loggingPackageVersion)
+ - name: effectiveAbstractionsVersion
+ value: $(abstractionsPackageVersion)
+ - name: effectiveSqlServerVersion
+ value: $(sqlServerPackageVersion)
+
+ jobs:
+ - ${{ if or(eq(parameters.buildAKVProvider, true), eq(parameters.buildSqlClient, true)) }}:
+ - template: /eng/pipelines/jobs/build-signed-csproj-package-job.yml@self
+ parameters:
+ packageName: Logging
+ packageFullName: Microsoft.Data.SqlClient.Extensions.Logging
+ packageVersion: $(effectiveLoggingVersion)
+ versionProperties: >-
+ -p:LoggingPackageVersion=$(effectiveLoggingVersion)
+ -p:LoggingAssemblyFileVersion=$(loggingAssemblyFileVersion)
+ assemblyFileVersion: $(loggingAssemblyFileVersion)
+ publishSymbols: ${{ parameters.publishSymbols }}
+ esrpConnectedServiceName: $(ESRPConnectedServiceName)
+ esrpClientId: $(ESRPClientId)
+ appRegistrationClientId: $(AppRegistrationClientId)
+ appRegistrationTenantId: $(AppRegistrationTenantId)
+ authAkvName: $(AuthAKVName)
+ authSignCertName: $(AuthSignCertName)
+
+ - ${{ if eq(parameters.buildSqlClient, true) }}:
+ - template: /eng/pipelines/jobs/build-signed-csproj-package-job.yml@self
+ parameters:
+ packageName: Abstractions
+ packageFullName: Microsoft.Data.SqlClient.Extensions.Abstractions
+ packageVersion: $(effectiveAbstractionsVersion)
+ versionProperties: >-
+ -p:AbstractionsPackageVersion=$(effectiveAbstractionsVersion)
+ -p:AbstractionsAssemblyFileVersion=$(abstractionsAssemblyFileVersion)
+ assemblyFileVersion: $(abstractionsAssemblyFileVersion)
+ publishSymbols: ${{ parameters.publishSymbols }}
+ esrpConnectedServiceName: $(ESRPConnectedServiceName)
+ esrpClientId: $(ESRPClientId)
+ appRegistrationClientId: $(AppRegistrationClientId)
+ appRegistrationTenantId: $(AppRegistrationTenantId)
+ authAkvName: $(AuthAKVName)
+ authSignCertName: $(AuthSignCertName)
+
+ - ${{ if eq(parameters.buildSqlServerServer, true) }}:
+ - template: /eng/pipelines/jobs/build-signed-csproj-package-job.yml@self
+ parameters:
+ packageName: SqlServer
+ packageFullName: Microsoft.SqlServer.Server
+ packageVersion: $(effectiveSqlServerVersion)
+ versionProperties: >-
+ -p:SqlServerAssemblyFileVersion=$(sqlServerAssemblyFileVersion)
+ -p:SqlServerPackageVersion=$(effectiveSqlServerVersion)
+ assemblyFileVersion: $(sqlServerAssemblyFileVersion)
+ publishSymbols: ${{ parameters.publishSymbols }}
+ esrpConnectedServiceName: $(ESRPConnectedServiceName)
+ esrpClientId: $(ESRPClientId)
+ appRegistrationClientId: $(AppRegistrationClientId)
+ appRegistrationTenantId: $(AppRegistrationTenantId)
+ authAkvName: $(AuthAKVName)
+ authSignCertName: $(AuthSignCertName)
+
+ # ====================================================================
+ # Stage 2: Core packages (depend on independent packages)
+ # MDS and Extensions.Azure build in parallel after Stage 1 completes.
+ # Stage name kept as 'build_dependent' for validate job compatibility.
+ # ====================================================================
+ - ${{ if eq(parameters.buildSqlClient, true) }}:
+ - stage: build_dependent
+ displayName: "Build Core Packages"
+ dependsOn: build_independent
+
+ variables:
+ # Resolved package versions: use preview versions when isPreview is true
+ - ${{ if parameters.isPreview }}:
+ - name: effectiveLoggingVersion
+ value: $(loggingPackagePreviewVersion)
+ - name: effectiveAbstractionsVersion
+ value: $(abstractionsPackagePreviewVersion)
+ - name: effectiveAzureVersion
+ value: $(azurePackagePreviewVersion)
+ - name: effectiveSqlServerVersion
+ value: $(sqlServerPackagePreviewVersion)
+ - name: effectiveMdsVersion
+ value: $(previewMdsPackageVersion)
+ - ${{ else }}:
+ - name: effectiveLoggingVersion
+ value: $(loggingPackageVersion)
+ - name: effectiveAbstractionsVersion
+ value: $(abstractionsPackageVersion)
+ - name: effectiveAzureVersion
+ value: $(azurePackageVersion)
+ - name: effectiveSqlServerVersion
+ value: $(sqlServerPackageVersion)
+ - name: effectiveMdsVersion
+ value: $(mdsPackageVersion)
+
+ jobs:
+ - template: /eng/pipelines/common/templates/jobs/build-signed-package-job.yml@self
+ parameters:
+ publishSymbols: ${{ parameters.publishSymbols }}
+ isPreview: ${{ parameters.isPreview }}
+ # TODO: This job should use the effective versions for Abstractions, Logging,
+ # SqlServer, and SqlClient.
+
+ - template: /eng/pipelines/jobs/build-signed-csproj-package-job.yml@self
+ parameters:
+ packageName: Azure
+ packageFullName: Microsoft.Data.SqlClient.Extensions.Azure
+ packageVersion: $(effectiveAzureVersion)
+ versionProperties: >-
+ -p:AzurePackageVersion=$(effectiveAzureVersion)
+ -p:AzureAssemblyFileVersion=$(azureAssemblyFileVersion)
+ -p:AbstractionsPackageVersion=$(effectiveAbstractionsVersion)
+ assemblyFileVersion: $(azureAssemblyFileVersion)
+ publishSymbols: ${{ parameters.publishSymbols }}
+ esrpConnectedServiceName: $(ESRPConnectedServiceName)
+ esrpClientId: $(ESRPClientId)
+ appRegistrationClientId: $(AppRegistrationClientId)
+ appRegistrationTenantId: $(AppRegistrationTenantId)
+ authAkvName: $(AuthAKVName)
+ authSignCertName: $(AuthSignCertName)
+
+ # ====================================================================
+ # Stage 3: Add-on packages (depend on core packages)
+ # AKV Provider builds after MDS completes.
+ # ====================================================================
+ - ${{ if and(eq(parameters.buildAKVProvider, true), eq(parameters.buildSqlClient, true)) }}:
+ - stage: build_addons
+ displayName: "Build Add-on Packages"
+ dependsOn: build_dependent
+
+ variables:
+ # Legacy AKV job variables; to be replaced with ob_sdl_apiscan_* variables within the job
+ # definition itself, like the other job templates to.
+ - name: PACKAGE_NAME
+ value: "Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider"
+ - name: apiScanDllPath
+ value: "$(Build.SourcesDirectory)/apiScan/dlls"
+ - name: apiScanPdbPath
+ value: "$(Build.SourcesDirectory)/apiScan/pdbs"
+
+ # Resolved package versions: use preview versions when isPreview is true
+ - ${{ if parameters.isPreview }}:
+ - name: effectiveLoggingVersion
+ value: $(loggingPackagePreviewVersion)
+ - name: effectiveAbstractionsVersion
+ value: $(abstractionsPackagePreviewVersion)
+ - name: effectiveSqlServerVersion
+ value: $(sqlServerPackagePreviewVersion)
+ - name: effectiveAkvVersion
+ value: $(akvPackagePreviewVersion)
+ - name: effectiveMdsVersion
+ value: $(previewMdsPackageVersion)
+ - ${{ else }}:
+ - name: effectiveLoggingVersion
+ value: $(loggingPackageVersion)
+ - name: effectiveAbstractionsVersion
+ value: $(abstractionsPackageVersion)
+ - name: effectiveSqlServerVersion
+ value: $(sqlServerPackageVersion)
+ - name: effectiveAkvVersion
+ value: $(akvPackageVersion)
+ - name: effectiveMdsVersion
+ value: $(mdsPackageVersion)
+
+ jobs:
+ - template: /eng/pipelines/jobs/build-akv-official-job.yml@self
+ parameters:
+ akvAssemblyFileVersion: $(akvAssemblyFileVersion)
+ akvPackageVersion: $(effectiveAkvVersion)
+ apiScanDllPath: $(apiScanDllPath)
+ apiScanPdbPath: $(apiScanPdbPath)
+ buildConfiguration: Release
+ mdsPackageVersion: $(effectiveMdsVersion)
+ loggingPackageVersion: $(effectiveLoggingVersion)
+ abstractionsPackageVersion: $(effectiveAbstractionsVersion)
+ publishSymbols: ${{ parameters.publishSymbols }}
+ appRegistrationClientId: $(appRegistrationClientId)
+ appRegistrationTenantId: $(appRegistrationTenantId)
+ authAkvName: $(AuthAkvName)
+ authSignCertName: $(AuthSignCertName)
+ esrpClientId: $(EsrpClientId)
+ esrpConnectedServiceName: $(EsrpConnectedServiceName)
+ symbolsAzureSubscription: $(SymbolsAzureSubscription)
+ symbolsPublishProjectName: $(SymbolsPublishProjectName)
+ symbolsPublishServer: $(SymbolsPublishServer)
+ symbolsPublishTokenUri: $(SymbolsPublishTokenUri)
+ symbolsUploadAccount: $(SymbolsUploadAccount)
+
+ # ====================================================================
+ # Validation
+ # ====================================================================
+ - ${{ if eq(parameters.buildSqlClient, true) }}:
+ - stage: mds_package_validation
+ displayName: "MDS Package Validation"
+ dependsOn: build_dependent
+ jobs:
+ - template: /eng/pipelines/common/templates/jobs/validate-signed-package-job.yml@self
+ parameters:
+ artifactName: $(sqlClientArtifactsName)
+ isPreview: ${{ parameters.isPreview }}
+
+ # ====================================================================
+ # Release Stage — on-demand selective publish to NuGet
+ #
+ # Compile-time conditional: stage is removed entirely when no release
+ # parameters are selected, avoiding OneBranch validation errors.
+ #
+ # Official pipeline → Production environment, approval gate,
+ # dryRun controlled by releaseDryRun parameter.
+ # Non-official pipeline → Test/DryRun environment, dryRun always true.
+ # ====================================================================
+ - ${{ if or(parameters.releaseSqlServerServer, parameters.releaseLogging, parameters.releaseAbstractions, parameters.releaseSqlClient, parameters.releaseExtAzure, parameters.releaseAKVProvider) }}:
+ # ── Official (Production) release ────────────────────────────────
+ - ${{ if eq(parameters.isOfficial, true) }}:
+ - stage: Production_Release
+ displayName: "Release to NuGet"
+ dependsOn:
+ - ${{ if or(parameters.releaseSqlServerServer, parameters.releaseLogging, parameters.releaseAbstractions) }}:
+ - build_independent
+ - ${{ if or(parameters.releaseSqlClient, parameters.releaseExtAzure) }}:
+ - build_dependent
+ - mds_package_validation
+ - ${{ if parameters.releaseAKVProvider }}:
+ - build_addons
+ variables:
+ ob_release_environment: "Production"
+ ob_release_usedeploymentjob: true
+ ob_deploymentjob_environment: "NuGet-Production"
+ jobs:
+ - ${{ if eq(parameters.releaseSqlServerServer, true) }}:
+ - template: /eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml@self
+ parameters:
+ packageDisplayName: Microsoft.SqlServer.Server
+ artifactName: drop_build_independent_build_package_SqlServer
+ nugetServiceConnection: $(NuGetServiceConnection)
+ isProduction: true
+ dryRun: ${{ parameters.releaseDryRun }}
+
+ - ${{ if eq(parameters.releaseLogging, true) }}:
+ - template: /eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml@self
+ parameters:
+ packageDisplayName: Microsoft.Data.SqlClient.Extensions.Logging
+ artifactName: drop_build_independent_build_package_Logging
+ nugetServiceConnection: $(NuGetServiceConnection)
+ isProduction: true
+ dryRun: ${{ parameters.releaseDryRun }}
+
+ - ${{ if eq(parameters.releaseAbstractions, true) }}:
+ - template: /eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml@self
+ parameters:
+ packageDisplayName: Microsoft.Data.SqlClient.Extensions.Abstractions
+ artifactName: drop_build_independent_build_package_Abstractions
+ nugetServiceConnection: $(NuGetServiceConnection)
+ isProduction: true
+ dryRun: ${{ parameters.releaseDryRun }}
+
+ - ${{ if eq(parameters.releaseSqlClient, true) }}:
+ - template: /eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml@self
+ parameters:
+ packageDisplayName: Microsoft.Data.SqlClient
+ artifactName: drop_build_dependent_build_package_SqlClient
+ nugetServiceConnection: $(NuGetServiceConnection)
+ isProduction: true
+ dryRun: ${{ parameters.releaseDryRun }}
+
+ - ${{ if eq(parameters.releaseExtAzure, true) }}:
+ - template: /eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml@self
+ parameters:
+ packageDisplayName: Microsoft.Data.SqlClient.Extensions.Azure
+ artifactName: drop_build_dependent_build_package_Azure
+ nugetServiceConnection: $(NuGetServiceConnection)
+ isProduction: true
+ dryRun: ${{ parameters.releaseDryRun }}
+
+ - ${{ if eq(parameters.releaseAKVProvider, true) }}:
+ - template: /eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml@self
+ parameters:
+ packageDisplayName: Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+ artifactName: drop_build_addons_buildSignedAkvPackage
+ nugetServiceConnection: $(NuGetServiceConnection)
+ isProduction: true
+ dryRun: ${{ parameters.releaseDryRun }}
+
+ # ── Non-official (Dry Run) release ───────────────────────────────
+ - ${{ else }}:
+ - stage: Test_Release
+ displayName: "Release to NuGet (Dry Run)"
+ dependsOn:
+ - ${{ if or(parameters.releaseSqlServerServer, parameters.releaseLogging, parameters.releaseAbstractions) }}:
+ - build_independent
+ - ${{ if or(parameters.releaseSqlClient, parameters.releaseExtAzure) }}:
+ - build_dependent
+ - mds_package_validation
+ - ${{ if parameters.releaseAKVProvider }}:
+ - build_addons
+ variables:
+ ob_release_environment: "Test"
+ ob_release_usedeploymentjob: true
+ ob_deploymentjob_environment: "NuGet-DryRun"
+ jobs:
+ - ${{ if eq(parameters.releaseSqlServerServer, true) }}:
+ - template: /eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml@self
+ parameters:
+ packageDisplayName: Microsoft.SqlServer.Server
+ artifactName: drop_build_independent_build_package_SqlServer
+ nugetServiceConnection: $(NuGetServiceConnection)
+ dryRun: true
+
+ - ${{ if eq(parameters.releaseLogging, true) }}:
+ - template: /eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml@self
+ parameters:
+ packageDisplayName: Microsoft.Data.SqlClient.Extensions.Logging
+ artifactName: drop_build_independent_build_package_Logging
+ nugetServiceConnection: $(NuGetServiceConnection)
+ dryRun: true
+
+ - ${{ if eq(parameters.releaseAbstractions, true) }}:
+ - template: /eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml@self
+ parameters:
+ packageDisplayName: Microsoft.Data.SqlClient.Extensions.Abstractions
+ artifactName: drop_build_independent_build_package_Abstractions
+ nugetServiceConnection: $(NuGetServiceConnection)
+ dryRun: true
+
+ - ${{ if eq(parameters.releaseSqlClient, true) }}:
+ - template: /eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml@self
+ parameters:
+ packageDisplayName: Microsoft.Data.SqlClient
+ artifactName: drop_build_dependent_build_package_SqlClient
+ nugetServiceConnection: $(NuGetServiceConnection)
+ dryRun: true
+
+ - ${{ if eq(parameters.releaseExtAzure, true) }}:
+ - template: /eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml@self
+ parameters:
+ packageDisplayName: Microsoft.Data.SqlClient.Extensions.Azure
+ artifactName: drop_build_dependent_build_package_Azure
+ nugetServiceConnection: $(NuGetServiceConnection)
+ dryRun: true
+
+ - ${{ if eq(parameters.releaseAKVProvider, true) }}:
+ - template: /eng/pipelines/common/templates/jobs/publish-nuget-package-job.yml@self
+ parameters:
+ packageDisplayName: Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+ artifactName: drop_build_addons_buildSignedAkvPackage
+ nugetServiceConnection: $(NuGetServiceConnection)
+ dryRun: true
diff --git a/eng/pipelines/steps/compound-build-akv-step.yml b/eng/pipelines/steps/compound-build-akv-step.yml
index 9cb977ca34..750e9021bf 100644
--- a/eng/pipelines/steps/compound-build-akv-step.yml
+++ b/eng/pipelines/steps/compound-build-akv-step.yml
@@ -15,6 +15,7 @@ parameters:
- name: akvPackageVersion
type: string
+ # The C# build configuration to use (e.g. Debug or Release).
- name: buildConfiguration
type: string
values:
@@ -24,6 +25,12 @@ parameters:
- name: mdsPackageVersion
type: string
+ - name: loggingPackageVersion
+ type: string
+
+ - name: abstractionsPackageVersion
+ type: string
+
steps:
- task: DownloadSecureFile@1
displayName: 'Download Signing Key'
@@ -41,6 +48,8 @@ steps:
-p:AssemblyFileVersion=${{ parameters.akvAssemblyFileVersion }}
-p:AkvPackageVersion=${{ parameters.akvPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
+ -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
-p:ReferenceType=Package
-p:SigningKeyPath=$(Agent.TempDirectory)/netfxKeypair.snk
diff --git a/eng/pipelines/steps/compound-build-csproj-step.yml b/eng/pipelines/steps/compound-build-csproj-step.yml
new file mode 100644
index 0000000000..88810e866c
--- /dev/null
+++ b/eng/pipelines/steps/compound-build-csproj-step.yml
@@ -0,0 +1,54 @@
+#################################################################################
+# 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. #
+#################################################################################
+
+# Generic build step for csproj-based Extension packages (Logging, Abstractions, Azure). Each
+# project uses a build.proj target that runs Build only and produces assemblies within
+# $(BUILD_OUTPUT). Downstream ESRP DLL signing must locate the assemblies within $(BUILD_OUTPUT)
+# for all target frameworks that the csproj targets. NuGet packaging is done separately via
+# compound-pack-csproj-step.yml after DLL signing.
+
+parameters:
+ # The MSBuild build target in build.proj (e.g. BuildLogging, BuildAbstractions,
+ # BuildAzure).
+ - name: buildTarget
+ type: string
+
+ # Build Configuration.
+ - name: buildConfiguration
+ type: string
+ values:
+ - Debug
+ - Release
+
+ # Additional MSBuild arguments for version properties, e.g.
+ # -p:LoggingPackageVersion=1.0.0 -p:LoggingAssemblyFileVersion=1.0.123
+ - name: versionProperties
+ type: string
+ default: ''
+
+steps:
+ - task: DownloadSecureFile@1
+ displayName: Download Signing Key
+ inputs:
+ retryCount: 5
+ secureFile: netfxKeypair.snk
+
+ - task: MSBuild@1
+ displayName: Build.proj - ${{ parameters.buildTarget }}
+ inputs:
+ solution: $(REPO_ROOT)/build.proj
+ configuration: ${{ parameters.buildConfiguration }}
+ msbuildArguments: >-
+ -t:${{ parameters.buildTarget }}
+ -p:ReferenceType=Package
+ -p:SigningKeyPath=$(Agent.TempDirectory)/netfxKeypair.snk
+ ${{ parameters.versionProperties }}
+
+ - script: tree /a /f $(BUILD_OUTPUT)
+ displayName: List Build Output Tree
+
+ - script: tree /a /f $(PACK_OUTPUT)
+ displayName: List Pack Output Tree
diff --git a/eng/pipelines/steps/compound-esrp-dll-signing-step.yml b/eng/pipelines/steps/compound-esrp-dll-signing-step.yml
index 866ca15ee5..44649f94aa 100644
--- a/eng/pipelines/steps/compound-esrp-dll-signing-step.yml
+++ b/eng/pipelines/steps/compound-esrp-dll-signing-step.yml
@@ -5,64 +5,71 @@
#################################################################################
parameters:
+ # App Registration Client Id.
- name: appRegistrationClientId
type: string
+ # App Registration Tenant Id.
- name: appRegistrationTenantId
type: string
- - # Name of the Azure Key Vault to retrieve certificates from.
- # note: This has nothing to do with the AKV provider package.
- name: authAkvName
+ # Name of the Azure Key Vault to retrieve certificates from.
+ # note: This has nothing to do with the AKV provider package.
+ - name: authAkvName
type: string
+ # Auth Sign Cert Name.
- name: authSignCertName
type: string
+ # Esrp Connected Service Name.
- name: esrpConnectedServiceName
type: string
+ # Esrp Client Id.
- name: esrpClientId
type: string
-
- - # Globbing pattern for the files to sign. All files in $(BUILD_OUTPUT) and all subdirectories
- # that match this pattern will be scanned and signed. This should end with ".dll".
- name: pattern
+
+ # Globbing pattern for the files to sign. All files in $(BUILD_OUTPUT)/Package/bin
+ # that match this pattern will be scanned and signed. This should end with ".dll".
+ - name: pattern
type: string
-
+
steps:
- - task: EsrpMalwareScanning@5
- displayName: 'ESRP DLL Malware Scanning'
+ # See: https://aka.ms/esrp.scantask
+ - task: EsrpMalwareScanning@6
+ displayName: ESRP DLL Malware Scanning
inputs:
- AppRegistrationClientId: '${{ parameters.appRegistrationClientId }}'
- AppRegistrationTenantId: '${{ parameters.appRegistrationTenantId }}'
+ AppRegistrationClientId: ${{ parameters.appRegistrationClientId }}
+ AppRegistrationTenantId: ${{ parameters.appRegistrationTenantId }}
CleanupTempStorage: 1
- ConnectedServiceName: '${{ parameters.esrpConnectedServiceName }}'
- EsrpClientId: '${{ parameters.esrpClientId }}'
- FolderPath: '$(BUILD_OUTPUT)'
- Pattern: '${{ parameters.pattern }}'
+ ConnectedServiceName: ${{ parameters.esrpConnectedServiceName }}
+ EsrpClientId: ${{ parameters.esrpClientId }}
+ FolderPath: $(BUILD_OUTPUT)/Package/bin
+ Pattern: ${{ parameters.pattern }}
UseMSIAuthentication: true
VerboseLogin: 1
-
- - task: EsrpCodeSigning@5
- displayName: 'ESRP DLL Signing'
+
+ # See: https://aka.ms/esrp.signtask
+ - task: EsrpCodeSigning@6
+ displayName: ESRP DLL Signing
inputs:
- AppRegistrationClientId: '${{ parameters.appRegistrationClientId }}'
- AppRegistrationTenantId: '${{ parameters.appRegistrationTenantId }}'
- AuthAKVName: '${{ parameters.authAkvName }}'
- AuthSignCertName: '${{ parameters.authSignCertName }}'
- ConnectedServiceName: '${{ parameters.esrpConnectedServiceName }}'
- EsrpClientId: '${{ parameters.esrpClientId }}'
- FolderPath: '$(BUILD_OUTPUT)'
- Pattern: '${{ parameters.pattern }}'
- signConfigType: 'inlineSignParams'
+ AppRegistrationClientId: ${{ parameters.appRegistrationClientId }}
+ AppRegistrationTenantId: ${{ parameters.appRegistrationTenantId }}
+ AuthAKVName: ${{ parameters.authAkvName }}
+ AuthSignCertName: ${{ parameters.authSignCertName }}
+ ConnectedServiceName: ${{ parameters.esrpConnectedServiceName }}
+ EsrpClientId: ${{ parameters.esrpClientId }}
+ FolderPath: $(BUILD_OUTPUT)/Package/bin
+ Pattern: ${{ parameters.pattern }}
+ signConfigType: inlineSignParams
UseMSIAuthentication: true
inlineOperation: |
- [
+ [
{
"keyCode": "CP-230012",
"operationSetCode": "SigntoolSign",
- "parameters":
+ "parameters":
[
{
"parameterName": "OpusName",
diff --git a/eng/pipelines/steps/compound-esrp-nuget-signing-step.yml b/eng/pipelines/steps/compound-esrp-nuget-signing-step.yml
index 0d47b1f087..34e903465f 100644
--- a/eng/pipelines/steps/compound-esrp-nuget-signing-step.yml
+++ b/eng/pipelines/steps/compound-esrp-nuget-signing-step.yml
@@ -5,28 +5,34 @@
#################################################################################
parameters:
+ # App Registration Client Id.
- name: appRegistrationClientId
type: string
+ # App Registration Tenant Id.
- name: appRegistrationTenantId
type: string
- - # Name of the Azure Key Vault to retrieve certificates from.
- # note: This has nothing to do with the AKV provider package.
- name: authAkvName
+ # Name of the Azure Key Vault to retrieve certificates from.
+ # note: This has nothing to do with the AKV provider package.
+ - name: authAkvName
type: string
+ # Auth Sign Cert Name.
- name: authSignCertName
type: string
+ # Esrp Connected Service Name.
- name: esrpConnectedServiceName
type: string
+ # Esrp Client Id.
- name: esrpClientId
type: string
-
+
steps:
- - task: EsrpMalwareScanning@5
+ # See: https://aka.ms/esrp.scantask
+ - task: EsrpMalwareScanning@6
displayName: 'ESRP Nuget Malware Scanning'
inputs:
AppRegistrationClientId: '${{ parameters.appRegistrationClientId }}'
@@ -34,12 +40,13 @@ steps:
CleanupTempStorage: 1
ConnectedServiceName: '${{ parameters.esrpConnectedServiceName }}'
EsrpClientId: '${{ parameters.esrpClientId }}'
- FolderPath: '$(ARTIFACT_PATH)'
+ FolderPath: '$(PACK_OUTPUT)'
Pattern: '*.*nupkg'
UseMSIAuthentication: true
VerboseLogin: 1
-
- - task: EsrpCodeSigning@5
+
+ # See: https://aka.ms/esrp.signtask
+ - task: EsrpCodeSigning@6
displayName: 'ESRP Signing NuGet Package'
inputs:
AppRegistrationClientId: '${{ parameters.appRegistrationClientId }}'
@@ -48,24 +55,24 @@ steps:
EsrpClientId: '${{ parameters.esrpClientId }}'
AuthAKVName: '${{ parameters.authAkvName }}'
AuthSignCertName: '${{ parameters.authSignCertName }}'
- FolderPath: '$(ARTIFACT_PATH)'
+ FolderPath: '$(PACK_OUTPUT)'
Pattern: '*.*nupkg'
signConfigType: 'inlineSignParams'
UseMSIAuthentication: true
inlineOperation: |
- [
- {
- "keyCode": "CP-401405",
- "operationSetCode": "NuGetSign",
- "parameters": [ ],
- "toolName": "sign",
- "toolVersion": "1.0"
+ [
+ {
+ "keyCode": "CP-401405",
+ "operationSetCode": "NuGetSign",
+ "parameters": [ ],
+ "toolName": "sign",
+ "toolVersion": "1.0"
},
- {
- "keyCode": "CP-401405",
- "operationSetCode": "NuGetVerify",
- "parameters": [ ],
- "toolName": "sign",
- "toolVersion": "1.0"
- }
+ {
+ "keyCode": "CP-401405",
+ "operationSetCode": "NuGetVerify",
+ "parameters": [ ],
+ "toolName": "sign",
+ "toolVersion": "1.0"
+ }
]
diff --git a/eng/pipelines/steps/compound-extract-akv-apiscan-files-step.yml b/eng/pipelines/steps/compound-extract-akv-apiscan-files-step.yml
index ebd6743361..77c342da2a 100644
--- a/eng/pipelines/steps/compound-extract-akv-apiscan-files-step.yml
+++ b/eng/pipelines/steps/compound-extract-akv-apiscan-files-step.yml
@@ -7,29 +7,33 @@
# @TODO: This can be made generic when the output folders match the package names.
parameters:
+ # The C# build configuration to use (e.g. Debug or Release).
- name: buildConfiguration
type: string
values:
- Debug
- Release
-
- - # Path where the dll files should be copied
- name: dllPath
+
+ # Path where the dll files should be copied
+ - name: dllPath
type: string
-
- - # Path where the pdb files should be copied
- name: pdbPath
+
+ # Path where the pdb files should be copied
+ - name: pdbPath
type: string
-
+
+ # The C# project reference type to use when building and packing the packages.
- name: referenceType
type: string
values:
- - Package
- - Project
-
- - # Short form of the target framework version to extract. Used to build the path to the files
- # to extract. Eg, net462
- name: targetFramework
+ # Reference sibling packages as NuGet packages.
+ - Package
+ # Reference sibling packages as C# projects.
+ - Project
+
+ # Short form of the target framework version to extract. Used to build the path to the files
+ # to extract. Eg, net462
+ - name: targetFramework
type: string
steps:
@@ -39,11 +43,10 @@ steps:
contents: 'Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.dll'
sourceFolder: '$(BUILD_OUTPUT)/${{ parameters.referenceType }}/bin/Windows_NT/${{ parameters.buildConfiguration }}.AnyCPU/AzureKeyVaultProvider/${{ parameters.targetFramework }}/'
targetFolder: '${{ parameters.dllPath }}/win/${{ parameters.targetFramework }}/'
-
+
- task: CopyFiles@2
displayName: 'Copy ${{ parameters.targetFramework }} PDB'
inputs:
contents: 'Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.pdb'
sourceFolder: '$(BUILD_OUTPUT)/${{ parameters.referenceType }}/bin/Windows_NT/${{ parameters.buildConfiguration }}.AnyCPU/AzureKeyVaultProvider/${{ parameters.targetFramework }}/'
targetFolder: '${{ parameters.pdbPath }}/win/${{ parameters.targetFramework }}/'
-
diff --git a/eng/pipelines/steps/compound-nuget-pack-step.yml b/eng/pipelines/steps/compound-nuget-pack-step.yml
index 41905c8483..ef1f3b946a 100644
--- a/eng/pipelines/steps/compound-nuget-pack-step.yml
+++ b/eng/pipelines/steps/compound-nuget-pack-step.yml
@@ -5,6 +5,7 @@
#################################################################################
parameters:
+ # The C# build configuration to use (e.g. Debug or Release).
- name: buildConfiguration
type: string
values:
@@ -23,14 +24,16 @@ parameters:
- name: outputDirectory
type: string
+ # The C# project reference type to use when building and packing the packages.
- name: referenceType
type: string
values:
+ # Reference sibling packages as NuGet packages.
- Package
+ # Reference sibling packages as C# projects.
- Project
-
- # Semi-colon separated properties to pass to nuget via the -properties
- # argument.
+
+ # Semi-colon separated properties to pass to nuget via the -properties argument.
- name: properties
type: string
default: ''
@@ -75,7 +78,7 @@ steps:
displayName: 'Generate NuGet Package'
inputs:
command: custom
- arguments: >-
+ arguments: >-
pack
${{ parameters.nuspecPath }}
-Version ${{ parameters.packageVersion }}
diff --git a/eng/pipelines/steps/compound-pack-csproj-step.yml b/eng/pipelines/steps/compound-pack-csproj-step.yml
new file mode 100644
index 0000000000..5198b405e3
--- /dev/null
+++ b/eng/pipelines/steps/compound-pack-csproj-step.yml
@@ -0,0 +1,41 @@
+#################################################################################
+# 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. #
+#################################################################################
+
+# Generic pack step for csproj-based Extension packages (Logging, Abstractions,
+# Azure). This step runs the Pack target after DLLs have been signed. The
+# NoBuild=true property ensures the DLLs are not rebuilt.
+
+parameters:
+ # The MSBuild pack target in build.proj (e.g. PackLogging, PackAbstractions,
+ # PackAzure).
+ - name: packTarget
+ type: string
+
+ # Build Configuration.
+ - name: buildConfiguration
+ type: string
+ values:
+ - Debug
+ - Release
+
+ # Additional MSBuild arguments for version properties.
+ - name: versionProperties
+ type: string
+ default: ''
+
+steps:
+ - task: MSBuild@1
+ displayName: Build.proj - ${{ parameters.packTarget }}
+ inputs:
+ solution: $(REPO_ROOT)/build.proj
+ configuration: ${{ parameters.buildConfiguration }}
+ msbuildArguments: >-
+ -t:${{ parameters.packTarget }}
+ -p:ReferenceType=Package
+ ${{ parameters.versionProperties }}
+
+ - script: tree /a /f $(PACK_OUTPUT)
+ displayName: List Pack Output Tree After Pack
diff --git a/eng/pipelines/steps/compound-publish-symbols-step.yml b/eng/pipelines/steps/compound-publish-symbols-step.yml
index c636b59915..1b2e3cb3b9 100644
--- a/eng/pipelines/steps/compound-publish-symbols-step.yml
+++ b/eng/pipelines/steps/compound-publish-symbols-step.yml
@@ -7,62 +7,66 @@
# For more details, see https://www.osgwiki.com/wiki/Symbols_Publishing_Pipeline_to_SymWeb_and_MSDL
parameters:
- - # Name of the symbols artifact that will be published
- name: artifactName
+ # Name of the symbols artifact that will be published
+ - name: artifactName
type: string
- - # Azure subscription where the publishing task will execute
- name: azureSubscription
+ # Azure subscription where the publishing task will execute
+ - name: azureSubscription
type: string
- - # Package name, typically the name of the nuget package being built
- name: packageName
+ # Package name, typically the name of the nuget package being built
+ - name: packageName
type: string
- - # Project that symbols will belong to (decided during symbols onboarding)
- name: publishProjectName
+ # Project that symbols will belong to (decided during symbols onboarding)
+ - name: publishProjectName
type: string
- - # Where symbols publishing service is hosted, will be prepended to trafficmanager.net
- name: publishServer
+ # Where symbols publishing service is hosted, will be prepended to trafficmanager.net
+ - name: publishServer
type: string
- - # Whether to publish the uploaded symbols to the internal symbols servers
- name: publishToInternal
+ # Whether to publish the uploaded symbols to the internal symbols servers
+ - name: publishToInternal
type: boolean
- - # Whether to publish the uploaded symbols to the public symbols servers
- name: publishToPublic
+ # Whether to publish the uploaded symbols to the public symbols servers
+ - name: publishToPublic
type: boolean
- - # URI to use for requesting a bearer-token for publishing the symbols
- name: publishTokenUri
+ # URI to use for requesting a bearer-token for publishing the symbols
+ - name: publishTokenUri
type: string
- - # Type of build, used to determine path to search for symbols files
- name: referenceType
+ # The C# project reference type to use when building and packing the packages.
+ - name: referenceType
type: string
values:
- - Project
+ # Reference sibling packages as NuGet packages.
- Package
+ # Reference sibling packages as C# projects.
+ - Project
- - # Pattern to use to search for pdb symbols files to upload/publish
- name: searchPattern
+ # Pattern to use to search for pdb symbols files to upload/publish
+ - name: searchPattern
type: string
- - # Account/org where the symbols will be uploaded
- name: uploadAccount
+ # Account/org where the symbols will be uploaded
+ - name: uploadAccount
type: string
- - # Version of the symbols to publish, typically the same as the NuGet package version
- name: version
+ # Version of the symbols to publish, typically the same as the NuGet package version
+ - name: version
type: string
steps:
- - # Set variable for downstream tasks (allegedly)
- # Note: Because variables cannot be set in top-level of template, this has to be done during
- # runtime.
- script: 'echo ##vso[task.setvariable variable=ArtifactServices.Symbol.AccountName;]${{ parameters.uploadAccount }}'
+ # Set variable for downstream tasks (allegedly).
+ #
+ # Note: Because variables cannot be set in top-level of template, this has to be done during
+ # runtime.
+ #
+ - script: 'echo ##vso[task.setvariable variable=ArtifactServices.Symbol.AccountName;]${{ parameters.uploadAccount }}'
displayName: 'Set ArtifactServices.Symbol.AccountName to ${{ parameters.uploadAccount }}'
- task: PublishSymbols@2
@@ -89,28 +93,28 @@ steps:
# Propagate parameters to PS variables ################################################
$artifactName = "${{ parameters.artifactName }}"
echo "artifactName= $artifactName"
-
+
$publishProjectName = "${{ parameters.publishProjectName }}"
echo "publishProjectName= $publishProjectName"
-
+
$publishToInternal = "${{ parameters.publishToInternal }}".ToLower()
echo "publishToInternal= $publishToInternal"
-
+
$publishToPublic = "${{ parameters.publishToPublic }}".ToLower()
echo "publishToPublic= $publishToPublic"
-
+
$publishServer = "${{ parameters.publishServer }}"
echo "publishServer= $publishServer"
-
+
$publishTokenUri = "${{ parameters.publishTokenUri }}"
echo "publishTokenUri= $publishTokenUri"
-
- # Publish symbols #####################################################################
+
+ # Publish symbols #####################################################################
# 1) Get the access token for the symbol publishing service
echo "> 1.Acquiring symbol publishing token..."
$symbolPublishingToken = az account get-access-token --resource $publishTokenUri --query accessToken -o tsv
echo "> 1.Symbol publishing token acquired."
-
+
# 2) Register the request name
echo "> 2.Registering request name..."
$requestNameRegistrationBody = "{'requestName': '$artifactName'}"
@@ -121,7 +125,7 @@ steps:
-ContentType "application/json" `
-Body $requestNameRegistrationBody
echo "> 2.Request name registered successfully."
-
+
# 3) Publish the symbols
echo "> 3.Submitting request to publish symbols..."
$publishSymbolsBody = "{'publishToInternalServer': $publishToInternal, 'publishToPublicServer': $publishToPublic}"
@@ -132,7 +136,7 @@ steps:
-ContentType "application/json" `
-Body $publishSymbolsBody
echo "> 3.Request to publish symbols submitted successfully."
-
+
# The following REST calls are used to check publishing status.
echo "> 4.Checking the status of the request ..."
Invoke-RestMethod `
@@ -140,23 +144,19 @@ steps:
-Uri "https://$publishServer.trafficmanager.net/projects/$publishProjectName/requests/$artifactName" `
-Headers @{ Authorization = "Bearer $symbolPublishingToken" } `
-ContentType "application/json"
-
+
echo "Use below tables to interpret the values of xxxServerStatus and xxxServerResult fields from the response."
-
+
echo "PublishingStatus"
echo "-----------------"
echo "0 NotRequested; The request has not been requested to publish."
echo "1 Submitted; The request is submitted to be published"
echo "2 Processing; The request is still being processed"
echo "3 Completed; The request has been completed processing. It can be failed or successful. Check PublishingResult to get more details"
-
+
echo "PublishingResult"
echo "-----------------"
echo "0 Pending; The request has not completed or has not been requested."
echo "1 Succeeded; The request has published successfully"
echo "2 Failed; The request has failed to publish"
echo "3 Cancelled; The request was cancelled"
-
-
-
-
diff --git a/eng/pipelines/steps/install-dotnet.yml b/eng/pipelines/steps/install-dotnet.yml
index 5b0c413475..e6a50ee03f 100644
--- a/eng/pipelines/steps/install-dotnet.yml
+++ b/eng/pipelines/steps/install-dotnet.yml
@@ -24,11 +24,11 @@ parameters:
- arm64
default: x64
- # True to enable debug logging.
+ # True to emit debug information and steps.
- name: debug
type: boolean
default: false
-
+
# The directory to install to.
- name: installDir
type: string
@@ -53,7 +53,7 @@ steps:
# Use the UseDotNet@2 task for all architectures except ARM64.
- ${{ if ne(parameters.architecture, 'arm64') }}:
-
+
# Install the SDK listed in the global.json file.
- task: UseDotNet@2
displayName: Install .NET SDK (global.json)
@@ -65,7 +65,7 @@ steps:
env:
PROCESSOR_ARCHITECTURE: x86
- # Install the desired Runtimes, if any.
+ # Install the desired Runtimes, if any.
- ${{ each version in parameters.runtimes }}:
- task: UseDotNet@2
displayName: Install .NET ${{ version }} Runtime
diff --git a/eng/pipelines/steps/roslyn-analyzers-akv-step.yml b/eng/pipelines/steps/roslyn-analyzers-akv-step.yml
index 8b2b4bd331..de08672965 100644
--- a/eng/pipelines/steps/roslyn-analyzers-akv-step.yml
+++ b/eng/pipelines/steps/roslyn-analyzers-akv-step.yml
@@ -30,6 +30,12 @@ parameters:
- name: mdsPackageVersion
type: string
+ - name: loggingPackageVersion
+ type: string
+
+ - name: abstractionsPackageVersion
+ type: string
+
steps:
- task: securedevelopmentteam.vss-secure-development-tools.build-task-roslynanalyzers.RoslynAnalyzers@3
displayName: 'Roslyn Analyzers'
@@ -42,6 +48,8 @@ steps:
-p:Configuration=${{ parameters.buildConfiguration }}
-p:AkvPackageVersion=${{ parameters.akvPackageVersion }}
-p:MdsPackageVersion=${{ parameters.mdsPackageVersion }}
+ -p:LoggingPackageVersion=${{ parameters.loggingPackageVersion }}
+ -p:AbstractionsPackageVersion=${{ parameters.abstractionsPackageVersion }}
-p:ReferenceType=Package
msBuildVersion: 17.0
setupCommandLinePicker: vs2022
diff --git a/eng/pipelines/stress-tests-pipeline.yml b/eng/pipelines/stress-tests-pipeline.yml
index e694a4cb03..e08f255e5a 100644
--- a/eng/pipelines/stress-tests-pipeline.yml
+++ b/eng/pipelines/stress-tests-pipeline.yml
@@ -64,6 +64,7 @@ parameters:
- Debug
- Release
+ # True to emit debug information and steps.
- name: debug
displayName: Enable debug output
type: boolean
diff --git a/eng/pipelines/variables/akv-official-variables.yml b/eng/pipelines/variables/akv-official-variables.yml
deleted file mode 100644
index 7137202a05..0000000000
--- a/eng/pipelines/variables/akv-official-variables.yml
+++ /dev/null
@@ -1,43 +0,0 @@
-#################################################################################
-# Licensed to the .NET Foundation under one or more agreements. #
-# The .NET Foundation licenses this file to you under the MIT license. #
-# See the LICENSE file in the project root for more information. #
-#################################################################################
-
-# This file is only included in AKV OneBranch Official pipelines.
-
-# @TODO: These seem to only really apply to official builds. Name should probably be adjusted to match.
-
-variables:
- # @TODO: If symbols variables are indeed shared between projects and not expected to change
- # then they can be removed from this variable group.
- - group: 'akv-variables-v2'
- # SymbolsAzureSubscription
- # SymbolsPublishProjectName
- # SymbolsPublishServer
- # SymbolsPublishTokenUri
- # SymbolsUploadAccount
-
- # Well-Known Variables -------------------------------------------------
- - name: PACKAGE_NAME
- value: 'Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider'
-
- # Base Variables -------------------------------------------------------
- - name: mdsPackageVersion
- value: '7.0.0-preview3.25342.7'
-
- # @TODO: Version should ideally be pulled from one location (versions.props?)
- - name: versionMajor
- value: '7'
- - name: versionMinor
- value: '0'
- - name: versionPatch
- value: '0'
- - name: versionPreview
- value: '-preview3'
-
- # Compound Variables ---------------------------------------------------
- - name: akvAssemblyFileVersion
- value: '${{ variables.versionMajor }}.${{ variables.versionMinor }}${{ variables.versionPatch }}.$(Build.BuildNumber)'
- - name: akvPackageVersion
- value: '${{ variables.versionMajor }}.${{ variables.versionMinor }}.${{ variables.versionPatch }}${{ variables.versionPreview }}'
diff --git a/eng/pipelines/variables/common-variables.yml b/eng/pipelines/variables/common-variables.yml
deleted file mode 100644
index 275d473aa3..0000000000
--- a/eng/pipelines/variables/common-variables.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-#################################################################################
-# Licensed to the .NET Foundation under one or more agreements. #
-# The .NET Foundation licenses this file to you under the MIT license. #
-# See the LICENSE file in the project root for more information. #
-#################################################################################
-
-# This file is only included in AKV OneBranch Official pipelines.
-
-variables:
- # Well-known paths
- - name: REPO_ROOT
- value: '$(Build.SourcesDirectory)'
- readonly: true
-
- - name: BUILD_OUTPUT
- value: '$(Build.SourcesDirectory)/artifacts'
- readonly: true
-
- - name: ARTIFACT_PATH
- value: '$(Build.SourcesDirectory)/packages'
- readonly: true
diff --git a/eng/pipelines/variables/esrp-signing-variables.yml b/eng/pipelines/variables/esrp-signing-variables.yml
deleted file mode 100644
index a768b509c4..0000000000
--- a/eng/pipelines/variables/esrp-signing-variables.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-#################################################################################
-# Licensed to the .NET Foundation under one or more agreements. #
-# The .NET Foundation licenses this file to you under the MIT license. #
-# See the LICENSE file in the project root for more information. #
-#################################################################################
-
-# This file is only included in AKV OneBranch Official pipelines.
-
-# These variables are used for running ESRP signing tasks. All names start with "Signing" to make
-# it clear that these variables are used for signing (as opposed to other msc tasks).
-
-variables:
- - group: 'esrp-variables-v2'
- # SigningAppRegistrationClientId
- # SigningAppRegistrationTenantId
- # SigningAuthAkvName
- # SigningAuthSignCertName
- # SigningEsrpClientId
- # SigningEsrpConnectedServiceName
diff --git a/eng/pipelines/variables/onebranch-variables.yml b/eng/pipelines/variables/onebranch-variables.yml
deleted file mode 100644
index 38436d7440..0000000000
--- a/eng/pipelines/variables/onebranch-variables.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-#################################################################################
-# Licensed to the .NET Foundation under one or more agreements. #
-# The .NET Foundation licenses this file to you under the MIT license. #
-# See the LICENSE file in the project root for more information. #
-#################################################################################
-
-# This file is only included in AKV OneBranch Official pipelines.
-
-variables:
- # Variables defined by us ----------------------------------------------
- - name: apiScanDllPath
- value: '$(Build.SourcesDirectory)/apiScan/dlls'
-
- - name: apiScanPdbPath
- value: '$(Build.SourcesDirectory)/apiScan/pdbs'
-
- # Variables defined by OneBranch ---------------------------------------
- - name: Packaging.EnableSBOMSigning
- value: true
-
- - # Docker image which is used to build the project https://aka.ms/obpipelines/containers
- name: WindowsContainerImage
- value: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest'
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
index 424d3e9e65..28c55f05c5 100644
--- a/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
+++ b/src/Microsoft.Data.SqlClient.Extensions/Abstractions/src/Abstractions.csproj
@@ -14,6 +14,15 @@
netstandard2.0
+
+
+ $(SigningKeyPath)
+
+
+ true
+ $(SigningKeyPath)
+
+
enable
@@ -40,8 +49,6 @@
$(AbstractionsAssemblyFileVersion)
$(AbstractionsAssemblyFileVersion)
$(AbstractionsPackageVersion)
-
- $(Artifacts)/doc/$(TargetFramework)/$(AssemblyName).xml
@@ -60,6 +67,23 @@
+
+
+
+
+ $(Artifacts)/obj/$(Configuration)/$(AssemblyName)
+
+
+ $(Artifacts)/bin/$(Configuration)/$(AssemblyName)
+
+
+ $(Artifacts)/doc/$(TargetFramework)/$(AssemblyName).xml
+
+
+
-
+
@@ -37,7 +34,7 @@
parts of its value, for example 1.0.0.345.
- Otherwise, defaults to:
$(DefaultMajorVersion).0.0.$(BuildNumber).
-
+
We use private properties to hold the computed values, and then always
assign those to the public properties. After importing this file, the
public properties will always be set.
@@ -56,7 +53,7 @@
<_OurAssemblyFileVersion Condition="'$(AbstractionsAssemblyFileVersion)' == '' and '$(AbstractionsPackageVersion)' != ''">$(AbstractionsPackageVersion.Split('-')[0])
- <_OurAssemblyFileVersion Condition="'$(AbstractionsAssemblyFileVersion)' == '' and '$(AbstractionsPackageVersion)' == ''">$(AbstractionsDefaultMajorVersion).0.0.$(BuildNumber)
+ <_OurAssemblyFileVersion Condition="'$(AbstractionsAssemblyFileVersion)' == '' and '$(AbstractionsPackageVersion)' == ''">$(AbstractionsDefaultMajorVersion).0.0.$(AssemblyBuildNumber)
+
+ $(SigningKeyPath)
+
+
+ true
+ $(SigningKeyPath)
+
+
enable
@@ -40,8 +49,6 @@
$(AzureAssemblyFileVersion)
$(AzureAssemblyFileVersion)
$(AzurePackageVersion)
-
- $(Artifacts)/doc/$(TargetFramework)/$(AssemblyName).xml
@@ -60,6 +67,23 @@
+
+
+
+
+ $(Artifacts)/obj/$(Configuration)/$(AssemblyName)
+
+
+ $(Artifacts)/bin/$(Configuration)/$(AssemblyName)
+
+
+ $(Artifacts)/doc/$(TargetFramework)/$(AssemblyName).xml
+
+
+
+
-
+
@@ -36,7 +33,7 @@
parts of its value, for example 1.0.0.345.
- Otherwise, defaults to:
$(DefaultMajorVersion).0.0.$(BuildNumber).
-
+
We use private properties to hold the computed values, and then always
assign those to the public properties. After importing this file, the
public properties will always be set.
@@ -55,7 +52,7 @@
<_OurAssemblyFileVersion Condition="'$(AzureAssemblyFileVersion)' == '' and '$(AzurePackageVersion)' != ''">$(AzurePackageVersion.Split('-')[0])
- <_OurAssemblyFileVersion Condition="'$(AzureAssemblyFileVersion)' == '' and '$(AzurePackageVersion)' == ''">$(AzureDefaultMajorVersion).0.0.$(BuildNumber)
+ <_OurAssemblyFileVersion Condition="'$(AzureAssemblyFileVersion)' == '' and '$(AzurePackageVersion)' == ''">$(AzureDefaultMajorVersion).0.0.$(AssemblyBuildNumber)
+
+
+
+ netstandard2.0
+
+
+
+
+ $(SigningKeyPath)
+
+
+ true
+ $(SigningKeyPath)
+
+
+
+
+ enable
+ enable
+
+
+
+
+ Microsoft.Data.SqlClient.Extensions.Logging
+
+
+
+
+
+ $(LoggingDefaultMajorVersion).0.0.0
+
+ $(LoggingAssemblyFileVersion)
+ $(LoggingAssemblyFileVersion)
+ $(LoggingPackageVersion)
+
+
+
+
+ <_Parameter1>true
+
+
+
+
+
+
+
+
+
+
+
+ $(Artifacts)/obj/$(Configuration)/$(AssemblyName)
+
+
+ $(Artifacts)/bin/$(Configuration)/$(AssemblyName)
+
+
+ $(Artifacts)/doc/$(TargetFramework)/$(AssemblyName).xml
+
+
+
+
+
+ $(AssemblyName)
+ $(LoggingPackageVersion)
+ $(PackagesDir)
+ true
+ snupkg
+
+ Microsoft Corporation
+ Microsoft Corporation
+ Microsoft.Data.SqlClient Extensions Logging - ETW EventSource for SqlClient tracing and diagnostics.
+ https://github.com/dotnet/SqlClient
+ MIT
+ dotnet.png
+ README.md
+
+
+
+
+
+
+
+
+
+ $(AssemblyName)
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Logging/src/LoggingVersions.props b/src/Microsoft.Data.SqlClient.Extensions/Logging/src/LoggingVersions.props
new file mode 100644
index 0000000000..597a692457
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Logging/src/LoggingVersions.props
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+ <_OurPackageVersion Condition="'$(LoggingPackageVersion)' != ''">$(LoggingPackageVersion)
+ <_OurPackageVersion Condition="'$(LoggingPackageVersion)' == ''">$(LoggingDefaultMajorVersion).0.0.$(BuildNumber)-dev
+
+
+
+ <_OurAssemblyFileVersion Condition="'$(LoggingAssemblyFileVersion)' != ''">$(LoggingAssemblyFileVersion)
+
+ <_OurAssemblyFileVersion Condition="'$(LoggingAssemblyFileVersion)' == '' and '$(LoggingPackageVersion)' != ''">$(LoggingPackageVersion.Split('-')[0])
+
+ <_OurAssemblyFileVersion Condition="'$(LoggingAssemblyFileVersion)' == '' and '$(LoggingPackageVersion)' == ''">$(LoggingDefaultMajorVersion).0.0.$(AssemblyBuildNumber)
+
+
+ $(_OurPackageVersion)
+ $(_OurAssemblyFileVersion)
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Logging/src/PackageReadme.md b/src/Microsoft.Data.SqlClient.Extensions/Logging/src/PackageReadme.md
new file mode 100644
index 0000000000..436bcc4f5b
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Logging/src/PackageReadme.md
@@ -0,0 +1,109 @@
+# Microsoft.Data.SqlClient.Extensions.Logging
+
+[](https://www.nuget.org/packages/Microsoft.Data.SqlClient.Extensions.Logging)
+[](https://www.nuget.org/packages/Microsoft.Data.SqlClient.Extensions.Logging)
+
+## Description
+
+This package provides **ETW EventSource tracing and diagnostics** for [Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient). It enables comprehensive logging and telemetry capabilities for SQL Server database operations.
+
+## Key Features
+
+- **ETW EventSource Integration**: Structured logging using Event Tracing for Windows (ETW)
+- **Diagnostic Listeners**: Hook into SqlClient diagnostic events
+- **Performance Counters**: Track connection pool and query performance metrics
+- **Correlation Support**: Integrate with distributed tracing systems
+
+## Supportability
+
+This package supports:
+
+- .NET Standard 2.0 (compatible with .NET Framework 4.6.1+, .NET Core 2.0+, and .NET 5+)
+
+## Installation
+
+Install the package via NuGet:
+
+```bash
+dotnet add package Microsoft.Data.SqlClient.Extensions.Logging
+```
+
+Or via the Package Manager Console:
+
+```powershell
+Install-Package Microsoft.Data.SqlClient.Extensions.Logging
+```
+
+## Getting Started
+
+### Enable ETW Tracing
+
+Use tools like PerfView or Windows Performance Recorder to capture ETW events:
+
+```bash
+# Using PerfView
+PerfView.exe collect /Providers=*Microsoft.Data.SqlClient.EventSource
+```
+
+### Subscribe to Diagnostic Events
+
+```csharp
+using System.Diagnostics;
+
+// Subscribe to SqlClient diagnostic events
+DiagnosticListener.AllListeners.Subscribe(new SqlClientObserver());
+
+public class SqlClientObserver : IObserver
+{
+ public void OnNext(DiagnosticListener listener)
+ {
+ if (listener.Name == "SqlClientDiagnosticListener")
+ {
+ listener.Subscribe(new SqlClientEventObserver());
+ }
+ }
+
+ public void OnError(Exception error) { }
+ public void OnCompleted() { }
+}
+
+public class SqlClientEventObserver : IObserver>
+{
+ public void OnNext(KeyValuePair value)
+ {
+ Console.WriteLine($"Event: {value.Key}");
+ // Process event data...
+ }
+
+ public void OnError(Exception error) { }
+ public void OnCompleted() { }
+}
+```
+
+## Event Categories
+
+The logging extension emits events in these categories:
+
+| Category | Events |
+|----------|--------|
+| **Connection** | Open, Close, Pool operations |
+| **Commands** | Before/After execution, Errors |
+| **Transactions** | Begin, Commit, Rollback |
+| **Pool** | Connection acquired/released, Pool sizing |
+| **Errors** | Exceptions, Retries, Timeouts |
+
+## Documentation
+
+- [SqlClient Diagnostic Tracing](https://learn.microsoft.com/sql/connect/ado-net/tracing)
+- [ETW Tracing in .NET](https://learn.microsoft.com/dotnet/core/diagnostics/eventsource)
+- [Microsoft.Data.SqlClient Documentation](https://learn.microsoft.com/sql/connect/ado-net/introduction-microsoft-data-sqlclient-namespace)
+
+## License
+
+This package is licensed under the [MIT License](https://licenses.nuget.org/MIT).
+
+## Related Packages
+
+- [Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient) - The main SqlClient driver
+- [Microsoft.Data.SqlClient.Extensions.Abstractions](https://www.nuget.org/packages/Microsoft.Data.SqlClient.Extensions.Abstractions) - Core abstractions
+- [Microsoft.Data.SqlClient.Extensions.Azure](https://www.nuget.org/packages/Microsoft.Data.SqlClient.Extensions.Azure) - Azure integration extensions
diff --git a/src/Microsoft.Data.SqlClient.Extensions/Logging/src/SqlClientEventSource.cs b/src/Microsoft.Data.SqlClient.Extensions/Logging/src/SqlClientEventSource.cs
new file mode 100644
index 0000000000..712e5ee72b
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient.Extensions/Logging/src/SqlClientEventSource.cs
@@ -0,0 +1,1543 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics.Tracing;
+using System.Runtime.CompilerServices;
+using System.Text;
+
+namespace Microsoft.Data.SqlClient
+{
+ // Any changes to event writers might be considered as a breaking change.
+ // Other libraries such as OpenTelemetry and ApplicationInsight have based part of their code on BeginExecute and EndExecute arguments number.
+
+ ///
+ /// ETW EventSource for Microsoft.Data.SqlClient tracing and diagnostics.
+ ///
+ [EventSource(Name = "Microsoft.Data.SqlClient.EventSource")]
+ public class SqlClientEventSource : EventSource
+ {
+ ///
+ /// Defines the singleton instance for the Resources ETW provider.
+ ///
+ public static readonly SqlClientEventSource Log = new();
+
+ ///
+ /// A callback that is invoked when the EventSource receives an Enable command.
+ /// Can be used to hook metrics or other subsystems that need to respond to EventSource enablement.
+ ///
+ public static Action? OnEventSourceEnabled { get; set; }
+
+ ///
+ /// Gets a value indicating whether the EventSource has been enabled at least once.
+ /// This can be checked by downstream consumers to handle early enabling that may
+ /// occur before callbacks are registered.
+ ///
+ public static bool WasEnabled { get; private set; }
+
+ private SqlClientEventSource() { }
+
+ private const string NullStr = "null";
+ private const string SqlCommand_ClassName = "SqlCommand";
+
+ ///
+ protected override void OnEventCommand(EventCommandEventArgs command)
+ {
+ base.OnEventCommand(command);
+
+ if (command.Command == EventCommand.Enable)
+ {
+ WasEnabled = true;
+ OnEventSourceEnabled?.Invoke();
+ }
+ }
+
+ #region Event IDs
+ // Initialized static Scope IDs
+ private static long s_nextScopeId = 0;
+ private static long s_nextNotificationScopeId = 0;
+ private static long s_nextPoolerScopeId = 0;
+ private static long s_nextSNIScopeId = 0;
+
+ ///
+ /// Defines EventId for BeginExecute (Reader, Scalar, NonQuery, XmlReader).
+ ///
+ private const int BeginExecuteEventId = 1;
+
+ ///
+ /// Defines EventId for EndExecute (Reader, Scalar, NonQuery, XmlReader).
+ ///
+ private const int EndExecuteEventId = 2;
+
+ ///
+ /// Defines EventId for Trace() events
+ ///
+ private const int TraceEventId = 3;
+
+ ///
+ /// Defines EventId for ScopeEnter() events
+ ///
+ private const int ScopeEnterId = 4;
+
+ ///
+ /// Defines EventId for ScopeLeave() events
+ ///
+ private const int ScopeExitId = 5;
+
+ ///
+ /// Defines EventId for NotificationScopeEnter() events
+ ///
+ private const int NotificationScopeEnterId = 6;
+
+ ///
+ /// Defines EventId for NotificationScopeLeave() events
+ ///
+ private const int NotificationScopeExitId = 7;
+
+ ///
+ /// Defines EventId for NotificationScopeTrace() events
+ ///
+ private const int NotificationTraceId = 8;
+
+ ///
+ /// Defines EventId for PoolerScopeEnter() events
+ ///
+ private const int PoolerScopeEnterId = 9;
+
+ ///
+ /// Defines EventId for PoolerScopeLeave() events
+ ///
+ private const int PoolerScopeExitId = 10;
+
+ ///
+ /// Defines EventId for PoolerTrace() events
+ ///
+ private const int PoolerTraceId = 11;
+
+ ///
+ /// Defines EventId for AdvancedTrace() events
+ ///
+ private const int AdvancedTraceId = 12;
+
+ ///
+ /// Defines EventId for AdvancedScopeEnter() events
+ ///
+ private const int AdvancedScopeEnterId = 13;
+
+ ///
+ /// Defines EventId for AdvancedScopeLeave() events
+ ///
+ private const int AdvancedScopeExitId = 14;
+
+ ///
+ /// Defines EventId for AdvancedTraceBin() events
+ ///
+ private const int AdvancedTraceBinId = 15;
+
+ ///
+ /// Defines EventId for AdvancedTraceError() events
+ ///
+ private const int AdvancedTraceErrorId = 16;
+
+ ///
+ /// Defines EventId for CorrelationTrace() events
+ ///
+ private const int CorrelationTraceId = 17;
+
+ ///
+ /// Defines EventId for StateDump() events
+ ///
+ private const int StateDumpEventId = 18;
+
+ ///
+ /// Defines EventId for SNITrace() events
+ ///
+ private const int SNITraceEventId = 19;
+
+ ///
+ /// Defines EventId for SNIEnterScope() events
+ ///
+ private const int SNIScopeEnterId = 20;
+
+ ///
+ /// Defines EventId for SNIExitScope() events
+ ///
+ private const int SNIScopeExitId = 21;
+ #endregion
+
+ ///
+ /// These represent logical groups of events that can be turned on and off independently.
+ /// Often each task has a keyword, but where tasks are determined by subsystem, keywords
+ /// are determined by usefulness to end users to filter.
+ ///
+ ///
+ /// The visibility of the enum has to be public, otherwise there will be an ArgumentException
+ /// on calling related WriteEvent() method.
+ /// The Keywords class has to be a nested class.
+ /// Each keyword must be a power of 2.
+ ///
+ #region Keywords
+ public class Keywords
+ {
+ ///
+ /// Captures Start/Stop events before and after command execution.
+ ///
+ public const EventKeywords ExecutionTrace = (EventKeywords)1;
+
+ ///
+ /// Captures basic application flow trace events.
+ ///
+ public const EventKeywords Trace = (EventKeywords)2;
+
+ ///
+ /// Captures basic application scope entering and exiting events.
+ ///
+ public const EventKeywords Scope = (EventKeywords)4;
+
+ ///
+ /// Captures SqlNotification flow trace events.
+ ///
+ public const EventKeywords NotificationTrace = (EventKeywords)8;
+
+ ///
+ /// Captures SqlNotification scope entering and exiting events.
+ ///
+ public const EventKeywords NotificationScope = (EventKeywords)16;
+
+ ///
+ /// Captures connection pooling flow trace events.
+ ///
+ public const EventKeywords PoolerTrace = (EventKeywords)32;
+
+ ///
+ /// Captures connection pooling scope trace events.
+ ///
+ public const EventKeywords PoolerScope = (EventKeywords)64;
+
+ ///
+ /// Captures advanced flow trace events.
+ ///
+ public const EventKeywords AdvancedTrace = (EventKeywords)128;
+
+ ///
+ /// Captures advanced flow trace events with additional information.
+ ///
+ public const EventKeywords AdvancedTraceBin = (EventKeywords)256;
+
+ ///
+ /// Captures correlation flow trace events.
+ ///
+ public const EventKeywords CorrelationTrace = (EventKeywords)512;
+
+ ///
+ /// Captures full state dump of SqlConnection.
+ ///
+ public const EventKeywords StateDump = (EventKeywords)1024;
+
+ ///
+ /// Captures application flow traces from Managed networking implementation.
+ ///
+ public const EventKeywords SNITrace = (EventKeywords)2048;
+
+ ///
+ /// Captures scope trace events from Managed networking implementation.
+ ///
+ public const EventKeywords SNIScope = (EventKeywords)4096;
+ }
+ #endregion
+
+ #region Tasks
+ ///
+ /// Tasks supported by SqlClient's EventSource implementation.
+ ///
+ public static class Tasks
+ {
+ ///
+ /// Task that tracks SqlCommand execution.
+ ///
+ public const EventTask ExecuteCommand = (EventTask)1;
+
+ ///
+ /// Task that tracks trace scope.
+ ///
+ public const EventTask Scope = (EventTask)2;
+
+ ///
+ /// Task that tracks pooler scope.
+ ///
+ public const EventTask PoolerScope = (EventTask)3;
+
+ ///
+ /// Task that tracks notification scope.
+ ///
+ public const EventTask NotificationScope = (EventTask)4;
+
+ ///
+ /// Task that tracks SNI scope.
+ ///
+ public const EventTask SNIScope = (EventTask)5;
+ }
+ #endregion
+
+ #region Enable/Disable Events
+ ///
+ /// Checks if execution trace events are enabled.
+ ///
+ [NonEvent]
+ public bool IsExecutionTraceEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.ExecutionTrace);
+
+ ///
+ /// Checks if trace events are enabled.
+ ///
+ [NonEvent]
+ public bool IsTraceEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.Trace);
+
+ ///
+ /// Checks if scope events are enabled.
+ ///
+ [NonEvent]
+ public bool IsScopeEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.Scope);
+
+ ///
+ /// Checks if notification trace events are enabled.
+ ///
+ [NonEvent]
+ public bool IsNotificationTraceEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.NotificationTrace);
+
+ ///
+ /// Checks if notification scope events are enabled.
+ ///
+ [NonEvent]
+ public bool IsNotificationScopeEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.NotificationScope);
+
+ ///
+ /// Checks if pooler trace events are enabled.
+ ///
+ [NonEvent]
+ public bool IsPoolerTraceEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.PoolerTrace);
+
+ ///
+ /// Checks if pooler scope events are enabled.
+ ///
+ [NonEvent]
+ public bool IsPoolerScopeEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.PoolerScope);
+
+ ///
+ /// Checks if advanced trace events are enabled.
+ ///
+ [NonEvent]
+ public bool IsAdvancedTraceOn() => Log.IsEnabled(EventLevel.Verbose, Keywords.AdvancedTrace);
+
+ ///
+ /// Checks if advanced trace binary events are enabled.
+ ///
+ [NonEvent]
+ public bool IsAdvancedTraceBinOn() => Log.IsEnabled(EventLevel.Verbose, Keywords.AdvancedTraceBin);
+
+ ///
+ /// Checks if correlation trace events are enabled.
+ ///
+ [NonEvent]
+ public bool IsCorrelationEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.CorrelationTrace);
+
+ ///
+ /// Checks if state dump events are enabled.
+ ///
+ [NonEvent]
+ public bool IsStateDumpEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.StateDump);
+
+ ///
+ /// Checks if SNI trace events are enabled.
+ ///
+ [NonEvent]
+ public bool IsSNITraceEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.SNITrace);
+
+ ///
+ /// Checks if SNI scope events are enabled.
+ ///
+ [NonEvent]
+ public bool IsSNIScopeEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.SNIScope);
+ #endregion
+
+ private string GetFormattedMessage(string className, string memberName, string eventType, string message) =>
+ new StringBuilder(className).Append(".").Append(memberName).Append(eventType).Append(message).ToString();
+
+ #region overloads
+ //Never use event writer directly as they are not checking for enabled/disabled situations. Always use overloads.
+
+ #region Trace
+
+ #region Traces without if statements
+ ///
+ /// Writes a formatted trace event with two arguments.
+ ///
+ [NonEvent]
+ public void TraceEvent(string message, T0 args0, T1 args1)
+ {
+ Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
+ }
+
+ ///
+ /// Writes a formatted trace event with three arguments.
+ ///
+ [NonEvent]
+ public void TraceEvent(string message, T0 args0, T1 args1, T2 args2)
+ {
+ Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
+ }
+
+ ///
+ /// Writes a formatted trace event with four arguments.
+ ///
+ [NonEvent]
+ public void TraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
+ {
+ Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
+ }
+ #endregion
+
+ #region Traces with if statements
+ ///
+ /// Writes a trace event if trace is enabled.
+ ///
+ [NonEvent]
+ public void TryTraceEvent(string message)
+ {
+ if (Log.IsTraceEnabled())
+ {
+ Trace(message);
+ }
+ }
+
+ ///
+ /// Writes a formatted trace event with one argument if trace is enabled.
+ ///
+ [NonEvent]
+ public void TryTraceEvent(string message, T0 args0)
+ {
+ if (Log.IsTraceEnabled())
+ {
+ Trace(string.Format(message, args0?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted trace event with two arguments if trace is enabled.
+ ///
+ [NonEvent]
+ public void TryTraceEvent(string message, T0 args0, T1 args1)
+ {
+ if (Log.IsTraceEnabled())
+ {
+ Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted trace event with three arguments if trace is enabled.
+ ///
+ [NonEvent]
+ public void TryTraceEvent(string message, T0 args0, T1 args1, T2 args2)
+ {
+ if (Log.IsTraceEnabled())
+ {
+ Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted trace event with four arguments if trace is enabled.
+ ///
+ [NonEvent]
+ public void TryTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
+ {
+ if (Log.IsTraceEnabled())
+ {
+ Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted trace event with five arguments if trace is enabled.
+ ///
+ [NonEvent]
+ public void TryTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4)
+ {
+ if (Log.IsTraceEnabled())
+ {
+ Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted trace event with six arguments if trace is enabled.
+ ///
+ [NonEvent]
+ public void TryTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, T5 args5)
+ {
+ if (Log.IsTraceEnabled())
+ {
+ Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr, args5?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted trace event with seven arguments if trace is enabled.
+ ///
+ [NonEvent]
+ public void TryTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, T5 args5, T6 arg6)
+ {
+ if (Log.IsTraceEnabled())
+ {
+ Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr, args5?.ToString() ?? NullStr, arg6?.ToString() ?? NullStr));
+ }
+ }
+ #endregion
+
+ #endregion
+
+ #region Scope
+ ///
+ /// Enters a scope and writes a scope event if scope tracing is enabled.
+ ///
+ [NonEvent]
+ public long TryScopeEnterEvent(string className, [CallerMemberName] string memberName = "")
+ {
+ if (Log.IsScopeEnabled())
+ {
+ StringBuilder sb = new StringBuilder(className);
+ sb.Append(".").Append(memberName).Append(" | INFO | SCOPE | Entering Scope {0}");
+ return ScopeEnter(sb.ToString());
+ }
+ return 0;
+ }
+
+ ///
+ /// Enters a scope with one formatted argument if scope tracing is enabled.
+ ///
+ [NonEvent]
+ public long TryScopeEnterEvent(string message, T0 args0)
+ {
+ if (Log.IsScopeEnabled())
+ {
+ return ScopeEnter(string.Format(message, args0?.ToString() ?? NullStr));
+ }
+ return 0;
+ }
+
+ ///
+ /// Enters a scope with two formatted arguments if scope tracing is enabled.
+ ///
+ [NonEvent]
+ public long TryScopeEnterEvent(string message, T0 args0, T1 args1)
+ {
+ if (Log.IsScopeEnabled())
+ {
+ return ScopeEnter(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
+ }
+ return 0;
+ }
+
+ ///
+ /// Enters a scope with three formatted arguments if scope tracing is enabled.
+ ///
+ [NonEvent]
+ public long TryScopeEnterEvent(string message, T0 args0, T1 args1, T2 args2)
+ {
+ if (Log.IsScopeEnabled())
+ {
+ return ScopeEnter(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
+ }
+ return 0;
+ }
+
+ ///
+ /// Enters a scope with four formatted arguments if scope tracing is enabled.
+ ///
+ [NonEvent]
+ public long TryScopeEnterEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
+ {
+ if (Log.IsScopeEnabled())
+ {
+ return ScopeEnter(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
+ }
+ return 0;
+ }
+
+ ///
+ /// Leaves a scope if scope tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryScopeLeaveEvent(long scopeId)
+ {
+ if (Log.IsScopeEnabled())
+ {
+ ScopeLeave(string.Format("Exit Scope {0}", scopeId));
+ }
+ }
+ #endregion
+
+ #region Execution Trace
+ ///
+ /// Writes a BeginExecute trace event if execution tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryBeginExecuteEvent(int objectId, string dataSource, string database, string commandText, Guid? connectionId, [CallerMemberName] string memberName = "")
+ {
+ if (Log.IsExecutionTraceEnabled())
+ {
+ BeginExecute(objectId, dataSource, database, commandText, GetFormattedMessage(SqlCommand_ClassName, memberName, EventType.INFO, $"Object Id {objectId}, Client connection Id {connectionId}, Command Text {commandText}"));
+ }
+ }
+
+ ///
+ /// Writes an EndExecute trace event if execution tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryEndExecuteEvent(int objectId, int compositeState, int sqlExceptionNumber, Guid? connectionId, [CallerMemberName] string memberName = "")
+ {
+ if (Log.IsExecutionTraceEnabled())
+ {
+ EndExecute(objectId, compositeState, sqlExceptionNumber, GetFormattedMessage(SqlCommand_ClassName, memberName, EventType.INFO, $"Object Id {objectId}, Client Connection Id {connectionId}, Composite State {compositeState}, Sql Exception Number {sqlExceptionNumber}"));
+ }
+ }
+ #endregion
+
+ #region Notification Trace
+
+ #region Notification Traces without if statements
+ ///
+ /// Writes a formatted notification trace event with two arguments.
+ ///
+ [NonEvent]
+ public void NotificationTraceEvent(string message, T0 args0, T1 args1)
+ {
+ NotificationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
+ }
+ #endregion
+
+ #region Notification Traces with if statements
+ ///
+ /// Writes a notification trace event if notification tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryNotificationTraceEvent(string message)
+ {
+ if (Log.IsNotificationTraceEnabled())
+ {
+ NotificationTrace(message);
+ }
+ }
+
+ ///
+ /// Writes a formatted notification trace event with one argument if notification tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryNotificationTraceEvent(string message, T0 args0)
+ {
+ if (Log.IsNotificationTraceEnabled())
+ {
+ NotificationTrace(string.Format(message, args0?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted notification trace event with two arguments if notification tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryNotificationTraceEvent(string message, T0 args0, T1 args1)
+ {
+ if (Log.IsNotificationTraceEnabled())
+ {
+ NotificationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted notification trace event with three arguments if notification tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryNotificationTraceEvent(string message, T0 args0, T1 args1, T2 args2)
+ {
+ if (Log.IsNotificationTraceEnabled())
+ {
+ NotificationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted notification trace event with four arguments if notification tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryNotificationTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
+ {
+ if (Log.IsNotificationTraceEnabled())
+ {
+ NotificationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
+ }
+ }
+ #endregion
+
+ #endregion
+
+ #region Notification Scope
+ ///
+ /// Enters a notification scope with one formatted argument if notification scope tracing is enabled.
+ ///
+ [NonEvent]
+ public long TryNotificationScopeEnterEvent(string message, T0 args0)
+ {
+ if (Log.IsNotificationScopeEnabled())
+ {
+ return NotificationScopeEnter(string.Format(message, args0?.ToString() ?? NullStr));
+ }
+ return 0;
+ }
+
+ ///
+ /// Enters a notification scope with two formatted arguments if notification scope tracing is enabled.
+ ///
+ [NonEvent]
+ public long TryNotificationScopeEnterEvent(string message, T0 args0, T1 args1)
+ {
+ if (Log.IsNotificationScopeEnabled())
+ {
+ return NotificationScopeEnter(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
+ }
+ return 0;
+ }
+
+ ///
+ /// Enters a notification scope with three formatted arguments if notification scope tracing is enabled.
+ ///
+ [NonEvent]
+ public long TryNotificationScopeEnterEvent(string message, T0 args0, T1 args1, T2 args2)
+ {
+ if (Log.IsNotificationScopeEnabled())
+ {
+ return NotificationScopeEnter(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
+ }
+ return 0;
+ }
+
+ ///
+ /// Enters a notification scope with four formatted arguments if notification scope tracing is enabled.
+ ///
+ [NonEvent]
+ public long TryNotificationScopeEnterEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
+ {
+ if (Log.IsNotificationScopeEnabled())
+ {
+ return NotificationScopeEnter(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
+ }
+ return 0;
+ }
+
+ ///
+ /// Leaves a notification scope if notification scope tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryNotificationScopeLeaveEvent(long scopeId)
+ {
+ if (Log.IsNotificationScopeEnabled())
+ {
+ NotificationScopeLeave(string.Format("Exit Notification Scope {0}", scopeId));
+ }
+ }
+ #endregion
+
+ #region Pooler Trace
+ ///
+ /// Writes a pooler trace event if pooler tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryPoolerTraceEvent(string message)
+ {
+ if (Log.IsPoolerTraceEnabled())
+ {
+ PoolerTrace(message);
+ }
+ }
+
+ ///
+ /// Writes a formatted pooler trace event with one argument if pooler tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryPoolerTraceEvent(string message, T0 args0)
+ {
+ if (Log.IsPoolerTraceEnabled())
+ {
+ PoolerTrace(string.Format(message, args0?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted pooler trace event with two arguments if pooler tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryPoolerTraceEvent(string message, T0 args0, T1 args1)
+ {
+ if (Log.IsPoolerTraceEnabled())
+ {
+ PoolerTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted pooler trace event with three arguments if pooler tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryPoolerTraceEvent(string message, T0 args0, T1 args1, T2 args2)
+ {
+ if (Log.IsPoolerTraceEnabled())
+ {
+ PoolerTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted pooler trace event with four arguments if pooler tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryPoolerTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
+ {
+ if (Log.IsPoolerTraceEnabled())
+ {
+ PoolerTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
+ }
+ }
+ #endregion
+
+ #region Pooler Scope
+ ///
+ /// Enters a pooler scope with one formatted argument if pooler scope tracing is enabled.
+ ///
+ [NonEvent]
+ public long TryPoolerScopeEnterEvent(string message, T0 args0)
+ {
+ if (Log.IsPoolerScopeEnabled())
+ {
+ return PoolerScopeEnter(string.Format(message, args0?.ToString() ?? NullStr));
+ }
+ return 0;
+ }
+
+ ///
+ /// Leaves a pooler scope if pooler scope tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryPoolerScopeLeaveEvent(long scopeId)
+ {
+ if (Log.IsPoolerScopeEnabled())
+ {
+ PoolerScopeLeave(string.Format("Exit Pooler Scope {0}", scopeId));
+ }
+ }
+ #endregion
+
+ #region AdvancedTrace
+
+ #region AdvancedTraces without if statements
+ ///
+ /// Writes a formatted advanced trace event with one argument.
+ ///
+ [NonEvent]
+ public void AdvancedTraceEvent(string message, T0 args0)
+ {
+ AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr));
+ }
+
+ ///
+ /// Writes a formatted advanced trace event with two arguments.
+ ///
+ [NonEvent]
+ public void AdvancedTraceEvent(string message, T0 args0, T1 args1)
+ {
+ AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
+ }
+
+ ///
+ /// Writes a formatted advanced trace event with three arguments.
+ ///
+ [NonEvent]
+ public void AdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2)
+ {
+ AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
+ }
+
+ ///
+ /// Writes a formatted advanced trace event with four arguments.
+ ///
+ [NonEvent]
+ public void AdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
+ {
+ AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
+ }
+ #endregion
+
+ #region AdvancedTraces with if statements
+ ///
+ /// Writes an advanced trace event if advanced tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryAdvancedTraceEvent(string message)
+ {
+ if (Log.IsAdvancedTraceOn())
+ {
+ AdvancedTrace(message);
+ }
+ }
+
+ ///
+ /// Writes a formatted advanced trace event with one argument if advanced tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryAdvancedTraceEvent(string message, T0 args0)
+ {
+ if (Log.IsAdvancedTraceOn())
+ {
+ AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted advanced trace event with two arguments if advanced tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryAdvancedTraceEvent(string message, T0 args0, T1 args1)
+ {
+ if (Log.IsAdvancedTraceOn())
+ {
+ AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted advanced trace event with three arguments if advanced tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryAdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2)
+ {
+ if (Log.IsAdvancedTraceOn())
+ {
+ AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted advanced trace event with four arguments if advanced tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryAdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
+ {
+ if (Log.IsAdvancedTraceOn())
+ {
+ AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted advanced trace event with five arguments if advanced tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryAdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4)
+ {
+ if (Log.IsAdvancedTraceOn())
+ {
+ AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted advanced trace event with six arguments if advanced tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryAdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, T5 args5)
+ {
+ if (Log.IsAdvancedTraceOn())
+ {
+ AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr, args5?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted advanced trace event with eight arguments if advanced tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryAdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, T5 args5, T6 args6, T7 args7)
+ {
+ if (Log.IsAdvancedTraceOn())
+ {
+ AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr, args5?.ToString() ?? NullStr, args6?.ToString() ?? NullStr, args7?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted advanced trace event with seven arguments if advanced tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryAdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, T5 args5, T6 args6)
+ {
+ if (Log.IsAdvancedTraceOn())
+ {
+ AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr, args5?.ToString() ?? NullStr, args6?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Enters an advanced scope with one formatted argument if advanced tracing is enabled.
+ ///
+ [NonEvent]
+ public long TryAdvancedScopeEnterEvent(string message, T0 args0)
+ {
+ if (Log.IsAdvancedTraceOn())
+ {
+ return AdvancedScopeEnter(string.Format(message, args0?.ToString() ?? NullStr));
+ }
+ return 0;
+ }
+
+ ///
+ /// Leaves an advanced scope if advanced tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryAdvanceScopeLeave(long scopeId)
+ {
+ if (Log.IsAdvancedTraceOn())
+ {
+ AdvancedScopeLeave(string.Format("Exit Advanced Scope {0}", scopeId));
+ }
+ }
+
+ ///
+ /// Writes a formatted advanced trace binary event with three arguments if advanced binary tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryAdvancedTraceBinEvent(string message, T0 args0, T1 args1, T2 args2)
+ {
+ if (Log.IsAdvancedTraceBinOn())
+ {
+ if (args1 is byte[] args1Bytes)
+ {
+ AdvancedTraceBin(string.Format(message, args0?.ToString() ?? NullStr, BitConverter.ToString(args1Bytes).Replace("-", ""), args2?.ToString() ?? NullStr));
+ }
+ else
+ {
+ AdvancedTraceBin(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
+ }
+ }
+ }
+
+ ///
+ /// Writes a formatted advanced trace error event with five arguments if advanced tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryAdvancedTraceErrorEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4)
+ {
+ if (Log.IsAdvancedTraceOn())
+ {
+ AdvancedTraceError(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr));
+ }
+ }
+ #endregion
+
+ #endregion
+
+ #region Correlation Trace
+
+ ///
+ /// Writes a correlation trace event if correlation tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryCorrelationTraceEvent(string message)
+ {
+ if (Log.IsCorrelationEnabled())
+ {
+ CorrelationTrace(message);
+ }
+ }
+
+ ///
+ /// Writes a formatted correlation trace event with one argument if correlation tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryCorrelationTraceEvent(string message, T0 args0)
+ {
+ if (Log.IsCorrelationEnabled())
+ {
+ CorrelationTrace(string.Format(message, args0?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted correlation trace event with two arguments if correlation tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryCorrelationTraceEvent(string message, T0 args0, T1 args1)
+ {
+ if (Log.IsCorrelationEnabled())
+ {
+ CorrelationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted correlation trace event with three arguments if correlation tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryCorrelationTraceEvent(string message, T0 args0, T1 args1, T2 args2)
+ {
+ if (Log.IsCorrelationEnabled())
+ {
+ CorrelationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted correlation trace event with four arguments if correlation tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryCorrelationTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
+ {
+ if (Log.IsCorrelationEnabled())
+ {
+ CorrelationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted correlation trace event with five arguments if correlation tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryCorrelationTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4)
+ {
+ if (Log.IsCorrelationEnabled())
+ {
+ CorrelationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr));
+ }
+ }
+
+ ///
+ /// Writes a formatted correlation trace event with six arguments if correlation tracing is enabled.
+ ///
+ [NonEvent]
+ public void TryCorrelationTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, T5 args5)
+ {
+ if (Log.IsCorrelationEnabled())
+ {
+ CorrelationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr, args5?.ToString() ?? NullStr));
+ }
+ }
+ #endregion
+
+ #region State Dump without if statements
+ ///
+ /// Writes a formatted state dump event with two arguments.
+ ///
+ [NonEvent]
+ public void StateDumpEvent(string message, T0 args0, T1 args1)
+ {
+ StateDump(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
+ }
+
+ ///
+ /// Writes a formatted state dump event with three arguments.
+ ///
+ [NonEvent]
+ public void StateDumpEvent(string message, T0 args0, T1 args1, T2 args2)
+ {
+ StateDump(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
+ }
+ #endregion
+
+ #region SNI Trace
+ ///
+ /// Writes an SNI trace event if SNI tracing is enabled.
+ ///
+ [NonEvent]
+ public void TrySNITraceEvent(string className, string eventType, string message, [CallerMemberName] string memberName = "")
+ {
+ if (Log.IsSNITraceEnabled())
+ {
+ SNITrace(GetFormattedMessage(className, memberName, eventType, message));
+ }
+ }
+
+ ///
+ /// Writes a formatted SNI trace event with one argument if SNI tracing is enabled.
+ ///
+ [NonEvent]
+ public void TrySNITraceEvent(string className, string eventType, string message, T0 args0, [CallerMemberName] string memberName = "")
+ {
+ if (Log.IsSNITraceEnabled())
+ {
+ SNITrace(GetFormattedMessage(className, memberName, eventType, string.Format(message, args0?.ToString() ?? NullStr)));
+ }
+ }
+
+ ///
+ /// Writes a formatted SNI trace event with two arguments if SNI tracing is enabled.
+ ///
+ [NonEvent]
+ public void TrySNITraceEvent(string className, string eventType, string message, T0 args0, T1 args1, [CallerMemberName] string memberName = "")
+ {
+ if (Log.IsSNITraceEnabled())
+ {
+ SNITrace(GetFormattedMessage(className, memberName, eventType, string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr)));
+ }
+ }
+
+ ///
+ /// Writes a formatted SNI trace event with three arguments if SNI tracing is enabled.
+ ///
+ [NonEvent]
+ public void TrySNITraceEvent(string className, string eventType, string message, T0 args0, T1 args1, T2 args2, [CallerMemberName] string memberName = "")
+ {
+ if (Log.IsSNITraceEnabled())
+ {
+ SNITrace(GetFormattedMessage(className, memberName, eventType, string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr)));
+ }
+ }
+
+ ///
+ /// Writes a formatted SNI trace event with four arguments if SNI tracing is enabled.
+ ///
+ [NonEvent]
+ public void TrySNITraceEvent(string className, string eventType, string message, T0 args0, T1 args1, T2 args2, T3 args3, [CallerMemberName] string memberName = "")
+ {
+ if (Log.IsSNITraceEnabled())
+ {
+ SNITrace(GetFormattedMessage(className, memberName, eventType, string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr)));
+ }
+ }
+
+ ///
+ /// Writes a formatted SNI trace event with five arguments if SNI tracing is enabled.
+ ///
+ [NonEvent]
+ public void TrySNITraceEvent(string className, string eventType, string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, [CallerMemberName] string memberName = "")
+ {
+ if (Log.IsSNITraceEnabled())
+ {
+ SNITrace(GetFormattedMessage(className, memberName, eventType, string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr)));
+ }
+ }
+
+ ///
+ /// Writes a formatted SNI trace event with six arguments if SNI tracing is enabled.
+ ///
+ [NonEvent]
+ public void TrySNITraceEvent(string className, string eventType, string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, T5 args5, [CallerMemberName] string memberName = "")
+ {
+ if (Log.IsSNITraceEnabled())
+ {
+ SNITrace(GetFormattedMessage(className, memberName, eventType, string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr, args5?.ToString() ?? NullStr)));
+ }
+ }
+ #endregion
+
+ #region SNI Scope
+ ///
+ /// Enters an SNI scope if SNI scope tracing is enabled.
+ ///
+ [NonEvent]
+ public long TrySNIScopeEnterEvent(string className, [CallerMemberName] string memberName = "")
+ {
+ if (Log.IsSNIScopeEnabled())
+ {
+ long scopeId = Interlocked.Increment(ref s_nextSNIScopeId);
+ WriteEvent(SNIScopeEnterId, $"{className}.{memberName} | SNI | INFO | SCOPE | Entering Scope {scopeId}");
+ return scopeId;
+ }
+ return 0;
+ }
+
+ ///
+ /// Leaves an SNI scope if SNI scope tracing is enabled.
+ ///
+ [NonEvent]
+ public void TrySNIScopeLeaveEvent(long scopeId)
+ {
+ if (Log.IsSNIScopeEnabled())
+ {
+ SNIScopeLeave(string.Format("Exit SNI Scope {0}", scopeId));
+ }
+ }
+ #endregion
+
+ #endregion
+
+ #region Write Events
+ // Do not change the first 4 arguments in this Event writer as OpenTelemetry and ApplicationInsight are relating to the same format,
+ // unless you have checked with them and they are able to change their design. Additional items could be added at the end.
+
+ ///
+ /// Writes a BeginExecute event.
+ ///
+ [Event(BeginExecuteEventId, Keywords = Keywords.ExecutionTrace, Task = Tasks.ExecuteCommand, Opcode = EventOpcode.Start)]
+ public void BeginExecute(int objectId, string dataSource, string database, string commandText, string message)
+ {
+ WriteEvent(BeginExecuteEventId, objectId, dataSource, database, commandText, message);
+ }
+
+ // Do not change the first 3 arguments in this Event writer as OpenTelemetry and ApplicationInsight are relating to the same format,
+ // unless you have checked with them and they are able to change their design. Additional items could be added at the end.
+
+ ///
+ /// Writes an EndExecute event.
+ ///
+ [Event(EndExecuteEventId, Keywords = Keywords.ExecutionTrace, Task = Tasks.ExecuteCommand, Opcode = EventOpcode.Stop)]
+ public void EndExecute(int objectId, int compositestate, int sqlExceptionNumber, string message)
+ {
+ WriteEvent(EndExecuteEventId, objectId, compositestate, sqlExceptionNumber, message);
+ }
+
+ ///
+ /// Writes a Trace event.
+ ///
+ [Event(TraceEventId, Level = EventLevel.Informational, Keywords = Keywords.Trace)]
+ public void Trace(string message) =>
+ WriteEvent(TraceEventId, message);
+
+ ///
+ /// Enters a scope.
+ ///
+ [Event(ScopeEnterId, Level = EventLevel.Informational, Task = Tasks.Scope, Opcode = EventOpcode.Start, Keywords = Keywords.Scope)]
+ public long ScopeEnter(string message)
+ {
+ long scopeId = Interlocked.Increment(ref s_nextScopeId);
+ WriteEvent(ScopeEnterId, string.Format(message, scopeId));
+ return scopeId;
+ }
+
+ ///
+ /// Leaves a scope.
+ ///
+ [Event(ScopeExitId, Level = EventLevel.Informational, Task = Tasks.Scope, Opcode = EventOpcode.Stop, Keywords = Keywords.Scope)]
+ public void ScopeLeave(string message) =>
+ WriteEvent(ScopeExitId, message);
+
+ ///
+ /// Writes a notification trace event.
+ ///
+ [Event(NotificationTraceId, Level = EventLevel.Informational, Keywords = Keywords.NotificationTrace)]
+ public void NotificationTrace(string message) =>
+ WriteEvent(NotificationTraceId, message);
+
+ ///
+ /// Enters a notification scope.
+ ///
+ [Event(NotificationScopeEnterId, Level = EventLevel.Informational, Task = Tasks.NotificationScope, Opcode = EventOpcode.Start, Keywords = Keywords.NotificationScope)]
+ public long NotificationScopeEnter(string message)
+ {
+ long scopeId = Interlocked.Increment(ref s_nextNotificationScopeId);
+ WriteEvent(NotificationScopeEnterId, string.Format(message, scopeId));
+ return scopeId;
+ }
+
+ ///
+ /// Leaves a notification scope.
+ ///
+ [Event(NotificationScopeExitId, Level = EventLevel.Informational, Task = Tasks.NotificationScope, Opcode = EventOpcode.Stop, Keywords = Keywords.NotificationScope)]
+ public void NotificationScopeLeave(string message) =>
+ WriteEvent(NotificationScopeExitId, message);
+
+ ///
+ /// Writes a pooler trace event.
+ ///
+ [Event(PoolerTraceId, Level = EventLevel.Informational, Keywords = Keywords.PoolerTrace)]
+ public void PoolerTrace(string message) =>
+ WriteEvent(PoolerTraceId, message);
+
+ ///
+ /// Enters a pooler scope.
+ ///
+ [Event(PoolerScopeEnterId, Level = EventLevel.Informational, Task = Tasks.PoolerScope, Opcode = EventOpcode.Start, Keywords = Keywords.PoolerScope)]
+ public long PoolerScopeEnter(string message)
+ {
+ long scopeId = Interlocked.Increment(ref s_nextPoolerScopeId);
+ WriteEvent(PoolerScopeEnterId, string.Format(message, scopeId));
+ return scopeId;
+ }
+
+ ///
+ /// Leaves a pooler scope.
+ ///
+ [Event(PoolerScopeExitId, Level = EventLevel.Informational, Task = Tasks.PoolerScope, Opcode = EventOpcode.Stop, Keywords = Keywords.PoolerScope)]
+ public void PoolerScopeLeave(string message) =>
+ WriteEvent(PoolerScopeExitId, message);
+
+ ///
+ /// Writes an advanced trace event.
+ ///
+ [Event(AdvancedTraceId, Level = EventLevel.Verbose, Keywords = Keywords.AdvancedTrace)]
+ public void AdvancedTrace(string message) =>
+ WriteEvent(AdvancedTraceId, message);
+
+ ///
+ /// Enters an advanced scope.
+ ///
+ [Event(AdvancedScopeEnterId, Level = EventLevel.Verbose, Opcode = EventOpcode.Start, Keywords = Keywords.AdvancedTrace)]
+ public long AdvancedScopeEnter(string message)
+ {
+ long scopeId = Interlocked.Increment(ref s_nextScopeId);
+ WriteEvent(AdvancedScopeEnterId, string.Format(message, scopeId));
+ return scopeId;
+ }
+
+ ///
+ /// Leaves an advanced scope.
+ ///
+ [Event(AdvancedScopeExitId, Level = EventLevel.Verbose, Opcode = EventOpcode.Stop, Keywords = Keywords.AdvancedTrace)]
+ public void AdvancedScopeLeave(string message) =>
+ WriteEvent(AdvancedScopeExitId, message);
+
+ ///
+ /// Writes an advanced trace binary event.
+ ///
+ [Event(AdvancedTraceBinId, Level = EventLevel.Verbose, Keywords = Keywords.AdvancedTraceBin)]
+ public void AdvancedTraceBin(string message) =>
+ WriteEvent(AdvancedTraceBinId, message);
+
+ ///
+ /// Writes an advanced trace error event.
+ ///
+ [Event(AdvancedTraceErrorId, Level = EventLevel.Error, Keywords = Keywords.AdvancedTrace)]
+ public void AdvancedTraceError(string message) =>
+ WriteEvent(AdvancedTraceErrorId, message);
+
+ ///
+ /// Writes a correlation trace event.
+ ///
+ [Event(CorrelationTraceId, Level = EventLevel.Informational, Keywords = Keywords.CorrelationTrace)]
+ public void CorrelationTrace(string message) =>
+ WriteEvent(CorrelationTraceId, message);
+
+ ///
+ /// Writes a state dump event.
+ ///
+ [Event(StateDumpEventId, Level = EventLevel.Verbose, Keywords = Keywords.StateDump)]
+ public void StateDump(string message) =>
+ WriteEvent(StateDumpEventId, message);
+
+ ///
+ /// Writes an SNI trace event.
+ ///
+ [Event(SNITraceEventId, Level = EventLevel.Informational, Keywords = Keywords.SNITrace)]
+ public void SNITrace(string message) =>
+ WriteEvent(SNITraceEventId, message);
+
+ ///
+ /// Enters an SNI scope.
+ ///
+ [Event(SNIScopeEnterId, Level = EventLevel.Informational, Task = Tasks.SNIScope, Opcode = EventOpcode.Start, Keywords = Keywords.SNIScope)]
+ public long SNIScopeEnter(string message)
+ {
+ long scopeId = Interlocked.Increment(ref s_nextSNIScopeId);
+ WriteEvent(SNIScopeEnterId, string.Format(message, scopeId));
+ return scopeId;
+ }
+
+ ///
+ /// Leaves an SNI scope.
+ ///
+ [Event(SNIScopeExitId, Level = EventLevel.Informational, Task = Tasks.SNIScope, Opcode = EventOpcode.Stop, Keywords = Keywords.SNIScope)]
+ public void SNIScopeLeave(string message) =>
+ WriteEvent(SNIScopeExitId, message);
+ #endregion
+ }
+
+ ///
+ /// Constants for event type labels used in formatted event messages.
+ ///
+ public static class EventType
+ {
+ ///
+ /// Informational event type label.
+ ///
+ public const string INFO = " | INFO | ";
+
+ ///
+ /// Error event type label.
+ ///
+ public const string ERR = " | ERR | ";
+ }
+
+ ///
+ /// A disposable scope for SNI event tracing. Automatically leaves the scope when disposed.
+ ///
+ public readonly struct SqlClientSNIEventScope : IDisposable
+ {
+ private readonly long _scopeId;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The scope identifier.
+ public SqlClientSNIEventScope(long scopeID) => _scopeId = scopeID;
+
+ ///
+ public void Dispose()
+ {
+ if (_scopeId == 0)
+ {
+ return;
+ }
+ SqlClientEventSource.Log.TrySNIScopeLeaveEvent(_scopeId);
+ }
+
+ ///
+ /// Creates a new SNI event scope.
+ ///
+ /// The class name for the scope.
+ /// The member name for the scope (auto-populated by caller).
+ /// A new instance.
+ public static SqlClientSNIEventScope Create(string className, [CallerMemberName] string memberName = "")
+ => new SqlClientSNIEventScope(SqlClientEventSource.Log.TrySNIScopeEnterEvent(className, memberName));
+ }
+
+ ///
+ /// A disposable scope for general event tracing. Automatically leaves the scope when disposed.
+ ///
+ public readonly ref struct SqlClientEventScope
+ {
+ private readonly long _scopeId;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The scope identifier.
+ public SqlClientEventScope(long scopeID) => _scopeId = scopeID;
+
+ ///
+ /// Disposes the scope, leaving the event scope if the scope ID is non-zero.
+ ///
+ public void Dispose()
+ {
+ if (_scopeId != 0)
+ {
+ SqlClientEventSource.Log.TryScopeLeaveEvent(_scopeId);
+ }
+ }
+
+ ///
+ /// Creates a new event scope with one formatted argument.
+ ///
+ public static SqlClientEventScope Create(string message, T0 args0) => new SqlClientEventScope(SqlClientEventSource.Log.TryScopeEnterEvent(message, args0));
+
+ ///
+ /// Creates a new event scope with two formatted arguments.
+ ///
+ public static SqlClientEventScope Create(string message, T0 args0, T1 args1) => new SqlClientEventScope(SqlClientEventSource.Log.TryScopeEnterEvent(message, args0, args1));
+
+ ///
+ /// Creates a new event scope for a class with the calling member name.
+ ///
+ public static SqlClientEventScope Create(string className, [CallerMemberName] string memberName = "") => new SqlClientEventScope(SqlClientEventSource.Log.TryScopeEnterEvent(className, memberName));
+
+ ///
+ /// Creates a new event scope with a pre-existing scope identifier.
+ ///
+ public static SqlClientEventScope Create(long scopeId) => new SqlClientEventScope(scopeId);
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient.sln b/src/Microsoft.Data.SqlClient.sln
index 78eddc267a..151c633480 100644
--- a/src/Microsoft.Data.SqlClient.sln
+++ b/src/Microsoft.Data.SqlClient.sln
@@ -356,6 +356,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{5AF52CDD-D
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azure.Test", "Microsoft.Data.SqlClient.Extensions\Azure\test\Azure.Test.csproj", "{4B953573-C3CD-4845-896B-EA0A0B7A7B27}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Logging", "Logging", "{B3A1F1C2-7D4E-4A5B-9C6D-8E2F0A1B3C4D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D4E5F6A7-1B2C-3D4E-5F6A-7B8C9D0E1F2A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logging", "Microsoft.Data.SqlClient.Extensions\Logging\src\Logging.csproj", "{A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D}"
+EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.SqlClient", "Microsoft.Data.SqlClient", "{7289C27E-D7DF-2C71-84B4-151F3A162493}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{7E0602AC-7F0A-362A-D734-0FDDFCC600B5}"
@@ -759,6 +765,18 @@ Global
{4B953573-C3CD-4845-896B-EA0A0B7A7B27}.Release|x64.Build.0 = Release|Any CPU
{4B953573-C3CD-4845-896B-EA0A0B7A7B27}.Release|x86.ActiveCfg = Release|Any CPU
{4B953573-C3CD-4845-896B-EA0A0B7A7B27}.Release|x86.Build.0 = Release|Any CPU
+ {A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D}.Debug|x64.Build.0 = Debug|Any CPU
+ {A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D}.Debug|x86.Build.0 = Debug|Any CPU
+ {A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D}.Release|x64.ActiveCfg = Release|Any CPU
+ {A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D}.Release|x64.Build.0 = Release|Any CPU
+ {A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D}.Release|x86.ActiveCfg = Release|Any CPU
+ {A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -826,6 +844,9 @@ Global
{DCD79241-612B-4081-A8CC-BD7A4ABC1662} = {0D2F834B-6D91-18D0-3F09-672D448751BD}
{5AF52CDD-DF78-3712-7516-5B49F94F9491} = {A20114E1-82D8-903A-C389-726EB4FD943F}
{4B953573-C3CD-4845-896B-EA0A0B7A7B27} = {5AF52CDD-DF78-3712-7516-5B49F94F9491}
+ {B3A1F1C2-7D4E-4A5B-9C6D-8E2F0A1B3C4D} = {19F1F1E5-3013-7660-661A-2A15F7D606C1}
+ {D4E5F6A7-1B2C-3D4E-5F6A-7B8C9D0E1F2A} = {B3A1F1C2-7D4E-4A5B-9C6D-8E2F0A1B3C4D}
+ {A1B2C3D4-E5F6-7A8B-9C0D-1E2F3A4B5C6D} = {D4E5F6A7-1B2C-3D4E-5F6A-7B8C9D0E1F2A}
{7E0602AC-7F0A-362A-D734-0FDDFCC600B5} = {7289C27E-D7DF-2C71-84B4-151F3A162493}
{134A5E42-015B-3575-2B2B-722614F4C835} = {7E0602AC-7F0A-362A-D734-0FDDFCC600B5}
{2B71F605-037E-5629-6E23-0FA3C297446D} = {7289C27E-D7DF-2C71-84B4-151F3A162493}
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/AKVEventSource.cs b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/AKVEventSource.cs
deleted file mode 100644
index 085232af78..0000000000
--- a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/AKVEventSource.cs
+++ /dev/null
@@ -1,127 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Diagnostics;
-using System.Diagnostics.Tracing;
-using System.Threading;
-
-namespace Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
-{
- [EventSource(Name = "Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.EventSource")]
- internal class AKVEventSource : EventSource
- {
- // Defines the singleton instance for the Resources ETW provider
- public static AKVEventSource Log = new();
-
- private AKVEventSource() { }
-
- // Initialized static Scope IDs
- private static long s_nextScopeId = 0;
-
- // Provides Correlation Manager Activity Id for current scope.
- private static Guid GetCorrelationActivityId()
- {
- if (Trace.CorrelationManager.ActivityId == Guid.Empty)
- {
- Trace.CorrelationManager.ActivityId = Guid.NewGuid();
- }
- return Trace.CorrelationManager.ActivityId;
- }
-
- #region Keywords
- public class Keywords
- {
- ///
- /// Captures basic application flow trace events.
- ///
- internal const EventKeywords Trace = (EventKeywords)1;
-
- ///
- /// Captures basic application scope entering and exiting events.
- ///
- internal const EventKeywords Scope = (EventKeywords)2;
- }
- #endregion
-
- #region Tasks
- ///
- /// Tasks supported by AKV Provider's EventSource implementation
- ///
- public class Tasks
- {
- ///
- /// Task that tracks trace scope.
- ///
- public const EventTask Scope = (EventTask)1;
- }
- #endregion
-
- [NonEvent]
- internal bool IsTraceEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.Trace);
-
- [NonEvent]
- internal bool IsScopeEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.Scope);
-
- #region Event Methods
- [NonEvent]
- internal void TryTraceEvent(string message, object p1 = null, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
- {
- if (IsTraceEnabled())
- {
- WriteTrace(string.Format("Caller: {0}, Message: {1}", memberName,
- p1 == null ? message :
- string.Format(message, p1.ToString().Length > 10 ?
- p1.ToString().Substring(0, 10) + "..." : p1)));
- }
- }
- [NonEvent]
- internal long TryScopeEnterEvent(string memberName)
- {
- if (IsScopeEnabled())
- {
- return ScopeEnter(memberName);
- }
- return default;
- }
- [NonEvent]
- internal void TryScopeExitEvent(long scopeId)
- {
- if (Log.IsScopeEnabled())
- {
- ScopeExit(scopeId);
- }
- }
- #endregion
-
- #region Write Events
- [Event(1, Level = EventLevel.Informational, Keywords = Keywords.Trace)]
- internal void WriteTrace(string message) => WriteEvent(1, message);
-
- [Event(2, Level = EventLevel.Informational, Task = Tasks.Scope, Opcode = EventOpcode.Start, Keywords = Keywords.Scope)]
- internal long ScopeEnter(string caller)
- {
- SetCurrentThreadActivityId(GetCorrelationActivityId());
- long scopeId = Interlocked.Increment(ref s_nextScopeId);
- WriteEvent(2, string.Format("Entered Scope: {0}, Caller: {1}", scopeId, caller));
- return scopeId;
- }
-
- [Event(3, Level = EventLevel.Informational, Task = Tasks.Scope, Opcode = EventOpcode.Stop, Keywords = Keywords.Scope)]
- internal void ScopeExit(long scopeId) => WriteEvent(3, scopeId);
- #endregion
- }
-
- internal readonly struct AKVScope : IDisposable
- {
- private readonly long _scopeId;
-
- public AKVScope(long scopeID) => _scopeId = scopeID;
- public void Dispose() =>
- AKVEventSource.Log.TryScopeExitEvent(_scopeId);
-
- public static AKVScope Create([System.Runtime.CompilerServices.CallerMemberName] string memberName = "") =>
- new(AKVEventSource.Log.TryScopeEnterEvent(memberName));
- }
-}
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/AzureSqlKeyCryptographer.cs b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/AzureSqlKeyCryptographer.cs
index c4e9eb8396..bf41db6dfc 100644
--- a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/AzureSqlKeyCryptographer.cs
+++ b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/AzureSqlKeyCryptographer.cs
@@ -97,12 +97,12 @@ internal KeyVaultKey GetKey(string keyIdentifierUri)
{
if (_keyDictionary.TryGetValue(keyIdentifierUri, out KeyVaultKey key))
{
- AKVEventSource.Log.TryTraceEvent("Fetched key name={0} from cache", key.Name);
+ SqlClientEventSource.Log.TryTraceEvent("Fetched key name={0} from cache", key.Name);
return key;
}
// Not a public exception - not likely to occur.
- AKVEventSource.Log.TryTraceEvent("Key not found; URI={0}", keyIdentifierUri);
+ SqlClientEventSource.Log.TryTraceEvent("Key not found; URI={0}", keyIdentifierUri);
throw ADP.MasterKeyNotFound(keyIdentifierUri);
}
@@ -128,21 +128,21 @@ internal byte[] SignData(byte[] message, string keyIdentifierUri)
internal bool VerifyData(byte[] message, byte[] signature, string keyIdentifierUri)
{
CryptographyClient cryptographyClient = GetCryptographyClient(keyIdentifierUri);
- AKVEventSource.Log.TryTraceEvent("Sending request to verify data");
+ SqlClientEventSource.Log.TryTraceEvent("Sending request to verify data");
return cryptographyClient.VerifyData(RS256, message, signature).IsValid;
}
internal byte[] UnwrapKey(KeyWrapAlgorithm keyWrapAlgorithm, byte[] encryptedKey, string keyIdentifierUri)
{
CryptographyClient cryptographyClient = GetCryptographyClient(keyIdentifierUri);
- AKVEventSource.Log.TryTraceEvent("Sending request to unwrap key.");
+ SqlClientEventSource.Log.TryTraceEvent("Sending request to unwrap key.");
return cryptographyClient.UnwrapKey(keyWrapAlgorithm, encryptedKey).Key;
}
internal byte[] WrapKey(KeyWrapAlgorithm keyWrapAlgorithm, byte[] key, string keyIdentifierUri)
{
CryptographyClient cryptographyClient = GetCryptographyClient(keyIdentifierUri);
- AKVEventSource.Log.TryTraceEvent("Sending request to wrap key.");
+ SqlClientEventSource.Log.TryTraceEvent("Sending request to wrap key.");
return cryptographyClient.WrapKey(keyWrapAlgorithm, key).EncryptedKey;
}
@@ -166,7 +166,7 @@ private CryptographyClient GetCryptographyClient(string keyIdentifierUri)
/// The version of the Azure Key Vault key
private KeyVaultKey FetchKeyFromKeyVault(KeyClient keyClient, string keyName, string keyVersion)
{
- AKVEventSource.Log.TryTraceEvent("Fetching key name={0}", keyName);
+ SqlClientEventSource.Log.TryTraceEvent("Fetching key name={0}", keyName);
Azure.Response keyResponse = keyClient?.GetKey(keyName, keyVersion);
@@ -175,10 +175,10 @@ private KeyVaultKey FetchKeyFromKeyVault(KeyClient keyClient, string keyName, st
// In such cases, we log the error and throw an exception.
if (keyResponse == null || keyResponse.Value == null || keyResponse.GetRawResponse().IsError)
{
- AKVEventSource.Log.TryTraceEvent("Get Key failed to fetch Key from Azure Key Vault for key {0}, version {1}", keyName, keyVersion);
+ SqlClientEventSource.Log.TryTraceEvent("Get Key failed to fetch Key from Azure Key Vault for key {0}, version {1}", keyName, keyVersion);
if (keyResponse?.GetRawResponse() is Azure.Response response)
{
- AKVEventSource.Log.TryTraceEvent("Response status {0} : {1}", response.Status, response.ReasonPhrase);
+ SqlClientEventSource.Log.TryTraceEvent("Response status {0} : {1}", response.Status, response.ReasonPhrase);
}
throw ADP.GetKeyFailed(keyName);
}
@@ -210,7 +210,7 @@ private static KeyVaultKey ValidateRsaKey(KeyVaultKey key)
{
if (key.KeyType != KeyType.Rsa && key.KeyType != KeyType.RsaHsm)
{
- AKVEventSource.Log.TryTraceEvent("Non-RSA KeyType received: {0}", key.KeyType);
+ SqlClientEventSource.Log.TryTraceEvent("Non-RSA KeyType received: {0}", key.KeyType);
throw ADP.NonRsaKeyFormat(key.KeyType.ToString());
}
@@ -231,8 +231,8 @@ private static void ParseAKVPath(string masterKeyPath, out Uri vaultUri, out str
masterKeyName = masterKeyPathUri.Segments[2];
masterKeyVersion = masterKeyPathUri.Segments.Length > 3 ? masterKeyPathUri.Segments[3] : null;
- AKVEventSource.Log.TryTraceEvent("Received Key Name: {0}", masterKeyName);
- AKVEventSource.Log.TryTraceEvent("Received Key Version: {0}", masterKeyVersion);
+ SqlClientEventSource.Log.TryTraceEvent("Received Key Name: {0}", masterKeyName);
+ SqlClientEventSource.Log.TryTraceEvent("Received Key Version: {0}", masterKeyVersion);
}
}
}
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/LocalCache.cs b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/LocalCache.cs
index 7fbffe0ae6..cbf7715d10 100644
--- a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/LocalCache.cs
+++ b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/LocalCache.cs
@@ -61,13 +61,13 @@ internal TValue GetOrCreate(TKey key, Func createItem)
{
if (TimeToLive <= TimeSpan.Zero)
{
- AKVEventSource.Log.TryTraceEvent("Key caching found disabled, fetching key information.");
+ SqlClientEventSource.Log.TryTraceEvent("Key caching found disabled, fetching key information.");
return createItem();
}
if (!_cache.TryGetValue(key, out TValue cacheEntry))
{
- AKVEventSource.Log.TryTraceEvent("Cached entry not found, creating new entry.");
+ SqlClientEventSource.Log.TryTraceEvent("Cached entry not found, creating new entry.");
if (_cache.Count == _maxSize)
{
_cache.Compact(Max(0.10, 1.0 / _maxSize));
@@ -80,11 +80,11 @@ internal TValue GetOrCreate(TKey key, Func createItem)
};
_cache.Set(key, cacheEntry, cacheEntryOptions);
- AKVEventSource.Log.TryTraceEvent("Entry added to local cache.");
+ SqlClientEventSource.Log.TryTraceEvent("Entry added to local cache.");
}
else
{
- AKVEventSource.Log.TryTraceEvent("Cached entry found.");
+ SqlClientEventSource.Log.TryTraceEvent("Cached entry found.");
}
return cacheEntry;
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj
index 8b1aa8539b..0eb60b0952 100644
--- a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj
+++ b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj
@@ -38,6 +38,14 @@
Condition="'$(ReferenceType)' == 'Package'" />
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/PackageReadme.md b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/PackageReadme.md
new file mode 100644
index 0000000000..fe6989b025
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/PackageReadme.md
@@ -0,0 +1,98 @@
+# Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+
+[](https://www.nuget.org/packages/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider)
+[](https://www.nuget.org/packages/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider)
+
+## Description
+
+This library provides an **Always Encrypted Azure Key Vault Provider** for [Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient). It enables .NET applications to use [Microsoft Azure Key Vault](https://azure.microsoft.com/services/key-vault/) with [Always Encrypted](https://aka.ms/AlwaysEncrypted) in Microsoft Azure SQL Database and Microsoft SQL Server.
+
+Always Encrypted allows clients to encrypt sensitive data inside client applications and never reveal the encryption keys to SQL Server. This provider enables storing column master keys (CMKs) in Azure Key Vault, providing centralized key management, secure key storage, and integration with Azure AD authentication.
+
+## Supportability
+
+This package supports:
+
+- .NET Framework 4.6.2+
+- .NET 8.0+
+
+## Installation
+
+Install the package via NuGet:
+
+```bash
+dotnet add package Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+```
+
+Or via the Package Manager Console:
+
+```powershell
+Install-Package Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+```
+
+## Getting Started
+
+### Register the Provider
+
+Before you can use Azure Key Vault with Always Encrypted, you must register the provider globally or per-connection:
+
+```csharp
+using Microsoft.Data.SqlClient;
+using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
+using Azure.Identity;
+
+// Create the AKV provider using Azure.Identity (recommended)
+var azureCredential = new DefaultAzureCredential();
+var akvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(azureCredential);
+
+// Register globally (once per application)
+SqlConnection.RegisterColumnEncryptionKeyStoreProviders(
+ new Dictionary
+ {
+ { SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, akvProvider }
+ });
+```
+
+### Use with a Connection
+
+Enable Always Encrypted in your connection string:
+
+```csharp
+var connectionString = "Server=myserver;Database=mydb;Column Encryption Setting=Enabled;...";
+
+using var connection = new SqlConnection(connectionString);
+await connection.OpenAsync();
+
+// Execute queries against encrypted columns - encryption/decryption is automatic
+using var command = new SqlCommand("SELECT SSN FROM Customers WHERE Id = @id", connection);
+command.Parameters.AddWithValue("@id", customerId);
+var ssn = await command.ExecuteScalarAsync();
+```
+
+## Key Features
+
+- **Azure Key Vault Integration**: Store and manage column master keys (CMKs) in Azure Key Vault
+- **Azure AD Authentication**: Supports Azure.Identity credentials for seamless Azure AD authentication
+- **Key Caching**: Built-in caching of column encryption keys (CEKs) for improved performance
+- **Multiple Authentication Methods**: Supports DefaultAzureCredential, ClientSecretCredential, ManagedIdentityCredential, and more
+
+## Documentation
+
+- [Always Encrypted Overview](https://learn.microsoft.com/sql/relational-databases/security/encryption/always-encrypted-database-engine)
+- [Configure Always Encrypted with Azure Key Vault](https://learn.microsoft.com/sql/relational-databases/security/encryption/configure-always-encrypted-keys-using-powershell)
+- [Microsoft.Data.SqlClient Documentation](https://learn.microsoft.com/sql/connect/ado-net/introduction-microsoft-data-sqlclient-namespace)
+- [Azure Key Vault Documentation](https://learn.microsoft.com/azure/key-vault/)
+
+## Release Notes
+
+Release notes are available at: https://go.microsoft.com/fwlink/?linkid=2090501
+
+## License
+
+This package is licensed under the [MIT License](https://licenses.nuget.org/MIT).
+
+## Related Packages
+
+- [Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient) - The main SqlClient driver
+- [Azure.Identity](https://www.nuget.org/packages/Azure.Identity) - Azure AD authentication library
+- [Azure.Security.KeyVault.Keys](https://www.nuget.org/packages/Azure.Security.KeyVault.Keys) - Azure Key Vault Keys client library
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/SqlColumnEncryptionAzureKeyVaultProvider.cs b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/SqlColumnEncryptionAzureKeyVaultProvider.cs
index d4740a1183..08639abe2c 100644
--- a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/SqlColumnEncryptionAzureKeyVaultProvider.cs
+++ b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/SqlColumnEncryptionAzureKeyVaultProvider.cs
@@ -119,7 +119,7 @@ public SqlColumnEncryptionAzureKeyVaultProvider(TokenCredential tokenCredential,
/// TrustedEndpoints are used to validate the master key path
public SqlColumnEncryptionAzureKeyVaultProvider(TokenCredential tokenCredential, string[] trustedEndpoints)
{
- using var _ = AKVScope.Create();
+ using var _ = SqlClientEventScope.Create(nameof(SqlColumnEncryptionAzureKeyVaultProvider));
ValidateNotNull(tokenCredential, nameof(tokenCredential));
ValidateNotNull(trustedEndpoints, nameof(trustedEndpoints));
ValidateNotEmpty(trustedEndpoints, nameof(trustedEndpoints));
@@ -140,7 +140,7 @@ public SqlColumnEncryptionAzureKeyVaultProvider(TokenCredential tokenCredential,
/// Encrypted column encryption key
public override byte[] SignColumnMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations)
{
- using var _ = AKVScope.Create();
+ using var _ = SqlClientEventScope.Create(nameof(SqlColumnEncryptionAzureKeyVaultProvider));
ValidateNonEmptyAKVPath(masterKeyPath, isSystemOp: false);
// Also validates key is of RSA type.
@@ -158,7 +158,7 @@ public override byte[] SignColumnMasterKeyMetadata(string masterKeyPath, bool al
/// Boolean indicating whether the master key metadata can be verified based on the provided signature
public override bool VerifyColumnMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations, byte[] signature)
{
- using var _ = AKVScope.Create();
+ using var _ = SqlClientEventScope.Create(nameof(SqlColumnEncryptionAzureKeyVaultProvider));
ValidateNonEmptyAKVPath(masterKeyPath, isSystemOp: true);
var key = Tuple.Create(masterKeyPath, allowEnclaveComputations, ToHexString(signature));
@@ -183,7 +183,7 @@ bool VerifyColumnMasterKeyMetadata()
/// Plain text column encryption key
public override byte[] DecryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] encryptedColumnEncryptionKey)
{
- using var _ = AKVScope.Create();
+ using var _ = SqlClientEventScope.Create(nameof(SqlColumnEncryptionAzureKeyVaultProvider));
// Validate the input parameters
ValidateNonEmptyAKVPath(masterKeyPath, isSystemOp: true);
ValidateEncryptionAlgorithm(encryptionAlgorithm, isSystemOp: true);
@@ -216,8 +216,8 @@ byte[] DecryptEncryptionKey()
// validate the ciphertext length
if (cipherTextLength != keySizeInBytes)
{
- AKVEventSource.Log.TryTraceEvent("Cipher Text length: {0}", cipherTextLength);
- AKVEventSource.Log.TryTraceEvent("keySizeInBytes: {0}", keySizeInBytes);
+ SqlClientEventSource.Log.TryTraceEvent("Cipher Text length: {0}", cipherTextLength);
+ SqlClientEventSource.Log.TryTraceEvent("keySizeInBytes: {0}", keySizeInBytes);
throw ADP.InvalidCipherTextLength(cipherTextLength, keySizeInBytes, masterKeyPath);
}
@@ -225,8 +225,8 @@ byte[] DecryptEncryptionKey()
int signatureLength = encryptedColumnEncryptionKey.Length - currentIndex - cipherTextLength;
if (signatureLength != keySizeInBytes)
{
- AKVEventSource.Log.TryTraceEvent("Signature length: {0}", signatureLength);
- AKVEventSource.Log.TryTraceEvent("keySizeInBytes: {0}", keySizeInBytes);
+ SqlClientEventSource.Log.TryTraceEvent("Signature length: {0}", signatureLength);
+ SqlClientEventSource.Log.TryTraceEvent("keySizeInBytes: {0}", keySizeInBytes);
throw ADP.InvalidSignatureLengthTemplate(signatureLength, keySizeInBytes, masterKeyPath);
}
@@ -251,7 +251,7 @@ byte[] DecryptEncryptionKey()
if (!KeyCryptographer.VerifyData(message, signature, masterKeyPath))
{
- AKVEventSource.Log.TryTraceEvent("Signature could not be verified.");
+ SqlClientEventSource.Log.TryTraceEvent("Signature could not be verified.");
throw ADP.InvalidSignatureTemplate(masterKeyPath);
}
return KeyCryptographer.UnwrapKey(s_keyWrapAlgorithm, cipherText, masterKeyPath);
@@ -268,7 +268,7 @@ byte[] DecryptEncryptionKey()
/// Encrypted column encryption key
public override byte[] EncryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] columnEncryptionKey)
{
- using var _ = AKVScope.Create();
+ using var _ = SqlClientEventScope.Create(nameof(SqlColumnEncryptionAzureKeyVaultProvider));
// Validate the input parameters
ValidateNonEmptyAKVPath(masterKeyPath, isSystemOp: true);
ValidateEncryptionAlgorithm(encryptionAlgorithm, isSystemOp: true);
@@ -293,8 +293,8 @@ public override byte[] EncryptColumnEncryptionKey(string masterKeyPath, string e
if (cipherText.Length != keySizeInBytes)
{
- AKVEventSource.Log.TryTraceEvent("Cipher Text length: {0}", cipherText.Length);
- AKVEventSource.Log.TryTraceEvent("keySizeInBytes: {0}", keySizeInBytes);
+ SqlClientEventSource.Log.TryTraceEvent("Cipher Text length: {0}", cipherText.Length);
+ SqlClientEventSource.Log.TryTraceEvent("keySizeInBytes: {0}", keySizeInBytes);
throw ADP.CipherTextLengthMismatch();
}
@@ -348,14 +348,14 @@ internal void ValidateNonEmptyAKVPath(string masterKeyPath, bool isSystemOp)
// throw appropriate error if masterKeyPath is null or empty
if (string.IsNullOrWhiteSpace(masterKeyPath))
{
- AKVEventSource.Log.TryTraceEvent("Azure Key Vault URI found null or empty.");
+ SqlClientEventSource.Log.TryTraceEvent("Azure Key Vault URI found null or empty.");
throw ADP.InvalidAKVPath(masterKeyPath, isSystemOp);
}
if (!Uri.TryCreate(masterKeyPath, UriKind.Absolute, out Uri parsedUri) || parsedUri.Segments.Length < 3)
{
// Return an error indicating that the AKV url is invalid.
- AKVEventSource.Log.TryTraceEvent("URI could not be created with provided master key path: {0}", masterKeyPath);
+ SqlClientEventSource.Log.TryTraceEvent("URI could not be created with provided master key path: {0}", masterKeyPath);
throw ADP.InvalidAKVUrl(masterKeyPath);
}
@@ -365,13 +365,13 @@ internal void ValidateNonEmptyAKVPath(string masterKeyPath, bool isSystemOp)
{
if (parsedUri.Host.EndsWith(trustedEndPoint, StringComparison.OrdinalIgnoreCase))
{
- AKVEventSource.Log.TryTraceEvent("Azure Key Vault URI validated successfully.");
+ SqlClientEventSource.Log.TryTraceEvent("Azure Key Vault URI validated successfully.");
return;
}
}
// Return an error indicating that the AKV url is invalid.
- AKVEventSource.Log.TryTraceEvent("Master Key Path could not be validated as it does not end with trusted endpoints: {0}", masterKeyPath);
+ SqlClientEventSource.Log.TryTraceEvent("Master Key Path could not be validated as it does not end with trusted endpoints: {0}", masterKeyPath);
throw ADP.InvalidAKVUrlTrustedEndpoints(masterKeyPath, string.Join(", ", TrustedEndPoints));
}
@@ -379,10 +379,10 @@ private void ValidateSignature(string masterKeyPath, byte[] message, byte[] sign
{
if (!KeyCryptographer.VerifyData(message, signature, masterKeyPath))
{
- AKVEventSource.Log.TryTraceEvent("Signature could not be verified.");
+ SqlClientEventSource.Log.TryTraceEvent("Signature could not be verified.");
throw ADP.InvalidSignature();
}
- AKVEventSource.Log.TryTraceEvent("Signature verified successfully.");
+ SqlClientEventSource.Log.TryTraceEvent("Signature verified successfully.");
}
private byte[] CompileMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations)
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
index 0a3b6bfd19..5f007565d2 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
@@ -1093,6 +1093,17 @@
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
index 6a00753f81..62a2cf2d0f 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
@@ -1083,6 +1083,17 @@
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj
index 7c82dbfcc7..7e1d3382f9 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj
@@ -159,6 +159,17 @@
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs
index a7debdb0bd..197d7a0cfc 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs
@@ -341,7 +341,7 @@ internal void ActivateConnection(Transaction transaction)
Activate(transaction);
- SqlClientEventSource.Metrics.EnterActiveConnection();
+ SqlClientDiagnostics.Metrics.EnterActiveConnection();
}
internal void AddWeakReference(object value, int tag)
@@ -454,7 +454,7 @@ internal virtual void CloseConnection(DbConnection owningObject, SqlConnectionFa
// and transactions may not get cleaned up...
Deactivate();
- SqlClientEventSource.Metrics.HardDisconnectRequest();
+ SqlClientDiagnostics.Metrics.HardDisconnectRequest();
// To prevent an endless recursion, we need to clear the owning object
// before we call dispose so that we can't get here a second time...
@@ -469,7 +469,7 @@ internal virtual void CloseConnection(DbConnection owningObject, SqlConnectionFa
}
else
{
- SqlClientEventSource.Metrics.ExitNonPooledConnection();
+ SqlClientDiagnostics.Metrics.ExitNonPooledConnection();
Dispose();
}
}
@@ -495,7 +495,7 @@ internal void DeactivateConnection()
// the Deactivate method publicly.
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Deactivating", ObjectID);
- SqlClientEventSource.Metrics.ExitActiveConnection();
+ SqlClientDiagnostics.Metrics.ExitActiveConnection();
if (!IsConnectionDoomed && Pool.UseLoadBalancing)
{
@@ -555,7 +555,7 @@ internal virtual void DelegatedTransactionEnded()
// once and for all, or the server will have fits about us
// leaving connections open until the client-side GC kicks
// in.
- SqlClientEventSource.Metrics.ExitNonPooledConnection();
+ SqlClientDiagnostics.Metrics.ExitNonPooledConnection();
Dispose();
}
@@ -776,7 +776,7 @@ internal void SetInStasis()
IsTxRootWaitingForTxEnd = true;
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Non-Pooled Connection has Delegated Transaction, waiting to Dispose.", ObjectID);
- SqlClientEventSource.Metrics.EnterStasisConnection();
+ SqlClientDiagnostics.Metrics.EnterStasisConnection();
}
///
@@ -939,7 +939,7 @@ private void TerminateStasis(bool returningToPool)
: "Delegated Transaction has ended, connection is closed/leaked. Disposing.";
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, {1}", ObjectID, message);
- SqlClientEventSource.Metrics.ExitStasisConnection();
+ SqlClientDiagnostics.Metrics.ExitStasisConnection();
IsTxRootWaitingForTxEnd = false;
}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolGroup.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolGroup.cs
index 3a7b01945a..3870b11ed6 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolGroup.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/DbConnectionPoolGroup.cs
@@ -194,7 +194,7 @@ internal IDbConnectionPool GetConnectionPool(SqlConnectionFactory connectionFact
newPool.Startup(); // must start pool before usage
bool addResult = _poolCollection.TryAdd(currentIdentity, newPool);
Debug.Assert(addResult, "No other pool with current identity should exist at this point");
- SqlClientEventSource.Metrics.EnterActiveConnectionPool();
+ SqlClientDiagnostics.Metrics.EnterActiveConnectionPool();
pool = newPool;
}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/TransactedConnectionPool.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/TransactedConnectionPool.cs
index b8e56bd9e3..3132d310d1 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/TransactedConnectionPool.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/TransactedConnectionPool.cs
@@ -263,7 +263,7 @@ internal void PutTransactedObject(Transaction transaction, DbConnectionInternal
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Transaction {1}, Connection {2}, Added.", Id, transaction.GetHashCode(), transactedObject.ObjectID);
}
- SqlClientEventSource.Metrics.EnterFreeConnection();
+ SqlClientDiagnostics.Metrics.EnterFreeConnection();
}
///
@@ -344,7 +344,7 @@ internal void TransactionEnded(Transaction transaction, DbConnectionInternal tra
// TODO: can we give this responsibility to the main pool?
// The bi-directional dependency between the main pool and this pool
// is messy and hard to understand.
- SqlClientEventSource.Metrics.ExitFreeConnection();
+ SqlClientDiagnostics.Metrics.ExitFreeConnection();
Pool.PutObjectFromTransactedPool(transactedObject);
}
}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/WaitHandleDbConnectionPool.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/WaitHandleDbConnectionPool.cs
index ae56af3bcd..9956a17cef 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/WaitHandleDbConnectionPool.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/WaitHandleDbConnectionPool.cs
@@ -364,7 +364,7 @@ private void CleanupCallback(object state)
Debug.Assert(obj != null, "null connection is not expected");
// If we obtained one from the old stack, destroy it.
- SqlClientEventSource.Metrics.ExitFreeConnection();
+ SqlClientDiagnostics.Metrics.ExitFreeConnection();
// Transaction roots must survive even aging out (TxEnd event will clean them up).
bool shouldDestroy = true;
@@ -464,14 +464,14 @@ public void Clear()
{
Debug.Assert(obj != null, "null connection is not expected");
- SqlClientEventSource.Metrics.ExitFreeConnection();
+ SqlClientDiagnostics.Metrics.ExitFreeConnection();
DestroyObject(obj);
}
while (_stackOld.TryPop(out obj))
{
Debug.Assert(obj != null, "null connection is not expected");
- SqlClientEventSource.Metrics.ExitFreeConnection();
+ SqlClientDiagnostics.Metrics.ExitFreeConnection();
DestroyObject(obj);
}
@@ -543,7 +543,7 @@ private DbConnectionInternal CreateObject(DbConnection owningObject, DbConnectio
_objectList.Add(newObj);
_totalObjects = _objectList.Count;
- SqlClientEventSource.Metrics.EnterPooledConnection();
+ SqlClientDiagnostics.Metrics.EnterPooledConnection();
}
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Connection {1}, Added to pool.", Id, newObj?.ObjectID);
@@ -760,12 +760,12 @@ private void DestroyObject(DbConnectionInternal obj)
{
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Connection {1}, Removed from pool.", Id, obj.ObjectID);
- SqlClientEventSource.Metrics.ExitPooledConnection();
+ SqlClientDiagnostics.Metrics.ExitPooledConnection();
}
obj.Dispose();
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Connection {1}, Disposed.", Id, obj.ObjectID);
- SqlClientEventSource.Metrics.HardDisconnectRequest();
+ SqlClientDiagnostics.Metrics.HardDisconnectRequest();
}
}
@@ -1104,7 +1104,7 @@ private bool TryGetConnection(DbConnection owningObject, uint waitForMultipleObj
connection = obj;
- SqlClientEventSource.Metrics.SoftConnectRequest();
+ SqlClientDiagnostics.Metrics.SoftConnectRequest();
return true;
}
@@ -1142,7 +1142,7 @@ public DbConnectionInternal ReplaceConnection(DbConnection owningObject, DbConne
if (newConnection != null)
{
- SqlClientEventSource.Metrics.SoftConnectRequest();
+ SqlClientDiagnostics.Metrics.SoftConnectRequest();
PrepareConnection(owningObject, newConnection, oldConnection.EnlistedTransaction);
oldConnection.PrepareForReplaceConnection();
oldConnection.DeactivateConnection();
@@ -1181,7 +1181,7 @@ private DbConnectionInternal GetFromGeneralPool()
{
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Connection {1}, Popped from general pool.", Id, obj.ObjectID);
- SqlClientEventSource.Metrics.ExitFreeConnection();
+ SqlClientDiagnostics.Metrics.ExitFreeConnection();
}
return obj;
}
@@ -1199,7 +1199,7 @@ private DbConnectionInternal GetFromTransactedPool(out Transaction transaction)
{
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Connection {1}, Popped from transacted pool.", Id, obj.ObjectID);
- SqlClientEventSource.Metrics.ExitFreeConnection();
+ SqlClientDiagnostics.Metrics.ExitFreeConnection();
if (obj.IsTransactionRoot)
{
@@ -1344,7 +1344,7 @@ private void PutNewObject(DbConnectionInternal obj)
_stackNew.Push(obj);
_waitHandles.PoolSemaphore.Release(1);
- SqlClientEventSource.Metrics.EnterFreeConnection();
+ SqlClientDiagnostics.Metrics.EnterFreeConnection();
}
@@ -1352,7 +1352,7 @@ public void ReturnInternalConnection(DbConnectionInternal obj, DbConnection owni
{
Debug.Assert(obj != null, "null obj?");
- SqlClientEventSource.Metrics.SoftDisconnectRequest();
+ SqlClientDiagnostics.Metrics.SoftDisconnectRequest();
// Once a connection is closing (which is the state that we're in at
// this point in time) you cannot delegate a transaction to or enlist
@@ -1469,7 +1469,7 @@ private bool ReclaimEmancipatedObjects()
DbConnectionInternal obj = reclaimedObjects[i];
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Connection {1}, Reclaiming.", Id, obj.ObjectID);
- SqlClientEventSource.Metrics.ReclaimedConnectionRequest();
+ SqlClientDiagnostics.Metrics.ReclaimedConnectionRequest();
emancipatedObjectFound = true;
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.windows.cs
index b949e494d7..70449314c6 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.windows.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/LocalDB.netcore.windows.cs
@@ -111,7 +111,7 @@ internal static string MapLocalDBErrorStateToErrorMessage(LocalDBErrorState erro
///
private bool LoadUserInstanceDll()
{
- using (TrySNIEventScope.Create(nameof(LocalDB)))
+ using (SqlClientSNIEventScope.Create(nameof(LocalDB)))
{
// Check in a non thread-safe way if the handle is already set for performance.
if (_sqlUserInstanceLibraryHandle != null)
@@ -194,7 +194,7 @@ private bool LoadUserInstanceDll()
///
private string GetUserInstanceDllPath(out LocalDBErrorState errorState)
{
- using (TrySNIEventScope.Create(nameof(LocalDB)))
+ using (SqlClientSNIEventScope.Create(nameof(LocalDB)))
{
string dllPath = null;
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(LocalDBInstalledVersionRegistryKey))
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniCommon.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniCommon.netcore.cs
index 6adcf66036..640141fabd 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniCommon.netcore.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniCommon.netcore.cs
@@ -56,7 +56,7 @@ internal class SniCommon
/// True if certificate is valid
internal static bool ValidateSslServerCertificate(Guid connectionId, string targetServerName, string hostNameInCertificate, X509Certificate serverCert, string validationCertFileName, SslPolicyErrors policyErrors)
{
- using (TrySNIEventScope.Create(nameof(SniCommon)))
+ using (SqlClientSNIEventScope.Create(nameof(SniCommon)))
{
if (policyErrors == SslPolicyErrors.None)
{
@@ -174,7 +174,7 @@ internal static IPAddress[] GetDnsIpAddresses(string serverName, TimeoutTimer ti
internal static IPAddress[] GetDnsIpAddresses(string serverName)
{
- using (TrySNIEventScope.Create(nameof(SniCommon)))
+ using (SqlClientSNIEventScope.Create(nameof(SniCommon)))
{
SqlClientEventSource.Log.TrySNITraceEvent(nameof(SniCommon), EventType.INFO, "Getting DNS host entries for serverName {0}.", args0: serverName);
return Dns.GetHostAddresses(serverName);
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsConnection.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsConnection.netcore.cs
index 11e91c2b92..f10f10e061 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsConnection.netcore.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsConnection.netcore.cs
@@ -74,7 +74,7 @@ public SniMarsHandle CreateMarsSession(object callbackObject, bool async)
///
public uint StartReceive()
{
- using (TrySNIEventScope.Create(nameof(SniMarsConnection)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsConnection)))
{
SniPacket packet = null;
@@ -95,7 +95,7 @@ public uint StartReceive()
/// SNI error code
public uint Send(SniPacket packet)
{
- using (TrySNIEventScope.Create(nameof(SniMarsConnection)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsConnection)))
{
lock (DemuxerSync)
{
@@ -111,7 +111,7 @@ public uint Send(SniPacket packet)
/// SNI error code
public uint SendAsync(SniPacket packet)
{
- using (TrySNIEventScope.Create(nameof(SniMarsConnection)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsConnection)))
{
lock (DemuxerSync)
{
@@ -127,7 +127,7 @@ public uint SendAsync(SniPacket packet)
/// SNI error code
public uint ReceiveAsync(ref SniPacket packet)
{
- using (TrySNIEventScope.Create(nameof(SniMarsConnection)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsConnection)))
{
if (packet != null)
{
@@ -155,7 +155,7 @@ public uint ReceiveAsync(ref SniPacket packet)
/// SNI error status
public uint CheckConnection()
{
- using (TrySNIEventScope.Create(nameof(SniMarsConnection)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsConnection)))
{
lock (DemuxerSync)
{
@@ -205,7 +205,7 @@ public void HandleSendComplete(SniPacket packet, uint sniErrorCode)
/// SNI error code
public void HandleReceiveComplete(SniPacket packet, uint sniErrorCode)
{
- using (TrySNIEventScope.Create(nameof(SniMarsConnection)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsConnection)))
{
SniSmuxHeader currentHeader = null;
SniPacket currentPacket = null;
@@ -363,7 +363,7 @@ public void HandleReceiveComplete(SniPacket packet, uint sniErrorCode)
///
public uint EnableSsl(uint options)
{
- using (TrySNIEventScope.Create(nameof(SniMarsConnection)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsConnection)))
{
return _lowerHandle.EnableSsl(options);
}
@@ -374,7 +374,7 @@ public uint EnableSsl(uint options)
///
public void DisableSsl()
{
- using (TrySNIEventScope.Create(nameof(SniMarsConnection)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsConnection)))
{
_lowerHandle.DisableSsl();
}
@@ -396,7 +396,7 @@ public void ReturnPacket(SniPacket packet)
///
public void KillConnection()
{
- using (TrySNIEventScope.Create(nameof(SniMarsConnection)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsConnection)))
{
_lowerHandle.KillConnection();
}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsHandle.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsHandle.netcore.cs
index de5e8fac77..393afe1c94 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsHandle.netcore.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniMarsHandle.netcore.cs
@@ -57,7 +57,7 @@ internal sealed class SniMarsHandle : SniHandle
///
public override void Dispose()
{
- using (TrySNIEventScope.Create(nameof(SniMarsHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsHandle)))
{
try
{
@@ -97,7 +97,7 @@ public SniMarsHandle(SniMarsConnection connection, ushort sessionId, object call
/// SMUX header flags
private void SendControlPacket(SniSmuxFlags flags)
{
- using (TrySNIEventScope.Create(nameof(SniMarsHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsHandle)))
{
SniPacket packet = RentPacket(headerSize: SniSmuxHeader.HEADER_LENGTH, dataSize: 0);
#if DEBUG
@@ -158,7 +158,7 @@ private SniPacket SetPacketSMUXHeader(SniPacket packet)
public override uint Send(SniPacket packet)
{
Debug.Assert(packet.ReservedHeaderSize == SniSmuxHeader.HEADER_LENGTH, "mars handle attempting to send muxed packet without smux reservation in Send");
- using (TrySNIEventScope.Create(nameof(SniMarsHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsHandle)))
{
while (true)
{
@@ -198,7 +198,7 @@ public override uint Send(SniPacket packet)
private uint InternalSendAsync(SniPacket packet)
{
Debug.Assert(packet.ReservedHeaderSize == SniSmuxHeader.HEADER_LENGTH, "mars handle attempting to send muxed packet without smux reservation in InternalSendAsync");
- using (TrySNIEventScope.Create(nameof(SniMarsHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsHandle)))
{
lock (this)
{
@@ -222,7 +222,7 @@ private uint InternalSendAsync(SniPacket packet)
/// SNI error code
private uint SendPendingPackets()
{
- using (TrySNIEventScope.Create(nameof(SniMarsHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsHandle)))
{
SniPacket packet = null;
@@ -269,7 +269,7 @@ private uint SendPendingPackets()
/// SNI error code
public override uint SendAsync(SniPacket packet)
{
- using (TrySNIEventScope.Create(nameof(SniMarsHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsHandle)))
{
packet.SetAsyncIOCompletionCallback(_handleSendCompleteCallback);
lock (this)
@@ -291,7 +291,7 @@ public override uint SendAsync(SniPacket packet)
/// SNI error code
public override uint ReceiveAsync(ref SniPacket packet)
{
- using (TrySNIEventScope.Create(nameof(SniMarsHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsHandle)))
{
lock (_receivedPacketQueue)
{
@@ -338,7 +338,7 @@ public override uint ReceiveAsync(ref SniPacket packet)
///
public void HandleReceiveError(SniPacket packet)
{
- using (TrySNIEventScope.Create(nameof(SniMarsHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsHandle)))
{
// SNIMarsHandle should only receive calls to this function from the SNIMarsConnection aggregator class
// which should handle ownership of the packet because the individual mars handles are not aware of
@@ -362,7 +362,7 @@ public void HandleReceiveError(SniPacket packet)
/// SNI error code
public void HandleSendComplete(SniPacket packet, uint sniErrorCode)
{
- using (TrySNIEventScope.Create(nameof(SniMarsHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsHandle)))
{
lock (this)
{
@@ -383,7 +383,7 @@ public void HandleSendComplete(SniPacket packet, uint sniErrorCode)
/// Send highwater mark
public void HandleAck(uint highwater)
{
- using (TrySNIEventScope.Create(nameof(SniMarsHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsHandle)))
{
lock (this)
{
@@ -404,7 +404,7 @@ public void HandleAck(uint highwater)
/// SMUX header
public void HandleReceiveComplete(SniPacket packet, SniSmuxHeader header)
{
- using (TrySNIEventScope.Create(nameof(SniMarsHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsHandle)))
{
lock (this)
{
@@ -472,7 +472,7 @@ private void SendAckIfNecessary()
/// SNI error code
public override uint Receive(out SniPacket packet, int timeoutInMilliseconds)
{
- using (TrySNIEventScope.Create(nameof(SniMarsHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniMarsHandle)))
{
packet = null;
int queueCount;
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniNpHandle.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniNpHandle.netcore.cs
index f19dc4a33e..783fd5bd0b 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniNpHandle.netcore.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniNpHandle.netcore.cs
@@ -44,7 +44,7 @@ internal sealed class SniNpHandle : SniPhysicalHandle
public SniNpHandle(string serverName, string pipeName, TimeoutTimer timeout, bool tlsFirst, string hostNameInCertificate, string serverCertificateFilename)
{
- using (TrySNIEventScope.Create(nameof(SniNpHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniNpHandle)))
{
SqlClientEventSource.Log.TrySNITraceEvent(nameof(SniNpHandle), EventType.INFO, "Connection Id {0}, Setting server name = {1}, pipe name = {2}", args0: _connectionId, args1: serverName, args2: pipeName);
@@ -140,7 +140,7 @@ public override SslProtocols ProtocolVersion
public override uint CheckConnection()
{
- using (TrySNIEventScope.Create(nameof(SniNpHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniNpHandle)))
{
if (!_stream.CanWrite || !_stream.CanRead)
{
@@ -185,7 +185,7 @@ public override void Dispose()
public override uint Receive(out SniPacket packet, int timeout)
{
- using (TrySNIEventScope.Create(nameof(SniNpHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniNpHandle)))
{
SniPacket errorPacket;
lock (this)
@@ -227,7 +227,7 @@ public override uint Receive(out SniPacket packet, int timeout)
public override uint ReceiveAsync(ref SniPacket packet)
{
- using (TrySNIEventScope.Create(nameof(SniNpHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniNpHandle)))
{
SniPacket errorPacket;
packet = RentPacket(headerSize: 0, dataSize: _bufferSize);
@@ -257,7 +257,7 @@ public override uint ReceiveAsync(ref SniPacket packet)
public override uint Send(SniPacket packet)
{
- using (TrySNIEventScope.Create(nameof(SniNpHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniNpHandle)))
{
bool releaseLock = false;
try
@@ -311,7 +311,7 @@ public override uint Send(SniPacket packet)
public override uint SendAsync(SniPacket packet)
{
- using (TrySNIEventScope.Create(nameof(SniNpHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniNpHandle)))
{
SqlClientEventSource.Log.TrySNITraceEvent(nameof(SniNpHandle), EventType.INFO, "Connection Id {0}, Packet writing to stream, dataLeft {1}", args0: _connectionId, args1: packet?.DataLeft);
packet.WriteToStreamAsync(_stream, _sendCallback, SniProviders.NP_PROV);
@@ -327,7 +327,7 @@ public override void SetAsyncCallbacks(SniAsyncCallback receiveCallback, SniAsyn
public override uint EnableSsl(uint options)
{
- using (TrySNIEventScope.Create(nameof(SniNpHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniNpHandle)))
{
_validateCert = (options & TdsEnums.SNI_SSL_VALIDATE_CERTIFICATE) != 0;
try
@@ -381,7 +381,7 @@ public override void DisableSsl()
/// true if valid
private bool ValidateServerCertificate(object sender, X509Certificate serverCertificate, X509Chain chain, SslPolicyErrors policyErrors)
{
- using (TrySNIEventScope.Create(nameof(SniNpHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniNpHandle)))
{
if (!_validateCert)
{
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniTcpHandle.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniTcpHandle.netcore.cs
index 5466e0fb32..3bc29c1473 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniTcpHandle.netcore.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniTcpHandle.netcore.cs
@@ -138,7 +138,7 @@ public SniTcpHandle(
string hostNameInCertificate,
string serverCertificateFilename)
{
- using (TrySNIEventScope.Create(nameof(SniTcpHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniTcpHandle)))
{
SqlClientEventSource.Log.TrySNITraceEvent(nameof(SniTcpHandle), EventType.INFO, "Connection Id {0}, Setting server name = {1}", args0: _connectionId, args1: serverName);
@@ -299,7 +299,7 @@ public SniTcpHandle(
// Only write to the DNS cache when we receive IsSupported flag as true in the Feature Ext Ack from server.
private Socket TryConnectParallel(string hostName, int port, TimeoutTimer timeout, ref bool callerReportError, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
{
- using (TrySNIEventScope.Create(nameof(SniTcpHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniTcpHandle)))
{
Socket availableSocket = null;
bool isInfiniteTimeOut = timeout.IsInfinite;
@@ -368,7 +368,7 @@ private static IEnumerable GetHostAddressesSortedByPreference(string
// Only write to the DNS cache when we receive IsSupported flag as true in the Feature Ext Ack from server.
private static Socket Connect(string serverName, int port, TimeoutTimer timeout, SqlConnectionIPAddressPreference ipPreference, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
{
- using (TrySNIEventScope.Create(nameof(SniTcpHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniTcpHandle)))
{
SqlClientEventSource.Log.TrySNITraceEvent(nameof(SniTcpHandle), EventType.INFO, "IP preference : {0}", Enum.GetName(typeof(SqlConnectionIPAddressPreference), ipPreference));
bool isInfiniteTimeout = timeout.IsInfinite;
@@ -516,7 +516,7 @@ private static Socket Connect(string serverName, int port, TimeoutTimer timeout,
private static Socket ParallelConnect(IPAddress[] serverAddresses, int port, TimeoutTimer timeout, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
{
- using (TrySNIEventScope.Create(nameof(SniTcpHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniTcpHandle)))
{
if (serverAddresses == null)
{
@@ -726,7 +726,7 @@ private static Socket ParallelConnect(IPAddress[] serverAddresses, int port, Tim
///
public override uint EnableSsl(uint options)
{
- using (TrySNIEventScope.Create(nameof(SniHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniHandle)))
{
_validateCert = (options & TdsEnums.SNI_SSL_VALIDATE_CERTIFICATE) != 0;
@@ -767,7 +767,7 @@ public override uint EnableSsl(uint options)
///
public override void DisableSsl()
{
- using (TrySNIEventScope.Create(nameof(SniTcpHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniTcpHandle)))
{
_sslStream.Dispose();
_sslStream = null;
@@ -1001,7 +1001,7 @@ public override void SetAsyncCallbacks(SniAsyncCallback receiveCallback, SniAsyn
/// SNI error code
public override uint SendAsync(SniPacket packet)
{
- using (TrySNIEventScope.Create(nameof(SniTcpHandle)))
+ using (SqlClientSNIEventScope.Create(nameof(SniTcpHandle)))
{
packet.WriteToStreamAsync(_stream, _sendCallback, SniProviders.TCP_PROV);
SqlClientEventSource.Log.TrySNITraceEvent(nameof(SniTcpHandle), EventType.INFO, "Connection Id {0}, Data sent to stream asynchronously", args0: _connectionId);
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SslOverTdsStream.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SslOverTdsStream.netcore.cs
index 1d18e9d63c..70ee8adea9 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SslOverTdsStream.netcore.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SslOverTdsStream.netcore.cs
@@ -122,7 +122,7 @@ public override int Read(byte[] buffer, int offset, int count) =>
///
public override int Read(Span buffer)
{
- using (TrySNIEventScope.Create(nameof(SslOverTdsStream)))
+ using (SqlClientSNIEventScope.Create(nameof(SslOverTdsStream)))
{
if (!_encapsulate)
{
@@ -178,7 +178,7 @@ public override Task ReadAsync(byte[] buffer, int offset, int count, Cancel
///
public override async ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default)
{
- using (TrySNIEventScope.Create(nameof(SslOverTdsStream)))
+ using (SqlClientSNIEventScope.Create(nameof(SslOverTdsStream)))
{
if (!_encapsulate)
{
@@ -283,7 +283,7 @@ public override void Write(byte[] buffer, int offset, int count) =>
///
public override void Write(ReadOnlySpan buffer)
{
- using (TrySNIEventScope.Create(nameof(SslOverTdsStream)))
+ using (SqlClientSNIEventScope.Create(nameof(SslOverTdsStream)))
{
// During the SSL negotiation phase, SSL is tunnelled over TDS packet type 0x12. After
// negotiation, the underlying socket only sees SSL frames.
@@ -341,7 +341,7 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati
///
public override async ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default)
{
- using (TrySNIEventScope.Create(nameof(SslOverTdsStream)))
+ using (SqlClientSNIEventScope.Create(nameof(SslOverTdsStream)))
{
if (!_encapsulate)
{
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SsrpClient.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SsrpClient.netcore.cs
index 733e99ee6d..f4665729ed 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SsrpClient.netcore.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SsrpClient.netcore.cs
@@ -40,7 +40,7 @@ internal static int GetPortByInstanceName(string browserHostName, string instanc
{
Debug.Assert(!string.IsNullOrWhiteSpace(browserHostName), "browserHostName should not be null, empty, or whitespace");
Debug.Assert(!string.IsNullOrWhiteSpace(instanceName), "instanceName should not be null, empty, or whitespace");
- using (TrySNIEventScope.Create(nameof(SsrpClient)))
+ using (SqlClientSNIEventScope.Create(nameof(SsrpClient)))
{
byte[] instanceInfoRequest = CreateInstanceInfoRequest(instanceName);
byte[] responsePacket = null;
@@ -88,7 +88,7 @@ internal static int GetPortByInstanceName(string browserHostName, string instanc
private static byte[] CreateInstanceInfoRequest(string instanceName)
{
Debug.Assert(!string.IsNullOrWhiteSpace(instanceName), "instanceName should not be null, empty, or whitespace");
- using (TrySNIEventScope.Create(nameof(SsrpClient)))
+ using (SqlClientSNIEventScope.Create(nameof(SsrpClient)))
{
const byte ClntUcastInst = 0x04;
instanceName += char.MinValue;
@@ -172,7 +172,7 @@ private class SsrpResult
/// response packet from UDP server
private static byte[] SendUDPRequest(string browserHostname, int port, byte[] requestPacket, TimeoutTimer timeout, bool allIPsInParallel, SqlConnectionIPAddressPreference ipPreference)
{
- using (TrySNIEventScope.Create(nameof(SsrpClient)))
+ using (SqlClientSNIEventScope.Create(nameof(SsrpClient)))
{
Debug.Assert(!string.IsNullOrWhiteSpace(browserHostname), "browserhostname should not be null, empty, or whitespace");
Debug.Assert(port >= 0 && port <= 65535, "Invalid port");
@@ -406,7 +406,7 @@ internal static string SendBroadcastUDPRequest()
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/mc-sqlr/f2640a2d-3beb-464b-a443-f635842ebc3e#Appendix_A_3
int currentTimeOut = FirstTimeoutForCLNT_BCAST_EX;
- using (TrySNIEventScope.Create(nameof(SsrpClient)))
+ using (SqlClientSNIEventScope.Create(nameof(SsrpClient)))
{
using (UdpClient clientListener = new UdpClient())
{
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SspiContextProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SspiContextProvider.cs
index dcf2b9061e..a8531ea004 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SspiContextProvider.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SSPI/SspiContextProvider.cs
@@ -75,7 +75,7 @@ private protected virtual void Initialize()
internal void WriteSSPIContext(ReadOnlySpan receivedBuff, IBufferWriter outgoingBlobWriter)
{
- using var _ = TrySNIEventScope.Create(nameof(SspiContextProvider));
+ using var _ = SqlClientSNIEventScope.Create(nameof(SspiContextProvider));
if (_primaryAuthParams is { })
{
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientEventSource.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientEventSource.cs
index 11fd3a316d..fed5b80c33 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientEventSource.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientEventSource.cs
@@ -3,1181 +3,43 @@
// See the LICENSE file in the project root for more information.
using Microsoft.Data.SqlClient.Diagnostics;
-using System;
-using System.Diagnostics.Tracing;
-using System.Text;
-using System.Threading;
namespace Microsoft.Data.SqlClient
{
- // Any changes to event writers might be considered as a breaking change.
- // Other libraries such as OpenTelemetry and ApplicationInsight have based part of their code on BeginExecute and EndExecute arguments number.
- [EventSource(Name = "Microsoft.Data.SqlClient.EventSource")]
- internal partial class SqlClientEventSource : EventSource
+ ///
+ /// Internal bridge that provides access to SqlClientMetrics from the main driver.
+ /// The SqlClientEventSource class itself is now defined in the
+ /// Microsoft.Data.SqlClient.Extensions.Logging package.
+ ///
+ internal static class SqlClientDiagnostics
{
private static bool s_initialMetricsEnabled = false;
- // Defines the singleton instance for the Resources ETW provider
- public static readonly SqlClientEventSource Log = new();
+ // Provides access to metrics counters.
+ public static readonly SqlClientMetrics Metrics;
- // Provides access to metrics.
- public static readonly SqlClientMetrics Metrics = new SqlClientMetrics(Log, s_initialMetricsEnabled);
-
- private SqlClientEventSource() { }
-
- private const string NullStr = "null";
- private const string SqlCommand_ClassName = nameof(SqlCommand);
-
-#if NET
- protected override void OnEventCommand(EventCommandEventArgs command)
+ static SqlClientDiagnostics()
{
- base.OnEventCommand(command);
-
- if (command.Command == EventCommand.Enable)
+ // Register callback to handle EventSource Enable events for metrics.
+ // This callback may fire before Metrics is assigned (during type initialization),
+ // so we capture the flag to pass to the SqlClientMetrics constructor.
+ SqlClientEventSource.OnEventSourceEnabled = () =>
{
- if (Metrics == null)
+ if (Metrics is null)
{
s_initialMetricsEnabled = true;
}
else
{
- Metrics.EnableEventCounters();
- }
- }
- }
-#endif
-
- #region Event IDs
- // Initialized static Scope IDs
- private static long s_nextScopeId = 0;
- private static long s_nextNotificationScopeId = 0;
- private static long s_nextPoolerScopeId = 0;
- private static long s_nextSNIScopeId = 0;
-
- ///
- /// Defines EventId for BeginExecute (Reader, Scalar, NonQuery, XmlReader).
- ///
- private const int BeginExecuteEventId = 1;
-
- ///
- /// Defines EventId for EndExecute (Reader, Scalar, NonQuery, XmlReader).
- ///
- private const int EndExecuteEventId = 2;
-
- ///
- /// Defines EventId for Trace() events
- ///
- private const int TraceEventId = 3;
-
- ///
- /// Defines EventId for ScopeEnter() events
- ///
- private const int ScopeEnterId = 4;
-
- ///
- /// Defines EventId for ScopeLeave() events
- ///
- private const int ScopeExitId = 5;
-
- ///
- /// Defines EventId for NotificationScopeEnter() events
- ///
- private const int NotificationScopeEnterId = 6;
-
- ///
- /// Defines EventId for NotificationScopeLeave() events
- ///
- private const int NotificationScopeExitId = 7;
-
- ///
- /// Defines EventId for NotificationScopeTrace() events
- ///
- private const int NotificationTraceId = 8;
-
- ///
- /// Defines EventId for PoolerScopeEnter() events
- ///
- private const int PoolerScopeEnterId = 9;
-
- ///
- /// Defines EventId for PoolerScopeLeave() events
- ///
- private const int PoolerScopeExitId = 10;
-
- ///
- /// Defines EventId for PoolerTrace() events
- ///
- private const int PoolerTraceId = 11;
-
- ///
- /// Defines EventId for AdvancedTrace() events
- ///
- private const int AdvancedTraceId = 12;
-
- ///
- /// Defines EventId for AdvancedScopeEnter() events
- ///
- private const int AdvancedScopeEnterId = 13;
-
- ///
- /// Defines EventId for AdvancedScopeLeave() events
- ///
- private const int AdvancedScopeExitId = 14;
-
- ///
- /// Defines EventId for AdvancedTraceBin() events
- ///
- private const int AdvancedTraceBinId = 15;
-
- ///
- /// Defines EventId for AdvancedTraceError() events
- ///
- private const int AdvancedTraceErrorId = 16;
-
- ///
- /// Defines EventId for CorrelationTrace() events
- ///
- private const int CorrelationTraceId = 17;
-
- ///
- /// Defines EventId for StateDump() events
- ///
- private const int StateDumpEventId = 18;
-
- ///
- /// Defines EventId for SNITrace() events
- ///
- private const int SNITraceEventId = 19;
-
- ///
- /// Defines EventId for SNIEnterScope() events
- ///
- private const int SNIScopeEnterId = 20;
-
- ///
- /// Defines EventId for SNIExitScope() events
- ///
- private const int SNIScopeExitId = 21;
- #endregion
-
- ///
- /// These represent logical groups of events that can be turned on and off independently
- /// Often each task has a keyword, but where tasks are determined by subsystem, keywords
- /// are determined by usefulness to end users to filter.
- ///
- /// Generally users don't mind extra events if they are not high volume, so grouping low
- /// volume events together in a single keywords is OK (users can post-filter by task if desired)
- ///
- ///
- /// The visibility of the enum has to be public, otherwise there will be an ArgumentException
- /// on calling related WriteEvent() method.
- ///
- /// The Keywords class has to be a nested class.
- /// Each keyword must be a power of 2.
- ///
- ///
- ///
- #region Keywords
- public class Keywords
- {
- ///
- /// Captures Start/Stop events before and after command execution.
- ///
- internal const EventKeywords ExecutionTrace = (EventKeywords)1;
-
- ///
- /// Captures basic application flow trace events.
- ///
- internal const EventKeywords Trace = (EventKeywords)2;
-
- ///
- /// Captures basic application scope entering and exiting events.
- ///
- internal const EventKeywords Scope = (EventKeywords)4;
-
- ///
- /// Captures `SqlNotification` flow trace events.
- ///
- internal const EventKeywords NotificationTrace = (EventKeywords)8;
-
- ///
- /// Captures `SqlNotification` scope entering and exiting events.
- ///
- internal const EventKeywords NotificationScope = (EventKeywords)16;
-
- ///
- /// Captures connection pooling flow trace events.
- ///
- internal const EventKeywords PoolerTrace = (EventKeywords)32;
-
- ///
- /// Captures connection pooling scope trace events.
- ///
- internal const EventKeywords PoolerScope = (EventKeywords)64;
-
- ///
- /// Captures advanced flow trace events.
- ///
- internal const EventKeywords AdvancedTrace = (EventKeywords)128;
-
- ///
- /// Captures advanced flow trace events with additional information.
- ///
- internal const EventKeywords AdvancedTraceBin = (EventKeywords)256;
-
- ///
- /// Captures correlation flow trace events.
- ///
- internal const EventKeywords CorrelationTrace = (EventKeywords)512;
-
- ///
- /// Captures full state dump of `SqlConnection`
- ///
- internal const EventKeywords StateDump = (EventKeywords)1024;
-
- ///
- /// Captures application flow traces from Managed networking implementation
- ///
- internal const EventKeywords SNITrace = (EventKeywords)2048;
-
- ///
- /// Captures scope trace events from Managed networking implementation
- ///
- internal const EventKeywords SNIScope = (EventKeywords)4096;
- }
- #endregion
-
- #region Tasks
- ///
- /// Tasks supported by SqlClient's EventSource implementation
- ///
- public static class Tasks
- {
- ///
- /// Task that tracks SqlCommand execution.
- ///
- public const EventTask ExecuteCommand = (EventTask)1;
-
- ///
- /// Task that tracks trace scope.
- ///
- public const EventTask Scope = (EventTask)2;
-
- ///
- /// Task that tracks trace scope.
- ///
- public const EventTask PoolerScope = (EventTask)3;
-
- ///
- /// Task that tracks trace scope.
- ///
- public const EventTask NotificationScope = (EventTask)4;
-
- ///
- /// Task that tracks trace scope.
- ///
- public const EventTask SNIScope = (EventTask)5;
- }
- #endregion
-
- #region Enable/Disable Events
- [NonEvent]
- internal bool IsExecutionTraceEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.ExecutionTrace);
-
- [NonEvent]
- internal bool IsTraceEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.Trace);
-
- [NonEvent]
- internal bool IsScopeEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.Scope);
-
- [NonEvent]
- internal bool IsNotificationTraceEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.NotificationTrace);
-
- [NonEvent]
- internal bool IsNotificationScopeEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.NotificationScope);
-
- [NonEvent]
- internal bool IsPoolerTraceEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.PoolerTrace);
-
- [NonEvent]
- internal bool IsPoolerScopeEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.PoolerScope);
-
- [NonEvent]
- internal bool IsAdvancedTraceOn() => Log.IsEnabled(EventLevel.Verbose, Keywords.AdvancedTrace);
-
- [NonEvent]
- internal bool IsAdvancedTraceBinOn() => Log.IsEnabled(EventLevel.Verbose, Keywords.AdvancedTraceBin);
-
- [NonEvent]
- internal bool IsCorrelationEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.CorrelationTrace);
-
- [NonEvent]
- internal bool IsStateDumpEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.StateDump);
-
- [NonEvent]
- internal bool IsSNITraceEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.SNITrace);
-
- [NonEvent]
- internal bool IsSNIScopeEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.SNIScope);
- #endregion
-
- private string GetFormattedMessage(string className, string memberName, string eventType, string message) =>
- new StringBuilder(className).Append(".").Append(memberName).Append(eventType).Append(message).ToString();
-
- #region overloads
- //Never use event writer directly as they are not checking for enabled/disabled situations. Always use overloads.
-
- #region Trace
-
- #region Traces without if statements
- [NonEvent]
- internal void TraceEvent(string message, T0 args0, T1 args1)
- {
- Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
- }
-
- [NonEvent]
- internal void TraceEvent(string message, T0 args0, T1 args1, T2 args2)
- {
- Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
- }
-
- [NonEvent]
- internal void TraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
- {
- Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
- }
- #endregion
-
- #region Traces with if statements
- [NonEvent]
- internal void TryTraceEvent(string message)
- {
- if (Log.IsTraceEnabled())
- {
- Trace(message);
- }
- }
-
- [NonEvent]
- internal void TryTraceEvent(string message, T0 args0)
- {
- if (Log.IsTraceEnabled())
- {
- Trace(string.Format(message, args0?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryTraceEvent(string message, T0 args0, T1 args1)
- {
- if (Log.IsTraceEnabled())
- {
- Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryTraceEvent(string message, T0 args0, T1 args1, T2 args2)
- {
- if (Log.IsTraceEnabled())
- {
- Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
- {
- if (Log.IsTraceEnabled())
- {
- Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4)
- {
- if (Log.IsTraceEnabled())
- {
- Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, T5 args5)
- {
- if (Log.IsTraceEnabled())
- {
- Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr, args5?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, T5 args5, T6 arg6)
- {
- if (Log.IsTraceEnabled())
- {
- Trace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr, args5?.ToString() ?? NullStr, arg6?.ToString() ?? NullStr));
- }
- }
- #endregion
-
- #endregion
-
- #region Scope
- [NonEvent]
- internal long TryScopeEnterEvent(string className, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
- {
- if (Log.IsScopeEnabled())
- {
- StringBuilder sb = new StringBuilder(className);
- sb.Append(".").Append(memberName).Append(" | INFO | SCOPE | Entering Scope {0}");
- return ScopeEnter(sb.ToString());
- }
- return 0;
- }
-
- [NonEvent]
- internal long TryScopeEnterEvent(string message, T0 args0)
- {
- if (Log.IsScopeEnabled())
- {
- return ScopeEnter(string.Format(message, args0?.ToString() ?? NullStr));
- }
- return 0;
- }
-
- [NonEvent]
- internal long TryScopeEnterEvent(string message, T0 args0, T1 args1)
- {
- if (Log.IsScopeEnabled())
- {
- return ScopeEnter(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
- }
- return 0;
- }
-
- [NonEvent]
- internal long TryScopeEnterEvent(string message, T0 args0, T1 args1, T2 args2)
- {
- if (Log.IsScopeEnabled())
- {
- return ScopeEnter(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
- }
- return 0;
- }
-
- [NonEvent]
- internal long TryScopeEnterEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
- {
- if (Log.IsScopeEnabled())
- {
- return ScopeEnter(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
- }
- return 0;
- }
-
- [NonEvent]
- internal void TryScopeLeaveEvent(long scopeId)
- {
- if (Log.IsScopeEnabled())
- {
- ScopeLeave(string.Format("Exit Scope {0}", scopeId));
- }
- }
- #endregion
-
- #region Execution Trace
- [NonEvent]
- internal void TryBeginExecuteEvent(int objectId, string dataSource, string database, string commandText, Guid? connectionId, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
- {
- if (Log.IsExecutionTraceEnabled())
- {
- BeginExecute(objectId, dataSource, database, commandText, GetFormattedMessage(SqlCommand_ClassName, memberName, EventType.INFO, $"Object Id {objectId}, Client connection Id {connectionId}, Command Text {commandText}"));
- }
- }
-
- [NonEvent]
- internal void TryEndExecuteEvent(int objectId, int compositeState, int sqlExceptionNumber, Guid? connectionId, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
- {
- if (Log.IsExecutionTraceEnabled())
- {
- EndExecute(objectId, compositeState, sqlExceptionNumber, GetFormattedMessage(SqlCommand_ClassName, memberName, EventType.INFO, $"Object Id {objectId}, Client Connection Id {connectionId}, Composite State {compositeState}, Sql Exception Number {sqlExceptionNumber}"));
- }
- }
- #endregion
-
- #region Notification Trace
-
- #region Notification Traces without if statements
- [NonEvent]
- internal void NotificationTraceEvent(string message, T0 args0, T1 args1)
- {
- NotificationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
- }
- #endregion
-
- #region Notification Traces with if statements
- [NonEvent]
- internal void TryNotificationTraceEvent(string message)
- {
- if (Log.IsNotificationTraceEnabled())
- {
- NotificationTrace(message);
- }
- }
-
- [NonEvent]
- internal void TryNotificationTraceEvent(string message, T0 args0)
- {
- if (Log.IsNotificationTraceEnabled())
- {
- NotificationTrace(string.Format(message, args0?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryNotificationTraceEvent(string message, T0 args0, T1 args1)
- {
- if (Log.IsNotificationTraceEnabled())
- {
- NotificationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryNotificationTraceEvent(string message, T0 args0, T1 args1, T2 args2)
- {
- if (Log.IsNotificationTraceEnabled())
- {
- NotificationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryNotificationTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
- {
- if (Log.IsNotificationTraceEnabled())
- {
- NotificationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
- }
- }
- #endregion
-
- #endregion
-
- #region Notification Scope
- [NonEvent]
- internal long TryNotificationScopeEnterEvent(string message, T0 args0)
- {
- if (Log.IsNotificationScopeEnabled())
- {
- return NotificationScopeEnter(string.Format(message, args0?.ToString() ?? NullStr));
- }
- return 0;
- }
-
- [NonEvent]
- internal long TryNotificationScopeEnterEvent(string message, T0 args0, T1 args1)
- {
- if (Log.IsNotificationScopeEnabled())
- {
- return NotificationScopeEnter(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
- }
- return 0;
- }
-
- [NonEvent]
- internal long TryNotificationScopeEnterEvent(string message, T0 args0, T1 args1, T2 args2)
- {
- if (Log.IsNotificationScopeEnabled())
- {
- return NotificationScopeEnter(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
- }
- return 0;
- }
-
- [NonEvent]
- internal long TryNotificationScopeEnterEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
- {
- if (Log.IsNotificationScopeEnabled())
- {
- return NotificationScopeEnter(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
- }
- return 0;
- }
-
- [NonEvent]
- internal void TryNotificationScopeLeaveEvent(long scopeId)
- {
- if (Log.IsNotificationScopeEnabled())
- {
- NotificationScopeLeave(string.Format("Exit Notification Scope {0}", scopeId));
- }
- }
- #endregion
-
- #region Pooler Trace
- [NonEvent]
- internal void TryPoolerTraceEvent(string message)
- {
- if (Log.IsPoolerTraceEnabled())
- {
- PoolerTrace(message);
- }
- }
-
- [NonEvent]
- internal void TryPoolerTraceEvent(string message, T0 args0)
- {
- if (Log.IsPoolerTraceEnabled())
- {
- PoolerTrace(string.Format(message, args0?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryPoolerTraceEvent(string message, T0 args0, T1 args1)
- {
- if (Log.IsPoolerTraceEnabled())
- {
- PoolerTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryPoolerTraceEvent(string message, T0 args0, T1 args1, T2 args2)
- {
- if (Log.IsPoolerTraceEnabled())
- {
- PoolerTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryPoolerTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
- {
- if (Log.IsPoolerTraceEnabled())
- {
- PoolerTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
- }
- }
- #endregion
-
- #region Pooler Scope
- [NonEvent]
- internal long TryPoolerScopeEnterEvent(string message, T0 args0)
- {
- if (Log.IsPoolerScopeEnabled())
- {
- return PoolerScopeEnter(string.Format(message, args0?.ToString() ?? NullStr));
- }
- return 0;
- }
-
- [NonEvent]
- internal void TryPoolerScopeLeaveEvent(long scopeId)
- {
- if (Log.IsPoolerScopeEnabled())
- {
- PoolerScopeLeave(string.Format("Exit Pooler Scope {0}", scopeId));
- }
- }
- #endregion
-
- #region AdvancedTrace
-
- #region AdvancedTraces without if statements
- [NonEvent]
- internal void AdvancedTraceEvent(string message, T0 args0)
- {
- AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr));
- }
-
- [NonEvent]
- internal void AdvancedTraceEvent(string message, T0 args0, T1 args1)
- {
- AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
- }
-
- [NonEvent]
- internal void AdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2)
- {
- AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
- }
-
- [NonEvent]
- internal void AdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
- {
- AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
- }
- #endregion
-
- #region AdvancedTraces with if statements
- [NonEvent]
- internal void TryAdvancedTraceEvent(string message)
- {
- if (Log.IsAdvancedTraceOn())
- {
- AdvancedTrace(message);
- }
- }
-
- [NonEvent]
- internal void TryAdvancedTraceEvent(string message, T0 args0)
- {
- if (Log.IsAdvancedTraceOn())
- {
- AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryAdvancedTraceEvent(string message, T0 args0, T1 args1)
- {
- if (Log.IsAdvancedTraceOn())
- {
- AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryAdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2)
- {
- if (Log.IsAdvancedTraceOn())
- {
- AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryAdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
- {
- if (Log.IsAdvancedTraceOn())
- {
- AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryAdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4)
- {
- if (Log.IsAdvancedTraceOn())
- {
- AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryAdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, T5 args5)
- {
- if (Log.IsAdvancedTraceOn())
- {
- AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr, args5?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryAdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, T5 args5, T6 args6, T7 args7)
- {
- if (Log.IsAdvancedTraceOn())
- {
- AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr, args5?.ToString() ?? NullStr, args6?.ToString() ?? NullStr, args7?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryAdvancedTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, T5 args5, T6 args6)
- {
- if (Log.IsAdvancedTraceOn())
- {
- AdvancedTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr, args5?.ToString() ?? NullStr, args6?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal long TryAdvancedScopeEnterEvent(string message, T0 args0)
- {
- if (Log.IsAdvancedTraceOn())
- {
- return AdvancedScopeEnter(string.Format(message, args0?.ToString() ?? NullStr));
- }
- return 0;
- }
-
- [NonEvent]
- internal void TryAdvanceScopeLeave(long scopeId)
- {
- if (Log.IsAdvancedTraceOn())
- {
- AdvancedScopeLeave(string.Format("Exit Advanced Scope {0}", scopeId));
- }
- }
-
- [NonEvent]
- internal void TryAdvancedTraceBinEvent(string message, T0 args0, T1 args1, T2 args2)
- {
- if (Log.IsAdvancedTraceBinOn())
- {
-
- if (args1 is byte[] args1Bytes)
- {
#if NET
- AdvancedTraceBin(string.Format(message, args0?.ToString() ?? NullStr, Convert.ToHexString(args1Bytes), args2?.ToString() ?? NullStr));
-#else
-
- AdvancedTraceBin(string.Format(message, args0?.ToString() ?? NullStr, BitConverter.ToString(args1Bytes).Replace("-", ""), args2?.ToString() ?? NullStr));
+ Metrics.EnableEventCounters();
#endif
}
- else
- {
- AdvancedTraceBin(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
- }
- }
- }
-
- [NonEvent]
- internal void TryAdvancedTraceErrorEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4)
- {
- if (Log.IsAdvancedTraceOn())
- {
- AdvancedTraceError(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr));
- }
- }
- #endregion
-
- #endregion
-
- #region Correlation Trace
-
- [NonEvent]
- internal void TryCorrelationTraceEvent(string message)
- {
- if (Log.IsCorrelationEnabled())
- {
- CorrelationTrace(message);
- }
- }
-
- [NonEvent]
- internal void TryCorrelationTraceEvent(string message, T0 args0)
- {
- if (Log.IsCorrelationEnabled())
- {
- CorrelationTrace(string.Format(message, args0?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryCorrelationTraceEvent(string message, T0 args0, T1 args1)
- {
- if (Log.IsCorrelationEnabled())
- {
- CorrelationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
- }
- }
+ };
- [NonEvent]
- internal void TryCorrelationTraceEvent(string message, T0 args0, T1 args1, T2 args2)
- {
- if (Log.IsCorrelationEnabled())
- {
- CorrelationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryCorrelationTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3)
- {
- if (Log.IsCorrelationEnabled())
- {
- CorrelationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr));
- }
+ Metrics = new SqlClientMetrics(
+ SqlClientEventSource.Log,
+ SqlClientEventSource.WasEnabled || s_initialMetricsEnabled);
}
-
- [NonEvent]
- internal void TryCorrelationTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4)
- {
- if (Log.IsCorrelationEnabled())
- {
- CorrelationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr));
- }
- }
-
- [NonEvent]
- internal void TryCorrelationTraceEvent(string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, T5 args5)
- {
- if (Log.IsCorrelationEnabled())
- {
- CorrelationTrace(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr, args5?.ToString() ?? NullStr));
- }
- }
- #endregion
-
- #region State Dump without if statements
- [NonEvent]
- internal void StateDumpEvent(string message, T0 args0, T1 args1)
- {
- StateDump(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr));
- }
-
- [NonEvent]
- internal void StateDumpEvent(string message, T0 args0, T1 args1, T2 args2)
- {
- StateDump(string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr));
- }
- #endregion
-
- #region SNI Trace
- [NonEvent]
- internal void TrySNITraceEvent(string className, string eventType, string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
- {
- if (Log.IsSNITraceEnabled())
- {
- SNITrace(GetFormattedMessage(className, memberName, eventType, message));
- }
- }
-
- [NonEvent]
- internal void TrySNITraceEvent(string className, string eventType, string message, T0 args0, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
- {
- if (Log.IsSNITraceEnabled())
- {
- SNITrace(GetFormattedMessage(className, memberName, eventType, string.Format(message, args0?.ToString() ?? NullStr)));
- }
- }
-
- [NonEvent]
- internal void TrySNITraceEvent(string className, string eventType, string message, T0 args0, T1 args1, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
- {
- if (Log.IsSNITraceEnabled())
- {
- SNITrace(GetFormattedMessage(className, memberName, eventType, string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr)));
- }
- }
-
- [NonEvent]
- internal void TrySNITraceEvent(string className, string eventType, string message, T0 args0, T1 args1, T2 args2, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
- {
- if (Log.IsSNITraceEnabled())
- {
- SNITrace(GetFormattedMessage(className, memberName, eventType, string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr)));
- }
- }
-
- [NonEvent]
- internal void TrySNITraceEvent(string className, string eventType, string message, T0 args0, T1 args1, T2 args2, T3 args3, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
- {
- if (Log.IsSNITraceEnabled())
- {
- SNITrace(GetFormattedMessage(className, memberName, eventType, string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr)));
- }
- }
-
- [NonEvent]
- internal void TrySNITraceEvent(string className, string eventType, string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
- {
- if (Log.IsSNITraceEnabled())
- {
- SNITrace(GetFormattedMessage(className, memberName, eventType, string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr)));
- }
- }
-
- [NonEvent]
- internal void TrySNITraceEvent(string className, string eventType, string message, T0 args0, T1 args1, T2 args2, T3 args3, T4 args4, T5 args5, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
- {
- if (Log.IsSNITraceEnabled())
- {
- SNITrace(GetFormattedMessage(className, memberName, eventType, string.Format(message, args0?.ToString() ?? NullStr, args1?.ToString() ?? NullStr, args2?.ToString() ?? NullStr, args3?.ToString() ?? NullStr, args4?.ToString() ?? NullStr, args5?.ToString() ?? NullStr)));
- }
- }
- #endregion
-
- #region SNI Scope
- [NonEvent]
- internal long TrySNIScopeEnterEvent(string className, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
- {
- if (Log.IsSNIScopeEnabled())
- {
- long scopeId = Interlocked.Increment(ref s_nextSNIScopeId);
- WriteEvent(SNIScopeEnterId, $"{className}.{memberName} | SNI | INFO | SCOPE | Entering Scope {scopeId}");
- return scopeId;
- }
- return 0;
- }
-
- [NonEvent]
- internal void TrySNIScopeLeaveEvent(long scopeId)
- {
- if (Log.IsSNIScopeEnabled())
- {
- SNIScopeLeave(string.Format("Exit SNI Scope {0}", scopeId));
- }
- }
- #endregion
-
- #endregion
-
- #region Write Events
- // Do not change the first 4 arguments in this Event writer as OpenTelemetry and ApplicationInsight are relating to the same format,
- // unless you have checked with them and they are able to change their design. Additional items could be added at the end.
- [Event(BeginExecuteEventId, Keywords = Keywords.ExecutionTrace, Task = Tasks.ExecuteCommand, Opcode = EventOpcode.Start)]
- internal void BeginExecute(int objectId, string dataSource, string database, string commandText, string message)
- {
- WriteEvent(BeginExecuteEventId, objectId, dataSource, database, commandText, message);
- }
-
- // Do not change the first 3 arguments in this Event writer as OpenTelemetry and ApplicationInsight are relating to the same format,
- // unless you have checked with them and they are able to change their design. Additional items could be added at the end.
- [Event(EndExecuteEventId, Keywords = Keywords.ExecutionTrace, Task = Tasks.ExecuteCommand, Opcode = EventOpcode.Stop)]
- internal void EndExecute(int objectId, int compositestate, int sqlExceptionNumber, string message)
- {
- WriteEvent(EndExecuteEventId, objectId, compositestate, sqlExceptionNumber, message);
- }
-
- [Event(TraceEventId, Level = EventLevel.Informational, Keywords = Keywords.Trace)]
- internal void Trace(string message) =>
- WriteEvent(TraceEventId, message);
-
- [Event(ScopeEnterId, Level = EventLevel.Informational, Task = Tasks.Scope, Opcode = EventOpcode.Start, Keywords = Keywords.Scope)]
- internal long ScopeEnter(string message)
- {
- long scopeId = Interlocked.Increment(ref s_nextScopeId);
- WriteEvent(ScopeEnterId, string.Format(message, scopeId));
- return scopeId;
- }
-
- [Event(ScopeExitId, Level = EventLevel.Informational, Task = Tasks.Scope, Opcode = EventOpcode.Stop, Keywords = Keywords.Scope)]
- internal void ScopeLeave(string message) =>
- WriteEvent(ScopeExitId, message);
-
- [Event(NotificationTraceId, Level = EventLevel.Informational, Keywords = Keywords.NotificationTrace)]
- internal void NotificationTrace(string message) =>
- WriteEvent(NotificationTraceId, message);
-
- [Event(NotificationScopeEnterId, Level = EventLevel.Informational, Task = Tasks.NotificationScope, Opcode = EventOpcode.Start, Keywords = Keywords.NotificationScope)]
- internal long NotificationScopeEnter(string message)
- {
- long scopeId = Interlocked.Increment(ref s_nextNotificationScopeId);
- WriteEvent(NotificationScopeEnterId, string.Format(message, scopeId));
- return scopeId;
- }
-
- [Event(NotificationScopeExitId, Level = EventLevel.Informational, Task = Tasks.NotificationScope, Opcode = EventOpcode.Stop, Keywords = Keywords.NotificationScope)]
- internal void NotificationScopeLeave(string message) =>
- WriteEvent(NotificationScopeExitId, message);
-
- [Event(PoolerTraceId, Level = EventLevel.Informational, Keywords = Keywords.PoolerTrace)]
- internal void PoolerTrace(string message) =>
- WriteEvent(PoolerTraceId, message);
-
- [Event(PoolerScopeEnterId, Level = EventLevel.Informational, Task = Tasks.PoolerScope, Opcode = EventOpcode.Start, Keywords = Keywords.PoolerScope)]
- internal long PoolerScopeEnter(string message)
- {
- long scopeId = Interlocked.Increment(ref s_nextPoolerScopeId);
- WriteEvent(PoolerScopeEnterId, string.Format(message, scopeId));
- return scopeId;
- }
-
- [Event(PoolerScopeExitId, Level = EventLevel.Informational, Task = Tasks.PoolerScope, Opcode = EventOpcode.Stop, Keywords = Keywords.PoolerScope)]
- internal void PoolerScopeLeave(string message) =>
- WriteEvent(PoolerScopeExitId, message);
-
- [Event(AdvancedTraceId, Level = EventLevel.Verbose, Keywords = Keywords.AdvancedTrace)]
- internal void AdvancedTrace(string message) =>
- WriteEvent(AdvancedTraceId, message);
-
- [Event(AdvancedScopeEnterId, Level = EventLevel.Verbose, Opcode = EventOpcode.Start, Keywords = Keywords.AdvancedTrace)]
- internal long AdvancedScopeEnter(string message)
- {
- long scopeId = Interlocked.Increment(ref s_nextScopeId);
- WriteEvent(AdvancedScopeEnterId, string.Format(message, scopeId));
- return scopeId;
- }
-
- [Event(AdvancedScopeExitId, Level = EventLevel.Verbose, Opcode = EventOpcode.Stop, Keywords = Keywords.AdvancedTrace)]
- internal void AdvancedScopeLeave(string message) =>
- WriteEvent(AdvancedScopeExitId, message);
-
- [Event(AdvancedTraceBinId, Level = EventLevel.Verbose, Keywords = Keywords.AdvancedTraceBin)]
- internal void AdvancedTraceBin(string message) =>
- WriteEvent(AdvancedTraceBinId, message);
-
- [Event(AdvancedTraceErrorId, Level = EventLevel.Error, Keywords = Keywords.AdvancedTrace)]
- internal void AdvancedTraceError(string message) =>
- WriteEvent(AdvancedTraceErrorId, message);
-
- [Event(CorrelationTraceId, Level = EventLevel.Informational, Keywords = Keywords.CorrelationTrace)]
- internal void CorrelationTrace(string message) =>
- WriteEvent(CorrelationTraceId, message);
-
- [Event(StateDumpEventId, Level = EventLevel.Verbose, Keywords = Keywords.StateDump)]
- internal void StateDump(string message) =>
- WriteEvent(StateDumpEventId, message);
-
- [Event(SNITraceEventId, Level = EventLevel.Informational, Keywords = Keywords.SNITrace)]
- internal void SNITrace(string message) =>
- WriteEvent(SNITraceEventId, message);
-
- [Event(SNIScopeEnterId, Level = EventLevel.Informational, Task = Tasks.SNIScope, Opcode = EventOpcode.Start, Keywords = Keywords.SNIScope)]
- internal long SNIScopeEnter(string message)
- {
- long scopeId = Interlocked.Increment(ref s_nextSNIScopeId);
- WriteEvent(SNIScopeEnterId, string.Format(message, scopeId));
- return scopeId;
- }
-
- [Event(SNIScopeExitId, Level = EventLevel.Informational, Task = Tasks.SNIScope, Opcode = EventOpcode.Stop, Keywords = Keywords.SNIScope)]
- internal void SNIScopeLeave(string message) =>
- WriteEvent(SNIScopeExitId, message);
- #endregion
- }
-
- internal static class EventType
- {
- public const string INFO = " | INFO | ";
- public const string ERR = " | ERR | ";
- }
-
- internal readonly struct TrySNIEventScope : IDisposable
- {
- private readonly long _scopeId;
-
- public TrySNIEventScope(long scopeID) => _scopeId = scopeID;
- public void Dispose()
- {
- if (_scopeId == 0)
- {
- return;
- }
- SqlClientEventSource.Log.TrySNIScopeLeaveEvent(_scopeId);
- }
-
- public static TrySNIEventScope Create(string className, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
- => new TrySNIEventScope(SqlClientEventSource.Log.TrySNIScopeEnterEvent(className, memberName));
- }
-
- internal readonly ref struct TryEventScope : IDisposable
- {
- private readonly long _scopeId;
-
- public TryEventScope(long scopeID) => _scopeId = scopeID;
-
- public void Dispose()
- {
- if (_scopeId != 0)
- {
- SqlClientEventSource.Log.TryScopeLeaveEvent(_scopeId);
- }
- }
-
- public static TryEventScope Create(string message, T0 args0) => new TryEventScope(SqlClientEventSource.Log.TryScopeEnterEvent(message, args0));
-
- public static TryEventScope Create(string message, T0 args0, T1 args1) => new TryEventScope(SqlClientEventSource.Log.TryScopeEnterEvent(message, args0, args1));
-
- public static TryEventScope Create(string className, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "") => new TryEventScope(SqlClientEventSource.Log.TryScopeEnterEvent(className, memberName));
-
- public static TryEventScope Create(long scopeId) => new TryEventScope(scopeId);
}
}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.NonQuery.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.NonQuery.cs
index 5d4cba4976..92263ca577 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.NonQuery.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.NonQuery.cs
@@ -88,7 +88,7 @@ public override int ExecuteNonQuery()
using var diagnosticScope = s_diagnosticListener.CreateCommandScope(this, _transaction);
- using var eventScope = TryEventScope.Create($"SqlCommand.ExecuteNonQuery | API | Object Id {ObjectID}");
+ using var eventScope = SqlClientEventScope.Create($"SqlCommand.ExecuteNonQuery | API | Object Id {ObjectID}");
SqlClientEventSource.Log.TryCorrelationTraceEvent(
"SqlCommand.ExecuteNonQuery | API | Correlation | " +
$"Object Id {ObjectID}, " +
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Reader.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Reader.cs
index dda6534047..fcd95d35d9 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Reader.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Reader.cs
@@ -114,7 +114,7 @@ public SqlDataReader EndExecuteReader(IAsyncResult asyncResult)
Guid operationId = s_diagnosticListener.WriteCommandBefore(this, _transaction);
Exception e = null;
- using var eventScope = TryEventScope.Create($"SqlCommand.ExecuteReader | API | Object Id {ObjectID}");
+ using var eventScope = SqlClientEventScope.Create($"SqlCommand.ExecuteReader | API | Object Id {ObjectID}");
// @TODO: Do we want to have a correlation trace event here like nonquery and xml?
// @TODO: Basically, this doesn't follow the same pattern as nonquery, scalar, or xml. Doesn't seem right.
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Scalar.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Scalar.cs
index 64c12c4ecb..d0e2b8cb2b 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Scalar.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Scalar.cs
@@ -30,7 +30,7 @@ public override object ExecuteScalar()
using var diagnosticScope = s_diagnosticListener.CreateCommandScope(this, _transaction);
- using var eventScope = TryEventScope.Create($"SqlCommand.ExecuteScalar | API | Object Id {ObjectID}");
+ using var eventScope = SqlClientEventScope.Create($"SqlCommand.ExecuteScalar | API | Object Id {ObjectID}");
SqlClientEventSource.Log.TryCorrelationTraceEvent(
"SqlCommand.ExecuteScalar | API | Correlation | " +
$"Object Id {ObjectID}, " +
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Xml.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Xml.cs
index add7f90407..38afb87560 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Xml.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Xml.cs
@@ -90,7 +90,7 @@ public XmlReader ExecuteXmlReader()
using var diagnosticScope = s_diagnosticListener.CreateCommandScope(this, _transaction);
- using var eventScope = TryEventScope.Create($"SqlCommand.ExecuteXmlReader | API | Object Id {ObjectID}");
+ using var eventScope = SqlClientEventScope.Create($"SqlCommand.ExecuteXmlReader | API | Object Id {ObjectID}");
SqlClientEventSource.Log.TryCorrelationTraceEvent(
"SqlCommand.ExecuteXmlReader | API | Correlation | " +
$"Object Id {ObjectID}, " +
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.cs
index f3a85723c6..2ff95f2e3b 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.cs
@@ -1057,7 +1057,7 @@ public override void Cancel()
// cancel because immediately after checking the connection can be closed or removed
// via another thread.
- using var eventScope = TryEventScope.Create($"SqlCommand.Cancel | API | Object Id {ObjectID}");
+ using var eventScope = SqlClientEventScope.Create($"SqlCommand.Cancel | API | Object Id {ObjectID}");
SqlClientEventSource.Log.TryCorrelationTraceEvent(
"SqlCommand.Cancel | API | Correlation | " +
$"Object Id {ObjectID}, " +
@@ -1169,7 +1169,7 @@ public override void Prepare()
SqlConnection.ExecutePermission.Demand();
#endif
- using var eventScope = TryEventScope.Create($"SqlCommand.Prepare | API | Object Id {ObjectID}");
+ using var eventScope = SqlClientEventScope.Create($"SqlCommand.Prepare | API | Object Id {ObjectID}");
SqlClientEventSource.Log.TryCorrelationTraceEvent(
"SqlCommand.Prepare | API | Correlation | " +
$"Object Id {ObjectID}, " +
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandSet.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandSet.cs
index 7265d82175..834055e8f4 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandSet.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandSet.cs
@@ -242,7 +242,7 @@ internal int ExecuteNonQuery()
#if NETFRAMEWORK
SqlConnection.ExecutePermission.Demand();
#endif
- using (TryEventScope.Create("SqlCommandSet.ExecuteNonQuery | API | Object Id {0}, Commands executed in Batch RPC mode", ObjectID))
+ using (SqlClientEventScope.Create("SqlCommandSet.ExecuteNonQuery | API | Object Id {0}, Commands executed in Batch RPC mode", ObjectID))
{
ValidateCommandBehavior(nameof(ExecuteNonQuery), CommandBehavior.Default);
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.cs
index e1fb1f325c..073f6c2e20 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnection.cs
@@ -1276,7 +1276,7 @@ public SqlTransaction BeginTransaction(string transactionName)
[SuppressMessage("Microsoft.Reliability", "CA2004:RemoveCallsToGCKeepAlive")]
override protected DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
{
- using (TryEventScope.Create("SqlConnection.BeginDbTransaction | API | Object Id {0}, Isolation Level {1}", ObjectID, (int)isolationLevel))
+ using (SqlClientEventScope.Create("SqlConnection.BeginDbTransaction | API | Object Id {0}, Isolation Level {1}", ObjectID, (int)isolationLevel))
{
DbTransaction transaction = BeginTransaction(isolationLevel);
@@ -1295,7 +1295,7 @@ public SqlTransaction BeginTransaction(IsolationLevel iso, string transactionNam
{
WaitForPendingReconnection();
SqlStatistics statistics = null;
- using (TryEventScope.Create(SqlClientEventSource.Log.TryScopeEnterEvent("SqlConnection.BeginTransaction | API | Object Id {0}, Iso {1}, Transaction Name '{2}'", ObjectID, (int)iso, transactionName)))
+ using (SqlClientEventScope.Create(SqlClientEventSource.Log.TryScopeEnterEvent("SqlConnection.BeginTransaction | API | Object Id {0}, Iso {1}, Transaction Name '{2}'", ObjectID, (int)iso, transactionName)))
{
try
{
@@ -1382,7 +1382,7 @@ private void CloseInnerConnection()
///
public override void Close()
{
- using (TryEventScope.Create("SqlConnection.Close | API | Object Id {0}", ObjectID))
+ using (SqlClientEventScope.Create("SqlConnection.Close | API | Object Id {0}", ObjectID))
{
SqlClientEventSource.Log.TryCorrelationTraceEvent("SqlConnection.Close | API | Correlation | Object Id {0}, Activity Id {1}, Client Connection Id {2}", ObjectID, ActivityCorrelator.Current, ClientConnectionId);
@@ -1478,7 +1478,7 @@ public override void Close()
///
protected override DbCommand CreateDbCommand()
{
- using (TryEventScope.Create(" {0}", ObjectID))
+ using (SqlClientEventScope.Create(" {0}", ObjectID))
{
DbCommand command = SqlClientFactory.Instance.CreateCommand();
command.Connection = this;
@@ -1604,7 +1604,7 @@ private bool TryOpenWithRetry(TaskCompletionSource retry,
///
public void Open(SqlConnectionOverrides overrides)
{
- using (TryEventScope.Create("SqlConnection.Open | API | Correlation | Object Id {0}, Activity Id {1}", ObjectID, ActivityCorrelator.Current))
+ using (SqlClientEventScope.Create("SqlConnection.Open | API | Correlation | Object Id {0}, Activity Id {1}", ObjectID, ActivityCorrelator.Current))
{
SqlClientEventSource.Log.TryCorrelationTraceEvent("SqlConnection.Open | API | Correlation | Object Id {0}, Activity Id {1}", ObjectID, ActivityCorrelator.Current);
@@ -2597,7 +2597,7 @@ internal void OnInfoMessage(SqlInfoMessageEventArgs imevent, out bool notified)
///
public static void ChangePassword(string connectionString, string newPassword)
{
- using (TryEventScope.Create("SqlConnection.ChangePassword | API | Password change requested."))
+ using (SqlClientEventScope.Create("SqlConnection.ChangePassword | API | Password change requested."))
{
SqlClientEventSource.Log.TryCorrelationTraceEvent("SqlConnection.ChangePassword | API | Correlation | ActivityID {0}", ActivityCorrelator.Current);
@@ -2638,7 +2638,7 @@ public static void ChangePassword(string connectionString, string newPassword)
///
public static void ChangePassword(string connectionString, SqlCredential credential, SecureString newSecurePassword)
{
- using (TryEventScope.Create("SqlConnection.ChangePassword | API | Password change requested."))
+ using (SqlClientEventScope.Create("SqlConnection.ChangePassword | API | Password change requested."))
{
SqlClientEventSource.Log.TryCorrelationTraceEvent("SqlConnection.ChangePassword | API | Correlation | ActivityID {0}", ActivityCorrelator.Current);
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs
index 79c1c4a239..0fd0746665 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs
@@ -80,7 +80,7 @@ protected SqlConnectionFactory()
internal void ClearAllPools()
{
- using TryEventScope scope = TryEventScope.Create(nameof(SqlConnectionFactory));
+ using SqlClientEventScope scope = SqlClientEventScope.Create(nameof(SqlConnectionFactory));
foreach (DbConnectionPoolGroup group in _connectionPoolGroups.Values)
{
group?.Clear();
@@ -91,7 +91,7 @@ internal void ClearPool(DbConnection connection)
{
ADP.CheckArgumentNull(connection, nameof(connection));
- using TryEventScope scope = TryEventScope.Create(" {0}", GetObjectId(connection));
+ using SqlClientEventScope scope = SqlClientEventScope.Create(" {0}", GetObjectId(connection));
DbConnectionPoolGroup poolGroup = GetConnectionPoolGroup(connection);
poolGroup?.Clear();
}
@@ -100,7 +100,7 @@ internal void ClearPool(DbConnectionPoolKey key)
{
ADP.CheckArgumentNull(key.ConnectionString, $"{nameof(key)}.{nameof(key.ConnectionString)}");
- using TryEventScope scope = TryEventScope.Create(" connectionString");
+ using SqlClientEventScope scope = SqlClientEventScope.Create(" connectionString");
if (_connectionPoolGroups.TryGetValue(key, out DbConnectionPoolGroup poolGroup))
{
poolGroup?.Clear();
@@ -129,7 +129,7 @@ internal DbConnectionInternal CreateNonPooledConnection(
userOptions);
if (newConnection is not null)
{
- SqlClientEventSource.Metrics.HardConnectRequest();
+ SqlClientDiagnostics.Metrics.HardConnectRequest();
newConnection.MakeNonPooledObject(owningConnection);
}
@@ -164,7 +164,7 @@ internal DbConnectionInternal CreatePooledConnection(
throw ADP.InternalError(ADP.InternalErrorCode.NewObjectCannotBePooled); // CreateObject succeeded, but non-poolable object
}
- SqlClientEventSource.Metrics.HardConnectRequest();
+ SqlClientDiagnostics.Metrics.HardConnectRequest();
newConnection.MakePooledConnection(pool);
SqlClientEventSource.Log.TryTraceEvent(" {0}, Pooled database connection created.", ObjectId);
@@ -244,7 +244,7 @@ internal DbConnectionPoolGroup GetConnectionPoolGroup(
// lock prevents race condition with PruneConnectionPoolGroups
newConnectionPoolGroups.Add(key, newConnectionPoolGroup);
- SqlClientEventSource.Metrics.EnterActiveConnectionPoolGroup();
+ SqlClientDiagnostics.Metrics.EnterActiveConnectionPoolGroup();
connectionPoolGroup = newConnectionPoolGroup;
_connectionPoolGroups = newConnectionPoolGroups;
}
@@ -296,8 +296,8 @@ internal void QueuePoolForRelease(IDbConnectionPool pool, bool clearing)
_poolsToRelease.Add(pool);
}
- SqlClientEventSource.Metrics.EnterInactiveConnectionPool();
- SqlClientEventSource.Metrics.ExitActiveConnectionPool();
+ SqlClientDiagnostics.Metrics.EnterInactiveConnectionPool();
+ SqlClientDiagnostics.Metrics.ExitActiveConnectionPool();
}
internal void QueuePoolGroupForRelease(DbConnectionPoolGroup poolGroup)
@@ -310,8 +310,8 @@ internal void QueuePoolGroupForRelease(DbConnectionPoolGroup poolGroup)
_poolGroupsToRelease.Add(poolGroup);
}
- SqlClientEventSource.Metrics.EnterInactiveConnectionPoolGroup();
- SqlClientEventSource.Metrics.ExitActiveConnectionPoolGroup();
+ SqlClientDiagnostics.Metrics.EnterInactiveConnectionPoolGroup();
+ SqlClientDiagnostics.Metrics.ExitActiveConnectionPoolGroup();
}
internal bool TryGetConnection(
@@ -416,7 +416,7 @@ internal bool TryGetConnection(
connection = CreateNonPooledConnection(owningConnection, poolGroup, userOptions);
- SqlClientEventSource.Metrics.EnterNonPooledConnection();
+ SqlClientDiagnostics.Metrics.EnterNonPooledConnection();
}
else
{
@@ -863,7 +863,7 @@ private void PruneConnectionPoolGroups(object state)
_poolsToRelease.Remove(pool);
SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0}, ReleasePool={1}", ObjectId, pool.Id);
- SqlClientEventSource.Metrics.ExitInactiveConnectionPool();
+ SqlClientDiagnostics.Metrics.ExitInactiveConnectionPool();
}
}
}
@@ -889,7 +889,7 @@ private void PruneConnectionPoolGroups(object state)
_poolGroupsToRelease.Remove(poolGroup);
SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0}, ReleasePoolGroup={1}", ObjectId, poolGroup.ObjectID);
- SqlClientEventSource.Metrics.ExitInactiveConnectionPoolGroup();
+ SqlClientDiagnostics.Metrics.ExitInactiveConnectionPoolGroup();
}
}
}
@@ -955,7 +955,7 @@ private void TryGetConnectionCompletedContinuation(Task ta
}
else
{
- SqlClientEventSource.Metrics.EnterNonPooledConnection();
+ SqlClientDiagnostics.Metrics.EnterNonPooledConnection();
}
}
}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDataReader.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDataReader.cs
index f0975d5bee..2567918726 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDataReader.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlDataReader.cs
@@ -871,7 +871,7 @@ protected override void Dispose(bool disposing)
///
public override void Close()
{
- using (TryEventScope.Create("SqlDataReader.Close | API | Object Id {0}, Command Object Id {1}", ObjectID, Command?.ObjectID))
+ using (SqlClientEventScope.Create("SqlDataReader.Close | API | Object Id {0}, Command Object Id {1}", ObjectID, Command?.ObjectID))
{
SqlStatistics statistics = null;
try
@@ -1482,7 +1482,7 @@ override public int GetProviderSpecificValues(object[] values)
public override DataTable GetSchemaTable()
{
SqlStatistics statistics = null;
- using (TryEventScope.Create("SqlDataReader.GetSchemaTable | API | Object Id {0}, Command Object Id {1}", ObjectID, Command?.ObjectID))
+ using (SqlClientEventScope.Create("SqlDataReader.GetSchemaTable | API | Object Id {0}, Command Object Id {1}", ObjectID, Command?.ObjectID))
{
try
{
@@ -3492,7 +3492,7 @@ private TdsOperationStatus TryNextResult(out bool more)
{
TdsOperationStatus result;
SqlStatistics statistics = null;
- using (TryEventScope.Create("SqlDataReader.NextResult | API | Object Id {0}", ObjectID))
+ using (SqlClientEventScope.Create("SqlDataReader.NextResult | API | Object Id {0}", ObjectID))
{
try
{
@@ -3662,7 +3662,7 @@ public override bool Read()
private TdsOperationStatus TryReadInternal(bool setTimeout, out bool more)
{
SqlStatistics statistics = null;
- using (TryEventScope.Create("SqlDataReader.TryReadInternal | API | Object Id {0}", ObjectID))
+ using (SqlClientEventScope.Create("SqlDataReader.TryReadInternal | API | Object Id {0}", ObjectID))
{
try
{
@@ -4597,7 +4597,7 @@ private void AssertReaderState(bool requireData, bool permitAsync, int? columnIn
///
public override Task NextResultAsync(CancellationToken cancellationToken)
{
- using (TryEventScope.Create("SqlDataReader.NextResultAsync | API | Object Id {0}", ObjectID))
+ using (SqlClientEventScope.Create("SqlDataReader.NextResultAsync | API | Object Id {0}", ObjectID))
using (var registrationHolder = new DisposableTemporaryOnStack())
{
TaskCompletionSource source = new TaskCompletionSource();
@@ -4927,7 +4927,7 @@ out bytesRead
///
public override Task ReadAsync(CancellationToken cancellationToken)
{
- using (TryEventScope.Create("SqlDataReader.ReadAsync | API | Object Id {0}", ObjectID))
+ using (SqlClientEventScope.Create("SqlDataReader.ReadAsync | API | Object Id {0}", ObjectID))
using (var registrationHolder = new DisposableTemporaryOnStack())
{
if (IsClosed)
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs
index cc43c59e99..29dc81de15 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs
@@ -225,7 +225,7 @@ internal void CloseFromConnection()
internal void Commit()
{
- using (TryEventScope.Create("SqlInternalTransaction.Commit | API | Object Id {0}", ObjectID))
+ using (SqlClientEventScope.Create("SqlInternalTransaction.Commit | API | Object Id {0}", ObjectID))
{
if (_innerConnection.IsLockedForBulkCopy)
{
@@ -330,7 +330,7 @@ internal void InitParent(SqlTransaction transaction)
internal void Rollback()
{
- using (TryEventScope.Create("SqlInternalTransaction.Rollback | API | Object Id {0}", ObjectID))
+ using (SqlClientEventScope.Create("SqlInternalTransaction.Rollback | API | Object Id {0}", ObjectID))
{
if (_innerConnection.IsLockedForBulkCopy)
{
@@ -370,7 +370,7 @@ internal void Rollback()
internal void Rollback(string transactionName)
{
- using (TryEventScope.Create("SqlInternalTransaction.Rollback | API | Object Id {0}, Transaction Name {1}", ObjectID, transactionName))
+ using (SqlClientEventScope.Create("SqlInternalTransaction.Rollback | API | Object Id {0}, Transaction Name {1}", ObjectID, transactionName))
{
if (_innerConnection.IsLockedForBulkCopy)
{
@@ -406,7 +406,7 @@ internal void Rollback(string transactionName)
internal void Save(string savePointName)
{
- using (TryEventScope.Create("SqlInternalTransaction.Save | API | Object Id {0}, Save Point Name {1}", ObjectID, savePointName))
+ using (SqlClientEventScope.Create("SqlInternalTransaction.Save | API | Object Id {0}, Save Point Name {1}", ObjectID, savePointName))
{
_innerConnection.ValidateConnectionForExecute(null);
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.cs
index 28f8a3d6db..35bd82cf21 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.cs
@@ -96,7 +96,7 @@ public override void Commit()
ZombieCheck();
- using (TryEventScope.Create("SqlTransaction.Commit | API | Object Id {0}", ObjectId))
+ using (SqlClientEventScope.Create("SqlTransaction.Commit | API | Object Id {0}", ObjectId))
{
SqlStatistics statistics = null;
@@ -179,7 +179,7 @@ public override void Rollback()
ZombieCheck();
SqlStatistics statistics = null;
- using (TryEventScope.Create("SqlTransaction.Rollback | API | Object Id {0}", ObjectId))
+ using (SqlClientEventScope.Create("SqlTransaction.Rollback | API | Object Id {0}", ObjectId))
{
SqlClientEventSource.Log.TryCorrelationTraceEvent(
"SqlTransaction.Rollback | API | Correlation | Object Id {0}, ActivityID {1}, Client Connection Id {2}",
@@ -229,7 +229,7 @@ public void Rollback(string transactionName)
ZombieCheck();
- var eventScopeEnter = TryEventScope.Create(SqlClientEventSource.Log.TryScopeEnterEvent(
+ var eventScopeEnter = SqlClientEventScope.Create(SqlClientEventSource.Log.TryScopeEnterEvent(
"SqlTransaction.Rollback | API | Object Id {0}, Transaction Name='{1}', ActivityID {2}, Client Connection Id {3}",
ObjectId,
transactionName,
@@ -273,7 +273,7 @@ public void Save(string savePointName)
ZombieCheck();
SqlStatistics statistics = null;
- using (TryEventScope.Create("SqlTransaction.Save | API | Object Id {0} | Save Point Name '{1}'", ObjectId, savePointName))
+ using (SqlClientEventScope.Create("SqlTransaction.Save | API | Object Id {0} | Save Point Name '{1}'", ObjectId, savePointName))
{
try
{
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs
index d99b40cdea..a661d55607 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs
@@ -1750,7 +1750,7 @@ internal void ThrowExceptionAndWarning(TdsParserStateObject stateObj, SqlCommand
internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
{
- using TryEventScope _ = TryEventScope.Create(nameof(TdsParser));
+ using SqlClientEventScope _ = SqlClientEventScope.Create(nameof(TdsParser));
#if DEBUG
// There is an exception here for MARS as its possible that another thread has closed the connection just as we see an error
Debug.Assert(SniContext.Undefined != stateObj.DebugOnlyCopyOfSniContext || ((_fMARS) && ((_state == TdsParserState.Closed) || (_state == TdsParserState.Broken))), "SniContext must not be None");
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSessionPool.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSessionPool.cs
index 04bd173f0c..64fd2590a4 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSessionPool.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSessionPool.cs
@@ -60,7 +60,7 @@ internal void Deactivate()
// When being deactivated, we check all the sessions in the
// cache to make sure they're cleaned up and then we dispose of
// sessions that are past what we want to keep around.
- using (TryEventScope.Create(" {0} deactivating cachedCount={1}", ObjectID, _cachedCount))
+ using (SqlClientEventScope.Create(" {0} deactivating cachedCount={1}", ObjectID, _cachedCount))
{
lock (_cache)
{
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.windows.cs
index 9338cf03b1..e90b91db8c 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.windows.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlFileStream.windows.cs
@@ -112,7 +112,7 @@ public SqlFileStream(
#endif
long scopeId = SqlClientEventSource.Log.TryScopeEnterEvent(scopeFormat, _objectId, (int)access, (int)options, path);
- using (TryEventScope.Create(scopeId))
+ using (SqlClientEventScope.Create(scopeId))
{
//-----------------------------------------------------------------
// precondition validation
diff --git a/src/Microsoft.Data.SqlClient/src/PackageReadme.md b/src/Microsoft.Data.SqlClient/src/PackageReadme.md
new file mode 100644
index 0000000000..bd0674ea06
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/src/PackageReadme.md
@@ -0,0 +1,197 @@
+# Microsoft.Data.SqlClient
+
+[](https://www.nuget.org/packages/Microsoft.Data.SqlClient)
+[](https://www.nuget.org/packages/Microsoft.Data.SqlClient)
+
+## Description
+
+**Microsoft.Data.SqlClient** is the official .NET data provider for [Microsoft SQL Server](https://aka.ms/sql) and [Azure SQL](https://aka.ms/azure_sql) databases. It provides access to SQL Server and encapsulates database-specific protocols, including Tabular Data Stream (TDS).
+
+This library grew from a union of the two `System.Data.SqlClient` components which live independently in .NET and .NET Framework. Going forward, support for new SQL Server and Azure SQL features will only be implemented in Microsoft.Data.SqlClient.
+
+## Supportability
+
+This package supports:
+
+- .NET Framework 4.6.2+
+- .NET 8.0+
+
+## Installation
+
+Install the package via NuGet:
+
+```bash
+dotnet add package Microsoft.Data.SqlClient
+```
+
+Or via the Package Manager Console:
+
+```powershell
+Install-Package Microsoft.Data.SqlClient
+```
+
+## Getting Started
+
+### Basic Connection
+
+```csharp
+using Microsoft.Data.SqlClient;
+
+var connectionString = "Server=myserver;Database=mydb;Integrated Security=true;";
+
+using var connection = new SqlConnection(connectionString);
+await connection.OpenAsync();
+
+Console.WriteLine("Connected successfully!");
+```
+
+### Execute a Query
+
+```csharp
+using Microsoft.Data.SqlClient;
+
+var connectionString = "Server=myserver;Database=mydb;Integrated Security=true;";
+
+using var connection = new SqlConnection(connectionString);
+await connection.OpenAsync();
+
+using var command = new SqlCommand("SELECT Id, Name FROM Customers", connection);
+using var reader = await command.ExecuteReaderAsync();
+
+while (await reader.ReadAsync())
+{
+ Console.WriteLine($"Id: {reader.GetInt32(0)}, Name: {reader.GetString(1)}");
+}
+```
+
+### Parameterized Query
+
+```csharp
+using Microsoft.Data.SqlClient;
+
+var connectionString = "Server=myserver;Database=mydb;Integrated Security=true;";
+
+using var connection = new SqlConnection(connectionString);
+await connection.OpenAsync();
+
+using var command = new SqlCommand("SELECT * FROM Customers WHERE Id = @id", connection);
+command.Parameters.AddWithValue("@id", customerId);
+
+using var reader = await command.ExecuteReaderAsync();
+// Process results...
+```
+
+### Using Transactions
+
+```csharp
+using Microsoft.Data.SqlClient;
+
+using var connection = new SqlConnection(connectionString);
+await connection.OpenAsync();
+
+using var transaction = connection.BeginTransaction();
+
+try
+{
+ using var command = new SqlCommand("INSERT INTO Orders (CustomerId, Total) VALUES (@customerId, @total)", connection, transaction);
+ command.Parameters.AddWithValue("@customerId", customerId);
+ command.Parameters.AddWithValue("@total", orderTotal);
+
+ await command.ExecuteNonQueryAsync();
+ await transaction.CommitAsync();
+}
+catch
+{
+ await transaction.RollbackAsync();
+ throw;
+}
+```
+
+## Key Features
+
+| Feature | Description |
+|---------|-------------|
+| **Cross-Platform** | Runs on Windows, Linux, and macOS |
+| **Azure AD Authentication** | Multiple Azure Active Directory authentication modes |
+| **Always Encrypted** | Client-side encryption for sensitive data |
+| **Connection Pooling** | Efficient connection management |
+| **TLS 1.3 Support** | Enhanced security with strict encryption mode |
+| **MARS** | Multiple Active Result Sets on a single connection |
+| **Async Programming** | Full async/await support |
+| **SqlBatch** | Batch multiple commands for improved performance |
+| **JSON/Vector Support** | Native support for JSON and Vector data types (SQL Server 2025+) |
+
+## Commonly Used Types
+
+```
+Microsoft.Data.SqlClient.SqlConnection
+Microsoft.Data.SqlClient.SqlCommand
+Microsoft.Data.SqlClient.SqlDataReader
+Microsoft.Data.SqlClient.SqlParameter
+Microsoft.Data.SqlClient.SqlTransaction
+Microsoft.Data.SqlClient.SqlException
+Microsoft.Data.SqlClient.SqlParameterCollection
+Microsoft.Data.SqlClient.SqlClientFactory
+Microsoft.Data.SqlClient.SqlBulkCopy
+Microsoft.Data.SqlClient.SqlConnectionStringBuilder
+```
+
+## Authentication Methods
+
+| Method | Connection String |
+|--------|-------------------|
+| SQL Server Authentication | `User ID=user;Password=pass;` |
+| Windows Authentication | `Integrated Security=true;` |
+| Azure AD Password | `Authentication=Active Directory Password;User ID=user;Password=pass;` |
+| Azure AD Integrated | `Authentication=Active Directory Integrated;` |
+| Azure AD Interactive | `Authentication=Active Directory Interactive;` |
+| Azure AD Managed Identity | `Authentication=Active Directory Managed Identity;` |
+| Azure AD Service Principal | `Authentication=Active Directory Service Principal;User ID=clientId;Password=clientSecret;` |
+| Azure AD Default | `Authentication=Active Directory Default;` |
+
+## Encryption Modes
+
+| Mode | Description |
+|------|-------------|
+| `Encrypt=Optional` | Encryption is used if available |
+| `Encrypt=Mandatory` | Encryption is required (default) |
+| `Encrypt=Strict` | TDS 8.0 with TLS 1.3 support |
+
+## SNI (SQL Server Network Interface)
+
+Two implementations are available:
+
+- **Native SNI**: Windows-only, provided via [Microsoft.Data.SqlClient.SNI](https://www.nuget.org/packages/Microsoft.Data.SqlClient.SNI) (.NET Framework) or [Microsoft.Data.SqlClient.SNI.runtime](https://www.nuget.org/packages/Microsoft.Data.SqlClient.SNI.runtime) (.NET on Windows)
+- **Managed SNI**: Cross-platform managed implementation, used by default on Unix platforms
+
+## Documentation
+
+- [Microsoft.Data.SqlClient Documentation](https://learn.microsoft.com/sql/connect/ado-net/introduction-microsoft-data-sqlclient-namespace)
+- [Connection String Syntax](https://learn.microsoft.com/sql/connect/ado-net/connection-string-syntax)
+- [Connection Pooling](https://learn.microsoft.com/sql/connect/ado-net/sql-server-connection-pooling)
+- [Always Encrypted](https://learn.microsoft.com/sql/relational-databases/security/encryption/always-encrypted-database-engine)
+- [Azure AD Authentication](https://learn.microsoft.com/sql/connect/ado-net/sql/azure-active-directory-authentication)
+
+## Release Notes
+
+Release notes are available at: https://go.microsoft.com/fwlink/?linkid=2090501
+
+## Migrating from System.Data.SqlClient
+
+If you're migrating from `System.Data.SqlClient`, see the [porting cheat sheet](https://github.com/dotnet/SqlClient/blob/main/porting-cheat-sheet.md) for guidance.
+
+Key changes:
+1. Change namespace from `System.Data.SqlClient` to `Microsoft.Data.SqlClient`
+2. Update package reference to `Microsoft.Data.SqlClient`
+3. Review connection string defaults (e.g., `Encrypt=Mandatory` is now the default)
+
+## License
+
+This package is licensed under the [MIT License](https://licenses.nuget.org/MIT).
+
+## Related Packages
+
+- [Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider](https://www.nuget.org/packages/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider) - Azure Key Vault integration for Always Encrypted
+- [Microsoft.SqlServer.Server](https://www.nuget.org/packages/Microsoft.SqlServer.Server) - SQL CLR UDT support
+- [Microsoft.Data.SqlClient.SNI](https://www.nuget.org/packages/Microsoft.Data.SqlClient.SNI) - Native SNI for .NET Framework
+- [Microsoft.Data.SqlClient.SNI.runtime](https://www.nuget.org/packages/Microsoft.Data.SqlClient.SNI.runtime) - Native SNI runtime for .NET on Windows
diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/MetricsTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/MetricsTest.cs
index f0b1b53b48..fbcb27bb8c 100644
--- a/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/MetricsTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/MetricsTest.cs
@@ -409,7 +409,7 @@ internal static class SqlClientEventSourceProps
static SqlClientEventSourceProps()
{
Type sqlClientEventSourceType =
- Assembly.GetAssembly(typeof(SqlConnection))!.GetType("Microsoft.Data.SqlClient.SqlClientEventSource");
+ Assembly.GetAssembly(typeof(SqlConnection))!.GetType("Microsoft.Data.SqlClient.SqlClientDiagnostics");
Debug.Assert(sqlClientEventSourceType != null);
FieldInfo metricsField = sqlClientEventSourceType.GetField("Metrics", BindingFlags.Static | BindingFlags.Public);
Debug.Assert(metricsField != null);
diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Build.props b/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Build.props
index fb26623a2e..c26651ba7d 100644
--- a/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Build.props
+++ b/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Build.props
@@ -3,8 +3,13 @@
-
+
+ $(MSBuildThisFileDirectory)../../../../
+
+
+ $(MSBuildThisFileDirectory)
+
net462;net8.0;net9.0;net10.0
diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Packages.props b/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Packages.props
index 4e0e64326d..9b5f2bbb32 100644
--- a/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Packages.props
+++ b/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Packages.props
@@ -14,43 +14,4 @@
true
-
-
-
-
- $(MdsPackageVersion)
-
-
-
-
-
-
- 6.1.4
-
-
-
-
-
-
-
-
- $(AzurePackageVersion)
-
-
-
-
- 1.0.0
-
-
-
-
-
-
-
-
-
diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/SqlClient.Stress.Framework.csproj b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/SqlClient.Stress.Framework.csproj
index ba086b58a8..6feb8f34d4 100644
--- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/SqlClient.Stress.Framework.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/SqlClient.Stress.Framework.csproj
@@ -5,12 +5,10 @@
-
-
-
+
+
-
-
+
diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/SqlClient.Stress.Runner.csproj b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/SqlClient.Stress.Runner.csproj
index 9689097795..d0c325fcef 100644
--- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/SqlClient.Stress.Runner.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/SqlClient.Stress.Runner.csproj
@@ -6,13 +6,11 @@
-
-
+
-
-
-
-
+
+
+
diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClient.Stress.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClient.Stress.Tests.csproj
index 6eb77bec44..90cdaf6e2b 100644
--- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClient.Stress.Tests.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClient.Stress.Tests.csproj
@@ -5,11 +5,9 @@
-
-
+
-
-
+
diff --git a/src/Microsoft.SqlServer.Server/Microsoft.SqlServer.Server.csproj b/src/Microsoft.SqlServer.Server/Microsoft.SqlServer.Server.csproj
index 89d6d91b37..4ca05d229c 100644
--- a/src/Microsoft.SqlServer.Server/Microsoft.SqlServer.Server.csproj
+++ b/src/Microsoft.SqlServer.Server/Microsoft.SqlServer.Server.csproj
@@ -1,17 +1,84 @@
-
+
Microsoft.SqlServer.Server
This is the helper library for Microsoft.Data.SqlClient for cross framework compatibility support of UDT types.
Microsoft SqlServer Server
net46;netstandard2.0
- $(ObjFolder)$(Configuration).$(Platform)\$(AssemblyName)\
- $(BinFolder)$(Configuration).$(Platform)\$(AssemblyName)\
- $(OutputPath)$(TargetFramework)\$(AssemblyName).xml
portable
false
true
+
+
+
+
+ $(Artifacts)/obj/$(Configuration)/$(AssemblyName)
+
+
+ $(Artifacts)/bin/$(Configuration)/$(AssemblyName)
+
+
+ $(Artifacts)/doc/$(TargetFramework)/$(AssemblyName).xml
+
+
+
+
+
+ $(AssemblyName)
+ $(SqlServerPackageVersion)
+ $(PackagesDir)
+ true
+ snupkg
+
+ Microsoft.SqlServer.Server
+ Microsoft Corporation
+ Microsoft Corporation
+ This is a helper library for Microsoft.Data.SqlClient enabling cross framework support of UDT types.
+
+Available Types:
+Microsoft.SqlServer.Server.IBinarySerializer
+Microsoft.SqlServer.Server.InvalidUdtException
+Microsoft.SqlServer.Server.SqlFacetAttribute
+Microsoft.SqlServer.Server.SqlFunctionAttribute
+Microsoft.SqlServer.Server.SqlMethodAttribute
+Microsoft.SqlServer.Server.SqlUserDefinedAggregateAttribute
+Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute
+Microsoft.SqlServer.Server.DataAccessKind
+Microsoft.SqlServer.Server.SystemDataAccessKind
+Microsoft.SqlServer.Server.Format
+ © Microsoft Corporation. All rights reserved.
+ sqlserver microsoft.sqlserver.server
+ https://go.microsoft.com/fwlink/?linkid=2185441
+ true
+ git
+ https://github.com/dotnet/SqlClient
+ https://aka.ms/sqlclientproject
+ MIT
+ dotnet.png
+ README.md
+
+
+
+
+
+
+
+
+ $(SigningKeyPath)
+
+
+ true
+ $(SigningKeyPath)
+
+
diff --git a/src/Microsoft.SqlServer.Server/PackageReadme.md b/src/Microsoft.SqlServer.Server/PackageReadme.md
new file mode 100644
index 0000000000..2c683cabd5
--- /dev/null
+++ b/src/Microsoft.SqlServer.Server/PackageReadme.md
@@ -0,0 +1,167 @@
+# Microsoft.SqlServer.Server
+
+[](https://www.nuget.org/packages/Microsoft.SqlServer.Server)
+[](https://www.nuget.org/packages/Microsoft.SqlServer.Server)
+
+## Description
+
+This is a helper library for [Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient), enabling cross-framework support for **User-Defined Types (UDTs)** in SQL Server.
+
+The package provides the types and attributes needed to create SQL Server CLR user-defined types, user-defined aggregates, and user-defined functions that work seamlessly across .NET Framework and .NET Core/.NET.
+
+## Supportability
+
+This package supports:
+
+- .NET Framework 4.6+
+- .NET Standard 2.0 (for .NET Core 2.0+ and .NET 5+)
+
+## Installation
+
+Install the package via NuGet:
+
+```bash
+dotnet add package Microsoft.SqlServer.Server
+```
+
+Or via the Package Manager Console:
+
+```powershell
+Install-Package Microsoft.SqlServer.Server
+```
+
+## Available Types
+
+This package provides the following types in the `Microsoft.SqlServer.Server` namespace:
+
+| Type | Description |
+|------|-------------|
+| `IBinarySerialize` | Interface for custom binary serialization of UDTs |
+| `InvalidUdtException` | Exception thrown when a UDT is invalid |
+| `SqlFacetAttribute` | Specifies additional information about UDT properties |
+| `SqlFunctionAttribute` | Marks a method as a SQL Server function |
+| `SqlMethodAttribute` | Specifies method properties for UDT methods |
+| `SqlUserDefinedAggregateAttribute` | Marks a class as a user-defined aggregate |
+| `SqlUserDefinedTypeAttribute` | Marks a class as a user-defined type |
+| `DataAccessKind` | Describes data access behavior for a function |
+| `SystemDataAccessKind` | Describes system data access behavior |
+| `Format` | Specifies the serialization format for UDTs |
+
+## Getting Started
+
+### Creating a User-Defined Type
+
+```csharp
+using Microsoft.SqlServer.Server;
+using System.Data.SqlTypes;
+
+[SqlUserDefinedType(Format.Native)]
+public struct Point : INullable
+{
+ private bool _isNull;
+ private double _x;
+ private double _y;
+
+ public bool IsNull => _isNull;
+
+ public static Point Null
+ {
+ get
+ {
+ var p = new Point();
+ p._isNull = true;
+ return p;
+ }
+ }
+
+ public double X
+ {
+ get => _x;
+ set => _x = value;
+ }
+
+ public double Y
+ {
+ get => _y;
+ set => _y = value;
+ }
+
+ public static Point Parse(SqlString s)
+ {
+ if (s.IsNull)
+ return Null;
+
+ var parts = s.Value.Split(',');
+ return new Point
+ {
+ X = double.Parse(parts[0]),
+ Y = double.Parse(parts[1])
+ };
+ }
+
+ public override string ToString() => _isNull ? "NULL" : $"{_x},{_y}";
+}
+```
+
+### Creating a User-Defined Aggregate
+
+```csharp
+using Microsoft.SqlServer.Server;
+using System.Data.SqlTypes;
+using System.IO;
+
+[SqlUserDefinedAggregate(Format.UserDefined, MaxByteSize = 8000)]
+public class Concatenate : IBinarySerialize
+{
+ private StringBuilder _builder;
+
+ public void Init()
+ {
+ _builder = new StringBuilder();
+ }
+
+ public void Accumulate(SqlString value)
+ {
+ if (!value.IsNull)
+ {
+ if (_builder.Length > 0)
+ _builder.Append(",");
+ _builder.Append(value.Value);
+ }
+ }
+
+ public void Merge(Concatenate other)
+ {
+ if (other._builder.Length > 0)
+ {
+ if (_builder.Length > 0)
+ _builder.Append(",");
+ _builder.Append(other._builder);
+ }
+ }
+
+ public SqlString Terminate() => new SqlString(_builder.ToString());
+
+ public void Read(BinaryReader reader) => _builder = new StringBuilder(reader.ReadString());
+ public void Write(BinaryWriter writer) => writer.Write(_builder.ToString());
+}
+```
+
+## Documentation
+
+- [SQL Server CLR Integration](https://learn.microsoft.com/sql/relational-databases/clr-integration/clr-integration-overview)
+- [CLR User-Defined Types](https://learn.microsoft.com/sql/relational-databases/clr-integration-database-objects-user-defined-types/clr-user-defined-types)
+- [CLR User-Defined Aggregates](https://learn.microsoft.com/sql/relational-databases/clr-integration-database-objects-user-defined-functions/clr-user-defined-aggregates)
+- [Microsoft.Data.SqlClient Documentation](https://learn.microsoft.com/sql/connect/ado-net/introduction-microsoft-data-sqlclient-namespace)
+
+## Release Notes
+
+Release notes are available at: https://go.microsoft.com/fwlink/?linkid=2185441
+
+## License
+
+This package is licensed under the [MIT License](https://licenses.nuget.org/MIT).
+
+## Related Packages
+
+- [Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient) - The main SqlClient driver
diff --git a/tools/props/Versions.props b/tools/props/Versions.props
index 35678a59d9..46264bc363 100644
--- a/tools/props/Versions.props
+++ b/tools/props/Versions.props
@@ -4,6 +4,12 @@
0
+
+ $(BuildNumber.Split('.')[0])
@@ -14,12 +20,15 @@
1.0.0.0
1.0.0.0
1.0.0.$(BuildNumber)-dev
- $(SqlServerPackageVersion)
+ $(SqlServerPackageVersion)
+
+
+
7.0.0
@@ -43,13 +52,13 @@
eng/pipelines/common/templates/jobs/validate-signed-package-job.yml
-->
- $(MdsVersionDefault).$(BuildNumber)
-
+ $(MdsVersionDefault).$(AssemblyBuildNumber)
+
7.0.0.0
$(AssemblyFileVersion)
-
+
+
@@ -54,6 +55,7 @@
+
@@ -65,6 +67,7 @@
+
@@ -76,6 +79,7 @@
+
@@ -112,7 +116,7 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec b/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec
index e55fb4e7cb..64f3f862f7 100644
--- a/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec
+++ b/tools/specs/add-ons/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.nuspec
@@ -9,6 +9,7 @@
MIT
https://aka.ms/sqlclientproject
dotnet.png
+ README.md
Always Encrypted Azure Key Vault Provider for Microsoft.Data.SqlClient.
@@ -44,12 +45,13 @@ Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyStoreProvider.SqlColumnEncrypti
+
-
+
diff --git a/tools/targets/GenerateSqlServerPackage.targets b/tools/targets/GenerateSqlServerPackage.targets
deleted file mode 100644
index 909c0da6e0..0000000000
--- a/tools/targets/GenerateSqlServerPackage.targets
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-