-
Notifications
You must be signed in to change notification settings - Fork 102
Add API Compat for TFMs #1033
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Add API Compat for TFMs #1033
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
f301b86
Add API Compat for TFMs
mtmk 279c154
Add apicompat workflow to solution and fix script execution command
mtmk dd94e20
Update apicompat workflow to include read permissions for contents
mtmk feb830d
Add "Platform Compatibility" documentation to advanced topics
mtmk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| name: API Compatibility | ||
|
|
||
| on: | ||
| pull_request: {} | ||
| push: | ||
| branches: | ||
| - main | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| apicompat: | ||
| name: Check TFM API Compatibility | ||
| runs-on: ubuntu-latest | ||
| env: | ||
| DOTNET_CLI_TELEMETRY_OPTOUT: 1 | ||
| DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 | ||
| NUGET_XMLDOC_MODE: skip | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup dotnet | ||
| uses: actions/setup-dotnet@v4 | ||
| with: | ||
| dotnet-version: 8.x | ||
|
|
||
| - name: Run API Compatibility Check | ||
| run: bash scripts/apicompat.sh --build | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids --> | ||
| <!-- These are intentional TFM-specific polyfill types that differ between netstandard2.0 and newer TFMs --> | ||
| <Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> | ||
| <!-- SslClientAuthenticationOptions is a polyfill for netstandard2.0 where the BCL type doesn't exist --> | ||
| <Suppression> | ||
| <DiagnosticId>CP0001</DiagnosticId> | ||
| <Target>T:NATS.Client.Core.SslClientAuthenticationOptions</Target> | ||
| </Suppression> | ||
| <!-- ConfigureClientAuthentication uses the polyfill type in its signature --> | ||
| <Suppression> | ||
| <DiagnosticId>CP0002</DiagnosticId> | ||
| <Target>M:NATS.Client.Core.NatsTlsOpts.get_ConfigureClientAuthentication</Target> | ||
| </Suppression> | ||
| <!-- AddNats has an extra 'key' parameter in net8.0+ for keyed DI services --> | ||
| <Suppression> | ||
| <DiagnosticId>CP0002</DiagnosticId> | ||
| <Target>M:NATS.Client.Hosting.NatsHostingExtensions.AddNats(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Int32,System.Func{NATS.Client.Core.NatsOpts,NATS.Client.Core.NatsOpts},System.Action{NATS.Client.Core.NatsConnection})</Target> | ||
| </Suppression> | ||
| </Suppressions> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| #!/bin/bash | ||
| # API Compatibility Check Script | ||
| # Verifies that APIs are compatible across different TFMs | ||
| # Usage: ./scripts/apicompat.sh [--build] | ||
|
|
||
| set -e | ||
|
|
||
| # Get script directory (works on both Windows and Linux) | ||
| SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" | ||
| ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" | ||
|
|
||
| PROJECTS="NATS.Client.Abstractions NATS.Client.Core NATS.Client.Hosting NATS.Client.JetStream NATS.Client.KeyValueStore NATS.Client.ObjectStore NATS.Client.Services NATS.Client.Serializers.Json NATS.Client.Simplified NATS.Net NATS.Extensions.Microsoft.DependencyInjection" | ||
|
|
||
| SUPPRESSION_FILE="$ROOT_DIR/apicompat.suppression.xml" | ||
|
|
||
| # Check if apicompat is installed | ||
| if ! command -v apicompat &> /dev/null; then | ||
| echo "Installing Microsoft.DotNet.ApiCompat.Tool..." | ||
| dotnet tool install --global Microsoft.DotNet.ApiCompat.Tool | ||
| fi | ||
|
|
||
| # Build if requested | ||
| if [ "$1" = "--build" ]; then | ||
| echo "Building solution..." | ||
| dotnet build -c Release "$ROOT_DIR/NATS.Net.sln" | ||
| fi | ||
|
|
||
| check_compat() { | ||
| local baseline_tfm=$1 | ||
| local target_tfm=$2 | ||
| local failed=0 | ||
|
|
||
| echo "" | ||
| echo "==============================================" | ||
| echo "Checking: $baseline_tfm (baseline) vs $target_tfm" | ||
| echo "==============================================" | ||
|
|
||
| for project in $PROJECTS; do | ||
| left="$ROOT_DIR/src/$project/bin/Release/$baseline_tfm/$project.dll" | ||
| right="$ROOT_DIR/src/$project/bin/Release/$target_tfm/$project.dll" | ||
|
|
||
| if [ -f "$left" ] && [ -f "$right" ]; then | ||
| echo -n " $project: " | ||
| if apicompat --left "$left" --right "$right" --suppression-file "$SUPPRESSION_FILE" --permit-unnecessary-suppressions > /dev/null 2>&1; then | ||
| echo "OK" | ||
| else | ||
| echo "FAILED" | ||
| apicompat --left "$left" --right "$right" --suppression-file "$SUPPRESSION_FILE" --permit-unnecessary-suppressions 2>&1 | head -20 | ||
| failed=1 | ||
| fi | ||
| else | ||
| echo " $project: SKIPPED (assemblies not found)" | ||
| fi | ||
| done | ||
|
|
||
| return $failed | ||
| } | ||
|
|
||
| echo "API Compatibility Check" | ||
| echo "=======================" | ||
|
|
||
| exit_code=0 | ||
|
|
||
| # Only check against net8.0 as the target TFM | ||
| # net6.0 has known differences with init accessors | ||
| check_compat "netstandard2.0" "net8.0" || exit_code=1 | ||
| check_compat "netstandard2.1" "net8.0" || exit_code=1 | ||
|
|
||
| echo "" | ||
| if [ $exit_code -eq 0 ]; then | ||
| echo "All API compatibility checks passed!" | ||
| else | ||
| echo "Some API compatibility checks failed!" | ||
| fi | ||
|
|
||
| exit $exit_code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
tools/site_src/documentation/advanced/platform-compatibility.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| # Platform Compatibility | ||
|
|
||
| NATS.Net targets multiple .NET platforms to provide broad compatibility: | ||
|
|
||
| - `netstandard2.0` - .NET Framework 4.6.1+, .NET Core 2.0+, Mono, Xamarin, Unity | ||
| - `netstandard2.1` - .NET Core 3.0+ | ||
| - `net6.0` - .NET 6 | ||
| - `net8.0` - .NET 8 | ||
|
|
||
| While the API surface is designed to be consistent across all target frameworks, there are some | ||
| intentional differences due to platform capabilities. This page documents these differences. | ||
|
|
||
| ## TLS Configuration | ||
|
|
||
| ### SslClientAuthenticationOptions | ||
|
|
||
| The [`NatsTlsOpts.ConfigureClientAuthentication`](xref:NATS.Client.Core.NatsTlsOpts.ConfigureClientAuthentication) | ||
| property allows you to configure TLS client authentication options. | ||
|
|
||
| | Target Framework | Type | | ||
| |-----------------|------| | ||
| | `netstandard2.0` | `NATS.Client.Core.SslClientAuthenticationOptions` (polyfill) | | ||
| | `netstandard2.1`, `net6.0`, `net8.0` | `System.Net.Security.SslClientAuthenticationOptions` (BCL) | | ||
|
|
||
| On `netstandard2.0`, the library provides a polyfill type `NATS.Client.Core.SslClientAuthenticationOptions` | ||
| because the BCL type doesn't exist in that target framework. The polyfill provides a subset of the | ||
| properties available in the BCL type: | ||
|
|
||
| - `TargetHost` | ||
| - `EnabledSslProtocols` | ||
| - `ClientCertificates` | ||
| - `CertificateRevocationCheckMode` | ||
| - `RemoteCertificateValidationCallback` | ||
| - `LocalCertificateSelectionCallback` | ||
|
|
||
| If you need the full `SslClientAuthenticationOptions` functionality, consider targeting `netstandard2.1` or later. | ||
|
|
||
| ## Dependency Injection | ||
|
|
||
| ### Keyed Services | ||
|
|
||
| The [`AddNats`](xref:NATS.Client.Hosting.NatsHostingExtensions.AddNats*) extension method has different | ||
| signatures depending on the target framework: | ||
|
|
||
| **netstandard2.0, netstandard2.1, net6.0:** | ||
| ```csharp | ||
| public static IServiceCollection AddNats( | ||
| this IServiceCollection services, | ||
| int poolSize = 1, | ||
| Func<NatsOpts, NatsOpts>? configureOpts = null, | ||
| Action<NatsConnection>? configureConnection = null) | ||
| ``` | ||
|
|
||
| **net8.0:** | ||
| ```csharp | ||
| public static IServiceCollection AddNats( | ||
| this IServiceCollection services, | ||
| int poolSize = 1, | ||
| Func<NatsOpts, NatsOpts>? configureOpts = null, | ||
| Action<NatsConnection>? configureConnection = null, | ||
| object? key = null) // Additional parameter for keyed services | ||
| ``` | ||
|
|
||
| [Keyed dependency injection services](https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection#keyed-services) | ||
| were introduced in .NET 8. The `key` parameter allows you to register multiple NATS connections | ||
| with different keys: | ||
|
|
||
| ```csharp | ||
| // .NET 8+ only | ||
| services.AddNats(key: "primary", configureOpts: opts => opts with { Url = "nats://primary:4222" }); | ||
| services.AddNats(key: "secondary", configureOpts: opts => opts with { Url = "nats://secondary:4222" }); | ||
|
|
||
| // Inject with [FromKeyedServices("primary")] | ||
| public class MyService([FromKeyedServices("primary")] INatsConnection primaryNats) { } | ||
| ``` | ||
|
|
||
| ## API Compatibility Checking | ||
|
|
||
| The repository includes an API compatibility check that runs in CI to ensure APIs remain consistent | ||
| across target frameworks. Known intentional differences are documented in `apicompat.suppression.xml` | ||
| at the repository root. | ||
|
|
||
| To run the compatibility check locally: | ||
|
|
||
| ```bash | ||
| ./scripts/apicompat.sh --build | ||
| ``` | ||
|
|
||
| ## What's Next | ||
|
|
||
| - [Serialization](serialization.md) is the process of converting an object into a format that can be stored or transmitted. | ||
| - [Security](security.md) is an important aspect of any distributed system. NATS provides a number of security features to help you secure your applications. | ||
| - [AOT Deployment](aot.md) is a way to deploy your applications as native platform executables. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.