Skip to content

SentryCreateRelease not using AssemblyInformationalVersion from Nerdbank.GitVersioning #3536

Closed

Description

@meenzen

Package

Sentry.AspNetCore

.NET Flavor

.NET

.NET Version

8.0.400

OS

Linux

SDK Version

4.10.0

Self-Hosted Sentry Version

24.7.1

Steps to Reproduce

  1. Have an existing project that uses Nerdbank.GitVersioning

  2. Enable the new features by adding these properties to the project config:

    <SentryCreateRelease>true</SentryCreateRelease>
    <SentrySetCommits>true</SentrySetCommits>
  3. Build the new release

Nerdbank.GitVersioning adds code at compile time:

#pragma warning disable CA2243

[assembly: System.Reflection.AssemblyVersionAttribute("2.2.0.0")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("2.2")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("2.2.0-alpha.1231+d4b08efa99")]
#if NETSTANDARD || NETFRAMEWORK || NETCOREAPP
[System.CodeDom.Compiler.GeneratedCode("Nerdbank.GitVersioning.Tasks","3.6.141.978")]
#endif
#if NET40_OR_GREATER || NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
internal static partial class ThisAssembly {
    internal const string AssemblyConfiguration = "Debug";
    internal const string AssemblyFileVersion = "2.2";
    internal const string AssemblyInformationalVersion = "2.2.0-alpha.1231+d4b08efa99";
    internal const string AssemblyName = "ExampleApp";
    internal const string AssemblyTitle = "ExampleApp";
    internal const string AssemblyVersion = "2.2.0.0";
    internal static readonly System.DateTime GitCommitDate = new System.DateTime(638593071050000000L, System.DateTimeKind.Utc);
    internal const string GitCommitId = "d4b08efa99564ae8a294e3f8888a1292f06adab7";
    internal const bool IsPrerelease = true;
    internal const bool IsPublicRelease = true;
    internal const string RootNamespace = "ExampleApp";
}

Expected Result

The version from the AssemblyInformationalVersionAttribute is being used to create the release

The following code suggests this should work: https://github.com/getsentry/sentry-dotnet/pull/3462/files#diff-14707e966a1fc6c249c6ab6fb17b0aac9349add0d80942b4710d96f7af1f0217R278

Actual Result

A release using the AssemblyVersion is created:

  Getting Sentry Release...
  Sentry Release: ExampleApp@2.2.0.0
  Creating Sentry Release: ExampleApp@2.2.0.0
  Created release ExampleApp@2.2.0.0
  Setting Sentry commits
  +------------------------------+--------------+
  | Repository                   | Revision     |
  +------------------------------+--------------+
  | ExampleApp                   | 428ce4f05351 |
  +------------------------------+--------------+

I have not tested this without Nerdbank.GitVersioning but something is obviously wrong here.

Activity

  1. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Aug 15, 2024
  2. jamescrosswell commented on Aug 15, 2024

    @jamescrosswell
    Collaborator

    Hi @meenzen , can you run your dotnet build with detailed logging so that we can see what gets logged by the code that you linked to?

    -v, --verbosity <LEVEL>              Set the MSBuild verbosity level. Allowed values are q[uiet], m[inimal], 
                                           n[ormal], d[etailed], and diag[nostic].

    In particular, it'd be good check if an exception is raised when trying to read the AssemblyInformationalVersionAttribute. I think the only thing that might cause that is an AmbiguousMatchException from the Attribute.GetCustomAttribute but worth ruling this out.

    Otherwise, my best guess is that maybe NerdBank is applying the version information to a different assembly to the one that the Sentry build task is reading? Again, using detailed logging above would help determine that.

  3. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Aug 15, 2024
  4. meenzen commented on Aug 16, 2024

    @meenzen
    Author

    Reading the attribute does indeed fail:

    Getting assembly name...
    Assembly name: ExampleApp
    Reading AssemblyInformationalVersionAttribute...
    Failed to read informational version attribute
    Version: 2.2.0.0
    Compiling release information...
    

    Grabbing the attributes during runtime yields exactly one result as expected:

    typeof(Program).Assembly.GetCustomAttributes<AssemblyInformationalVersionAttribute>();
  5. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Aug 16, 2024
  6. jamescrosswell commented on Aug 16, 2024

    @jamescrosswell
    Collaborator

    Hm, are you able to put together a minimal reproducible example that we can look at? I'm not familiar with nerdbank and it looks like there are various ways you can integrate this.

  7. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Aug 16, 2024
  8. added
    BugSomething isn't working
    QuestionFurther information is requested
    on Aug 29, 2024
  9. 11 remaining items

  10. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Sep 30, 2024
  11. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Oct 18, 2024
  12. removed theissue type on Aug 6, 2025
  13. added
    .NETPull requests that update .net code
    on Mar 24, 2026
  14. meenzen commented on Oct 6, 2026

    @meenzen
    Author

    I put Claude Opus 5.5 up to the task and it looks like it figured out the problem:

    It isn't related to Nerdbank.GitVersioning: SentryGetApplicationVersion fails to read AssemblyInformationalVersion from any assembly that has an assembly-level attribute whose type can't be loaded in the MSBuild process.

    Cause

    SentryGetApplicationVersion loads the built assembly with Assembly.LoadFile and calls assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>(). To filter the attributes by type, GetCustomAttribute<T>() has to resolve the type of every assembly-level attribute. If one of them lives in an assembly MSBuild can't load, it throws, the exception is swallowed (Failed to read informational version attribute), and the task falls back to AssemblyVersion.

    A very common example is UserSecretsIdAttribute (Microsoft.Extensions.Configuration.UserSecrets), which the SDK generates for every project with a <UserSecretsId> – i.e. most Microsoft.NET.Sdk.Worker and Microsoft.NET.Sdk.Web projects created from the templates. ASP.NET Core projects have further attributes of this kind, so even without UserSecretsId they fall back to AssemblyVersion.

    Minimal repro (Sentry 6.12.0, .NET SDK 10.0.401)

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net10.0</TargetFramework>
        <InformationalVersion>1.2.3+abcdef</InformationalVersion>
        <UserSecretsId>test-123</UserSecretsId> <!-- remove this line and it works -->
      </PropertyGroup>
      <ItemGroup>
        <PackageReference Include="Sentry" Version="6.12.0" />
        <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.0" />
      </ItemGroup>
    </Project>
    dotnet build -p:SentryCreateRelease=true -p:UseSentryCLI=true -v n
    
    • with UserSecretsId: Failed to read informational version attribute → Sentry Release: App@1.0.0.0
    • without UserSecretsId: Sentry Release: App@1.2.3+abcdef

    Possible fixes: read the attribute with assembly.GetCustomAttributesData() / CustomAttributeData (doesn't instantiate or resolve other attribute types), or System.Reflection.Metadata, or – simpler – use the MSBuild properties ($(InformationalVersion), or the AssemblyAttribute items) instead of loading the assembly.

    Related: release detection doesn't run by default

    While testing I noticed a second problem: with only <SentryCreateRelease>true</SentryCreateRelease> (no SENTRY_RELEASE, no explicit UseSentryCLI), no release is created at all, and _GetSentryRelease never runs:

    • _GetSentryRelease runs AfterTargets="DispatchToInnerBuilds;AfterBuild" with Condition="... And '$(UseSentryCLI)' == 'true'", but UseSentryCLI gets its default in CheckSentryCLI, which runs AfterTargets="Build", i.e. later. So the condition is false at that point.
    • _CreateSentryRelease (DependsOnTargets="_GetSentryRelease") has Condition="... and '$(_SentryRelease)' != ''". MSBuild evaluates a target's condition before running its dependencies, so it's skipped as well, and _GetSentryRelease is never invoked through it.

    With the repro above (without UserSecretsId) and a sentry-cli stub that logs its arguments:

    • dotnet build -p:SentryCreateRelease=true → no Getting Sentry Release..., no releases new call
    • dotnet build -p:SentryCreateRelease=true -p:UseSentryCLI=true → releases new App@1.2.3+abcdef

    Setting SENTRY_RELEASE works around both problems, which is probably why it often goes unnoticed. A public MSBuild property for the release (e.g. SentryRelease) that can be set from a target would also help: we currently set the internal _SentryRelease after Nerdbank.GitVersioning's GetBuildVersion:

    <Target Name="SetSentryRelease" AfterTargets="GetBuildVersion" Condition="'$(_SentryRelease)' == ''">
      <PropertyGroup>
        <_SentryRelease>$(AssemblyName)@$(AssemblyInformationalVersion)</_SentryRelease>
      </PropertyGroup>
    </Target>
  15. jamescrosswell commented on Oct 7, 2026

    @jamescrosswell
    Collaborator
  16. jamescrosswell commented on Oct 7, 2026

    @jamescrosswell
    Collaborator

    If SentryCreateRelease gives you a release with the wrong version (e.g. App@1.0.0.0 instead of your informational version), do one of these:

    • Set the release yourself (works today). Set the SENTRY_RELEASE environment variable when you build, and give the app the same value at runtime, either through SENTRY_RELEASE in its environment or through options.Release.
    • Upgrade once fix: SentryCreateRelease uses the assembly's informational version and no longer requires UseSentryCLI #5679 ships, and let .NET generate your version attributes. That's the default for SDK-style projects: just don't set GenerateAssemblyInfo or GenerateAssemblyInformationalVersionAttribute to false. The build will then use the same version the Sentry SDK reports at runtime.

    🤖 Written with Claude Code

  17. added a commit that references this issue on Oct 8, 2026
    b415ffd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

.NETPull requests that update .net codeBugSomething isn't workingQuestionFurther information is requested

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions