Skip to content

Commit 9a57eec

Browse files
committed
build: add ApiCompat support to handle breaking changes
1 parent 7f33097 commit 9a57eec

11 files changed

Lines changed: 60 additions & 0 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,3 +417,6 @@ FodyWeavers.xsd
417417
*.msm
418418
*.msp
419419
.claude/
420+
421+
# ApiCompat baseline assemblies
422+
!**/LastMajorVersionBinary/*.dll

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,5 +220,22 @@ Pull requests are welcome. For major changes, please open an issue first to disc
220220

221221
Please make sure to update tests as appropriate.
222222

223+
## Breaking Changes
224+
The generated API surface is validated against a baseline using [ApiCompat](https://learn.microsoft.com/en-us/dotnet/fundamentals/apicompat/overview). Each `Example.OpenApi*` project has a `LastMajorVersionBinary/` directory containing the baseline reference assembly.
225+
226+
### Introduce Breaking Change
227+
Build will fail when a breaking change is detected. Generate a suppression file for the breaking changes, and commit it to accept the breaking changes:
228+
```Shell
229+
dotnet build -p:ApiCompatGenerateSuppressionFile=true
230+
```
231+
232+
### Update Baseline
233+
The baseline doesn't need to be updated when using suppression files, but if it for some reason should, run:
234+
```Shell
235+
dotnet build -p:_ApiCompatGenerateContractAssembly=true -p:ApiCompatValidateAssemblies=false
236+
```
237+
238+
This copies the current reference assemblies to `LastMajorVersionBinary/` for each example project. Commit the updated DLLs. The suppression files should also be purged at this point.
239+
223240
# License
224241
[MIT](LICENSE)

tests/Directory.Build.props

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project>
2+
<PropertyGroup>
3+
<_ApiCompatGenerateContractAssembly>false</_ApiCompatGenerateContractAssembly>
4+
<_ApiCompatCaptureGroupPattern>.+%5C$([System.IO.Path]::DirectorySeparatorChar)(.+)%5C$([System.IO.Path]::DirectorySeparatorChar)(.+)</_ApiCompatCaptureGroupPattern>
5+
</PropertyGroup>
6+
7+
<Target Name="ApiCompatGenerateContractAssembly" AfterTargets="Build" Condition="'$(_ApiCompatGenerateContractAssembly)' == 'true' And $([System.Text.RegularExpressions.Regex]::IsMatch($(MSBuildProjectName), '^Example\.OpenApi\d+$'))">
8+
<Copy SourceFiles="$(IntermediateOutputPath)ref/$(AssemblyName).dll"
9+
DestinationFolder="LastMajorVersionBinary" />
10+
</Target>
11+
12+
<ItemGroup>
13+
<!-- Generate OS-agnostic Right suppression directives -->
14+
<ApiCompatRightAssembliesTransformationPattern Include="$(_ApiCompatCaptureGroupPattern)" ReplacementString="obj/$1/$2" />
15+
</ItemGroup>
16+
</Project>

tests/Example.OpenApi20/Example.OpenApi20.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<RootNamespace>Example.OpenApi20</RootNamespace>
8+
9+
<ApiCompatValidateAssemblies>true</ApiCompatValidateAssemblies>
10+
<ApiCompatContractAssembly>LastMajorVersionBinary/$(AssemblyName).dll</ApiCompatContractAssembly>
11+
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/apicompat/diagnostic-ids -->
12+
<ApiCompatGenerateSuppressionFile>false</ApiCompatGenerateSuppressionFile>
813
</PropertyGroup>
914

1015
<ItemGroup>
1116
<PackageReference Include="Corvus.Json.ExtendedTypes" Version="4.4.2" />
1217
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.12" />
18+
<PackageReference Include="Microsoft.DotNet.ApiCompat.Task" Version="10.0.202" PrivateAssets="all" IsImplicitlyDefined="true" />
1319
<PackageReference Include="ParameterStyleParsers.OpenAPI" Version="1.4.0" />
1420
</ItemGroup>
1521

Binary file not shown.

tests/Example.OpenApi30/Example.OpenApi30.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<RootNamespace>Example.OpenApi30</RootNamespace>
8+
9+
<ApiCompatValidateAssemblies>true</ApiCompatValidateAssemblies>
10+
<ApiCompatContractAssembly>LastMajorVersionBinary/$(AssemblyName).dll</ApiCompatContractAssembly>
11+
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/apicompat/diagnostic-ids -->
12+
<ApiCompatGenerateSuppressionFile>false</ApiCompatGenerateSuppressionFile>
813
</PropertyGroup>
914

1015
<ItemGroup>
1116
<PackageReference Include="Corvus.Json.ExtendedTypes" Version="4.4.2" />
17+
<PackageReference Include="Microsoft.DotNet.ApiCompat.Task" Version="10.0.202" PrivateAssets="all" IsImplicitlyDefined="true" />
1218
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.12" />
1319
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="9.0.12" />
1420
<PackageReference Include="ParameterStyleParsers.OpenAPI" Version="1.4.0" />
Binary file not shown.

tests/Example.OpenApi31/Example.OpenApi31.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<RootNamespace>Example.OpenApi31</RootNamespace>
8+
9+
<ApiCompatValidateAssemblies>true</ApiCompatValidateAssemblies>
10+
<ApiCompatContractAssembly>LastMajorVersionBinary/$(AssemblyName).dll</ApiCompatContractAssembly>
11+
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/apicompat/diagnostic-ids -->
12+
<ApiCompatGenerateSuppressionFile>false</ApiCompatGenerateSuppressionFile>
813
</PropertyGroup>
914

1015
<ItemGroup>
1116
<PackageReference Include="Corvus.Json.ExtendedTypes" Version="4.4.2" />
17+
<PackageReference Include="Microsoft.DotNet.ApiCompat.Task" Version="10.0.202" PrivateAssets="all" IsImplicitlyDefined="true" />
1218
<PackageReference Include="Microsoft.AspNetCore.Authentication.Certificate" Version="9.0.12" />
1319
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.12" />
1420
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="9.0.12" />
Binary file not shown.

tests/Example.OpenApi32/Example.OpenApi32.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<RootNamespace>Example.OpenApi32</RootNamespace>
8+
9+
<ApiCompatValidateAssemblies>true</ApiCompatValidateAssemblies>
10+
<ApiCompatContractAssembly>LastMajorVersionBinary/$(AssemblyName).dll</ApiCompatContractAssembly>
11+
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/apicompat/diagnostic-ids -->
12+
<ApiCompatGenerateSuppressionFile>false</ApiCompatGenerateSuppressionFile>
813
</PropertyGroup>
914

1015
<ItemGroup>
1116
<PackageReference Include="Corvus.Json.ExtendedTypes" Version="4.4.2" />
17+
<PackageReference Include="Microsoft.DotNet.ApiCompat.Task" Version="10.0.202" PrivateAssets="all" IsImplicitlyDefined="true" />
1218
<PackageReference Include="Microsoft.AspNetCore.Authentication.Certificate" Version="9.0.12" />
1319
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.12" />
1420
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="9.0.12" />

0 commit comments

Comments
 (0)