Skip to content

fix: BuildProperty-Generator and AOT compilation detection #4333

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 22 commits into from
Jul 13, 2025

Conversation

Flash0ver
Copy link
Member

@Flash0ver Flash0ver commented Jul 9, 2025

Resolves #4331:

Proposing a bunch of changes to the Generated-code, considering the Generator so far never emitted any sources to the consuming compilation

  • missing <CompilerVisibleProperty Include="OutputType" /> in packed Sentry.targets, so the Generator never emitted any sources
    • replaced with Compilation.Options.OutputKind
    • this is more stable since it's evaluated Roslyn, rather than depending on an MSBuild Property
  • change new Dictionary<string, string> to new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
  • change from #if NET8_0_OR_GREATER to #if NET5_0_OR_GREATER
  • added #nullable enable
    • net5.0 has a default LangVersion of 9.0
    • generated code does not consider the project's default of <Nullable>enable</Nullable>
    • so every generated document needs to set #nullable enable individually
  • make generated type and member internal
    • a [ModuleInitializer] must be accessible from the containing module
    • so effectively public or internal in a non-file-local-type in a non-local-function
    • see Module Initializers
  • replace System.Runtime.CompilerServices.CompilerGeneratedAttribute with System.CodeDom.Compiler.GeneratedCodeAttribute
    • the CompilerGeneratedAttribute attribute is reserved for Compiler usage only
      • e.g. for members that the Compiler generates for record-types
    • GeneratedCodeAttribute is intended for Tools and Roslyn-Generator authors
  • renamed emitted Type-Name from BuildVariableInitializer to BuildPropertyInitializer
    • for consistency
  • renamed HintName from __BuildProperties.g.cs to Sentry.Generated.BuildPropertyInitializer.g.cs
    • for consistency with the ecosystem
  • fix inconsistent indentation
    • from mixed tabs and spaces
    • to spaces only

Additionally, proposing changes to the Generator itself and our MSBuild / Packaging

  • deleted redundant Sentry.SourceGenerators.targets
    • only Sentry.targets is automatically picked up from Sentry's NuGet-Package
    • and Sentry.SourceGenerators.targets was never Imported in any shipped Build-files
  • made BuildPropertySourceGenerator Not-Inheritable

Tests

  • slightly refactored existing tests
  • added new tests
  • added Verify-Scrubber that changes the Version of the generated GeneratedCodeAttribute to the string "Version" for test stability between releases

@Flash0ver Flash0ver self-assigned this Jul 9, 2025
@Flash0ver Flash0ver requested a review from jamescrosswell as a code owner July 9, 2025 15:11
@Flash0ver Flash0ver marked this pull request as draft July 9, 2025 20:30
@jamescrosswell
Copy link
Collaborator

jamescrosswell commented Jul 10, 2025

A couple of the integration tests are failing since they're erroneously detecting the the app has been compiled AOT when this is not the case.

I believe it's due to this:

if ($IsAOT)
{
$executable = getConsoleAppPath
If (!(Test-Path $executable))
{
publishConsoleApp
}
}
else
{
$executable = "dotnet run --project $path -c Release --framework $framework"
}

The test itself is valid. The PublishAot=true build setting only has any effect when publishing (not when building)... which I think means we probably need to change this logic:

if (TryGetBoolean("publishtrimmed", out var trimmed))
{
return trimmed;
}
if (TryGetBoolean("publishaot", out var aot))
{
return aot;
}

A couple of things would need to change in that logic then:

  1. We'd also need to detect whether a publish operation is being performed. In MS Build that can be done by inspecting the _IsPublishing build property...
  2. PublishTrimmed has the same caveat plus another one
    • Trimming only occurs during a publish operation (not a build operation)
    • Trimming only occurs if PublishSelfContained=true

@jamescrosswell jamescrosswell self-requested a review July 10, 2025 08:13
Copy link

@Copilot 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 refines the build‐property source generator to only emit code for executable outputs, renames and enhances the generated initializer, expands AOT detection, and updates related tests and MSBuild targets.

  • Generator now uses OutputKindExtensions.IsExe() and dynamic tool/version metadata to emit Sentry.Generated.BuildPropertyInitializer.g.cs.
  • AotHelper gains _IsPublishing & PublishSelfContained checks with diagnostic logging; called early in SentrySdk.InitHub.
  • MSBuild .targets add the _IsPublishing and PublishSelfContained properties; tests and verified baselines updated.

Reviewed Changes

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

Show a summary per file
File Description
test/VerifySettingsInitializer.cs Adds scrubber initializer to normalize version in snapshots.
test/BuildPropertySourceGeneratorTests.cs Refactors driver setup to use OutputKind, updates hint name, and adds new scenarios.
src/Sentry/buildTransitive/Sentry.targets Includes _IsPublishing and PublishSelfContained properties.
src/Sentry/buildTransitive/Sentry.SourceGenerators.targets Mirrors the new MSBuild properties for the source‐generator.
src/Sentry/SentrySdk.cs Invokes AotHelper.CheckIsTrimmed with logger.
src/Sentry/Internal/AotHelper.cs Enhances trimmed detection with _IsPublishing and PublishSelfContained, adds logging.
src/Sentry.SourceGenerators/OutputKindExtensions.cs New helper to test executable outputs.
src/Sentry.SourceGenerators/GeneratedCodeText.cs Introduces dynamic tool/version values for generation.
src/Sentry.SourceGenerators/BuildPropertySourceGenerator.cs Sealed class, raw string literal, indentation constant, renamed output, and metadata injection.
CHANGELOG.md Notes fix for build‐setting detection in AOT contexts.
Comments suppressed due to low confidence (2)

test/Sentry.SourceGenerators.Tests/BuildPropertySourceGeneratorTests.cs:52

  • There’s no test covering the new PublishSelfContained path in AotHelper.CheckIsTrimmed. Add a test scenario where _IsPublishing = true and PublishSelfContained = true to verify trimmed detection behaves as expected.
    [SkippableFact]

test/Sentry.SourceGenerators.Tests/VerifySettingsInitializer.cs:1

  • The scrubber method uses StringBuilder but there's no using System.Text; directive. Add it to ensure the code compiles.
using System.CodeDom.Compiler;

only "Sentry.targets" is picked up by a "PackageReference" and this file was never imported either
@Flash0ver
Copy link
Member Author

Flash0ver commented Jul 10, 2025

Additional Test of the CI-produced NuGet package, consumed via a Local NuGet Feed:

if (Sentry.CompilerServices.BuildProperties.Values is null)
{
    Console.WriteLine("not initialized");
    return;
}

foreach (KeyValuePair<string, string> value in Sentry.CompilerServices.BuildProperties.Values)
{
    Console.WriteLine($"Key: {value.Key}, Value: {value.Value}");
}

prints the available build variables, set via the [ModuleInitializer] of the generated code

image

@jamescrosswell jamescrosswell self-requested a review July 11, 2025 04:23
@jamescrosswell
Copy link
Collaborator

So we had a working PR back on commit 8fbade9... then the iOS device tests started failing.

Nothing in the new commits looks suspicious (essentially just tidying up around the edges). To test whether the new commits were potentially related, I forked this PR back on 8fbade9 and pushed it up in a new branch as #4335... and indeed, the iOS device tests are failing there as well.

Possibly the iOS device tests are flaky, and this is only apparent now that the source generators (and the AOT compilation detection) is now working?

@jamescrosswell
Copy link
Collaborator

The logs in the broken CI runs are showing:

Failed to install the application
Cleaning up the failed installation from 'iPhone Xs (iOS 18.5) - created by XHarness'
Uninstalling the application 'io.sentry.dotnet.maui.device.testapp' from 'iPhone Xs (iOS 18.5) - created by XHarness'
Failed to uninstall the app bundle! Check logs for more details!
XHarness exit code: 78 (PACKAGE_INSTALLATION_FAILURE)

About the only reference I can find to this error is here:

@jamescrosswell jamescrosswell changed the title fix: BuildProperty-Generator adds source when Executable fix: BuildProperty-Generator and AOT compilation detection Jul 11, 2025
@jamescrosswell jamescrosswell merged commit a02f8e5 into main Jul 13, 2025
30 checks passed
@jamescrosswell jamescrosswell deleted the fix/source-generator branch July 13, 2025 22:10
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.

Source Generators not working
2 participants