|
1 | 1 | --- |
2 | 2 | applyTo: "eng/pipelines/**/*.yml" |
3 | 3 | --- |
4 | | -# Azure DevOps Pipelines Guide |
5 | | - |
6 | | -## Overview |
7 | | - |
8 | | -This repository uses Azure DevOps Pipelines for CI/CD. The pipeline configurations are located in `eng/pipelines/`. |
9 | | - |
10 | | -**ADO Organization**: sqlclientdrivers |
11 | | -**ADO Project**: ADO.NET |
12 | | - |
13 | | -## Pipeline Structure |
14 | | - |
15 | | -``` |
16 | | -eng/pipelines/ |
17 | | -├── abstractions/ # Abstractions package pipelines |
18 | | -├── azure/ # Azure package pipelines |
19 | | -├── common/ # Shared templates |
20 | | -│ └── templates/ |
21 | | -│ ├── jobs/ # Reusable job templates |
22 | | -│ ├── stages/ # Reusable stage templates |
23 | | -│ └── steps/ # Reusable step templates |
24 | | -├── jobs/ # Top-level job definitions |
25 | | -├── libraries/ # Shared variable definitions |
26 | | -├── stages/ # Stage definitions |
27 | | -├── steps/ # Step definitions |
28 | | -├── variables/ # Variable templates |
29 | | -├── akv-official-pipeline.yml # AKV provider official/signing build |
30 | | -├── dotnet-sqlclient-ci-core.yml # Core CI pipeline (reusable) |
31 | | -├── dotnet-sqlclient-ci-package-reference-pipeline.yml # CI with package references |
32 | | -├── dotnet-sqlclient-ci-project-reference-pipeline.yml # CI with project references |
33 | | -├── dotnet-sqlclient-signing-pipeline.yml # Package signing pipeline |
34 | | -├── sqlclient-pr-package-ref-pipeline.yml # PR validation (package ref) |
35 | | -├── sqlclient-pr-project-ref-pipeline.yml # PR validation (project ref) |
36 | | -└── stress-tests-pipeline.yml # Stress testing |
37 | | -``` |
38 | | - |
39 | | -## Main Pipelines |
40 | | - |
41 | | -### CI Core Pipeline (`dotnet-sqlclient-ci-core.yml`) |
42 | | -Reusable core CI pipeline consumed by both project-reference and package-reference CI pipelines. Configurable parameters: |
43 | | - |
44 | | -| Parameter | Description | Default | |
45 | | -|-----------|-------------|---------| |
46 | | -| `targetFrameworks` | Windows test frameworks | `[net462, net8.0, net9.0, net10.0]` | |
47 | | -| `targetFrameworksUnix` | Unix test frameworks | `[net8.0, net9.0, net10.0]` | |
48 | | -| `referenceType` | Project or Package reference | Required | |
49 | | -| `buildConfiguration` | Debug or Release | Required | |
50 | | -| `useManagedSNI` | Test with managed SNI | `[false, true]` | |
51 | | -| `testJobTimeout` | Test job timeout (minutes) | Required | |
52 | | -| `runAlwaysEncryptedTests` | Include AE tests | `true` | |
53 | | -| `enableStressTests` | Include stress test stage | `false` | |
54 | | - |
55 | | -### CI Reference Pipelines |
56 | | -- `dotnet-sqlclient-ci-project-reference-pipeline.yml` — Full CI using project references (builds from source) |
57 | | -- `dotnet-sqlclient-ci-package-reference-pipeline.yml` — Full CI using package references (tests against published NuGet packages) |
58 | | - |
59 | | -### PR Validation Pipelines |
60 | | -- `sqlclient-pr-project-ref-pipeline.yml` — PR validation with project references |
61 | | -- `sqlclient-pr-package-ref-pipeline.yml` — PR validation with package references |
62 | | - |
63 | | -These pipelines trigger on pull requests and run a subset of the full CI matrix to provide fast feedback. |
64 | | - |
65 | | -### Official/Signing Pipeline (`dotnet-sqlclient-signing-pipeline.yml`) |
66 | | -Signs and publishes NuGet packages. Used for official releases. Requires secure service connections and key vault access for code signing. |
67 | | - |
68 | | -### AKV Official Pipeline (`akv-official-pipeline.yml`) |
69 | | -Builds and signs the `Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider` add-on package separately from the main driver. Uses 1ES pipeline templates for compliance. |
70 | | - |
71 | | -### Stress Tests Pipeline (`stress-tests-pipeline.yml`) |
72 | | -Optional pipeline for long-running stress and endurance testing. Enabled via `enableStressTests` parameter in CI core. |
73 | | - |
74 | | -## Build Stages |
75 | | - |
76 | | -1. **build_abstractions_package_stage**: Build and pack abstractions |
77 | | -2. **build_sqlclient_package_stage**: Build main driver and AKV packages |
78 | | -3. **build_azure_package_stage**: Build Azure extensions package |
79 | | -4. **stress_tests_stage**: Optional stress testing |
80 | | -5. **run_tests_stage**: Execute all test suites |
| 4 | +# Azure DevOps CI/CD Pipeline Guidelines |
| 5 | + |
| 6 | +## Purpose |
| 7 | + |
| 8 | +Rules and conventions for editing the Azure DevOps CI/CD pipelines that build, test, and validate Microsoft.Data.SqlClient. These pipelines live under `eng/pipelines/` (excluding `onebranch/`, which is covered by separate instructions). |
| 9 | + |
| 10 | +**ADO Organization**: sqlclientdrivers | **ADO Project**: ADO.NET |
| 11 | + |
| 12 | +## Pipeline Layout |
| 13 | + |
| 14 | +Two categories of pipelines exist in this repository: |
| 15 | + |
| 16 | +- **CI/PR pipelines** (`eng/pipelines/`) — Build, test, and validate on every push/PR |
| 17 | +- **OneBranch pipelines** (`eng/pipelines/onebranch/`) — Official signing/release builds (separate instructions file) |
| 18 | + |
| 19 | +Top-level CI/PR pipeline files: |
| 20 | +- `dotnet-sqlclient-ci-core.yml` — Reusable core template; all CI and PR pipelines extend this |
| 21 | +- `dotnet-sqlclient-ci-package-reference-pipeline.yml` — CI with Package references (Release) |
| 22 | +- `dotnet-sqlclient-ci-project-reference-pipeline.yml` — CI with Project references (Release) |
| 23 | +- `sqlclient-pr-package-ref-pipeline.yml` — PR validation with Package references |
| 24 | +- `sqlclient-pr-project-ref-pipeline.yml` — PR validation with Project references |
| 25 | +- `stress-tests-pipeline.yml` — Stress tests triggered after successful CI-Package runs |
| 26 | + |
| 27 | +Reusable templates are organized under: |
| 28 | +- `common/templates/jobs/` — Job templates (`ci-build-nugets-job`, `ci-code-coverage-job`, `ci-run-tests-job`) |
| 29 | +- `common/templates/stages/` — Stage templates (`ci-run-tests-stage`) |
| 30 | +- `common/templates/steps/` — Step templates (build, test, config, publish) |
| 31 | +- `jobs/` — Package-specific CI jobs (pack/test Abstractions, Azure, Logging, stress) |
| 32 | +- `stages/` — Package-specific CI stages (build Logging → Abstractions → SqlClient → Azure → verify → stress) |
| 33 | +- `libraries/` — Shared variables (`ci-build-variables.yml`) |
| 34 | +- `steps/` — SDK install steps |
| 35 | + |
| 36 | +## CI Core Template |
| 37 | + |
| 38 | +`dotnet-sqlclient-ci-core.yml` is the central orchestrator. All CI and PR pipelines extend it with different parameters. |
| 39 | + |
| 40 | +Key parameters: |
| 41 | +- `referenceType` (required) — `Package` or `Project`; controls how sibling packages are referenced |
| 42 | +- `buildConfiguration` (required) — `Debug` or `Release` |
| 43 | +- `testJobTimeout` (required) — test job timeout in minutes |
| 44 | +- `targetFrameworks` — Windows test TFMs; default `[net462, net8.0, net9.0, net10.0]` |
| 45 | +- `targetFrameworksUnix` — Unix test TFMs; default `[net8.0, net9.0, net10.0]` |
| 46 | +- `testSets` — test partitions; default `[1, 2, 3]` |
| 47 | +- `useManagedSNI` — SNI variants to test; default `[false, true]` |
| 48 | +- `runAlwaysEncryptedTests` — include AE test set; default `true` |
| 49 | +- `enableStressTests` — enable stress test stage; default `false` |
| 50 | +- `debug` — enable debug output; default `false` |
| 51 | +- `dotnetVerbosity` — MSBuild verbosity; default `normal` |
| 52 | + |
| 53 | +## Build Stage Order |
| 54 | + |
| 55 | +Stages execute in dependency order (Package reference mode requires artifacts from prior stages): |
| 56 | +1. `generate_secrets` — Generate test secrets |
| 57 | +2. `build_logging_package_stage` — Build Logging package |
| 58 | +3. `build_abstractions_package_stage` — Build Abstractions (depends on Logging) |
| 59 | +4. `build_sqlclient_package_stage` — Build SqlClient + AKV Provider (depends on Abstractions + Logging) |
| 60 | +5. `build_azure_package_stage` — Build Azure extensions (depends on Abstractions + Logging + SqlClient) |
| 61 | +6. `verify_nuget_packages_stage` — Verify NuGet package metadata |
| 62 | +7. `stress_tests_stage` — Optional stress tests |
| 63 | +8. `ci_run_tests_stage` — Run MDS and AKV test suites |
| 64 | + |
| 65 | +When adding a new build stage, respect the dependency graph and pass artifact names/versions to downstream stages. |
| 66 | + |
| 67 | +## PR vs CI Pipeline Differences |
| 68 | + |
| 69 | +PR pipelines: |
| 70 | +- Trigger on PRs to `dev/*`, `feat/*`, `main`; exclude `eng/pipelines/onebranch/*` paths |
| 71 | +- Use reduced TFM matrix: `[net462, net8.0, net9.0]` (excludes net10.0) |
| 72 | +- Timeout: 90 minutes |
| 73 | +- Package-ref PR disables Always Encrypted tests in Debug config |
| 74 | + |
| 75 | +CI pipelines: |
| 76 | +- Trigger on push to `main` (GitHub) and `internal/main` (ADO) with `batch: true` |
| 77 | +- Scheduled weekday builds (see individual pipeline files for cron times) |
| 78 | +- Full TFM matrix including net10.0 |
81 | 79 |
|
82 | 80 | ## Test Configuration |
83 | 81 |
|
84 | | -### Test Sets |
85 | | -Tests are divided into sets for parallelization: |
86 | | -- `TestSet=1` — First partition of tests |
87 | | -- `TestSet=2` — Second partition |
88 | | -- `TestSet=3` — Third partition |
89 | | -- `TestSet=AE` — Always Encrypted tests |
90 | | - |
91 | | -### Test Filters |
92 | | -Tests use category-based filtering. The default filter excludes both `failing` and `flaky` tests: |
93 | | -``` |
94 | | -category!=failing&category!=flaky |
95 | | -``` |
96 | | - |
97 | | -Category values: |
98 | | -- `nonnetfxtests` — Excluded on .NET Framework |
99 | | -- `nonnetcoreapptests` — Excluded on .NET Core |
100 | | -- `nonwindowstests` — Excluded on Windows |
101 | | -- `nonlinuxtests` — Excluded on Linux |
102 | | -- `failing` — Known permanent failures (excluded from all runs) |
103 | | -- `flaky` — Intermittently failing tests (quarantined, run separately) |
104 | | - |
105 | | -### Flaky Test Quarantine in Pipelines |
106 | | -Quarantined tests (`[Trait("Category", "flaky")]`) run in **separate pipeline steps** after the main test steps. This ensures: |
107 | | -- Main test runs are **not blocked** by intermittent failures |
108 | | -- Flaky tests are still **monitored** for regression or resolution |
109 | | -- Code coverage is **not collected** for flaky test runs |
110 | | -- Results appear in pipeline output for visibility |
111 | | - |
112 | | -The quarantine steps are configured in: |
113 | | -- `eng/pipelines/common/templates/steps/build-and-run-tests-netcore-step.yml` |
114 | | -- `eng/pipelines/common/templates/steps/build-and-run-tests-netfx-step.yml` |
115 | | -- `eng/pipelines/common/templates/steps/run-all-tests-step.yml` |
116 | | - |
117 | | -### Test Timeout |
118 | | -All test runs use `--blame-hang-timeout 10m` (configured in `build.proj`). Tests exceeding 10 minutes are killed and reported as failures. |
119 | | - |
120 | | -### SNI Testing |
121 | | -The `useManagedSNI` parameter controls testing with: |
122 | | -- Native SNI (`false`) - Windows native library |
123 | | -- Managed SNI (`true`) - Cross-platform managed implementation |
| 82 | +Test partitioning: |
| 83 | +- Tests split into `TestSet=1`, `TestSet=2`, `TestSet=3` for parallelization |
| 84 | +- `TestSet=AE` — Always Encrypted tests (controlled by `runAlwaysEncryptedTests`) |
124 | 85 |
|
125 | | -## Variables |
126 | | - |
127 | | -### Build Variables (`ci-build-variables.yml`) |
128 | | -Common build configuration: |
129 | | -- Package versions |
130 | | -- Build paths |
131 | | -- Signing configuration |
132 | | - |
133 | | -### Runtime Variables |
134 | | -Set via pipeline parameters or UI: |
135 | | -- `Configuration` - Debug/Release |
136 | | -- `Platform` - AnyCPU/x86/x64 |
137 | | -- `TF` - Target framework |
138 | | - |
139 | | -## Creating Pipeline Changes |
140 | | - |
141 | | -### Adding New Test Categories |
142 | | -1. Add category attribute to tests: `[Category("newcategory")]` |
143 | | -2. Update filter expressions in test job templates |
144 | | -3. Document category purpose in test documentation |
145 | | - |
146 | | -### Adding New Pipeline Parameters |
147 | | -1. Define parameter in appropriate `.yml` file |
148 | | -2. Add to parameter passing in calling templates |
149 | | -3. Document in this file |
150 | | - |
151 | | -### Modifying Build Steps |
152 | | -1. Changes should be made in template files for reusability |
153 | | -2. Test changes locally when possible |
154 | | -3. Submit as PR - validation will run |
| 86 | +Test filters — default excludes `failing` and `flaky` categories: |
| 87 | +- `failing` — known permanent failures, always excluded |
| 88 | +- `flaky` — intermittent failures, quarantined in separate pipeline steps |
| 89 | +- `nonnetfxtests` / `nonnetcoreapptests` — platform-specific exclusions |
| 90 | +- `nonwindowstests` / `nonlinuxtests` — OS-specific exclusions |
155 | 91 |
|
156 | | -## Best Practices |
| 92 | +Flaky test quarantine: |
| 93 | +- Quarantined tests (`[Trait("Category", "flaky")]`) run in separate steps after main tests |
| 94 | +- Main test runs are not blocked by flaky failures |
| 95 | +- No code coverage collected for flaky runs |
| 96 | +- Configured in `common/templates/steps/build-and-run-tests-netcore-step.yml`, `build-and-run-tests-netfx-step.yml`, and `run-all-tests-step.yml` |
157 | 97 |
|
158 | | -### Template Design |
159 | | -- Use templates for reusable definitions |
160 | | -- Pass parameters explicitly (avoid global variables) |
161 | | -- Use descriptive stage/job/step names |
| 98 | +SNI testing — `useManagedSNI` controls testing with native SNI (`false`) or managed SNI (`true`) |
162 | 99 |
|
163 | | -### Variable Management |
164 | | -- Use template variables for shared values |
165 | | -- Use pipeline parameters for per-run configuration |
166 | | -- Avoid hardcoding versions (use Directory.Packages.props) |
| 100 | +Test timeout — `--blame-hang-timeout 10m` (configured in `build.proj`); tests exceeding 10 minutes are killed |
167 | 101 |
|
168 | | -### Test Infrastructure |
169 | | -- Ensure tests are properly categorized |
170 | | -- Handle test configuration files properly |
171 | | -- Use test matrix for cross-platform coverage |
172 | | - |
173 | | -## Troubleshooting |
174 | | - |
175 | | -### Common Issues |
176 | | -1. **Test failures due to missing config**: Ensure `config.json` exists |
177 | | -2. **Platform-specific failures**: Check platform exclusion categories |
178 | | -3. **Timeout issues**: Increase `testJobTimeout` parameter |
179 | | - |
180 | | -### Debugging Pipelines |
181 | | -- Enable debug mode via `debug: true` parameter |
182 | | -- Use `dotnetVerbosity: diagnostic` for detailed output |
183 | | -- Check build logs in Azure DevOps |
184 | | - |
185 | | -## Security Considerations |
186 | | - |
187 | | -- Pipelines use service connections for artifact publishing |
188 | | -- Signing uses secure key vault integration |
189 | | -- Sensitive configuration should use pipeline secrets |
190 | | -- Never commit credentials in pipeline files |
191 | | - |
192 | | -## Related Documentation |
| 102 | +## Variables |
193 | 103 |
|
194 | | -- [BUILDGUIDE.md](../../BUILDGUIDE.md) - Local build instructions |
195 | | -- [Azure DevOps Documentation](https://learn.microsoft.com/azure/devops/pipelines/) |
| 104 | +- All CI build variables centralized in `libraries/ci-build-variables.yml` |
| 105 | +- Package versions use `-ci` suffix (e.g., `7.0.0.$(Build.BuildNumber)-ci`) |
| 106 | +- `assemblyBuildNumber` derived from first segment of `Build.BuildNumber` (16-bit safe) |
| 107 | +- `localFeedPath` = `$(Build.SourcesDirectory)/packages` — local NuGet feed for inter-package deps |
| 108 | +- `packagePath` = `$(Build.SourcesDirectory)/output` — NuGet pack output |
| 109 | + |
| 110 | +## Conventions When Editing Pipelines |
| 111 | + |
| 112 | +- Always use templates for reusable logic — do not inline complex steps |
| 113 | +- Pass parameters explicitly; avoid relying on global variables |
| 114 | +- Use descriptive stage/job/step display names |
| 115 | +- When adding parameters, define them in the core template and thread through calling pipelines |
| 116 | +- When adding test categories, update filter expressions in test step templates |
| 117 | +- PR pipelines should run a minimal matrix for fast feedback |
| 118 | +- Test changes via PR pipeline first — validation runs automatically |
| 119 | +- Enable `debug: true` and `dotnetVerbosity: diagnostic` for troubleshooting |
| 120 | +- Never commit credentials or secrets in pipeline files |
| 121 | +- Signing and release are handled by OneBranch pipelines — not these CI/PR pipelines |
0 commit comments