Skip to content

Add AOT compatibility for net8.0 TFM#197

Open
BenjaminMichaelis wants to merge 4 commits intomainfrom
agents/aot-compliance-research-multitool
Open

Add AOT compatibility for net8.0 TFM#197
BenjaminMichaelis wants to merge 4 commits intomainfrom
agents/aot-compliance-research-multitool

Conversation

@BenjaminMichaelis
Copy link
Copy Markdown
Member

Summary

Makes IntelliTect.Multitool AOT-compatible so that consumers on .NET 8+ can publish with NativeAOT or trimming without warnings originating from this library. Older consumers on netstandard2.1 are unaffected.

Changes

Multi-target netstandard2.1;net8.0

NuGet automatically selects the best matching TFM — net8.0+ consumers get the AOT-annotated assembly; older consumers fall back to netstandard2.1.

IsAotCompatible for net7.0+ TFMs

<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">true</IsAotCompatible>

Enables the AOT, trim, and single-file analyzers for net8.0 (and any future TFMs added). Uses IsTargetFrameworkCompatible instead of a hardcoded equality check so it automatically applies to net10.0, etc.

Fix non-generic reflection in ReleaseDateAttribute.GetReleaseDate

// Before — non-generic, causes IL2070 trim warning
object[]? attribute = assembly?.GetCustomAttributes(typeof(ReleaseDateAttribute), false);

// After — generic, trimmer can statically resolve the type
return assembly?.GetCustomAttribute<ReleaseDateAttribute>()?.ReleaseDate;

Null guard in RepositoryPaths.GetDefaultRepoRoot

Added && projectPath is not null to guard against the dictionary returning a null value — required for correctness under net8.0's stricter nullable annotations with TreatWarningsAsErrors.

Verification

  • ✅ Build passes with zero warnings across netstandard2.1, net8.0, and net10.0 (test project)
  • TreatWarningsAsErrors=true — all AOT/trim analyzers ran clean
  • ✅ 30/32 tests pass; 2 pre-existing failures are unrelated worktree path tests

- Multi-target netstandard2.1;net8.0 so existing consumers still work
  and net8.0+ consumers get a properly annotated AOT-compatible assembly
- Add IsAotCompatible conditionally for net7.0+ TFMs using
  MSBuild.IsTargetFrameworkCompatible, which also enables the trim and
  AOT Roslyn analyzers for that build slice
- Replace non-generic GetCustomAttributes(typeof(T), false) in
  ReleaseDateAttribute.GetReleaseDate() with the generic
  GetCustomAttribute<ReleaseDateAttribute>() extension — the generic
  overload lets the AOT linker statically resolve the type and removes
  the IL2070/IL2077 trim warning
- Fix pre-existing nullable correctness bug in RepositoryPaths.cs:
  TryGetValue on ReadOnlyDictionary<string, string?> can legitimately
  yield a null value; guard the FileInfo constructor call with an
  explicit null check. This latent bug was invisible under the
  netstandard2.1 build because the BCL lacked full nullable annotations
  there; it became a hard error (CS8604/TreatWarningsAsErrors) once the
  net8.0 TFM was added.
- Fix IsAotCompatible condition floor from net7.0 to net8.0 per MS docs
- Add IntelliTect.Multitool.AotTest console app with PublishAot=true
- Add AOT publish+run CI job (ubuntu-latest, linux-x64)
- Add AotTest project to solution
- Add TreatWarningsAsErrors to AotTest.csproj (ensures AOT analyzer
  warnings are errors, not just warnings, completing C coverage)
- Override aot-test CI job to use bash shell instead of inherited pwsh
- Add aot-test to automerge needs so Dependabot can't bypass AOT CI
- Fix misleading comment: GetCustomAttribute<T> uses AOT-safe reflection
- Add comment explaining RepositoryPaths exclusion from AOT test
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR multi-targets IntelliTect.Multitool for netstandard2.1 and net8.0 and adds AOT/trimming compatibility improvements, along with a CI-published NativeAOT smoke test to ensure the library stays warning-free under AOT tooling.

Changes:

  • Multi-target netstandard2.1;net8.0 and enable IsAotCompatible conditionally for the modern TFM.
  • Replace non-generic reflection usage in ReleaseDateAttribute with GetCustomAttribute<T> to avoid trim/AOT warnings.
  • Add a new IntelliTect.Multitool.AotTest project and CI job to publish/run it with NativeAOT on Linux.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
IntelliTect.Multitool/RepositoryPaths.cs Adds a null guard when reading ProjectPath from build variables.
IntelliTect.Multitool/ReleaseDateAttribute.cs Switches to generic custom-attribute retrieval for trimming/AOT friendliness.
IntelliTect.Multitool/IntelliTect.Multitool.csproj Multi-targets netstandard2.1 + net8.0 and enables IsAotCompatible under a TFM-compat condition.
IntelliTect.Multitool.slnx Includes the new AOT test project in the solution.
IntelliTect.Multitool.AotTest/Program.cs Adds a small runtime verification harness for AOT publishing.
IntelliTect.Multitool.AotTest/IntelliTect.Multitool.AotTest.csproj New AOT publishable console project referencing the library.
.github/workflows/build-and-test.yml Adds an AOT publish/run job and gates automerge on it.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread IntelliTect.Multitool/RepositoryPaths.cs Outdated
Comment thread IntelliTect.Multitool/IntelliTect.Multitool.csproj
A trimmed-empty string passes 'is not null' but throws in new FileInfo().
IsNullOrWhiteSpace covers both cases.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants