Skip to content

chore: Upgrade to .NET 11 with runtime async - #576

Merged
linkdotnet merged 1 commit into
masterfrom
chore/dotnet-11
Nov 10, 2026
Merged

linkdotnet merged 1 commit into
masterfrom
chore/dotnet-11

Conversation

@linkdotnet

Copy link
Copy Markdown
Owner

Summary

Upgrade to .NET 11 and turn on runtime async (<Features>runtime-async=on</Features>).

 global.json              sdk 10.0.100 -> 11.0.100
 Directory.Build.props
-  <TargetFramework>net10.0</TargetFramework>
+  <TargetFramework>net11.0</TargetFramework>
+  <Features>$(Features);runtime-async=on</Features>
+  <WarningsNotAsErrors>NU1608</WarningsNotAsErrors>   # Npgsql rc.3 pins EF Core rc.3
+  <NoWarn>BL0013;BL0016;S3881</NoWarn>                 # new .NET 11 analyzers
 Dockerfile / CI          10.0 -> 11.0
 Directory.Packages.props Microsoft.* 10.0.14 -> 11.0.0, rest to latest
   Npgsql.EntityFrameworkCore.PostgreSQL   10.0.3  -> 11.0.0-rc.3
   Microting.EntityFrameworkCore.MySql     10.0.14 -> 11.0.0-preview.1

Code changes the upgrade forced:

 BlogPost(Version)Configuration
-  builder.Property(x => x.Tags)           # EF 11: no longer becomes a primitive collection
+  builder.PrimitiveCollection(x => x.Tags)
 AuthExtensions / SitemapService           # CA1307
-  .StartsWith('/')
+  .StartsWith('/', StringComparison.Ordinal)
 6 x razor handlers                        # BL0012: @onclick / EventCallback re-render anyway
-  StateHasChanged();

Evidence

  • Before: after the bump, 16 integration tests (search and search-by-tag) failed:
    The LINQ expression 'DbSet<BlogPost>().Where(b => b.IsPublished && b.Tags.Contains(@Tag))' could not be translated
    After: dotnet test -c Release passed 700/700 (integration 228, unit 449, upgrade assistant 23)
  • Runtime async is active. Compiler-generated async state machines in LinkDotNet.Blog.Infrastructure.dll: 29 → 0

Merge Danger

Door: two-way

The stored data doesn't change: Tags was already stored as a JSON primitive collection, and no schema change is needed. Reverting the PR restores .NET 10.

Blast Radius: hosting

  • The host needs the .NET 11 runtime (the Docker image is handled).
  • The PostgreSQL and MySQL providers are prereleases, and the tests only run on SQLite, so those two providers are not tested.
  • Runtime async is a preview feature.

- Target net11.0, SDK 11.0.100, Docker images and CI on 11.0
- Enable runtime-async for all projects
- Bump Microsoft packages to 11.0.0 and other dependencies to latest
- Npgsql (11.0.0-rc.3) and MySQL (11.0.0-preview.1) providers are prereleases; NU1608 kept as warning until Npgsql 11 ships
- EF Core 11: map Tags via PrimitiveCollection instead of Property
- Drop explicit Microsoft.Extensions.Configuration.Abstractions (now pruned)
- Fix new CA1307 and BL0012 findings; suppress BL0013, BL0016 and S3881 on Razor-generated code
Copilot AI balanced review requested due to automatic review settings November 10, 2026 17:30
@linkdotnet
linkdotnet merged commit c68f9c5 into master Nov 10, 2026
4 checks passed
@linkdotnet
linkdotnet deleted the chore/dotnet-11 branch November 10, 2026 17:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Solution-wide preview async changes and prerelease PostgreSQL/MySQL providers with an overridden EF Core constraint require human-led compatibility validation beyond SQLite-only tests.

No open issues 🎉

What changed in this PR

Upgrades the blog application, build pipeline, and container images to .NET 11, enables runtime async, and adapts persistence mappings and UI code for the upgrade.

Changes:

  • Updates the SDK, target framework, dependencies, Docker images, and CI configuration.
  • Explicitly maps tag collections for EF Core 11 and adds ordinal URL comparisons.
  • Removes explicit render calls from selected Blazor handlers and adjusts analyzer warning handling.
File Description
tests/​LinkDotNet.Blog.IntegrationTests/​LinkDotNet.Blog.IntegrationTests.csproj Removes the direct configuration abstractions dependency.
src/​LinkDotNet.Blog.Web/​Features/​ShowBlogPost/​ShowBlogPostPage.razor Removes the explicit render call after bookmarking.
src/​LinkDotNet.Blog.Web/​Features/​Components/​ShortBlogPost.razor Removes the explicit render call after bookmarking.
src/​LinkDotNet.Blog.Web/​Features/​Admin/​Sitemap/​Services/​SitemapService.cs Uses an ordinal trailing-slash comparison.
src/​LinkDotNet.Blog.Web/​Features/​Admin/​BlogPostEditor/​UpdateBlogPostPage.razor Removes the explicit render call after restoring a version.
src/​LinkDotNet.Blog.Web/​Features/​Admin/​BlogPostEditor/​Components/​VersionDiffDialog.razor Removes the explicit render call when closing the dialog.
src/​LinkDotNet.Blog.Web/​Features/​Admin/​BlogPostEditor/​Components/​CreateNewBlogPost.razor Removes explicit render calls from shortcode and template handlers.
src/​LinkDotNet.Blog.Web/​Authentication/​OpenIdConnect/​AuthExtensions.cs Uses an ordinal logout-path comparison.
src/​LinkDotNet.Blog.Infrastructure/​Persistence/​Sql/​Mapping/​BlogPostVersionConfiguration.cs Explicitly maps version tags as a primitive collection.
src/​LinkDotNet.Blog.Infrastructure/​Persistence/​Sql/​Mapping/​BlogPostConfiguration.cs Explicitly maps post tags as a primitive collection.
global.json Selects the .NET 11 SDK.
Dockerfile Updates SDK and ASP.NET runtime images to .NET 11.
Directory.Packages.props Updates framework, provider, test, and tooling dependencies.
Directory.Build.props Targets .NET 11, enables runtime async, and adjusts warning handling.
.github/​workflows/​dotnet.yml Installs .NET 11 for build and test CI.
.github/​workflows/​codeql.yml Replaces .NET 10 with .NET 11 in the CodeQL SDK setup.

Review effort: Balanced

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