Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ When a new issue is created, follow these steps:
- Do not modify `CHANGELOG.md` unless executing a release workflow (see `release-notes` prompt).
- Do not close issues without a fix or without providing a clear reason.

## Terminal Execution Safety
- Treat any non-zero shell exit code as a failed step that requires correction before proceeding.
- If a bash process exits, do not wait for more output from that process; rerun the command in a fresh terminal session.
- Validate that expected command output was produced before using it as evidence for conclusions.
- When terminal execution fails, surface the failure immediately and retry with a corrected command.
- Avoid `set -e` in this automation workflow; use focused commands and verify each result explicitly so shell exits are observable and attributable.
- Prefer short, single-purpose terminal commands over long chained scripts when debugging or gathering state.

## 📝 Notes
- Update policies and guidelines in the `policy/` directory as needed based on trending practices and team feedback.
- Regularly review and update the `doc/` directory to ensure it reflects the current state of the project.
11 changes: 11 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ This repository provides reusable prompts in `.github/prompts/` for common maint
6. **Performance Optimization**: Use pooling, async, efficient allocations
7. **Observability**: EventSource tracing, meaningful errors

## Terminal Reliability Rules

When using shell/terminal tools, follow these rules strictly:

1. Treat non-zero terminal exit codes as immediate failures to investigate; do not continue as if the command succeeded.
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.
3. After any command expected to gather data, verify output was actually returned before proceeding.
4. If command execution failed, report the failure clearly and retry with a corrected command instead of waiting.
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.
6. Prefer shorter command batches over long chained scripts when collecting evidence; this makes bash exits easier to detect and recover from.

## Branch Naming

All branches created by AI agents **must** live under the `dev/automation/` prefix. Use a descriptive suffix, for example:
Expand Down
67 changes: 35 additions & 32 deletions BUILDGUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ on operating systems that do not support .NET Framework. As such, it is not nece
no action is required. On Linux and macOS systems, the `pwsh` command is required to be in the `$PATH` environment
variable. For specific instructions see: [Install PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/install-powershell)

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

## Developer Workflow

Expand All @@ -34,21 +33,16 @@ package the project. The `build.proj` file provides convenient targets to accomp
> may be noticed, possibly severe. All official build and test infrastructure uses the `build.proj` entrypoint, and it
> is recommended that `build.proj` is used for local development, as well.

> [!TIP]
> `build.proj` was written with the intention of being called from `msbuild`. As such, the examples below
> use `msbuild`. On systems where `msbuild` is not available, simply replace `msbuild` with `dotnet msbuild` to get the
> same behavior.

> [!TIP]
> This section is not exhaustive of all targets or parameters to `build.proj`. Complete documentation is available in
> [`build.proj`](build.proj).

### Building Projects

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

```bash
msbuild build.proj -t:<build_target> [optional_parameters]
dotnet build build.proj -t:<build_target> [optional_parameters]
```

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

Build all projects:

```bash
msbuild build.proj -t:Build
dotnet build build.proj -t:Build
Comment thread
paulmedynski marked this conversation as resolved.
```

Build Microsoft.Data.SqlClient in Release configuration:

```bash
msbuild build.proj -t:BuildSqlClient -p:Configuration=Release
dotnet build build.proj -t:BuildSqlClient -p:Configuration=Release
```

Build v1.2.3 of Microsoft.Data.SqlClient.Extensions.Abstractions:

```bash
msbuild build.proj -t:BuildAbstractions -p:PackageVersionAbstractions=1.2.3
dotnet build build.proj -t:BuildAbstractions -p:PackageVersionAbstractions=1.2.3
```

### Testing Projects

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

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

```bash
msbuild build.proj -t:<test_target> [optional_parameters]
dotnet build build.proj -t:<test_target> [optional_parameters]
```

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

```bash
msbuild build.proj -t:TestSqlClientUnit
dotnet build build.proj -t:TestSqlClientUnit
```

Run Microsoft.Data.SqlClient manual test set 2:
```bash
msbuild build.proj -t:TestSqlClientManual -p:TestSet=2
dotnet build build.proj -t:TestSqlClientManual -p:TestSet=2
```

Run Microsoft.Data.SqlClient functional tests against x86 dotnet:
```bash
msbuild build.proj -t:TestSqlClientFunctional -p:DotnetPath='C:\path\to\dotnet\x86\'
dotnet build build.proj -t:TestSqlClientFunctional -p:DotnetPath='C:\path\to\dotnet\x86\'
```

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

Run Microsoft.Data.SqlClient functional tests against net8.0 runtime:
```bash
msbuild build.proj -t:TestSqlClientFunctional -p:TestFramework=net8.0
dotnet build build.proj -t:TestSqlClientFunctional -p:TestFramework=net8.0
```

### Packaging Projects

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

```bash
msbuild build.proj -t:<pack_target> [optional_parameters]
dotnet build build.proj -t:<pack_target> [optional_parameters]
```

| `<pack_target>` | Description |
Expand All @@ -191,30 +188,36 @@ A selection of parameters for pack targets in `build.proj` relevant to common de
| `[optional_parameter]` | Default Value | Allowed Values | Description |
|------------------------------------|---------------|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `-p:Configuration=` | `Debug` | `Debug`, `Release` | Build configuration. Only applies if project and dependencies are being built. |
| `-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. |
| `-p:PackBuild=` | `true` | `true`, `false` | Whether or not to build the project before packing. If `false`, project must be built using the same parameters. |
| `-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. |

For `PackSqlClient`, these additional parameters are optional overrides for dependency versions injected into the SqlClient nuspec during pack:

- `-p:PackageVersionAbstractions=<version>`
- `-p:PackageVersionLogging=<version>`

If omitted, `PackSqlClient` computes `AbstractionsPackageVersion` and `LoggingPackageVersion` from sibling projects using the current `BuildNumber` and `BuildSuffix` context.

#### Examples

Package Microsoft.Data.SqlClient.Internal.Logging into a NuGet package:
```bash
msbuild build.proj -t:PackLogging
dotnet build build.proj -t:PackLogging
```

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

Package version 1.2.3 of Microsoft.Data.SqlClient.Extensions.Abstractions:
```bash
msbuild build.proj -t:PackAbstractions -p:PackageVersionAbstractions=1.2.3
dotnet build build.proj -t:PackAbstractions -p:PackageVersionAbstractions=1.2.3
```

Package Microsoft.Data.SqlClient.Extensions.Azure without building it beforehand:
```bash
msbuild build.proj -t:PackAzure -p:PackBuild=false
dotnet build build.proj -t:PackAzure -p:PackBuild=false
```

## Versioning
Expand Down Expand Up @@ -276,20 +279,20 @@ and Microsoft.Data.SqlClient.Internal.Logging v2.2.2.

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

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

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

Run Microsoft.Data.SqlClient functional tests against the versions built above:
```bash
msbuild build.proj -t:TestSqlClientFunctional \
dotnet build build.proj -t:TestSqlClientFunctional \
-p:ReferenceType=Package \
-p:PackageVersionSqlClient=7.1.1 \
-p:PackageVersionAbstractions=1.0.1 \
Expand Down
44 changes: 19 additions & 25 deletions TESTGUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,7 @@ These projects target `net8.0`, `net9.0`, and `net10.0` on all platforms. On Win
Use [build.proj](build.proj) from the repository root:

```bash
msbuild build.proj -t:<test_target> [optional_parameters]
```

If `msbuild` is not available, use `dotnet msbuild`:

```bash
dotnet msbuild build.proj -t:<test_target> [optional_parameters]
dotnet build build.proj -t:<test_target> [optional_parameters]
```

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

```bash
msbuild build.proj -t:TestSqlClientUnit
dotnet build build.proj -t:TestSqlClientUnit
```

Run the SqlClient functional tests:

```bash
msbuild build.proj -t:TestSqlClientFunctional
dotnet build build.proj -t:TestSqlClientFunctional
```

Run the SqlClient manual tests:

```bash
msbuild build.proj -t:TestSqlClientManual
dotnet build build.proj -t:TestSqlClientManual
```

Run only manual test set 2:

```bash
msbuild build.proj -t:TestSqlClientManual -p:TestSet=2
dotnet build build.proj -t:TestSqlClientManual -p:TestSet=2
```

Run manual test sets 1 and 3:

```bash
msbuild build.proj -t:TestSqlClientManual -p:TestSet=13
dotnet build build.proj -t:TestSqlClientManual -p:TestSet=13
```

Run Always Encrypted manual tests:

```bash
msbuild build.proj -t:TestSqlClientManual -p:TestSet=AE
dotnet build build.proj -t:TestSqlClientManual -p:TestSet=AE
```

Run a specific target framework:

```bash
msbuild build.proj -t:TestSqlClientFunctional -p:TestFramework=net8.0
dotnet build build.proj -t:TestSqlClientFunctional -p:TestFramework=net8.0
```

Run functional tests against an x86 `dotnet` installation:

```bash
msbuild build.proj -t:TestSqlClientFunctional -p:DotnetPath='C:\path\to\dotnet\x86\'
dotnet build build.proj -t:TestSqlClientFunctional -p:DotnetPath='C:\path\to\dotnet\x86\'
```

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

```bash
msbuild build.proj -t:TestAzure -p:TestFilters=category!=failing
dotnet build build.proj -t:TestAzure -p:TestFilters=category!=failing
```

## Test Parameters
Expand Down Expand Up @@ -132,13 +126,13 @@ Examples:

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

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

# Disable the default filter.
msbuild build.proj -t:TestSqlClientFunctional -p:TestFilters=none
dotnet build build.proj -t:TestSqlClientFunctional -p:TestFilters=none
```

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

```bash
MDS_TEST_CONFIG=/path/to/config.json msbuild build.proj -t:TestSqlClientManual -p:TestSet=2
MDS_TEST_CONFIG=/path/to/config.json dotnet build build.proj -t:TestSqlClientManual -p:TestSet=2
```

On PowerShell:

```powershell
$env:MDS_TEST_CONFIG = "C:\path\to\config.json"
msbuild build.proj -t:TestSqlClientManual -p:TestSet=2
dotnet build build.proj -t:TestSqlClientManual -p:TestSet=2
```

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

```bash
msbuild build.proj -t:TestSqlClientUnit -p:TestResultsFolderPath=/tmp/sqlclient-test-results
dotnet build build.proj -t:TestSqlClientUnit -p:TestResultsFolderPath=/tmp/sqlclient-test-results
```

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

```bash
msbuild build.proj -t:TestSqlClientManual -p:TestBlameTimeout=30m
dotnet build build.proj -t:TestSqlClientManual -p:TestBlameTimeout=30m
```

To disable hang blame collection:

```bash
msbuild build.proj -t:TestSqlClientManual -p:TestBlameTimeout=0
dotnet build build.proj -t:TestSqlClientManual -p:TestBlameTimeout=0
```

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

```bash
msbuild build.proj -t:TestSqlClientUnit -p:TestCodeCoverage=false
dotnet build build.proj -t:TestSqlClientUnit -p:TestCodeCoverage=false
```
Loading
Loading