Skip to content

Commit 9a64f95

Browse files
authored
dotnet 10 build cleanup (#305)
## 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.0` → `net10.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.
2 parents d6fdd18 + 98742f2 commit 9a64f95

25 files changed

Lines changed: 168 additions & 146 deletions

.github/workflows/build.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
strategy:
3434
fail-fast: false
3535
matrix:
36-
os: [ macos-14, ubuntu-22.04, windows-latest ]
36+
os: [ macos-latest, ubuntu-latest, windows-latest ]
3737

3838
env:
3939
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
@@ -47,7 +47,7 @@ jobs:
4747
- name: Set up dotnet
4848
uses: actions/setup-dotnet@6bd8b7f7774af54e05809fcc5431931b3eb1ddee # 4.0.1
4949
with:
50-
dotnet-version: 8
50+
dotnet-version: 10
5151
dotnet-quality: ga
5252

5353
- name: Build

Dockerfile

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,19 @@
1616

1717
# MAINTAINER Jan Friedrich
1818

19-
FROM ubuntu:20.04
20-
ENV DEBIAN_FRONTEND=noninteractive \
21-
TZ=Etc/UTC
19+
# Ubuntu 24.04 (noble) with the .NET 10 SDK already installed - noble is the only Ubuntu
20+
# variant published for .NET 10. The reference is fully qualified, so it needs no registry
21+
# configuration and no login, unlike the short name it replaces.
22+
FROM mcr.microsoft.com/dotnet/sdk:10.0-noble
23+
ENV TZ=Etc/UTC
2224

23-
# Install Mono SDK (compiler, msbuild, runtime, etc.)
24-
RUN apt-get update && \
25-
apt-get install -y gnupg ca-certificates && \
26-
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF && \
27-
echo "deb https://download.mono-project.com/repo/ubuntu stable-focal main" | tee /etc/apt/sources.list.d/mono-official-stable.list && \
28-
apt-get update && \
29-
apt-get install -y mono-complete && \
30-
rm -rf /var/lib/apt/lists/*
25+
# Mono is not required: the net4x targets are compiled against the
26+
# Microsoft.NETFramework.ReferenceAssemblies packages that the .NET SDK references implicitly.
27+
# Mono would only be needed to *execute* net4x assemblies, which this image does not do.
3128

32-
# Check Mono version
33-
RUN mono --version
34-
35-
RUN apt-get update \
36-
&& apt-get upgrade -y \
37-
&& apt-get install -y wget \
38-
&& apt-get install -y tree \
39-
&& wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh \
40-
&& chmod +x ./dotnet-install.sh \
41-
&& ./dotnet-install.sh --channel 8.0
4229
ENV DOTNET_NOLOGO=true
4330
ENV DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true
44-
ENV DOTNET_ROOT=/root/.dotnet
45-
ENV PATH="$PATH:$DOTNET_ROOT:$DOTNET_ROOT/tools"
46-
31+
4732
ADD . /logging-log4net
4833
RUN dotnet restore /logging-log4net/src/log4net.sln
4934
RUN dotnet build -c Release /logging-log4net/src/log4net.sln

doc/BUILDING.md

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ Log4net provides support for the following targets
66

77
TL;DR (Windows):
88
- install Visual Studio Build Tools (at least VS2019)
9-
- install nodejs (at least v16)
10-
- install dotnet (v8+) and the .NET SDK (current latest)
9+
- install the .NET SDK (v10 or better - the sources use C# 14 language features)
1110
- in the project folder:
12-
- `npm i`
13-
- `npm run build`
11+
- `dotnet build src/log4net.sln`
12+
- `dotnet test src/log4net.sln`
1413

1514
TL;DR (Docker):
1615
- install docker (if you haven't already)
@@ -25,49 +24,43 @@ TL;DR (Docker):
2524
- `dotnet test /logging-log4net/src/log4net.sln`
2625

2726
TL;DR (!Windows):
28-
- install the dotnet SDK - v8 or better
29-
- install Mono (you're going to need it to target certain versions of .NET)
30-
- install nodejs 16+
31-
- in the project folder:
32-
- `npm i`
33-
- `export DOTNET_CORE=1 npm run build`
34-
- we force using `dotnet` on non-windows targets for now. At some point,
35-
this should become automatic
27+
- install the dotnet SDK - v10 or better (the sources use C# 14 language features)
28+
- in the project folder:
29+
- `dotnet build src/log4net.sln`
30+
- `dotnet test src/log4net.sln`
31+
- Mono is *not* required. The `net462` / `net472` targets are compiled against the
32+
`Microsoft.NETFramework.ReferenceAssemblies` packages that the .NET SDK references
33+
implicitly. Mono would only be needed to *execute* net4x assemblies.
34+
- the `log4net.Tests` project skips `net462` on non-Windows platforms: VSTest hosts net4x tests
35+
through `TestHostNetFramework/testhost.exe`, which needs a .NET Framework runtime - Mono, off
36+
Windows. The Ubuntu 24.04 and macOS 26 runner images no longer ship Mono, so the run would
37+
abort with `TESTRUNABORT`. The `net462` tests run only on the Windows job in CI.
3638

3739
## The full story
3840

3941
Options:
4042
- build locally. Suggested environment:
4143
- Pre-requisites:
42-
- Visual Studio 2019 Build Tools
43-
- include desktop targets at least
44-
- include dotnet core targets or download and install
45-
the latest dotnet sdk (you will need at least v8)
44+
- the .NET SDK, at least v10 (the sources use C# 14 language features)
45+
- on Windows: Visual Studio 2019 Build Tools or later, including desktop targets
46+
- only Windows can *run* the `net462` tests; elsewhere that target is skipped
4647
- Binaries can be built with a Visual Studio or Rider installation
4748
- Binaries, packages and a release zip can be built via commandline
48-
- Ensure that you have a reasonably modern NodeJS installed (at least version 8+)
49-
- `npm ci`
50-
- `npm run build`
51-
- optionally `npm test` to run all tests
52-
- optionally `npm run release` to generate release artifacts
53-
- build locally (CLI edition)
54-
- install nodejs (at least v16)
55-
- `npm i`
56-
- `npm run build`
57-
- build via docker for windows, using the `build-with-docker-for-windows.bat` script
58-
- build via the vs2019 Windows AppVeyor image. There is an appveyor.yml file
59-
included which (should) build if you set up AppVeyer to track
60-
your fork. AppVeyer is free for open-source projects.
61-
(TODO: should have a link to the official AppVeyor build)
49+
- `dotnet build src/log4net.sln`
50+
- optionally `dotnet test src/log4net.sln` to run all tests
51+
- release artifacts are generated by the scripts under `scripts/`:
52+
- `scripts/build-preview.ps1` for a preview package
53+
- `scripts/build-release.ps1` for a full release
54+
- build via docker, see the Docker section above
6255

6356
## Updating the site
6457

6558
Log4Net uses Maven to build the site. Source artifacts can be found under `src/site`.
66-
Building the site can be accomplished with `npm run build-site`. You should have maven
67-
installed:
68-
- Windows: get it from Scoop
69-
- OSX: get it from Homebrew
70-
- Linux: use your package manager
59+
Building the site can be accomplished with `./mvnw site` (`.\mvnw.cmd site` on Windows) - the
60+
committed Maven wrapper fetches the pinned Maven version, so only a JDK is required. This is
61+
also what `scripts/build-release.ps1` uses. The `antora` profile inherited from `logging-parent`
62+
activates automatically because `src/site/antora` exists; it installs Antora and runs it against
63+
`antora-playbook.yaml`, so no separate npm step is needed.
7164

7265
The site will be generated in `target/site`, and can be viewed locally. Updates should
7366
be pushed to the `asf-staging` branch of [https://github.com/apache/logging-log4net-site](https://github.com/apache/logging-log4net-site])

scripts/build-preview.ps1

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,19 @@ param(
22
$Version = '3.4.0',
33
$Preview = '1'
44
)
5+
6+
Set-StrictMode -Version Latest
7+
$ErrorActionPreference = 'Stop'
8+
# $ErrorActionPreference alone does not apply to native commands: dotnet, gpg and git only set
9+
# $LASTEXITCODE, so without this a failing build would still be signed and tagged.
10+
# Requires PowerShell 7.3+.
11+
$PSNativeCommandUseErrorActionPreference = $true
12+
513
'building ...'
614
dotnet build -c Release "-p:GeneratePackages=true;PackageVersion=$Version-preview.$Preview" $PSScriptRoot/../src/log4net.sln
715
'signing ...'
8-
gpg --armor --output $PSScriptRoot\..\build\artifacts\log4net.$Version-preview.$Preview.nupkg.asc --detach-sig $PSScriptRoot\..\build\artifacts\log4net.$Version-preview.$Preview.nupkg
9-
gpg --armor --output $PSScriptRoot\..\build\artifacts\log4net.Ext.Mail.$Version-preview.$Preview.nupkg.asc --detach-sig $PSScriptRoot\..\build\artifacts\log4net.Ext.Mail.$Version-preview.$Preview.nupkg
16+
gpg --armor --output $PSScriptRoot/../build/artifacts/log4net.$Version-preview.$Preview.nupkg.asc --detach-sig $PSScriptRoot/../build/artifacts/log4net.$Version-preview.$Preview.nupkg
17+
gpg --armor --output $PSScriptRoot/../build/artifacts/log4net.Ext.Mail.$Version-preview.$Preview.nupkg.asc --detach-sig $PSScriptRoot/../build/artifacts/log4net.Ext.Mail.$Version-preview.$Preview.nupkg
1018
'create tag?'
1119
pause
1220
'creating tag ...'

scripts/build-release.ps1

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ param(
44

55
Set-StrictMode -Version Latest
66
$ErrorActionPreference = 'Stop'
7+
# $ErrorActionPreference alone does not apply to native commands: dotnet, git, zip, gpg and mvnw
8+
# only set $LASTEXITCODE, so without this a failing build would still be packaged and signed.
9+
# Requires PowerShell 7.3+.
10+
$PSNativeCommandUseErrorActionPreference = $true
711

812
function Write-HashAndSignature
913
{

src/MonoForFramework.targets

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xmlns="https://logging.apache.org/xml/ns"
4+
xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
5+
type="changed">
6+
<issue id="305" link="https://github.com/apache/logging-log4net/pull/305"/>
7+
<description format="asciidoc">
8+
Mono is no longer required to build the `net462` and `net472` targets on Linux and macOS.
9+
`MonoForFramework.targets` and its `FrameworkPathOverride` handling were removed in favour of
10+
the `Microsoft.NETFramework.ReferenceAssemblies` packages that the .NET SDK already references
11+
implicitly. Mono is still needed to *run* .NET Framework assemblies: CI moved to
12+
`ubuntu-latest` (Ubuntu 24.04) and `macos-latest` (macOS 26), which no longer ship Mono, so
13+
the `net462` tests now run only on the Windows job and the Mono guards in the test suite were
14+
dropped. Support for *running* log4net under Mono is unaffected - the runtime check in
15+
`log4net.Util.SystemInfo` is unchanged
16+
</description>
17+
</entry>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xmlns="https://logging.apache.org/xml/ns"
4+
xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
5+
type="changed">
6+
<issue id="305" link="https://github.com/apache/logging-log4net/pull/305"/>
7+
<description format="asciidoc">
8+
build the container image from `mcr.microsoft.com/dotnet/sdk:10.0-noble` instead of installing
9+
a SDK into `ubuntu:20.04` with `dotnet-install.sh`. This moves off an Ubuntu release that left
10+
standard support in April 2025 and drops the download step, the Mono packages and the
11+
`DOTNET_ROOT` and `PATH` handling
12+
</description>
13+
</entry>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xmlns="https://logging.apache.org/xml/ns"
4+
xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
5+
type="fixed">
6+
<issue id="305" link="https://github.com/apache/logging-log4net/pull/305"/>
7+
<description format="asciidoc">
8+
fix the `log4net.Ext.Mail` package failing to pack with `NU5039` (`The readme file 'README.md'
9+
does not exist in the package`), because the `README.md` item was packed without a
10+
`PackagePath`
11+
</description>
12+
</entry>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xmlns="https://logging.apache.org/xml/ns"
4+
xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
5+
type="fixed">
6+
<issue id="305" link="https://github.com/apache/logging-log4net/pull/305"/>
7+
<description format="asciidoc">
8+
fix the release scripts continuing after a failed step: `$ErrorActionPreference` does not apply
9+
to native commands, so a failing `dotnet`, `git`, `zip`, `gpg` or `mvnw` went unnoticed and the
10+
artifacts were packaged, signed and tagged anyway. Both `scripts/build-preview.ps1` and
11+
`scripts/build-release.ps1` now set `$PSNativeCommandUseErrorActionPreference`. Also fix
12+
`scripts/build-preview.ps1` outside Windows, where the artifact paths handed to `gpg` were
13+
built with backslashes, which are not path separators on Linux or macOS
14+
</description>
15+
</entry>

0 commit comments

Comments
 (0)