From a55cb8c35f377f9e68ab08aa7dc337384d482463 Mon Sep 17 00:00:00 2001 From: Jakob Date: Fri, 5 Jun 2026 15:30:40 +0200 Subject: [PATCH 1/2] Publish stable versions from main and drop GeneratePackageOnBuild Pass -p:PublicRelease=true in the Release workflow build and pack steps so merges to main publish stable versions (e.g. 7.0.3) instead of the -g prerelease suffix Nerdbank.GitVersioning emits when it does not treat the build as a public release. The previous publish produced 7.0.2-g7efc542658, which NuGet classified as prerelease. Also remove the redundant GeneratePackageOnBuild from the five packable projects: packaging is performed explicitly by the Release workflow pack step, and GeneratePackageOnBuild additionally emitted stray Debug-config packages during ordinary builds. --- .github/workflows/Release.yml | 4 ++-- .../CommandStation.Abstractions.csproj | 1 - .../CommandStation.Transport.Udp.csproj | 1 - src/Z21.Autofac/Z21.Autofac.csproj | 1 - src/Z21.Client/Z21.Client.csproj | 1 - src/Z21.DependencyInjection/Z21.DependencyInjection.csproj | 1 - 6 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 3edd8d9..d57866b 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -38,13 +38,13 @@ jobs: run: dotnet restore src/Z21.sln - name: Build (Release) - run: dotnet build src/Z21.sln --no-restore --configuration Release + run: dotnet build src/Z21.sln --no-restore --configuration Release -p:PublicRelease=true - name: Test run: dotnet test src/Z21.sln --no-build --configuration Release --verbosity normal - name: Pack - run: dotnet pack src/Z21.sln --no-build --configuration Release --output ./nupkgs + run: dotnet pack src/Z21.sln --no-build --configuration Release -p:PublicRelease=true --output ./nupkgs - name: Upload packages artifact uses: actions/upload-artifact@v4 diff --git a/src/CommandStation.Abstractions/CommandStation.Abstractions.csproj b/src/CommandStation.Abstractions/CommandStation.Abstractions.csproj index 28101b2..1be9873 100644 --- a/src/CommandStation.Abstractions/CommandStation.Abstractions.csproj +++ b/src/CommandStation.Abstractions/CommandStation.Abstractions.csproj @@ -5,7 +5,6 @@ enable 12 disable - true true $(NoWarn);CS1591;CS1573 CommandStation.Abstractions diff --git a/src/CommandStation.Transport.Udp/CommandStation.Transport.Udp.csproj b/src/CommandStation.Transport.Udp/CommandStation.Transport.Udp.csproj index 876e598..4256368 100644 --- a/src/CommandStation.Transport.Udp/CommandStation.Transport.Udp.csproj +++ b/src/CommandStation.Transport.Udp/CommandStation.Transport.Udp.csproj @@ -6,7 +6,6 @@ 12 disable CommandStation.Transport.Udp - true true $(NoWarn);CS1591;CS1573 CommandStation.Transport.Udp diff --git a/src/Z21.Autofac/Z21.Autofac.csproj b/src/Z21.Autofac/Z21.Autofac.csproj index e8ab2d0..f3687e0 100644 --- a/src/Z21.Autofac/Z21.Autofac.csproj +++ b/src/Z21.Autofac/Z21.Autofac.csproj @@ -2,7 +2,6 @@ net8.0;net8.0-windows - true true $(NoWarn);CS1591;CS1573 enable diff --git a/src/Z21.Client/Z21.Client.csproj b/src/Z21.Client/Z21.Client.csproj index 47b9df8..ae282fc 100644 --- a/src/Z21.Client/Z21.Client.csproj +++ b/src/Z21.Client/Z21.Client.csproj @@ -3,7 +3,6 @@ enable 12 - True true $(NoWarn);CS1591;CS1573 Z21 diff --git a/src/Z21.DependencyInjection/Z21.DependencyInjection.csproj b/src/Z21.DependencyInjection/Z21.DependencyInjection.csproj index bcfc4a2..812af9b 100644 --- a/src/Z21.DependencyInjection/Z21.DependencyInjection.csproj +++ b/src/Z21.DependencyInjection/Z21.DependencyInjection.csproj @@ -4,7 +4,6 @@ net8.0;net8.0-windows enable enable - true true $(NoWarn);CS1591;CS1573 Jakob Eichberger From 0ff6307b08560bc3bdaeb5d49ff3356c42d2e8ae Mon Sep 17 00:00:00 2001 From: Jakob Date: Fri, 5 Jun 2026 15:33:31 +0200 Subject: [PATCH 2/2] Add a README to each NuGet package Each packable project now ships a short package README (PackageReadmeFile + packed README.md), so the packages render documentation on NuGet.org and the "package is missing a readme" pack warning is resolved. --- .../CommandStation.Abstractions.csproj | 5 +++++ src/CommandStation.Abstractions/README.md | 16 ++++++++++++++ .../CommandStation.Transport.Udp.csproj | 5 +++++ src/CommandStation.Transport.Udp/README.md | 11 ++++++++++ src/Z21.Autofac/README.md | 19 ++++++++++++++++ src/Z21.Autofac/Z21.Autofac.csproj | 2 ++ src/Z21.Client/README.md | 22 +++++++++++++++++++ src/Z21.Client/Z21.Client.csproj | 2 ++ src/Z21.DependencyInjection/README.md | 20 +++++++++++++++++ .../Z21.DependencyInjection.csproj | 2 ++ 10 files changed, 104 insertions(+) create mode 100644 src/CommandStation.Abstractions/README.md create mode 100644 src/CommandStation.Transport.Udp/README.md create mode 100644 src/Z21.Autofac/README.md create mode 100644 src/Z21.Client/README.md create mode 100644 src/Z21.DependencyInjection/README.md diff --git a/src/CommandStation.Abstractions/CommandStation.Abstractions.csproj b/src/CommandStation.Abstractions/CommandStation.Abstractions.csproj index 1be9873..c184cfc 100644 --- a/src/CommandStation.Abstractions/CommandStation.Abstractions.csproj +++ b/src/CommandStation.Abstractions/CommandStation.Abstractions.csproj @@ -14,6 +14,11 @@ ModelRailway;CommandStation;DCC;Abstractions https://github.com/jaak0b/Z21 GPL-3.0-only + README.md + + + + diff --git a/src/CommandStation.Abstractions/README.md b/src/CommandStation.Abstractions/README.md new file mode 100644 index 0000000..7000cf0 --- /dev/null +++ b/src/CommandStation.Abstractions/README.md @@ -0,0 +1,16 @@ +# CommandStation.Abstractions + +The protocol- and transport-neutral contracts shared by the model-railway command-station +libraries. It has no dependency on any particular command station or wire format, so you +can code against the interfaces and swap implementations underneath. + +It defines the domain API (`ICommandStation` plus capability interfaces like `ILocoControl`, +`IAccessoryControl`, `ITrackPowerControl` and `ISystemInfoProvider`), the transport and +framing abstractions (`ITransport`, `IFrameReader`), and the shared domain model +(`LocoInfoData`, `SystemState`, `DccSpeedMode`, and friends). + +You normally don't install this directly — it comes in as a dependency of an +implementation such as [Z21](https://www.nuget.org/packages/Z21). Reach for it when you +want to write code (or your own command station) against the neutral abstractions. + +See the [project page](https://github.com/jaak0b/Z21). Licensed under GPL-3.0. diff --git a/src/CommandStation.Transport.Udp/CommandStation.Transport.Udp.csproj b/src/CommandStation.Transport.Udp/CommandStation.Transport.Udp.csproj index 4256368..a11548a 100644 --- a/src/CommandStation.Transport.Udp/CommandStation.Transport.Udp.csproj +++ b/src/CommandStation.Transport.Udp/CommandStation.Transport.Udp.csproj @@ -15,8 +15,13 @@ ModelRailway;CommandStation;UDP;Transport https://github.com/jaak0b/Z21 GPL-3.0-only + README.md + + + + diff --git a/src/CommandStation.Transport.Udp/README.md b/src/CommandStation.Transport.Udp/README.md new file mode 100644 index 0000000..1182fb3 --- /dev/null +++ b/src/CommandStation.Transport.Udp/README.md @@ -0,0 +1,11 @@ +# CommandStation.Transport.Udp + +A UDP implementation of `ITransport` from +[CommandStation.Abstractions](https://www.nuget.org/packages/CommandStation.Abstractions). +It's the raw byte pipe the command-station libraries send and receive frames over. + +Most people never use this directly — the [Z21](https://www.nuget.org/packages/Z21) DI +packages wire it up for you. Pull it in on its own only if you're composing the transport +by hand or building another command station on top of the shared abstractions. + +See the [project page](https://github.com/jaak0b/Z21). Licensed under GPL-3.0. diff --git a/src/Z21.Autofac/README.md b/src/Z21.Autofac/README.md new file mode 100644 index 0000000..dffb1bb --- /dev/null +++ b/src/Z21.Autofac/README.md @@ -0,0 +1,19 @@ +# Z21.Autofac + +Autofac wiring for the [Z21](https://www.nuget.org/packages/Z21) client. If you use +Autofac instead of Microsoft.Extensions.DependencyInjection, this package gives you the +same one-line setup: register the command station, the UDP transport and all protocol +handlers, then resolve `IZ21CommandStation`. + +```csharp +var builder = new ContainerBuilder(); +builder.AddZ21(t => t.RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.0.111"), 21105)); + +var container = builder.Build(); +var station = container.Resolve(); + +await station.ConnectAsync(); +await station.TrackPowerOnAsync(); +``` + +See the [project page](https://github.com/jaak0b/Z21) for the full API. Licensed under GPL-3.0. diff --git a/src/Z21.Autofac/Z21.Autofac.csproj b/src/Z21.Autofac/Z21.Autofac.csproj index f3687e0..2c8f5ab 100644 --- a/src/Z21.Autofac/Z21.Autofac.csproj +++ b/src/Z21.Autofac/Z21.Autofac.csproj @@ -9,6 +9,7 @@ Jakob Eichberger https://github.com/jaak0b/Z21 LICENSE + README.md true @@ -23,6 +24,7 @@ + diff --git a/src/Z21.Client/README.md b/src/Z21.Client/README.md new file mode 100644 index 0000000..69a89fe --- /dev/null +++ b/src/Z21.Client/README.md @@ -0,0 +1,22 @@ +# Z21 + +A small, event-driven .NET client for the ROCO/Fleischmann **Z21** digital command +station. It speaks the Z21 LAN protocol (V1.13) over UDP, so you can drive locomotives, +throw turnouts, switch track power, read CVs and query system state — and get typed +events back whenever something changes on the layout. + +```csharp +station.LocoInfoReceived += (_, loco) => + Console.WriteLine($"loco {loco.LocoAddress} now at speed {loco.LocoSpeed}"); + +await station.ConnectAsync(); +await station.TrackPowerOnAsync(); +await station.DriveAsync(3, DccSpeedMode.Steps128, DrivingDirection.Forward, 40); +``` + +You get an `IZ21CommandStation` from the DI container. To wire it up, add one of the +companion packages: **Z21.DependencyInjection** (Microsoft.Extensions.DependencyInjection) +or **Z21.Autofac** (Autofac). Both expose a single `AddZ21(...)` call. + +The full command/response support matrix and protocol notes live on the +[project page](https://github.com/jaak0b/Z21). Licensed under GPL-3.0. diff --git a/src/Z21.Client/Z21.Client.csproj b/src/Z21.Client/Z21.Client.csproj index ae282fc..1408105 100644 --- a/src/Z21.Client/Z21.Client.csproj +++ b/src/Z21.Client/Z21.Client.csproj @@ -16,12 +16,14 @@ net8.0;net8.0-windows true LICENSE + README.md Z21 Z21 + diff --git a/src/Z21.DependencyInjection/README.md b/src/Z21.DependencyInjection/README.md new file mode 100644 index 0000000..30ba4c0 --- /dev/null +++ b/src/Z21.DependencyInjection/README.md @@ -0,0 +1,20 @@ +# Z21.DependencyInjection + +Microsoft.Extensions.DependencyInjection wiring for the [Z21](https://www.nuget.org/packages/Z21) +client. One call registers the command station, the UDP transport and every protocol +handler, so you can resolve `IZ21CommandStation` and start talking to your Z21. + +```csharp +var services = new ServiceCollection(); +services.AddZ21(t => t.RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.0.111"), 21105)); + +await using var provider = services.BuildServiceProvider(); +var station = provider.GetRequiredService(); + +await station.ConnectAsync(); +await station.DriveAsync(3, DccSpeedMode.Steps128, DrivingDirection.Forward, 40); +``` + +`AddZ21` also takes an optional second configurator for protocol options such as the +broadcast flags to subscribe to. See the [project page](https://github.com/jaak0b/Z21) +for details. Licensed under GPL-3.0. diff --git a/src/Z21.DependencyInjection/Z21.DependencyInjection.csproj b/src/Z21.DependencyInjection/Z21.DependencyInjection.csproj index 812af9b..d939392 100644 --- a/src/Z21.DependencyInjection/Z21.DependencyInjection.csproj +++ b/src/Z21.DependencyInjection/Z21.DependencyInjection.csproj @@ -9,6 +9,7 @@ Jakob Eichberger https://github.com/jaak0b/Z21 LICENSE + README.md true @@ -19,6 +20,7 @@ +