Skip to content

dotnet 10 build cleanup - #305

Merged
FreeAndNil merged 9 commits into
masterfrom
Feature/305-dotnet-10-build-cleanup
Aug 5, 2026
Merged

dotnet 10 build cleanup#305
FreeAndNil merged 9 commits into
masterfrom
Feature/305-dotnet-10-build-cleanup

Conversation

@FreeAndNil

Copy link
Copy Markdown
Contributor

Why

The sources already use C# 14 (the field keyword in SmtpAppender's property accessors), which
requires the .NET 10 SDK. Nothing in the repo declared that: the test projects targeted net8.0,
CI installed .NET 8 and the Dockerfile fetched the 8.0 channel, so a clean checkout could not
compile - it failed with CS0501: 'SmtpAppender.To.get' must declare a body.

This PR makes the required toolchain explicit and cleans up the surrounding build, which turned up
several unrelated defects along the way.

The shipped surface is unchanged. log4net still targets net462;netstandard2.0 and
log4net.Ext.Mail still targets netstandard2.0. Nothing here affects consumers.

Changes

Commit What
Target .NET 10 / C# 14 test and integration-test projects net8.0net10.0; CI dotnet-version: 10
Build net4x without Mono delete MonoForFramework.targets and its two imports
Container image from the .NET 10 SDK image ubuntu:20.04 + dotnet-install.sh
mcr.microsoft.com/dotnet/sdk:10.0-noble
Stop the release scripts on failed steps $PSNativeCommandUseErrorActionPreference in both scripts, plus a path
fix
Fix the log4net.Ext.Mail package readme NU5039
Quieten the TelnetAppender test graceful socket shutdown
Update BUILDING.md document what the build actually is

Mono is no longer needed to build net4x

MonoForFramework.targets set FrameworkPathOverride to Mono's 4.6.2-api directory on Unix. That
is obsolete: the .NET SDK already adds an implicit PackageReference to
Microsoft.NETFramework.ReferenceAssemblies.<tfm> for net4x targets, and those packages were
already in the restore graph.

net462 tests are now Windows-only

VSTest hosts net4x tests through TestHostNetFramework/testhost.exe, a .NET Framework executable,
so dotnet test aborts with TESTRUNABORT on Linux and macOS. log4net.Tests now conditions its
TargetFrameworks on '$(OS)' != 'Windows_NT', so no unrunnable test assembly is produced. The
net462 library is still built on every platform; only the test target is gated.

This also fixes the ubuntu-22.04 and macos-14 CI jobs, which ran a bare dotnet test against a
net462 target they could not host.

Run CI on the latest runner images

macos-14 and ubuntu-22.04 are superseded by macos-latest (macOS 26) and ubuntu-latest (Ubuntu 24.04).
Neither new image ships Mono, so net4x tests cannot run there - which is why log4net.Tests restricts net462 to Windows.

Release scripts continued after failed steps

$ErrorActionPreference = 'Stop' does not apply to native commands — they only set
$LASTEXITCODE. A failing dotnet, git, zip, gpg or mvnw was therefore ignored, and
artifacts were packaged, signed and tagged anyway. Both scripts now set
$PSNativeCommandUseErrorActionPreference (PowerShell 7.3+).

This was not theoretical: NU5039 made the log4net.Ext.Mail pack fail, no .nupkg was produced,
and build-preview.ps1 went on to gpg-sign files that did not exist. build-preview.ps1 also built
its artifact paths with backslashes, which are not path separators outside Windows.

TelnetAppender test noise

SimpleTelnetClient.Dispose() disposed the TcpClient while the reader was blocked in
stream.Read, so teardown aborted the socket and dumped an IOException with a stack trace on
every passing run. The cancellation token never actually broke the loop — it was only checked after
a successful read. Now the socket is shut down first, the read returns 0, and the loop exits
normally. Exceptions arriving after disposal starts are not reported; genuine failures still are.

Verification

On Linux (Ubuntu-based, .NET SDK 10.0.110, self-built Mono present but unused by the build):

  • dotnet build ./src/log4net.sln - succeeds, 0 warnings
  • dotnet test ./src/log4net.sln - 292 total, 0 failed, 281 succeeded, 11 skipped (Windows-only)
  • net462 and net472 compile with MonoForFramework.targets deleted
  • log4net.Tests.Signing.AssemblyShouldBeSigned passes - strong naming survives the
    reference-assembly switch
  • ./mvnw site works
  • both scripts parse under pwsh 7.6.4; the native-error behaviour was verified directly

For reviewers to weigh

Nothing tests on the .NET 8 runtime any more. netstandard2.0 consumers on .NET 8 (LTS until
November 2026) are still supported but no longer exercised.

The MCR image reference is fully qualified, so it needs no registry configuration and no login.

@FreeAndNil FreeAndNil added this to the 3.4.0 milestone Aug 4, 2026
FreeAndNil added a commit that referenced this pull request Aug 4, 2026
  macos-14 and ubuntu-22.04 are superseded by macos-latest (macOS 26) and
  ubuntu-latest (Ubuntu 24.04). Neither new image ships Mono, so net4x
  tests cannot run there - which is why log4net.Tests restricts net462 to
  Windows. Correct the reason given in BUILDING.md and the changelog.
FreeAndNil added a commit that referenced this pull request Aug 4, 2026
 - Utils.IsMono and Utils.InconclusiveOnMono are gone, along with all 15 call sites. The net462 tests run only on Windows now and the net10.0 tests run on .NET 10, so the guard could never fire.
- SystemInfo.IsMono in the library is deliberately untouched: it detects the runtime executing log4net, which can still be Mono.
@FreeAndNil
FreeAndNil force-pushed the Feature/305-dotnet-10-build-cleanup branch from 87bb3d2 to 68b9a4d Compare August 4, 2026 22:20
FreeAndNil added a commit that referenced this pull request Aug 4, 2026
Utils.IsMono and Utils.InconclusiveOnMono are gone, along with all 15 call sites.
The net462 tests run only on Windows now and the net10.0 tests run on .NET 10, so the guard could never fire.

SystemInfo.IsMono in the library is deliberately untouched: it detects the runtime executing log4net, which can still be Mono.
@FreeAndNil
FreeAndNil force-pushed the Feature/305-dotnet-10-build-cleanup branch from 68b9a4d to 6dee635 Compare August 4, 2026 22:26
  The sources use C# 14, so a .NET 10 SDK is now required. Test and
  integration-test projects move from net8.0 to net10.0; the shipped
  log4net assembly keeps net462;netstandard2.0.
  Remove MonoForFramework.targets and its FrameworkPathOverride handling.
  The net462/net472 targets compile against the   Microsoft.NETFramework.ReferenceAssemblies packages that the .NET SDK
  already references implicitly, so Mono is only needed to run .NET
  Framework assemblies - not to build them (and mono is now deprecated by Microsoft).
  Replace ubuntu:20.04 + dotnet-install.sh with
  mcr.microsoft.com/dotnet/sdk:10.0-noble - Ubuntu 24.04 with the SDK
  preinstalled. Drops the Mono packages, the apt-key/stable-focal repo,
  wget, tree and the DOTNET_ROOT/PATH handling, leaving no apt layer at
  all. Ubuntu 20.04 left standard support in April 2025.
  $ErrorActionPreference does not apply to native commands, so a failing
  dotnet, git, zip, gpg or mvnw was ignored and the artifacts were
  packaged, signed and tagged anyway. Both scripts now set
  $PSNativeCommandUseErrorActionPreference (PowerShell 7.3+).

  Also fix build-preview.ps1 outside Windows, where the artifact paths
  handed to gpg used backslashes.
  PackageReadmeFile requires the readme at the package root, so packing
  README.md without a PackagePath failed with NU5039. Matches the pattern
  already used in log4net.csproj.
  Dispose disposed the TcpClient while the reader was blocked in
  stream.Read, so teardown always aborted the socket and dumped an
  IOException with a stack trace, even on a passing run. Shut the socket
  down first, so the read returns 0 and the loop ends normally, and only
  report exceptions that arrive before disposal. Progress chatter removed;
  the test now prints nothing unless it fails.

  Two things this fixes beyond the noise:

  - The cancellation token never actually stopped the loop. The check ran only after a successful read, so the reader
  could only be broken by disposing the socket under it. Now Shutdown(SocketShutdown.Both) ends the stream and the loop
  exits through its normal condition.
  - Diagnostics are preserved for real failures. log is still wired to TestContext.Out.WriteLine, gated on !_disposing - so a genuine client error still surfaces, and Assert.Fail on timeout still reports what was received.
  macos-14 and ubuntu-22.04 are superseded by macos-latest (macOS 26) and
  ubuntu-latest (Ubuntu 24.04). Neither new image ships Mono, so net4x
  tests cannot run there - which is why log4net.Tests restricts net462 to
  Windows. Correct the reason given in BUILDING.md and the changelog.
Utils.IsMono and Utils.InconclusiveOnMono are gone, along with all 15 call sites.
The net462 tests run only on Windows now and the net10.0 tests run on .NET 10, so the guard could never fire.

SystemInfo.IsMono in the library is deliberately untouched: it detects the runtime executing log4net, which can still be Mono.
@FreeAndNil
FreeAndNil force-pushed the Feature/305-dotnet-10-build-cleanup branch from 6dee635 to 98742f2 Compare August 4, 2026 22:30
Comment thread src/log4net.Tests/log4net.Tests.csproj
@FreeAndNil
FreeAndNil merged commit 9a64f95 into master Aug 5, 2026
3 checks passed
@FreeAndNil
FreeAndNil deleted the Feature/305-dotnet-10-build-cleanup branch August 5, 2026 06:51
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