Skip to content

Commit 822dca4

Browse files
authored
Migrate SqlClient packaging to dotnet pack and centralize pack fallback (#4257)
1 parent 959d2fc commit 822dca4

18 files changed

Lines changed: 493 additions & 537 deletions

File tree

.github/copilot-instructions.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,14 @@ When a new issue is created, follow these steps:
150150
- Do not modify `CHANGELOG.md` unless executing a release workflow (see `release-notes` prompt).
151151
- Do not close issues without a fix or without providing a clear reason.
152152

153+
## Terminal Execution Safety
154+
- Treat any non-zero shell exit code as a failed step that requires correction before proceeding.
155+
- If a bash process exits, do not wait for more output from that process; rerun the command in a fresh terminal session.
156+
- Validate that expected command output was produced before using it as evidence for conclusions.
157+
- When terminal execution fails, surface the failure immediately and retry with a corrected command.
158+
- Avoid `set -e` in this automation workflow; use focused commands and verify each result explicitly so shell exits are observable and attributable.
159+
- Prefer short, single-purpose terminal commands over long chained scripts when debugging or gathering state.
160+
153161
## 📝 Notes
154162
- Update policies and guidelines in the `policy/` directory as needed based on trending practices and team feedback.
155163
- Regularly review and update the `doc/` directory to ensure it reflects the current state of the project.

AGENTS.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,17 @@ This repository provides reusable prompts in `.github/prompts/` for common maint
5454
6. **Performance Optimization**: Use pooling, async, efficient allocations
5555
7. **Observability**: EventSource tracing, meaningful errors
5656

57+
## Terminal Reliability Rules
58+
59+
When using shell/terminal tools, follow these rules strictly:
60+
61+
1. Treat non-zero terminal exit codes as immediate failures to investigate; do not continue as if the command succeeded.
62+
2. If a bash session exits, assume it is dead and start a new command/session; do not wait for additional output from that session.
63+
3. After any command expected to gather data, verify output was actually returned before proceeding.
64+
4. If command execution failed, report the failure clearly and retry with a corrected command instead of waiting.
65+
5. Avoid `set -e` in this automation context; prefer single-purpose commands with explicit follow-up checks so failures are visible without killing the shell unexpectedly.
66+
6. Prefer shorter command batches over long chained scripts when collecting evidence; this makes bash exits easier to detect and recover from.
67+
5768
## Branch Naming
5869

5970
All branches created by AI agents **must** live under the `dev/automation/` prefix. Use a descriptive suffix, for example:

BUILDGUIDE.md

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@ on operating systems that do not support .NET Framework. As such, it is not nece
2020
no action is required. On Linux and macOS systems, the `pwsh` command is required to be in the `$PATH` environment
2121
variable. For specific instructions see: [Install PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/install-powershell)
2222

23-
The **NuGet** binary is required to package the Microsoft.Data.SqlClient project. For convenience, this can be done
24-
via the PowerShell script [tools/scripts/downloadLatestNuget.ps1](tools/scripts/downloadLatestNuget.ps1), however, any
25-
`nuget.exe` binary can be used.
23+
The **NuGet** binary is optional for inspection and feed-management workflows, but build and packaging flows in this
24+
repository are run through `dotnet build` against `build.proj`.
2625

2726
## Developer Workflow
2827

@@ -34,21 +33,16 @@ package the project. The `build.proj` file provides convenient targets to accomp
3433
> may be noticed, possibly severe. All official build and test infrastructure uses the `build.proj` entrypoint, and it
3534
> is recommended that `build.proj` is used for local development, as well.
3635
37-
> [!TIP]
38-
> `build.proj` was written with the intention of being called from `msbuild`. As such, the examples below
39-
> use `msbuild`. On systems where `msbuild` is not available, simply replace `msbuild` with `dotnet msbuild` to get the
40-
> same behavior.
41-
4236
> [!TIP]
4337
> This section is not exhaustive of all targets or parameters to `build.proj`. Complete documentation is available in
4438
> [`build.proj`](build.proj).
4539
4640
### Building Projects
4741

48-
From the root of your repository, run `msbuild` against `build.proj` with a build target, following this pattern:
42+
From the root of your repository, run `dotnet build` against `build.proj` with a build target, following this pattern:
4943

5044
```bash
51-
msbuild build.proj -t:<build_target> [optional_parameters]
45+
dotnet build build.proj -t:<build_target> [optional_parameters]
5246
```
5347

5448
The following build targets can be used to build the following projects. All targets will implicitly build any other
@@ -86,29 +80,32 @@ placed in `artifacts/Microsoft.Data.SqlClient.ref/Project-<configuration>/<tfm>`
8680
#### Examples
8781

8882
Build all projects:
83+
8984
```bash
90-
msbuild build.proj -t:Build
85+
dotnet build build.proj -t:Build
9186
```
9287

9388
Build Microsoft.Data.SqlClient in Release configuration:
89+
9490
```bash
95-
msbuild build.proj -t:BuildSqlClient -p:Configuration=Release
91+
dotnet build build.proj -t:BuildSqlClient -p:Configuration=Release
9692
```
9793

9894
Build v1.2.3 of Microsoft.Data.SqlClient.Extensions.Abstractions:
95+
9996
```bash
100-
msbuild build.proj -t:BuildAbstractions -p:PackageVersionAbstractions=1.2.3
97+
dotnet build build.proj -t:BuildAbstractions -p:PackageVersionAbstractions=1.2.3
10198
```
10299

103100
### Testing Projects
104101

105102
This section provides a summary and brief example of how to execute tests for projects in this repository. **For more
106103
information about test procedures, including config file setup, see [TESTGUIDE.md](TESTGUIDE.md).**
107104

108-
From the root of your repository, run `msbuild` against `build.proj` with a test target, following this pattern:
105+
From the root of your repository, run `dotnet build` against `build.proj` with a test target, following this pattern:
109106

110107
```bash
111-
msbuild build.proj -t:<test_target> [optional_parameters]
108+
dotnet build build.proj -t:<test_target> [optional_parameters]
112109
```
113110

114111
| `<test_target>` | Description |
@@ -140,37 +137,37 @@ A selection of parameters for test targets in `build.proj` relevant to common de
140137
Run Microsoft.Data.SqlClient unit tests:
141138

142139
```bash
143-
msbuild build.proj -t:TestSqlClientUnit
140+
dotnet build build.proj -t:TestSqlClientUnit
144141
```
145142

146143
Run Microsoft.Data.SqlClient manual test set 2:
147144
```bash
148-
msbuild build.proj -t:TestSqlClientManual -p:TestSet=2
145+
dotnet build build.proj -t:TestSqlClientManual -p:TestSet=2
149146
```
150147

151148
Run Microsoft.Data.SqlClient functional tests against x86 dotnet:
152149
```bash
153-
msbuild build.proj -t:TestSqlClientFunctional -p:DotnetPath='C:\path\to\dotnet\x86\'
150+
dotnet build build.proj -t:TestSqlClientFunctional -p:DotnetPath='C:\path\to\dotnet\x86\'
154151
```
155152

156153
Run all Microsoft.Data.SqlClient.Extensions.Azure unit tests, including interactive, but excluding failing tests:
157154
```bash
158-
msbuild build.proj -t:TestAzure -p:TestFilters=category!=failing
155+
dotnet build build.proj -t:TestAzure -p:TestFilters=category!=failing
159156
```
160157

161158
Run Microsoft.Data.SqlClient functional tests against net8.0 runtime:
162159
```bash
163-
msbuild build.proj -t:TestSqlClientFunctional -p:TestFramework=net8.0
160+
dotnet build build.proj -t:TestSqlClientFunctional -p:TestFramework=net8.0
164161
```
165162

166163
### Packaging Projects
167164

168165
Just like building and testing the various projects in this repository, packaging the projects into NuGet packages is
169-
also handled by `build.proj`. From the root of your repository, run `msbuild` against `build.proj` with a pack target,
166+
also handled by `build.proj`. From the root of your repository, run `dotnet build` against `build.proj` with a pack target,
170167
following this pattern:
171168

172169
```bash
173-
msbuild build.proj -t:<pack_target> [optional_parameters]
170+
dotnet build build.proj -t:<pack_target> [optional_parameters]
174171
```
175172

176173
| `<pack_target>` | Description |
@@ -191,30 +188,36 @@ A selection of parameters for pack targets in `build.proj` relevant to common de
191188
| `[optional_parameter]` | Default Value | Allowed Values | Description |
192189
|------------------------------------|---------------|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
193190
| `-p:Configuration=` | `Debug` | `Debug`, `Release` | Build configuration. Only applies if project and dependencies are being built. |
194-
| `-p:NugetPath=` | `[blank]` | eg. `C:\my\nuget.exe` | _Only applies to `PackSqlClient`._ Path to `nuget.exe` to use. If not provided, defaults to `nuget.exe` in the PATH. |
195191
| `-p:PackBuild=` | `true` | `true`, `false` | Whether or not to build the project before packing. If `false`, project must be built using the same parameters. |
196192
| `-p:PackageVersion<TargetPackage>=` | `[blank]` | eg. `1.2.3-dev123` | Version to assign to the package, where `<TargetPackage>` can be one of: `['Abstractions', 'Azure', 'AkvProvider', 'Logging', 'SqlClient', 'SqlServer']`. If `PackBuild` is `true`, the assembly and file versions will be derived from this version. See Versioning for more details. |
197193

194+
For `PackSqlClient`, these additional parameters are optional overrides for dependency versions injected into the SqlClient nuspec during pack:
195+
196+
- `-p:PackageVersionAbstractions=<version>`
197+
- `-p:PackageVersionLogging=<version>`
198+
199+
If omitted, `PackSqlClient` computes `AbstractionsPackageVersion` and `LoggingPackageVersion` from sibling projects using the current `BuildNumber` and `BuildSuffix` context.
200+
198201
#### Examples
199202

200203
Package Microsoft.Data.SqlClient.Internal.Logging into a NuGet package:
201204
```bash
202-
msbuild build.proj -t:PackLogging
205+
dotnet build build.proj -t:PackLogging
203206
```
204207

205-
Package Microsoft.Data.SqlClient if `nuget.exe` is not in the `$PATH` environment variable:
208+
Package Microsoft.Data.SqlClient:
206209
```bash
207-
msbuild build.proj -t:PackSqlClient -p:NugetPath="C:\my\nuget.exe"
210+
dotnet build build.proj -t:PackSqlClient
208211
```
209212

210213
Package version 1.2.3 of Microsoft.Data.SqlClient.Extensions.Abstractions:
211214
```bash
212-
msbuild build.proj -t:PackAbstractions -p:PackageVersionAbstractions=1.2.3
215+
dotnet build build.proj -t:PackAbstractions -p:PackageVersionAbstractions=1.2.3
213216
```
214217

215218
Package Microsoft.Data.SqlClient.Extensions.Azure without building it beforehand:
216219
```bash
217-
msbuild build.proj -t:PackAzure -p:PackBuild=false
220+
dotnet build build.proj -t:PackAzure -p:PackBuild=false
218221
```
219222

220223
## Versioning
@@ -276,20 +279,20 @@ and Microsoft.Data.SqlClient.Internal.Logging v2.2.2.
276279

277280
```bash
278281
# Build v2.2.2 of Logging and copy to packages
279-
msbuild build.proj -t:PackLogging \
282+
dotnet build build.proj -t:PackLogging \
280283
-p:ReferenceType=Package \
281284
-p:PackageVersionLogging=2.2.2
282285
cp artifacts/Microsoft.Data.SqlClient.Internal.Logging/Debug/*.*pkg packages/
283286

284287
# Build v1.0.1 of Abstractions that depends on v2.2.2 of Logging
285-
msbuild build.proj -t:PackAbstractions \
288+
dotnet build build.proj -t:PackAbstractions \
286289
-p:ReferenceType=Package \
287290
-p:PackageVersionAbstractions=1.0.1 \
288291
-p:PackageVersionLogging=2.2.2 \
289292
cp artifacts/Microsoft.Data.SqlClient.Extensions.Abstractions/Package-Debug/*.*pkg packages/
290293

291294
# Build SqlClient
292-
msbuild -t:PackSqlClient \
295+
dotnet build build.proj -t:PackSqlClient \
293296
-p:ReferenceType=Package \
294297
-p:PackageVersionSqlClient=7.1.1 \
295298
-p:PackageVersionAbstractions=1.0.1 \
@@ -299,7 +302,7 @@ cp artifacts/Microsoft.Data.SqlClient/Package-Debug/*.*pkg packages/
299302

300303
Run Microsoft.Data.SqlClient functional tests against the versions built above:
301304
```bash
302-
msbuild build.proj -t:TestSqlClientFunctional \
305+
dotnet build build.proj -t:TestSqlClientFunctional \
303306
-p:ReferenceType=Package \
304307
-p:PackageVersionSqlClient=7.1.1 \
305308
-p:PackageVersionAbstractions=1.0.1 \

TESTGUIDE.md

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,7 @@ These projects target `net8.0`, `net9.0`, and `net10.0` on all platforms. On Win
2323
Use [build.proj](build.proj) from the repository root:
2424

2525
```bash
26-
msbuild build.proj -t:<test_target> [optional_parameters]
27-
```
28-
29-
If `msbuild` is not available, use `dotnet msbuild`:
30-
31-
```bash
32-
dotnet msbuild build.proj -t:<test_target> [optional_parameters]
26+
dotnet build build.proj -t:<test_target> [optional_parameters]
3327
```
3428

3529
Test targets build the projects they depend on, so a separate build step is not required for normal test runs.
@@ -51,55 +45,55 @@ Test targets build the projects they depend on, so a separate build step is not
5145
Run the SqlClient unit tests:
5246

5347
```bash
54-
msbuild build.proj -t:TestSqlClientUnit
48+
dotnet build build.proj -t:TestSqlClientUnit
5549
```
5650

5751
Run the SqlClient functional tests:
5852

5953
```bash
60-
msbuild build.proj -t:TestSqlClientFunctional
54+
dotnet build build.proj -t:TestSqlClientFunctional
6155
```
6256

6357
Run the SqlClient manual tests:
6458

6559
```bash
66-
msbuild build.proj -t:TestSqlClientManual
60+
dotnet build build.proj -t:TestSqlClientManual
6761
```
6862

6963
Run only manual test set 2:
7064

7165
```bash
72-
msbuild build.proj -t:TestSqlClientManual -p:TestSet=2
66+
dotnet build build.proj -t:TestSqlClientManual -p:TestSet=2
7367
```
7468

7569
Run manual test sets 1 and 3:
7670

7771
```bash
78-
msbuild build.proj -t:TestSqlClientManual -p:TestSet=13
72+
dotnet build build.proj -t:TestSqlClientManual -p:TestSet=13
7973
```
8074

8175
Run Always Encrypted manual tests:
8276

8377
```bash
84-
msbuild build.proj -t:TestSqlClientManual -p:TestSet=AE
78+
dotnet build build.proj -t:TestSqlClientManual -p:TestSet=AE
8579
```
8680

8781
Run a specific target framework:
8882

8983
```bash
90-
msbuild build.proj -t:TestSqlClientFunctional -p:TestFramework=net8.0
84+
dotnet build build.proj -t:TestSqlClientFunctional -p:TestFramework=net8.0
9185
```
9286

9387
Run functional tests against an x86 `dotnet` installation:
9488

9589
```bash
96-
msbuild build.proj -t:TestSqlClientFunctional -p:DotnetPath='C:\path\to\dotnet\x86\'
90+
dotnet build build.proj -t:TestSqlClientFunctional -p:DotnetPath='C:\path\to\dotnet\x86\'
9791
```
9892

9993
Run all Azure extension tests, including `interactive` tests, while still excluding tests marked `failing` or `flaky`:
10094

10195
```bash
102-
msbuild build.proj -t:TestAzure -p:TestFilters=category!=failing
96+
dotnet build build.proj -t:TestAzure -p:TestFilters=category!=failing
10397
```
10498

10599
## Test Parameters
@@ -132,13 +126,13 @@ Examples:
132126

133127
```bash
134128
# Run a single test by fully-qualified name.
135-
msbuild build.proj -t:TestSqlClientUnit -p:TestFilters=FullyQualifiedName=Namespace.ClassName.MethodName
129+
dotnet build build.proj -t:TestSqlClientUnit -p:TestFilters=FullyQualifiedName=Namespace.ClassName.MethodName
136130

137131
# Run only flaky tests while investigating quarantine failures.
138-
msbuild build.proj -t:TestSqlClientManual -p:TestFilters=category=flaky
132+
dotnet build build.proj -t:TestSqlClientManual -p:TestFilters=category=flaky
139133

140134
# Disable the default filter.
141-
msbuild build.proj -t:TestSqlClientFunctional -p:TestFilters=none
135+
dotnet build build.proj -t:TestSqlClientFunctional -p:TestFilters=none
142136
```
143137

144138
When passing filter expressions that contain shell-sensitive characters such as `&`, quote or escape the value as
@@ -222,14 +216,14 @@ For SQL Server in a Linux container, WSL, or another host where SQL authenticati
222216
You can override the config file path with the `MDS_TEST_CONFIG` environment variable:
223217

224218
```bash
225-
MDS_TEST_CONFIG=/path/to/config.json msbuild build.proj -t:TestSqlClientManual -p:TestSet=2
219+
MDS_TEST_CONFIG=/path/to/config.json dotnet build build.proj -t:TestSqlClientManual -p:TestSet=2
226220
```
227221

228222
On PowerShell:
229223

230224
```powershell
231225
$env:MDS_TEST_CONFIG = "C:\path\to\config.json"
232-
msbuild build.proj -t:TestSqlClientManual -p:TestSet=2
226+
dotnet build build.proj -t:TestSqlClientManual -p:TestSet=2
233227
```
234228

235229
## Configuration Properties
@@ -289,23 +283,23 @@ If `TestSet` is omitted, all sets are compiled and run. You can combine sets by
289283
Test results are written to `test_results` by default. Override the location with `TestResultsFolderPath`:
290284

291285
```bash
292-
msbuild build.proj -t:TestSqlClientUnit -p:TestResultsFolderPath=/tmp/sqlclient-test-results
286+
dotnet build build.proj -t:TestSqlClientUnit -p:TestResultsFolderPath=/tmp/sqlclient-test-results
293287
```
294288

295289
Hang blame collection is enabled by default with a `10m` timeout. To increase the timeout:
296290

297291
```bash
298-
msbuild build.proj -t:TestSqlClientManual -p:TestBlameTimeout=30m
292+
dotnet build build.proj -t:TestSqlClientManual -p:TestBlameTimeout=30m
299293
```
300294

301295
To disable hang blame collection:
302296

303297
```bash
304-
msbuild build.proj -t:TestSqlClientManual -p:TestBlameTimeout=0
298+
dotnet build build.proj -t:TestSqlClientManual -p:TestBlameTimeout=0
305299
```
306300

307301
Code coverage is enabled by default. To disable it for a faster local run:
308302

309303
```bash
310-
msbuild build.proj -t:TestSqlClientUnit -p:TestCodeCoverage=false
304+
dotnet build build.proj -t:TestSqlClientUnit -p:TestCodeCoverage=false
311305
```

0 commit comments

Comments
 (0)