|
| 1 | +# Enable AOT compatibility regression testing in CI pipelines |
| 2 | + |
| 3 | +An increasing number of .NET Azure SDK libraries are committed to being compatible with native AOT. For more information about native AOT deployment see [this article](https://learn.microsoft.com/dotnet/core/deploying/native-aot/). To support this work, there is now an opt-in pipeline step called "Check for AOT compatibility regressions in \[Package Name\]". This pipeline creates a small sample app that uses a project reference to collect the set of trimming warnings reported for the specified library. This approach for collecting warnings is described in [this article](https://learn.microsoft.com/dotnet/core/deploying/trimming/prepare-libraries-for-trimming?pivots=dotnet-8-0#show-all-warnings-with-test-app). |
| 4 | + |
| 5 | +## How to enable the pipeline for your package |
| 6 | + |
| 7 | +### Collect any expected trimming warnings |
| 8 | + |
| 9 | +You can use any of the approaches described in the articles linked at the bottom of this document to find the warnings reported from your library. In an ideal scenario, this would be zero. However, there are cases where a library needs to baseline an expected set of warnings. Sometimes warnings are not straightforward \(or are even impossible\) to resolve, but are not expected to impact the majority of customer use cases. In other cases, warnings may be dependent on other work finishing first (for example, adding a net6.0 target, or upgrading a package dependency version). |
| 10 | + |
| 11 | +The text file should be formatted with each warning on its own line. The pipeline uses pattern matching to validate warnings. This means that warnings will need to be edited to avoid using special characters incorrectly. Even though it seems easier to just do simple string matching, the errors are formatted differently depending on the environment, so using correctly formatted pattern matching makes it easier. |
| 12 | + |
| 13 | +**Example**: |
| 14 | + |
| 15 | +Actual warning: |
| 16 | +> C:\Users\mredding\source\repos\azure-sdk-for-net\sdk\core\Azure.Core\src\JsonPatchDocument.cs(44): Trim analysis warning IL2026: Azure.JsonPatchDocument.JsonPatchDocument(ReadOnlyMemory`1<Byte>): Using member 'Azure.Core.Serialization.JsonObjectSerializer.JsonObjectSerializer()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. This class uses reflection-based JSON serialization and deserialization that is not compatible with trimming. [C:\Users\mredding\source\repos\ResolveAOT\ResolveAOT\ResolveAOT.csproj] |
| 17 | +
|
| 18 | +Line in the text file: |
| 19 | +> Azure\\.Core.src.JsonPatchDocument\\.cs\\(\\d*\\): Trim analysis warning IL2026: Azure\\.JsonPatchDocument\\.JsonPatchDocument\\(ReadOnlyMemory`1<Byte>\\): Using member 'Azure\\.Core\\.Serialization\\.JsonObjectSerializer\\.JsonObjectSerializer\\(\\)' which has 'RequiresUnreferencedCodeAttribute' |
| 20 | +
|
| 21 | +**Note**: In my case, my local environment uses forward slashes in filepaths, while the pipeline uses back slashes, so using a wildcard was the easiest way to reconcile this. |
| 22 | + |
| 23 | +### Update ci.yml file |
| 24 | + |
| 25 | +The ci.yml file needs to be updated to include the following information: |
| 26 | +```yml |
| 27 | +extends: |
| 28 | + template: /eng/pipelines/templates/stages/archetype-sdk-client.yml |
| 29 | + parameters: |
| 30 | + ServiceDirectory: [service directory] |
| 31 | + # [... other inputs] |
| 32 | + CheckAOTCompat: true |
| 33 | + AOTTestInputs: |
| 34 | + - ArtifactName: [Name of package] |
| 35 | + ExpectedAOTWarningsFilePath: None [or filepath of errors relative to the service directory] |
| 36 | +``` |
| 37 | +
|
| 38 | +**Example**: |
| 39 | +```yml |
| 40 | +extends: |
| 41 | + template: /eng/pipelines/templates/stages/archetype-sdk-client.yml |
| 42 | + parameters: |
| 43 | + ServiceDirectory: core |
| 44 | + # [... other inputs] |
| 45 | + CheckAOTCompat: true |
| 46 | + AOTTestInputs: |
| 47 | + - ArtifactName: Azure.Core |
| 48 | + ExpectedAOTWarningsFilepath: /Azure.Core/tests/aotcompatibility/ExpectedAotWarnings.txt |
| 49 | +``` |
| 50 | +**Example 2**: |
| 51 | +```yml |
| 52 | +extends: |
| 53 | + template: /eng/pipelines/templates/stages/archetype-sdk-client.yml |
| 54 | + parameters: |
| 55 | + ServiceDirectory: core |
| 56 | + # [... other inputs] |
| 57 | + CheckAOTCompat: true |
| 58 | + AOTTestInputs: |
| 59 | + - ArtifactName: Azure.Core |
| 60 | + ExpectedAOTWarningsFilepath: /Azure.Core/tests/aotcompatibility/ExpectedAotWarnings.txt |
| 61 | + - ArtifactName: Azure.Core.Experimental # For illustration only |
| 62 | + ExpectedAOTWarningsFilepath: None |
| 63 | +``` |
| 64 | +
|
| 65 | +## How to resolve trimming warnings |
| 66 | +
|
| 67 | +The following three articles provide comprehensive guidance for how to resolve trimming warnings and make libraries compatible with AOT: |
| 68 | +- ["How to make libraries compatible with native AOT"](https://devblogs.microsoft.com/dotnet/creating-aot-compatible-libraries/) by Eric Erhardt on November 30th, 2023 |
| 69 | +- ["Prepare .NET libraries for trimming"](https://learn.microsoft.com/dotnet/core/deploying/trimming/prepare-libraries-for-trimming) |
| 70 | +- ["Introduction to trim warnings"](https://learn.microsoft.com/dotnet/core/deploying/trimming/fixing-warnings) |
| 71 | +
|
| 72 | +Learning how to use source generation for serialization/deserialization: |
| 73 | +- [Introduction of C# source generation in .NET 6](https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/) |
| 74 | +- [How to use source generation](https://learn.microsoft.com/dotnet/standard/serialization/system-text-json/source-generation) |
0 commit comments