Paulo Morgado
Paulo Morgado
@paulomorgado.net
Technical Lead Vision-Box. ex-Microsoft. MVPAward alumnus. Opinions are my own.
202 followers327 following825 posts
dlvr.itLabcoat: the web UI I was missing for my .NET tests in Aspire — Erik LiebenI am a big fan of Aspire. It's the best way I know to give a project a proper onboarding experience, and it adds an extra layer of joy to building applications: everything that matters, in one view. On the frontend, that view includes my tests. Vitest UI gives me a web interface in which I bring my tests from red to green. On the backend I get dotnet test in a terminal, and while I feel at home there, watching my tests turn green is the one thing missing from my Aspire setup. So I built it: Labcoat, a web UI for tests on Microsoft.Testing.Platform that runs on its own or as a resource in your AppHost.
dlvr.itMicrosoft.Testing.Platform (MTP) in the Test Explorer: dotnet test, xUnit v3, MSTest and NUnit for C# and F#SharpLsp's VS Code Test Explorer now discovers, runs, debugs and covers Microsoft.Testing.Platform (MTP) tests: xUnit v3, MSTest and NUnit, in C# and F#, side by side with VSTest. How dotnet test on MTP works, how to opt in, and what we fixed along the way.
dlvr.itA Free .NET Profiler for VS Code: CPU, Memory and Leaks in C# and F#SharpLsp's profiler attaches to any running .NET process from VS Code, Cursor, Windsurf or VSCodium. Hot lines light up in your code, a flame graph opens beside it, and a live heap timeline ranks memory leak suspects. MIT-licensed, for C# and F#.
dlvr.itCore Framework v3 4.0.1 [2026 September 12] | xUnit.netToday, we're shipping two new releases:
xUnit.net Core Framework v3 4.0.1
xUnit.net Analyzers 2.1.0 (release notes)
It's been 4 weeks since the release of 4.0.0.
As always, we'd like to thank all the users who contributed to the success of xUnit.net through usage, feedback, and code. 🎉
Release Notes
These release notes are a list of changes from 4.0.0 to 4.0.1.
Core Framework
We have added the ability to disable all C# compiler warnings for generated code. Place this property into your .csproj file:
<PropertyGroup>
<DefineConstants>$(DefineConstants);XUNIT_GENERATED_DISABLE_WARNINGS</DefineConstants>
</PropertyGroup>
This disable warnings for the auto-generated entry point and all source generators for Native AOT. It should only be used if the generated code is conflicting with an analyzer, as compiler warnings can be helpful in diagnosing code generation issues.
BUG: Serialization of DateTime and DateTimeOffset were normalizing values to UTC, which lost the original timezone when deserialized. This could cause the test cases with identical moments in time in different timezones to be rejected as duplicate, even though the original data wasn't identical.
Runners
We have added a new Markdown results report (-result-markdown in xUnit.net command line UX, --report-xunit-markdown in Microsoft Testing Platform UX, and Markdown='filename' in the MSBuild runner). This is a simplified report which shows summary information as well as details for any non-passing tests. See the linked issue for an example multi-assembly report.
We have updated the CTRF report to add /results/summary/duration to show overall clock time of the test run, as well as adding /results/environment/extra/machine and /results/environment/extra/user to better align with the Microsoft Testing Platform CTRF results.
Extensibility
We have marked TestFrameworkExecutor.CreateDiscoverer as obsolete, because it was never being called. It will be removed in the next major release.
Microsoft Testing Platform
The Microsoft Testing Platform v2 packages have been updated to version 2.4.0.
dlvr.itBringing rich terminal experiences to AspireAspire 13.5 introduced WithTerminal() for interactive terminal sessions on app resources. Aspire 13.6 builds on it with richer terminal emulation and docked terminals for REPLs. See how to enable, attach to, and automate terminal experiences in your app.
dlvr.itVisual Studio September Update - Power Your Workflow with Your Model - Visual Studio BlogBring your own AI model with updates to BYOM, fix NuGet vulnerabilities from the Error List, explore pull requests with the Git agent, see which operand decides an if condition, and attach to Podman containers.
dlvr.itDual-exporting .NET metrics with OTLP and PrometheusMany applications export their metrics directly to Prometheus. If you’re unfamiliar with Prometheus, in a nutshell it’s a time-series database for storing metrics, like counters and histograms. Applications that store their metrics in Prometheus typically use a popular Prometheus client as part of the integration.
Now that OpenTelemetry is a graduated CNCF project, many companies are now increasingly looking to move to OpenTelemetry to add more signals beyond metrics to their observability architecture. Logs and traces are popular additions for getting further insight into how applications behave. Profiles are also starting to become a popular fourth telemetry signal for even deeper understanding.
dlvr.itCake - Cake v6.3.0 releasedVersion 6.3.0 of Cake has been released. Take it for a spin and give us feedback on our discussion board.
This release includes new features, improvements and bug fixes to Cake Scripting, Cake Frosting and Cake Sdk since the Cake v6.2.0 release! 🚀 🍰
Highlights of this release
GitHub Actions OIDC trusted publishing — The new NuGetLogin command exchanges a GitHub Actions OIDC token for a short-lived NuGet.org API key, so publishing no longer needs a long-lived secret.
Improved nullability support — Aliases generated from nullable-enabled addins keep their annotations, so #nullable addins no longer cause CS8632 warnings in Cake scripts or generated Cake.Sdk code.
Improved report rendering — The task summary table no longer assumes a dark terminal background, so it stays readable in light themes.
Typed dotnet tool aliases — DotNetToolInstall, DotNetToolRestore, DotNetToolRun, DotNetToolList, DotNetToolSearch, DotNetToolUpdate, DotNetToolUninstall, and DotNetToolExecute.
Verbosity via configuration — Set verbosity in cake.config or CAKE_SETTINGS_VERBOSITY; the --verbosity argument still takes precedence. Also supported by the Cake.Sdk generator.
Global exception handling in Cake.Sdk — Generated scripts catch unhandled exceptions, condense the output, and exit with a non-zero code without any manual setup.
Build provider improvements — GitHub Actions exposes the remaining default environment variables (workflow TriggeringActor, WorkflowRef, RepositoryId, and runner Environment / IsDebug, among others), and Azure Pipelines gained the ##[command] formatting command.
Tool & nested build fixes — InnoSetup locates Inno Setup 7, and CakeExecuteScript / CakeExecuteExpression now honour HandleExitCode, NoWorkingDirectory, PostAction, and SetupProcessSettings when running on Cake.Tool.
Dependency and SDK updates
GitHub Actions NuGetLogin for OIDC trusted publishing
NuGet.org trusted publishing lets you exchange a GitHub Actions OIDC identity token for a short-lived API key, which means you no longer need to store a long-lived NUGET_API_KEY secret in your repository. Cake 6.3.0 adds NuGetLogin (#4945) so you can do that exchange from within your Cake script, without adding a separate login action step to your workflow and passing the key back into the build:
Task("Publish")
.Does(async () =>
{
var apiKey = await GitHubActions.Commands.NuGetLogin(EnvironmentVariable("NUGET_USERNAME"));
var settings = new DotNetNuGetPushSettings
{
ApiKey = apiKey,
Source = "https://api.nuget.org/v3/index.json"
};
foreach (var package in GetFiles("./artifacts/*.nupkg"))
{
DotNetNuGetPush(package, settings);
}
});
The OIDC token and the returned API key are automatically registered as secrets, so they're masked in the build log. Your workflow needs the id-token: write permission for the token request to succeed:
jobs:
publish:
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/checkout@v5
- name: Run Cake
uses: cake-build/cake-action@v3
with:
target: Publish
env:
NUGET_USERNAME: your-nuget-account
If you publish to a different feed, the GitHubNuGetLoginSettings overload lets you override the token service URL and OIDC audience:
var apiKey = await GitHubActions.Commands.NuGetLogin(
new GitHubNuGetLoginSettings(
UserName: "your-nuget-account",
TokenServiceUrl: "https://www.nuget.org/api/v2/token",
Audience: "https://www.nuget.org"));
Improved nullability support
Addins compiled with nullable reference types enabled used to produce CS8632 warnings ("the annotation for nullable reference types should only be used in code within a #nullable annotations context") because Cake generates the alias declarations above your script, in a compilation where annotations are disabled. Adding #nullable disable to your own script didn't help.
Cake 6.3.0 makes alias generation nullability-aware (#4977) rather than suppressing the warning:
Only aliases that actually carry a nullable annotation are wrapped in #nullable enable / #nullable restore, so the rest of your script keeps the context it has today.
Annotations round-trip through generics and arrays, so IList<string?>, string?[]?, and Task<string?> are all generated correctly.
Generic parameter constraints keep their nullability, with class? and notnull emitted where applicable, while unconstrained type parameters stay unannotated.
The Cake.Sdk generator received the matching fix (#165), so nullable return types are retained in generated code and flow into your IDE's nullable analysis.
Improved report and exception rendering
The task summary table styled both foreground and background colors, which assumed a dark terminal and made the report hard to read — in some cases unreadable — in light themes and terminals with a custom background (#4870). The report now only sets foreground colors and lets your terminal's own background show through, so it looks right regardless of theme.
Cake.Sdk scripts also got better exception reporting (#179). Generated code now registers handlers for unhandled and unobserved task exceptions during bootstrap, formats them with Spectre.Console instead of dumping a raw stack trace, and exits with a non-zero code on critical failures. Failures that previously crashed silently — or scrolled past as unreadable output — are now condensed into a readable report, and it works without any setup in your script.
Contributors
This release was made possible thanks to the Cake team and the contribution of these awesome members of the Cake community listed below:
devlead
patriksvensson
paulomorgado
peymanr34
perclausen
gep13
Full details of everything that was included in this release can be seen below.
Issues
Cake
As part of this release we had Cake 60 issues closed.
Feature
#4991 Add support for verbosity via configuration.
#4945 Add GitHub Actions NuGetLogin for OIDC trusted publishing.
#4890 Add typed Cake aliases for dotnet tool subcommands.
Improvement
#4979 Update Microsoft.IdentityModel.JsonWebTokens to 8.22.0.
#4976 Update Microsoft.Extensions.DependencyInjection to 9.0.20 (net9.0) & 10.0.12 (net10.0).
#4968 Update Microsoft.CodeAnalysis.CSharp.Scripting ro 5.9.0.
#4966 Update Basic.Reference.Assemblies.* to 1.8.11.
#4964 Update Autofac to 9.3.2.
#4958 Update NuGet.* to 7.9.0.
#4956 Update .NET SDK to 10.0.401.
#4931 Update Spectre.Console to 0.57.2.
#4929 Update System.Security.Cryptography.Pkcs to 9.0.18 (net9.0) & 10.0.10 (net10.0).
#4925 Update Microsoft.CodeAnalysis.CSharp.Scripting to 5.6.0.
#4923 Update Autofac to 9.3.1.
#4921 Update Microsoft.Extensions.DependencyInjection to 9.0.18 (net9.0) & 10.0.10 (net10.0).
#4919 Update Microsoft.IdentityModel.JsonWebTokens to 8.19.2.
#4917 Update .NET SDK to 10.0.302.
#4916 Add format command support to IAzurePipelinesCommands.
#4909 Update Spectre.Console to 0.57.1.
#4904 Update Basic.Reference.Assemblies.* to 1.8.9.
#4902 Update Autofac to 9.3.0.
#4900 Add support for Inno Setup 7.
#4897 Update Autofac to 9.2.0.
#4893 Update Spectre.Console to 0.57.0.
#4891 Add missing GitHub Actions default environment variables to GitHubActions provider.
#4888 Update System.Security.Cryptography.Pkcs to 9.0.17 (net9.0) & 10.0.9 (net10.0).
#4882 Update Microsoft.Extensions.DependencyInjection to 9.0.17 (net9.0) & 10.0.9 (net10.0).
#4876 Update Spectre.Console to 0.56.0.
#4867 Update Microsoft.IdentityModel.JsonWebTokens to 8.19.1.
Bug
#4985 CakeExecuteScript/CakeExecuteExpression silently ignore several CakeSettings when running via Cake.Tool.
#4977 CS8632 when Cake.Tool generates aliases from nullable-enabled addins.
#4870 Report table rendering breaks in terminals without a black background.
Generator
As part of this release we had Generator 28 issues closed.
Feature
#197 Add support for verbosity via configuration.
#179 Add built-in global exception handling to generated Cake scripts.
Improvement
#199 Update Cake.* to 6.3.0
#185 Update Microsoft.Extensions.DependencyInjection to 9.0.20 (net9.0) & 10.0.12 (net10.0).
#181 Update .NET SDK to 10.0.401.
#171 Update Microsoft.Extensions.DependencyInjection to 9.0.18 (net9.0) & 10.0.10 (net10.0).
#167 Update .NET SDK to 10.0.302.
#154 Update .NET SDK to 10.0.301.
#142 Update Microsoft.Extensions.DependencyInjection to 9.0.17 (net9.0) & 10.0.9 (net10.0).
Bug
#165 Generator doesn't pick nullable return types it seems.
dlvr.itProtecting File Access in the wwwroot Folder in ASP.NETASP.NET Core treats files in wwwroot as public static content, but occasionally applications create files there that should only be available to authorized users. In this post I look at several ways to protect those files and show a small middleware solution that lets selectively access files easily.