From ee01e093734be1c970822192ada51f01065d7024 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 14:12:43 +0100 Subject: [PATCH 01/23] docs: add AI agent docs --- AGENTS.md | 54 ++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 13 +++++++++++ docs/Architecture.md | 47 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 AGENTS.md create mode 100644 CLAUDE.md create mode 100644 docs/Architecture.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..09bd4bb --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,54 @@ +# AGENTS.md + +Guidance for AI coding agents and contributors working in this repository. + +## Overview + +GeoJSON model types plus JSON converters for Newtonsoft.Json and System.Text.Json, published to +nuget.org as three packages: + +| Package | Contents | +|---------|----------| +| `Appy.Spatial.GeoJSON` | Model: `Feature`, `FeatureCollection`, geometries, `Crs`, `BoundingBox` | +| `Appy.Spatial.GeoJSON.Newtonsoft` | `FeatureConverter`, `GeometryConverter`, `JsonSerializerSettings.UseGeoJsonConverters()` | +| `Appy.Spatial.GeoJSON.TextJson` | `FeatureConverter`, `GeometryConverter`, `JsonSerializerOptions.UseGeoJsonConverters()` | + +Architecture and CI: [docs/Architecture.md](docs/Architecture.md). + +## Build Commands + +```bash +dotnet tool restore # Cake, MinVer CLI, gpr +dotnet cake # Default target: Clean, Build, Test, Package (.artifacts/) +dotnet test src/Appy.Spatial.Geojson.sln +dotnet test src/Appy.Spatial.Geojson.sln --filter "FullyQualifiedName~SerialisationTests.ShouldRoundTripPoint" +``` + +- `build.cake` builds the projects listed in `config.yml` (`Type: Package` or `Type: Test`); add new + projects there. +- Cake builds treat all warnings as errors. +- `Publish` and `Publish-Package-*` targets push to nuget.org and GitHub Packages. They run only in + GitHub Actions; never run them locally. + +## Conventions + +- **Central package management**: versions live in `src/Directory.Packages.props`; `PackageReference` + items carry no `Version`. Framework-specific versions use a `Condition` on `$(TargetFramework)`. +- **Shared metadata**: package info, SourceLink and MinVer are in `src/Directory.Build.props`. +- **Versioning**: MinVer derives the version from git tags (`1.4.0`). No version is stored in files. +- **Tests**: xUnit + FluentAssertions. Every geometry round-trips through both serializers, as the + base type and the concrete type, bare and inside a `Feature`. Keep both converter packages in step. +- **Target frameworks** are set per `.csproj`; the SDK is pinned in `global.json`. +- **Style**: `.editorconfig` (4 spaces, 2 for XML/JSON/YAML, CRLF). File-scoped namespaces. +- **Public repo**: no secrets, internal hostnames or private feed URLs in code, docs or commits. + +## Git Conventions + +- Branch: `feat/`, `fix/`, `docs/`. +- Commits: conventional commits, one line, e.g. `feat(net8): add net8 and drop support for net7`. + See [CONTRIBUTING.md](CONTRIBUTING.md). + +## Documentation + +- [docs/Architecture.md](docs/Architecture.md): overview, CI and release flow, plans +- [docs/plans/](docs/plans/): implementation plans diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..62212b2 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,13 @@ +# CLAUDE.md + +@./AGENTS.md + +## Build & Test + +```bash +dotnet tool restore +dotnet cake # Default: clean, build, test, pack into .artifacts/ +dotnet test src/Appy.Spatial.Geojson.sln # tests only +``` + +Never run the `Publish` cake target or `dotnet nuget push`: publishing happens only in GitHub Actions. diff --git a/docs/Architecture.md b/docs/Architecture.md new file mode 100644 index 0000000..4def896 --- /dev/null +++ b/docs/Architecture.md @@ -0,0 +1,47 @@ +# Appy.Spatial.GeoJSON Architecture + +## Overview + +A small library: plain GeoJSON model classes in `Appy.Spatial.GeoJSON`, and two converter packages +that teach Newtonsoft.Json and System.Text.Json how to read polymorphic geometries and features. +The model has no serializer dependency, so consumers pick one converter package. + +Build, test and conventions: [AGENTS.md](../AGENTS.md). + +## System Diagram + +```mermaid +graph TD + Core["Appy.Spatial.GeoJSON
model"] + NS["Appy.Spatial.GeoJSON.Newtonsoft"] --> Core + STJ["Appy.Spatial.GeoJSON.TextJson"] --> Core + NS --> NJ["Newtonsoft.Json"] + Tests["Appy.Spatial.GeoJSON.Tests"] --> NS + Tests --> STJ +``` + +## Key Patterns + +### Type discriminator + +Geometries derive from `Geometry` / `Geometry` and features from `Feature`, +`Feature` and `Feature`. The converters handle only the abstract +`Geometry` and `Feature` targets: they read the GeoJSON `type` property first (the geometry's +`type` for features), then deserialize into the concrete class (`Point`, `LineString`, `Polygon`, `MultiLineString`, +`MultiPolygon`, `GeometryCollection`). Unknown types throw the serializer's JSON exception. + +### Opt-in registration + +Each converter package exposes one extension, `UseGeoJsonConverters()`, on `JsonSerializerSettings` +(Newtonsoft) or `JsonSerializerOptions` (System.Text.Json). It adds `FeatureConverter` and +`GeometryConverter`. + +## CI and Release + +| Workflow | Trigger | Does | +|----------|---------|------| +| `.github/workflows/ci.yaml` | pull request | `dotnet cake` on Windows and macOS, then Linux | +| `.github/workflows/publish.yaml` | push to `master` touching `src/**`, or any tag | `dotnet cake --target=Publish`: packs, pushes to nuget.org and GitHub Packages | + +MinVer computes the version from the latest tag: a tag publishes that release, and a `master` push +publishes a `-preview` build with the commit height. From 1b02ba5045691f24fb07402d4ed10d4ec3783a36 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 14:16:40 +0100 Subject: [PATCH 02/23] docs(plan): add net10 migration plan --- docs/Architecture.md | 6 +++ docs/plans/001-net10-migration.md | 87 +++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 docs/plans/001-net10-migration.md diff --git a/docs/Architecture.md b/docs/Architecture.md index 4def896..65cd84d 100644 --- a/docs/Architecture.md +++ b/docs/Architecture.md @@ -45,3 +45,9 @@ Each converter package exposes one extension, `UseGeoJsonConverters()`, on `Json MinVer computes the version from the latest tag: a tag publishes that release, and a `master` push publishes a `-preview` build with the commit height. + +## Plans + +| Plan | Status | Summary | +|------|--------|---------| +| [001 .NET 10 Migration](plans/001-net10-migration.md) | Planned | `net10.0;net9.0;net8.0`, SDK 10, Cake 6, xUnit v3; release 2.0.0 | diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md new file mode 100644 index 0000000..52c364f --- /dev/null +++ b/docs/plans/001-net10-migration.md @@ -0,0 +1,87 @@ +# .NET 10 Migration + +- **Status:** Planned +- **Branch:** `feat/net10` + +## Summary + +Move the three packages to `net10.0;net9.0;net8.0` on the .NET 10 SDK, drop `net6.0` and +`netstandard2.0`, and bring the Cake build, GitHub Actions and test stack in line with +[Appy.Configuration](https://github.com/YellowLineParking/Appy.Configuration). Released as +**2.0.0**. No public API change. + +## Decisions + +| Decision | Context | Alternatives Considered | +|----------|---------|------------------------| +| Libraries `net10.0;net9.0;net8.0`, tests `net10.0` | `net6.0` is out of support; `net8.0` and `net9.0` keep current users building | Keep `netstandard2.0`: keeps the nullable shim and the System.Text.Json package for no current need | +| Version **2.0.0** | Dropping `netstandard2.0` ends .NET Framework and pre-net8 support: breaking under SemVer. Those users stay on 1.4.x | Minor bump (Appy.Configuration used 1.2.0 for the same drop): hides the break | +| Remove the `System.Text.Json` package | In-box on net8+; the package only served `netstandard2.0`/`net6.0` | Keep it: NU1510 pruning warning, fails the warnings-as-errors build | +| `Newtonsoft.Json` floor stays **13.0.3** | Raising it to 13.0.4 breaks users who pin 13.0.3 directly (NU1605). 13.0.3 has no advisory | 13.0.4 (latest): no functional gain | +| Tests: `xunit.v3` 3.2.2, `xunit.runner.visualstudio` 3.1.5, FluentAssertions 7.2.2, `Microsoft.NET.Test.Sdk` 18.10.1, `GitHubActionsTestLogger` 3.0.5, `XunitXml.TestLogger` 8.0.0 | xUnit v2 is in maintenance. FluentAssertions 8 needs a commercial licence | xUnit 2.9.3 (as in Appy.Configuration); `xunit.v3` 4.x | +| Build tooling as Appy.Configuration: Cake 6.0.0, Cake.MinVer 4.0.0, Cake.Yaml 6.0.0, YamlDotNet 16.2.0, MinVer 2.3.0, traversal `src/build.csproj`, `.sln` kept | Same pipeline across repos; MinVer 2.3.0 keeps versioning unchanged | MinVer 8: new pre-release options, out of scope | +| Package validation against 1.4.0 | Catches accidental API breaks; only the dropped TFMs are suppressed (PKV006) | None; Appy.Configuration has no validation | +| `MinVerMinimumMajorMinor` 2.0 (MSBuild and `build.cake`) | The master push that follows the merge publishes a preview. Without this it is `1.4.1-preview`, carrying breaking changes. Cake computes the package path, so both must agree | Skip it and accept one misleading preview | + +## Tasks + +- [ ] 1. `feat(net10): target net10.0, net9.0 and net8.0`. `global.json` SDK `10.0.103`, + `rollForward: latestFeature`. The three library csproj files go to `net10.0;net9.0;net8.0`, tests + to `net10.0`. Remove the `netstandard2.0` shims (`Nullable` package, `PackageDownload` + `Microsoft.NETCore.App.Ref`, `AnnotatedReferenceAssemblyVersion`, per-project `LangVersion`) and + the `System.Text.Json` package. `PackageTags` become `NET10;NET9;NET8`. + Test: the 6 `SerialisationTests` pass on `net10.0` (`dotnet test src/Appy.Spatial.Geojson.sln`). +- [ ] 2. `chore(deps): move tests to xunit v3`. Update `src/Directory.Packages.props` to the test + stack above. Remove unused entries (`Moq`, `MartinCostello.Logging.XUnit`, + `TunnelVisionLabs.ReferenceAssemblyAnnotator`, `coverlet.collector`) and the + `Version="$(...)"` attributes in the test csproj. + Test: same 6 tests pass. The run reports a non-zero count. +- [ ] 3. `chore(build): upgrade cake to 6.0.0 with traversal build`. Update `dotnet-tools.json`, + `build.cake` (addins, traversal branch), `global.json` `msbuild-sdks` (Traversal 4.1.82), and add + `src/build.csproj`. `config.yml` still drives packing and publishing. + Test: `dotnet tool restore && dotnet cake` is green. `.artifacts/` holds 3 nupkgs with + `lib/net8.0`, `lib/net9.0`, `lib/net10.0` only. +- [ ] 4. `ci: build and publish with .NET 10 SDK`. In `ci.yaml` and `publish.yaml`, move to + `actions/checkout@v6`, `actions/cache@v5` and `actions/setup-dotnet@v5`, with SDKs `8.0.x`, + `9.0.x` and `10.0.x`. Triggers stay as they are. + Test: PR checks green on Windows, macOS and Linux. +- [ ] 5. `build: validate packages against 1.4.0`. Add `EnablePackageValidation` and + `PackageValidationBaselineVersion` 1.4.0 to packable projects. Pack fails first on PKV006 (the + dropped TFMs). Then add a `CompatibilitySuppressions.xml` with PKV006 only. + Test: `dotnet cake` is green. No CP0xxx (API) diagnostics. +- [ ] 6. `build: start versions at 2.0`. Set `MinVerMinimumMajorMinor` 2.0 in + `src/Directory.Build.targets` and `.WithMinimumMajorMinor("2.0")` in `build.cake`. + Test: `dotnet cake` logs `2.0.0-preview.0.N`. The nupkg names match the version Cake logs. +- [ ] 7. `docs: update readme and contributing for net10`. The README gets a supported-frameworks + line and says that `netstandard2.0`/`net6.0` users should stay on 1.4.x. In `CONTRIBUTING.md`, + replace `build.ps1` with `dotnet tool restore && dotnet cake`. + Test: the links resolve. +- [ ] 8. Release (maintainers). Rebase-merge the PR. The master push publishes + `2.0.0-preview.0.N`. Tag `2.0.0` on master to publish the release. Then commit + `docs(readme): change packages version to 2.0.0` (badges). + +## Verification + +- [ ] `dotnet cake` (Default target) green locally on SDK 10, warnings as errors, 6/6 tests. +- [ ] Nuspecs: TextJson has no `System.Text.Json` dependency; Newtonsoft depends on + `Newtonsoft.Json` >= 13.0.3; groups only for net8.0, net9.0 and net10.0. +- [ ] Package validation passes with only PKV006 suppressed. +- [ ] PR CI green on all three OS jobs. +- [ ] Done when merged and nuget.org lists 2.0.0 for `Appy.Spatial.GeoJSON`, + `Appy.Spatial.GeoJSON.Newtonsoft` and `Appy.Spatial.GeoJSON.TextJson`. + +## Key Files + +``` +global.json # SDK 10 + Traversal SDK +dotnet-tools.json # Cake 6 +build.cake # Cake pipeline, MinVer settings +config.yml # projects to build, test and pack +src/build.csproj # traversal project (new) +src/Directory.Build.props # package metadata, package validation +src/Directory.Build.targets # MinVer settings +src/Directory.Packages.props # central package versions +src/*/*.csproj # target frameworks +.github/workflows/ci.yaml # PR build +.github/workflows/publish.yaml # publish on master push or tag +``` From c8b46b1b71b16d30c1fb63d20d465e9b51ff0820 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 14:47:21 +0100 Subject: [PATCH 03/23] docs(plan): apply review decisions --- docs/Architecture.md | 2 +- docs/plans/001-net10-migration.md | 29 ++++++++++++++++------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/docs/Architecture.md b/docs/Architecture.md index 65cd84d..d6e0daf 100644 --- a/docs/Architecture.md +++ b/docs/Architecture.md @@ -50,4 +50,4 @@ publishes a `-preview` build with the commit height. | Plan | Status | Summary | |------|--------|---------| -| [001 .NET 10 Migration](plans/001-net10-migration.md) | Planned | `net10.0;net9.0;net8.0`, SDK 10, Cake 6, xUnit v3; release 2.0.0 | +| [001 .NET 10 Migration](plans/001-net10-migration.md) | In Progress | `net10.0;net8.0`, SDK 10, Cake 6, xUnit v3; release 2.0.0 | diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index 52c364f..1f6cbb6 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -1,11 +1,11 @@ # .NET 10 Migration -- **Status:** Planned +- **Status:** In Progress - **Branch:** `feat/net10` ## Summary -Move the three packages to `net10.0;net9.0;net8.0` on the .NET 10 SDK, drop `net6.0` and +Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, `net6.0` and `netstandard2.0`, and bring the Cake build, GitHub Actions and test stack in line with [Appy.Configuration](https://github.com/YellowLineParking/Appy.Configuration). Released as **2.0.0**. No public API change. @@ -14,22 +14,23 @@ Move the three packages to `net10.0;net9.0;net8.0` on the .NET 10 SDK, drop `net | Decision | Context | Alternatives Considered | |----------|---------|------------------------| -| Libraries `net10.0;net9.0;net8.0`, tests `net10.0` | `net6.0` is out of support; `net8.0` and `net9.0` keep current users building | Keep `netstandard2.0`: keeps the nullable shim and the System.Text.Json package for no current need | +| Libraries `net10.0;net8.0`, tests `net10.0` | The two LTS releases. `net9.0` apps resolve the `net8.0` asset; `net6.0` is out of support | Also `net9.0`: no API gain. Keep `netstandard2.0`: keeps the nullable shim and the System.Text.Json package for no current need | | Version **2.0.0** | Dropping `netstandard2.0` ends .NET Framework and pre-net8 support: breaking under SemVer. Those users stay on 1.4.x | Minor bump (Appy.Configuration used 1.2.0 for the same drop): hides the break | | Remove the `System.Text.Json` package | In-box on net8+; the package only served `netstandard2.0`/`net6.0` | Keep it: NU1510 pruning warning, fails the warnings-as-errors build | | `Newtonsoft.Json` floor stays **13.0.3** | Raising it to 13.0.4 breaks users who pin 13.0.3 directly (NU1605). 13.0.3 has no advisory | 13.0.4 (latest): no functional gain | | Tests: `xunit.v3` 3.2.2, `xunit.runner.visualstudio` 3.1.5, FluentAssertions 7.2.2, `Microsoft.NET.Test.Sdk` 18.10.1, `GitHubActionsTestLogger` 3.0.5, `XunitXml.TestLogger` 8.0.0 | xUnit v2 is in maintenance. FluentAssertions 8 needs a commercial licence | xUnit 2.9.3 (as in Appy.Configuration); `xunit.v3` 4.x | | Build tooling as Appy.Configuration: Cake 6.0.0, Cake.MinVer 4.0.0, Cake.Yaml 6.0.0, YamlDotNet 16.2.0, MinVer 2.3.0, traversal `src/build.csproj`, `.sln` kept | Same pipeline across repos; MinVer 2.3.0 keeps versioning unchanged | MinVer 8: new pre-release options, out of scope | +| CI installs only the SDK in `global.json` | SDK 10 builds the `net8.0` target from reference packs; tests run on `net10.0`; the Cake, MinVer and gpr tools roll forward | Also install 8.0.x (as Appy.Configuration does): not needed | | Package validation against 1.4.0 | Catches accidental API breaks; only the dropped TFMs are suppressed (PKV006) | None; Appy.Configuration has no validation | | `MinVerMinimumMajorMinor` 2.0 (MSBuild and `build.cake`) | The master push that follows the merge publishes a preview. Without this it is `1.4.1-preview`, carrying breaking changes. Cake computes the package path, so both must agree | Skip it and accept one misleading preview | ## Tasks -- [ ] 1. `feat(net10): target net10.0, net9.0 and net8.0`. `global.json` SDK `10.0.103`, - `rollForward: latestFeature`. The three library csproj files go to `net10.0;net9.0;net8.0`, tests +- [ ] 1. `feat(net10): target net10.0 and net8.0`. `global.json` SDK `10.0.103`, + `rollForward: latestFeature`. The three library csproj files go to `net10.0;net8.0`, tests to `net10.0`. Remove the `netstandard2.0` shims (`Nullable` package, `PackageDownload` `Microsoft.NETCore.App.Ref`, `AnnotatedReferenceAssemblyVersion`, per-project `LangVersion`) and - the `System.Text.Json` package. `PackageTags` become `NET10;NET9;NET8`. + the `System.Text.Json` package. `PackageTags` become `NET10;NET8`. Test: the 6 `SerialisationTests` pass on `net10.0` (`dotnet test src/Appy.Spatial.Geojson.sln`). - [ ] 2. `chore(deps): move tests to xunit v3`. Update `src/Directory.Packages.props` to the test stack above. Remove unused entries (`Moq`, `MartinCostello.Logging.XUnit`, @@ -40,10 +41,10 @@ Move the three packages to `net10.0;net9.0;net8.0` on the .NET 10 SDK, drop `net `build.cake` (addins, traversal branch), `global.json` `msbuild-sdks` (Traversal 4.1.82), and add `src/build.csproj`. `config.yml` still drives packing and publishing. Test: `dotnet tool restore && dotnet cake` is green. `.artifacts/` holds 3 nupkgs with - `lib/net8.0`, `lib/net9.0`, `lib/net10.0` only. + `lib/net8.0` and `lib/net10.0` only. - [ ] 4. `ci: build and publish with .NET 10 SDK`. In `ci.yaml` and `publish.yaml`, move to - `actions/checkout@v6`, `actions/cache@v5` and `actions/setup-dotnet@v5`, with SDKs `8.0.x`, - `9.0.x` and `10.0.x`. Triggers stay as they are. + `actions/checkout@v6`, `actions/cache@v5` and `actions/setup-dotnet@v5`, SDK from `global.json` + only. Triggers stay as they are. Test: PR checks green on Windows, macOS and Linux. - [ ] 5. `build: validate packages against 1.4.0`. Add `EnablePackageValidation` and `PackageValidationBaselineVersion` 1.4.0 to packable projects. Pack fails first on PKV006 (the @@ -56,20 +57,22 @@ Move the three packages to `net10.0;net9.0;net8.0` on the .NET 10 SDK, drop `net line and says that `netstandard2.0`/`net6.0` users should stay on 1.4.x. In `CONTRIBUTING.md`, replace `build.ps1` with `dotnet tool restore && dotnet cake`. Test: the links resolve. -- [ ] 8. Release (maintainers). Rebase-merge the PR. The master push publishes - `2.0.0-preview.0.N`. Tag `2.0.0` on master to publish the release. Then commit - `docs(readme): change packages version to 2.0.0` (badges). ## Verification - [ ] `dotnet cake` (Default target) green locally on SDK 10, warnings as errors, 6/6 tests. - [ ] Nuspecs: TextJson has no `System.Text.Json` dependency; Newtonsoft depends on - `Newtonsoft.Json` >= 13.0.3; groups only for net8.0, net9.0 and net10.0. + `Newtonsoft.Json` >= 13.0.3; groups only for net8.0 and net10.0. - [ ] Package validation passes with only PKV006 suppressed. - [ ] PR CI green on all three OS jobs. - [ ] Done when merged and nuget.org lists 2.0.0 for `Appy.Spatial.GeoJSON`, `Appy.Spatial.GeoJSON.Newtonsoft` and `Appy.Spatial.GeoJSON.TextJson`. +## Release + +Maintainers rebase-merge the PR; the master push publishes `2.0.0-preview.0.N`. Tagging `2.0.0` on +master publishes the release. Then `docs(readme): change packages version to 2.0.0` (badges). + ## Key Files ``` From 092f6229f4ea550297aaa6531e30e6e59c138d94 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 14:48:23 +0100 Subject: [PATCH 04/23] feat(net10): target net10.0 and net8.0 --- docs/plans/001-net10-migration.md | 2 +- global.json | 4 ++-- .../Appy.Spatial.GeoJSON.Newtonsoft.csproj | 3 +-- .../Appy.Spatial.GeoJSON.Tests.csproj | 3 +-- .../Appy.Spatial.GeoJSON.TextJson.csproj | 20 +------------------ .../Appy.Spatial.GeoJSON.csproj | 16 +-------------- src/Directory.Build.props | 2 +- src/Directory.Packages.props | 4 ---- 8 files changed, 8 insertions(+), 46 deletions(-) diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index 1f6cbb6..59e24a3 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -26,7 +26,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` ## Tasks -- [ ] 1. `feat(net10): target net10.0 and net8.0`. `global.json` SDK `10.0.103`, +- [x] 1. `feat(net10): target net10.0 and net8.0`. `global.json` SDK `10.0.103`, `rollForward: latestFeature`. The three library csproj files go to `net10.0;net8.0`, tests to `net10.0`. Remove the `netstandard2.0` shims (`Nullable` package, `PackageDownload` `Microsoft.NETCore.App.Ref`, `AnnotatedReferenceAssemblyVersion`, per-project `LangVersion`) and diff --git a/global.json b/global.json index 989a69c..d92a294 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100", - "rollForward": "latestMinor" + "version": "10.0.103", + "rollForward": "latestFeature" } } \ No newline at end of file diff --git a/src/Appy.Spatial.GeoJSON.Newtonsoft/Appy.Spatial.GeoJSON.Newtonsoft.csproj b/src/Appy.Spatial.GeoJSON.Newtonsoft/Appy.Spatial.GeoJSON.Newtonsoft.csproj index 40b8203..ac81342 100644 --- a/src/Appy.Spatial.GeoJSON.Newtonsoft/Appy.Spatial.GeoJSON.Newtonsoft.csproj +++ b/src/Appy.Spatial.GeoJSON.Newtonsoft/Appy.Spatial.GeoJSON.Newtonsoft.csproj @@ -1,8 +1,7 @@ - net8.0;net6.0;netstandard2.0 - latest + net10.0;net8.0 diff --git a/src/Appy.Spatial.GeoJSON.Tests/Appy.Spatial.GeoJSON.Tests.csproj b/src/Appy.Spatial.GeoJSON.Tests/Appy.Spatial.GeoJSON.Tests.csproj index 389c774..56c7035 100644 --- a/src/Appy.Spatial.GeoJSON.Tests/Appy.Spatial.GeoJSON.Tests.csproj +++ b/src/Appy.Spatial.GeoJSON.Tests/Appy.Spatial.GeoJSON.Tests.csproj @@ -1,9 +1,8 @@ - net6.0 + net10.0 false - latest diff --git a/src/Appy.Spatial.GeoJSON.TextJson/Appy.Spatial.GeoJSON.TextJson.csproj b/src/Appy.Spatial.GeoJSON.TextJson/Appy.Spatial.GeoJSON.TextJson.csproj index addab36..c0f2df4 100644 --- a/src/Appy.Spatial.GeoJSON.TextJson/Appy.Spatial.GeoJSON.TextJson.csproj +++ b/src/Appy.Spatial.GeoJSON.TextJson/Appy.Spatial.GeoJSON.TextJson.csproj @@ -1,8 +1,7 @@ - net8.0;net6.0;netstandard2.0 - latest + net10.0;net8.0 @@ -13,21 +12,4 @@ - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - 3.0.0 - False - - diff --git a/src/Appy.Spatial.GeoJSON/Appy.Spatial.GeoJSON.csproj b/src/Appy.Spatial.GeoJSON/Appy.Spatial.GeoJSON.csproj index bc50726..c6605c6 100644 --- a/src/Appy.Spatial.GeoJSON/Appy.Spatial.GeoJSON.csproj +++ b/src/Appy.Spatial.GeoJSON/Appy.Spatial.GeoJSON.csproj @@ -1,25 +1,11 @@ - netstandard2.0 - latest + net10.0;net8.0 - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - 3.0.0 - False - - diff --git a/src/Directory.Build.props b/src/Directory.Build.props index d55bb4c..52246c3 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -24,7 +24,7 @@ https://github.com/YellowLineParking/Appy.Spatial.GeoJSON MIT https://github.com/YellowLineParking/Appy.Spatial.GeoJSON/releases - NET8;NET6;NetStandard + NET10;NET8 diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 16fefbf..cedebbb 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -3,10 +3,6 @@ true - - - - From 908b3a046b1029620ef3e98992ce78256190c7fa Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 14:50:34 +0100 Subject: [PATCH 05/23] chore(deps): move tests to xunit v3 --- docs/plans/001-net10-migration.md | 6 +++--- .../Appy.Spatial.GeoJSON.Tests.csproj | 13 ++++++------- src/Directory.Packages.props | 17 ++++++----------- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index 59e24a3..428a0cf 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -18,7 +18,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` | Version **2.0.0** | Dropping `netstandard2.0` ends .NET Framework and pre-net8 support: breaking under SemVer. Those users stay on 1.4.x | Minor bump (Appy.Configuration used 1.2.0 for the same drop): hides the break | | Remove the `System.Text.Json` package | In-box on net8+; the package only served `netstandard2.0`/`net6.0` | Keep it: NU1510 pruning warning, fails the warnings-as-errors build | | `Newtonsoft.Json` floor stays **13.0.3** | Raising it to 13.0.4 breaks users who pin 13.0.3 directly (NU1605). 13.0.3 has no advisory | 13.0.4 (latest): no functional gain | -| Tests: `xunit.v3` 3.2.2, `xunit.runner.visualstudio` 3.1.5, FluentAssertions 7.2.2, `Microsoft.NET.Test.Sdk` 18.10.1, `GitHubActionsTestLogger` 3.0.5, `XunitXml.TestLogger` 8.0.0 | xUnit v2 is in maintenance. FluentAssertions 8 needs a commercial licence | xUnit 2.9.3 (as in Appy.Configuration); `xunit.v3` 4.x | +| Tests: `xunit.v3` 3.2.2, `xunit.runner.visualstudio` 3.1.5, FluentAssertions 7.2.2, `Microsoft.NET.Test.Sdk` 18.10.1, `GitHubActionsTestLogger` 2.4.1 | xUnit v2 is in maintenance. FluentAssertions 8 needs a commercial licence. Logger 3.x and `XunitXml.TestLogger` 8.x need Microsoft.Testing.Platform 2 (CS1705 against xunit.v3 3.2.2's 1.9.1); the XML logger was unused | xUnit 2.9.3 (as in Appy.Configuration); `xunit.v3` 4.x | | Build tooling as Appy.Configuration: Cake 6.0.0, Cake.MinVer 4.0.0, Cake.Yaml 6.0.0, YamlDotNet 16.2.0, MinVer 2.3.0, traversal `src/build.csproj`, `.sln` kept | Same pipeline across repos; MinVer 2.3.0 keeps versioning unchanged | MinVer 8: new pre-release options, out of scope | | CI installs only the SDK in `global.json` | SDK 10 builds the `net8.0` target from reference packs; tests run on `net10.0`; the Cake, MinVer and gpr tools roll forward | Also install 8.0.x (as Appy.Configuration does): not needed | | Package validation against 1.4.0 | Catches accidental API breaks; only the dropped TFMs are suppressed (PKV006) | None; Appy.Configuration has no validation | @@ -32,9 +32,9 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` `Microsoft.NETCore.App.Ref`, `AnnotatedReferenceAssemblyVersion`, per-project `LangVersion`) and the `System.Text.Json` package. `PackageTags` become `NET10;NET8`. Test: the 6 `SerialisationTests` pass on `net10.0` (`dotnet test src/Appy.Spatial.Geojson.sln`). -- [ ] 2. `chore(deps): move tests to xunit v3`. Update `src/Directory.Packages.props` to the test +- [x] 2. `chore(deps): move tests to xunit v3`. Update `src/Directory.Packages.props` to the test stack above. Remove unused entries (`Moq`, `MartinCostello.Logging.XUnit`, - `TunnelVisionLabs.ReferenceAssemblyAnnotator`, `coverlet.collector`) and the + `TunnelVisionLabs.ReferenceAssemblyAnnotator`, `coverlet.collector`, `XunitXml.TestLogger`) and the `Version="$(...)"` attributes in the test csproj. Test: same 6 tests pass. The run reports a non-zero count. - [ ] 3. `chore(build): upgrade cake to 6.0.0 with traversal build`. Update `dotnet-tools.json`, diff --git a/src/Appy.Spatial.GeoJSON.Tests/Appy.Spatial.GeoJSON.Tests.csproj b/src/Appy.Spatial.GeoJSON.Tests/Appy.Spatial.GeoJSON.Tests.csproj index 56c7035..651aadc 100644 --- a/src/Appy.Spatial.GeoJSON.Tests/Appy.Spatial.GeoJSON.Tests.csproj +++ b/src/Appy.Spatial.GeoJSON.Tests/Appy.Spatial.GeoJSON.Tests.csproj @@ -2,20 +2,19 @@ net10.0 + Exe false - - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index cedebbb..d999e0f 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -4,17 +4,12 @@ - - - - - - - - - - + + + + + - \ No newline at end of file + From 42703a714fdc089dd955c2f3bddf11c84efbfd01 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 14:51:41 +0100 Subject: [PATCH 06/23] chore(build): upgrade cake to 6.0.0 with traversal build --- build.cake | 58 +++++++++++++++++++++++++++++-- docs/plans/001-net10-migration.md | 2 +- dotnet-tools.json | 2 +- global.json | 3 ++ src/Directory.Build.props | 2 +- src/build.csproj | 5 +++ 6 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 src/build.csproj diff --git a/build.cake b/build.cake index 9047caf..da0a18d 100644 --- a/build.cake +++ b/build.cake @@ -1,6 +1,6 @@ -#addin nuget:?package=YamlDotNet&version=13.7.1 +#addin nuget:?package=YamlDotNet&version=16.2.0 #addin nuget:?package=System.Xml.XDocument&version=4.3.0 -#addin nuget:?package=Cake.MinVer&version=3.0.0 +#addin nuget:?package=Cake.MinVer&version=4.0.0 #addin nuget:?package=Cake.Yaml&version=6.0.0 #load "./functions.cake" @@ -11,6 +11,7 @@ var artifactsPath = Context.Directory("./.artifacts"); var target = Argument("target", "Default"); var configuration = Argument("configuration", "Release"); var configFilePath = "config.yml"; +var transversalBuildFilePath = $"{basePath}/build.csproj"; var taskConfigManager = new ProjectTaskConfigurationManager(); var projectDescriptors = ProjectLoader.Load(Context, configFilePath, basePath, configuration).Projects; var version = MinVer(settings => settings @@ -38,6 +39,11 @@ Task("Clean") Task("Restore") .Does(() => { + if (FileExists(transversalBuildFilePath)) + { + return; + } + DotNetRestore(basePath, new DotNetRestoreSettings { @@ -49,6 +55,20 @@ Task("Build-Project") .IsDependentOn("Restore") .Does(context => { + if (FileExists(transversalBuildFilePath)) + { + context.Information("Building projects using Transversal Build"); + + DotNetBuild(transversalBuildFilePath, new DotNetBuildSettings { + Configuration = configuration, + Verbosity = DotNetVerbosity.Minimal, + MSBuildSettings = new DotNetMSBuildSettings() + .TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error) + }); + + return; + } + foreach(var projectDescriptor in projectDescriptors) { if (!taskConfigManager.CanBuild(projectDescriptor.Config)) continue; @@ -69,6 +89,24 @@ Task("Test") .IsDependentOn("Build-Project") .Does(context => { + if (FileExists(transversalBuildFilePath)) + { + context.Information("Testing projects using Transversal Build"); + + DotNetTest(transversalBuildFilePath, new DotNetTestSettings { + Configuration = configuration, + NoRestore = true, + NoBuild = true, + TestAdapterPath = ".", + Loggers = new string[] { + "GitHubActions;report-warnings=false" + }, + Verbosity = DotNetVerbosity.Quiet + }); + + return; + } + foreach(var projectDescriptor in projectDescriptors) { if (!taskConfigManager.CanTest(projectDescriptor.Config)) continue; @@ -93,6 +131,22 @@ Task("Package") .IsDependentOn("Test") .Does(context => { + if (FileExists(transversalBuildFilePath)) + { + context.Information("Packing projects using Transversal Build"); + + context.DotNetPack(transversalBuildFilePath, new DotNetPackSettings { + Configuration = configuration, + NoRestore = true, + NoBuild = true, + OutputDirectory = artifactsPath, + MSBuildSettings = new DotNetMSBuildSettings() + .TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error) + }); + + return; + } + foreach(var projectDescriptor in projectDescriptors) { if (!taskConfigManager.CanPack(projectDescriptor.Config)) continue; diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index 428a0cf..250e484 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -37,7 +37,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` `TunnelVisionLabs.ReferenceAssemblyAnnotator`, `coverlet.collector`, `XunitXml.TestLogger`) and the `Version="$(...)"` attributes in the test csproj. Test: same 6 tests pass. The run reports a non-zero count. -- [ ] 3. `chore(build): upgrade cake to 6.0.0 with traversal build`. Update `dotnet-tools.json`, +- [x] 3. `chore(build): upgrade cake to 6.0.0 with traversal build`. Update `dotnet-tools.json`, `build.cake` (addins, traversal branch), `global.json` `msbuild-sdks` (Traversal 4.1.82), and add `src/build.csproj`. `config.yml` still drives packing and publishing. Test: `dotnet tool restore && dotnet cake` is green. `.artifacts/` holds 3 nupkgs with diff --git a/dotnet-tools.json b/dotnet-tools.json index ea10713..60f01ea 100644 --- a/dotnet-tools.json +++ b/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "cake.tool": { - "version": "4.0.0", + "version": "6.0.0", "commands": [ "dotnet-cake" ] diff --git a/global.json b/global.json index d92a294..cbe7ff9 100644 --- a/global.json +++ b/global.json @@ -2,5 +2,8 @@ "sdk": { "version": "10.0.103", "rollForward": "latestFeature" + }, + "msbuild-sdks": { + "Microsoft.Build.Traversal": "4.1.82" } } \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 52246c3..a3cf9c0 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -28,7 +28,7 @@ - 1571;1572;1573;1574;1591 + 1571;1572;1573;1574;1591;NU1507 diff --git a/src/build.csproj b/src/build.csproj new file mode 100644 index 0000000..101d66b --- /dev/null +++ b/src/build.csproj @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file From ae558c6c1cfc5c530d8b48f4d4a093003114a029 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 14:52:01 +0100 Subject: [PATCH 07/23] ci: build and publish with .NET 10 SDK --- .github/workflows/ci.yaml | 20 ++++++++------------ .github/workflows/publish.yaml | 12 ++++-------- docs/plans/001-net10-migration.md | 2 +- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3f50c29..d4b9188 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -14,19 +14,19 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v6 with: fetch-depth: 0 - name: Cache packages - uses: actions/cache@v3 + uses: actions/cache@v5 with: path: ${{ env.NUGET_PACKAGES }} key: ${{ runner.os }}-nuget-${{ hashFiles('.config/dotnet-tools.json', '**/packages.lock.json') }} restore-keys: ${{ runner.os }}-nuget- - - name: Setup .NET SDK - uses: actions/setup-dotnet@v3 + - name: Setup .NET SDK (global.json) + uses: actions/setup-dotnet@v5 - name: Integration Tests shell: bash @@ -53,23 +53,19 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v6 with: fetch-depth: 0 - name: Cache packages - uses: actions/cache@v3 + uses: actions/cache@v5 with: path: ${{ env.NUGET_PACKAGES }} key: ${{ runner.os }}-nuget-${{ hashFiles('.config/dotnet-tools.json', '**/packages.lock.json') }} restore-keys: ${{ runner.os }}-nuget- - - name: Setup .NET SDK - uses: actions/setup-dotnet@v3 - with: - dotnet-version: | - 6.0.x - 8.0.x + - name: Setup .NET SDK (global.json) + uses: actions/setup-dotnet@v5 - name: Integration Tests shell: bash diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index a2c3fc7..482be12 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -21,23 +21,19 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v6 with: fetch-depth: 0 - name: Cache packages - uses: actions/cache@v3 + uses: actions/cache@v5 with: path: ${{ env.NUGET_PACKAGES }} key: ${{ runner.os }}-nuget-${{ hashFiles('.config/dotnet-tools.json', '**/packages.lock.json') }} restore-keys: ${{ runner.os }}-nuget- - - name: Setup .NET SDK - uses: actions/setup-dotnet@v3 - with: - dotnet-version: | - 6.0.x - 8.0.x + - name: Setup .NET SDK (global.json) + uses: actions/setup-dotnet@v5 - name: Publish shell: bash diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index 250e484..a10792c 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -42,7 +42,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` `src/build.csproj`. `config.yml` still drives packing and publishing. Test: `dotnet tool restore && dotnet cake` is green. `.artifacts/` holds 3 nupkgs with `lib/net8.0` and `lib/net10.0` only. -- [ ] 4. `ci: build and publish with .NET 10 SDK`. In `ci.yaml` and `publish.yaml`, move to +- [x] 4. `ci: build and publish with .NET 10 SDK`. In `ci.yaml` and `publish.yaml`, move to `actions/checkout@v6`, `actions/cache@v5` and `actions/setup-dotnet@v5`, SDK from `global.json` only. Triggers stay as they are. Test: PR checks green on Windows, macOS and Linux. From e3bac2088321db5f6881b7d116dd9905f2917607 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 14:55:44 +0100 Subject: [PATCH 08/23] build: validate packages against 1.4.0 --- docs/plans/001-net10-migration.md | 2 +- .../CompatibilitySuppressions.xml | 12 ++++++++++++ .../CompatibilitySuppressions.xml | 12 ++++++++++++ .../CompatibilitySuppressions.xml | 8 ++++++++ src/Directory.Build.targets | 9 +++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/Appy.Spatial.GeoJSON.Newtonsoft/CompatibilitySuppressions.xml create mode 100644 src/Appy.Spatial.GeoJSON.TextJson/CompatibilitySuppressions.xml create mode 100644 src/Appy.Spatial.GeoJSON/CompatibilitySuppressions.xml diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index a10792c..c62c8fc 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -46,7 +46,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` `actions/checkout@v6`, `actions/cache@v5` and `actions/setup-dotnet@v5`, SDK from `global.json` only. Triggers stay as they are. Test: PR checks green on Windows, macOS and Linux. -- [ ] 5. `build: validate packages against 1.4.0`. Add `EnablePackageValidation` and +- [x] 5. `build: validate packages against 1.4.0`. Add `EnablePackageValidation` and `PackageValidationBaselineVersion` 1.4.0 to packable projects. Pack fails first on PKV006 (the dropped TFMs). Then add a `CompatibilitySuppressions.xml` with PKV006 only. Test: `dotnet cake` is green. No CP0xxx (API) diagnostics. diff --git a/src/Appy.Spatial.GeoJSON.Newtonsoft/CompatibilitySuppressions.xml b/src/Appy.Spatial.GeoJSON.Newtonsoft/CompatibilitySuppressions.xml new file mode 100644 index 0000000..2b52f50 --- /dev/null +++ b/src/Appy.Spatial.GeoJSON.Newtonsoft/CompatibilitySuppressions.xml @@ -0,0 +1,12 @@ + + + + + PKV006 + .NETStandard,Version=v2.0 + + + PKV006 + net6.0 + + \ No newline at end of file diff --git a/src/Appy.Spatial.GeoJSON.TextJson/CompatibilitySuppressions.xml b/src/Appy.Spatial.GeoJSON.TextJson/CompatibilitySuppressions.xml new file mode 100644 index 0000000..2b52f50 --- /dev/null +++ b/src/Appy.Spatial.GeoJSON.TextJson/CompatibilitySuppressions.xml @@ -0,0 +1,12 @@ + + + + + PKV006 + .NETStandard,Version=v2.0 + + + PKV006 + net6.0 + + \ No newline at end of file diff --git a/src/Appy.Spatial.GeoJSON/CompatibilitySuppressions.xml b/src/Appy.Spatial.GeoJSON/CompatibilitySuppressions.xml new file mode 100644 index 0000000..da45c44 --- /dev/null +++ b/src/Appy.Spatial.GeoJSON/CompatibilitySuppressions.xml @@ -0,0 +1,8 @@ + + + + + PKV006 + .NETStandard,Version=v2.0 + + \ No newline at end of file diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 4b6ff93..5f04a22 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -1,4 +1,13 @@ + + true + 1.4.0 + + + + + preview From 5a0cd8a2c62d24ec6738994ee2d050a72fcebc69 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 14:56:17 +0100 Subject: [PATCH 09/23] build: start versions at 2.0 --- build.cake | 1 + docs/plans/001-net10-migration.md | 2 +- src/Directory.Build.targets | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build.cake b/build.cake index da0a18d..60dbdc6 100644 --- a/build.cake +++ b/build.cake @@ -15,6 +15,7 @@ var transversalBuildFilePath = $"{basePath}/build.csproj"; var taskConfigManager = new ProjectTaskConfigurationManager(); var projectDescriptors = ProjectLoader.Load(Context, configFilePath, basePath, configuration).Projects; var version = MinVer(settings => settings + .WithMinimumMajorMinor("2.0") .WithDefaultPreReleasePhase("preview") .WithVerbosity(MinVerVerbosity.Info)); diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index c62c8fc..58f26ef 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -50,7 +50,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` `PackageValidationBaselineVersion` 1.4.0 to packable projects. Pack fails first on PKV006 (the dropped TFMs). Then add a `CompatibilitySuppressions.xml` with PKV006 only. Test: `dotnet cake` is green. No CP0xxx (API) diagnostics. -- [ ] 6. `build: start versions at 2.0`. Set `MinVerMinimumMajorMinor` 2.0 in +- [x] 6. `build: start versions at 2.0`. Set `MinVerMinimumMajorMinor` 2.0 in `src/Directory.Build.targets` and `.WithMinimumMajorMinor("2.0")` in `build.cake`. Test: `dotnet cake` logs `2.0.0-preview.0.N`. The nupkg names match the version Cake logs. - [ ] 7. `docs: update readme and contributing for net10`. The README gets a supported-frameworks diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 5f04a22..4ea0d24 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -10,6 +10,7 @@ + 2.0 preview normal From 4fb710389eb1aada400b47269b5a2915cb46800c Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 14:56:43 +0100 Subject: [PATCH 10/23] docs: update readme and contributing for net10 --- CONTRIBUTING.md | 3 ++- README.md | 5 +++++ docs/plans/001-net10-migration.md | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7f49b6b..d2dc860 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -82,7 +82,8 @@ Before you submit your pull request consider the following guidelines: * Build your changes locally to ensure all the tests pass: ```shell - build.ps1 + dotnet tool restore + dotnet cake ``` * Push your branch to GitHub: diff --git a/README.md b/README.md index 3817122..a92d10f 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,11 @@ AppyWay geojson model and json serialization converters. | [Appy.Spatial.GeoJSON.Newtonsoft](https://www.nuget.org/packages/Appy.Spatial.GeoJSON.Newtonsoft) | [![Nuget Package](https://img.shields.io/badge/nuget-1.4.0-blue.svg)](https://www.nuget.org/packages/Appy.Spatial.GeoJSON.Newtonsoft) | | [Appy.Spatial.GeoJSON.TextJson](https://www.nuget.org/packages/Appy.Spatial.GeoJSON.TextJson) | [![Nuget Package](https://img.shields.io/badge/nuget-1.4.0-blue.svg)](https://www.nuget.org/packages/Appy.Spatial.GeoJSON.TextJson) | +## Supported frameworks + +The packages target `net10.0` and `net8.0`; apps on `net9.0` use the `net8.0` build. +Version 2.0 dropped `netstandard2.0` and `net6.0`: .NET Framework and older .NET apps should stay +on 1.4.x. ## Contribute It would be awesome if you would like to contribute code or help with bugs. Just follow the guidelines [CONTRIBUTING](https://github.com/YellowLineParking/Appy.Spatial.GeoJSON/blob/master/CONTRIBUTING.md) \ No newline at end of file diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index 58f26ef..8731791 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -53,7 +53,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` - [x] 6. `build: start versions at 2.0`. Set `MinVerMinimumMajorMinor` 2.0 in `src/Directory.Build.targets` and `.WithMinimumMajorMinor("2.0")` in `build.cake`. Test: `dotnet cake` logs `2.0.0-preview.0.N`. The nupkg names match the version Cake logs. -- [ ] 7. `docs: update readme and contributing for net10`. The README gets a supported-frameworks +- [x] 7. `docs: update readme and contributing for net10`. The README gets a supported-frameworks line and says that `netstandard2.0`/`net6.0` users should stay on 1.4.x. In `CONTRIBUTING.md`, replace `build.ps1` with `dotnet tool restore && dotnet cake`. Test: the links resolve. From 3d1d8e052f7a469892b6dc7d73eaaae782358acb Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 14:57:23 +0100 Subject: [PATCH 11/23] docs(plan): record local verification --- docs/plans/001-net10-migration.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index 8731791..c8502ac 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -60,10 +60,10 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` ## Verification -- [ ] `dotnet cake` (Default target) green locally on SDK 10, warnings as errors, 6/6 tests. -- [ ] Nuspecs: TextJson has no `System.Text.Json` dependency; Newtonsoft depends on +- [x] `dotnet cake` (Default target) green locally on SDK 10, warnings as errors, 6/6 tests. +- [x] Nuspecs: TextJson has no `System.Text.Json` dependency; Newtonsoft depends on `Newtonsoft.Json` >= 13.0.3; groups only for net8.0 and net10.0. -- [ ] Package validation passes with only PKV006 suppressed. +- [x] Package validation passes with only PKV006 suppressed. - [ ] PR CI green on all three OS jobs. - [ ] Done when merged and nuget.org lists 2.0.0 for `Appy.Spatial.GeoJSON`, `Appy.Spatial.GeoJSON.Newtonsoft` and `Appy.Spatial.GeoJSON.TextJson`. @@ -81,8 +81,9 @@ dotnet-tools.json # Cake 6 build.cake # Cake pipeline, MinVer settings config.yml # projects to build, test and pack src/build.csproj # traversal project (new) -src/Directory.Build.props # package metadata, package validation -src/Directory.Build.targets # MinVer settings +src/Directory.Build.props # package metadata +src/Directory.Build.targets # package validation, MinVer settings +src/*/CompatibilitySuppressions.xml # PKV006 for the dropped TFMs (new) src/Directory.Packages.props # central package versions src/*/*.csproj # target frameworks .github/workflows/ci.yaml # PR build From 4a4b936f301e4f19f7c5332f7a6a108016e26260 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 14:58:03 +0100 Subject: [PATCH 12/23] docs: note package validation baseline --- AGENTS.md | 2 ++ docs/plans/001-net10-migration.md | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 09bd4bb..b5156e7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,6 +36,8 @@ dotnet test src/Appy.Spatial.Geojson.sln --filter "FullyQualifiedName~Serialisat items carry no `Version`. Framework-specific versions use a `Condition` on `$(TargetFramework)`. - **Shared metadata**: package info, SourceLink and MinVer are in `src/Directory.Build.props`. - **Versioning**: MinVer derives the version from git tags (`1.4.0`). No version is stored in files. +- **Package validation**: `dotnet pack` checks each package against the last release + (`PackageValidationBaselineVersion` in `src/Directory.Build.targets`). API breaks fail the build. - **Tests**: xUnit + FluentAssertions. Every geometry round-trips through both serializers, as the base type and the concrete type, bare and inside a `Feature`. Keep both converter packages in step. - **Target frameworks** are set per `.csproj`; the SDK is pinned in `global.json`. diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index c8502ac..ba1dc93 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -71,7 +71,8 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` ## Release Maintainers rebase-merge the PR; the master push publishes `2.0.0-preview.0.N`. Tagging `2.0.0` on -master publishes the release. Then `docs(readme): change packages version to 2.0.0` (badges). +master publishes the release. Then `docs(readme): change packages version to 2.0.0` (badges), and +move `PackageValidationBaselineVersion` to 2.0.0 and delete the `CompatibilitySuppressions.xml` files. ## Key Files From 9d2b815094f6711d319ff7b0e40b0a6df3b98205 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 15:02:45 +0100 Subject: [PATCH 13/23] docs(plan): record ci verification --- docs/plans/001-net10-migration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index ba1dc93..bcf4494 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -64,7 +64,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` - [x] Nuspecs: TextJson has no `System.Text.Json` dependency; Newtonsoft depends on `Newtonsoft.Json` >= 13.0.3; groups only for net8.0 and net10.0. - [x] Package validation passes with only PKV006 suppressed. -- [ ] PR CI green on all three OS jobs. +- [x] PR CI green on all three OS jobs. - [ ] Done when merged and nuget.org lists 2.0.0 for `Appy.Spatial.GeoJSON`, `Appy.Spatial.GeoJSON.Newtonsoft` and `Appy.Spatial.GeoJSON.TextJson`. From f96bacdaae1229c8b83a3580c45abd37c7591c29 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 15:07:05 +0100 Subject: [PATCH 14/23] chore(deps): bump Newtonsoft.Json to 13.0.4 --- docs/plans/001-net10-migration.md | 4 ++-- src/Directory.Packages.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index bcf4494..a711366 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -17,7 +17,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` | Libraries `net10.0;net8.0`, tests `net10.0` | The two LTS releases. `net9.0` apps resolve the `net8.0` asset; `net6.0` is out of support | Also `net9.0`: no API gain. Keep `netstandard2.0`: keeps the nullable shim and the System.Text.Json package for no current need | | Version **2.0.0** | Dropping `netstandard2.0` ends .NET Framework and pre-net8 support: breaking under SemVer. Those users stay on 1.4.x | Minor bump (Appy.Configuration used 1.2.0 for the same drop): hides the break | | Remove the `System.Text.Json` package | In-box on net8+; the package only served `netstandard2.0`/`net6.0` | Keep it: NU1510 pruning warning, fails the warnings-as-errors build | -| `Newtonsoft.Json` floor stays **13.0.3** | Raising it to 13.0.4 breaks users who pin 13.0.3 directly (NU1605). 13.0.3 has no advisory | 13.0.4 (latest): no functional gain | +| `Newtonsoft.Json` **13.0.4** | Latest stable. Apps that pin a lower version directly must bump it with 2.0.0 (NU1605) | Keep 13.0.3: no advisory against it, but stays behind latest | | Tests: `xunit.v3` 3.2.2, `xunit.runner.visualstudio` 3.1.5, FluentAssertions 7.2.2, `Microsoft.NET.Test.Sdk` 18.10.1, `GitHubActionsTestLogger` 2.4.1 | xUnit v2 is in maintenance. FluentAssertions 8 needs a commercial licence. Logger 3.x and `XunitXml.TestLogger` 8.x need Microsoft.Testing.Platform 2 (CS1705 against xunit.v3 3.2.2's 1.9.1); the XML logger was unused | xUnit 2.9.3 (as in Appy.Configuration); `xunit.v3` 4.x | | Build tooling as Appy.Configuration: Cake 6.0.0, Cake.MinVer 4.0.0, Cake.Yaml 6.0.0, YamlDotNet 16.2.0, MinVer 2.3.0, traversal `src/build.csproj`, `.sln` kept | Same pipeline across repos; MinVer 2.3.0 keeps versioning unchanged | MinVer 8: new pre-release options, out of scope | | CI installs only the SDK in `global.json` | SDK 10 builds the `net8.0` target from reference packs; tests run on `net10.0`; the Cake, MinVer and gpr tools roll forward | Also install 8.0.x (as Appy.Configuration does): not needed | @@ -62,7 +62,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` - [x] `dotnet cake` (Default target) green locally on SDK 10, warnings as errors, 6/6 tests. - [x] Nuspecs: TextJson has no `System.Text.Json` dependency; Newtonsoft depends on - `Newtonsoft.Json` >= 13.0.3; groups only for net8.0 and net10.0. + `Newtonsoft.Json` >= 13.0.4; groups only for net8.0 and net10.0. - [x] Package validation passes with only PKV006 suppressed. - [x] PR CI green on all three OS jobs. - [ ] Done when merged and nuget.org lists 2.0.0 for `Appy.Spatial.GeoJSON`, diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index d999e0f..86d6888 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -3,7 +3,7 @@ true - + From b438b4547fc4b38e0fa0b1a91ddbf094b681c66a Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 17:23:36 +0100 Subject: [PATCH 15/23] chore(build): drop traversal build, keep config.yml --- build.cake | 54 ------------------------------- docs/plans/001-net10-migration.md | 10 +++--- global.json | 3 -- src/Directory.Build.targets | 2 +- src/build.csproj | 5 --- 5 files changed, 5 insertions(+), 69 deletions(-) delete mode 100644 src/build.csproj diff --git a/build.cake b/build.cake index 60dbdc6..b75657e 100644 --- a/build.cake +++ b/build.cake @@ -11,7 +11,6 @@ var artifactsPath = Context.Directory("./.artifacts"); var target = Argument("target", "Default"); var configuration = Argument("configuration", "Release"); var configFilePath = "config.yml"; -var transversalBuildFilePath = $"{basePath}/build.csproj"; var taskConfigManager = new ProjectTaskConfigurationManager(); var projectDescriptors = ProjectLoader.Load(Context, configFilePath, basePath, configuration).Projects; var version = MinVer(settings => settings @@ -40,11 +39,6 @@ Task("Clean") Task("Restore") .Does(() => { - if (FileExists(transversalBuildFilePath)) - { - return; - } - DotNetRestore(basePath, new DotNetRestoreSettings { @@ -56,20 +50,6 @@ Task("Build-Project") .IsDependentOn("Restore") .Does(context => { - if (FileExists(transversalBuildFilePath)) - { - context.Information("Building projects using Transversal Build"); - - DotNetBuild(transversalBuildFilePath, new DotNetBuildSettings { - Configuration = configuration, - Verbosity = DotNetVerbosity.Minimal, - MSBuildSettings = new DotNetMSBuildSettings() - .TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error) - }); - - return; - } - foreach(var projectDescriptor in projectDescriptors) { if (!taskConfigManager.CanBuild(projectDescriptor.Config)) continue; @@ -90,24 +70,6 @@ Task("Test") .IsDependentOn("Build-Project") .Does(context => { - if (FileExists(transversalBuildFilePath)) - { - context.Information("Testing projects using Transversal Build"); - - DotNetTest(transversalBuildFilePath, new DotNetTestSettings { - Configuration = configuration, - NoRestore = true, - NoBuild = true, - TestAdapterPath = ".", - Loggers = new string[] { - "GitHubActions;report-warnings=false" - }, - Verbosity = DotNetVerbosity.Quiet - }); - - return; - } - foreach(var projectDescriptor in projectDescriptors) { if (!taskConfigManager.CanTest(projectDescriptor.Config)) continue; @@ -132,22 +94,6 @@ Task("Package") .IsDependentOn("Test") .Does(context => { - if (FileExists(transversalBuildFilePath)) - { - context.Information("Packing projects using Transversal Build"); - - context.DotNetPack(transversalBuildFilePath, new DotNetPackSettings { - Configuration = configuration, - NoRestore = true, - NoBuild = true, - OutputDirectory = artifactsPath, - MSBuildSettings = new DotNetMSBuildSettings() - .TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error) - }); - - return; - } - foreach(var projectDescriptor in projectDescriptors) { if (!taskConfigManager.CanPack(projectDescriptor.Config)) continue; diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index a711366..9d1e8f4 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -19,7 +19,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` | Remove the `System.Text.Json` package | In-box on net8+; the package only served `netstandard2.0`/`net6.0` | Keep it: NU1510 pruning warning, fails the warnings-as-errors build | | `Newtonsoft.Json` **13.0.4** | Latest stable. Apps that pin a lower version directly must bump it with 2.0.0 (NU1605) | Keep 13.0.3: no advisory against it, but stays behind latest | | Tests: `xunit.v3` 3.2.2, `xunit.runner.visualstudio` 3.1.5, FluentAssertions 7.2.2, `Microsoft.NET.Test.Sdk` 18.10.1, `GitHubActionsTestLogger` 2.4.1 | xUnit v2 is in maintenance. FluentAssertions 8 needs a commercial licence. Logger 3.x and `XunitXml.TestLogger` 8.x need Microsoft.Testing.Platform 2 (CS1705 against xunit.v3 3.2.2's 1.9.1); the XML logger was unused | xUnit 2.9.3 (as in Appy.Configuration); `xunit.v3` 4.x | -| Build tooling as Appy.Configuration: Cake 6.0.0, Cake.MinVer 4.0.0, Cake.Yaml 6.0.0, YamlDotNet 16.2.0, MinVer 2.3.0, traversal `src/build.csproj`, `.sln` kept | Same pipeline across repos; MinVer 2.3.0 keeps versioning unchanged | MinVer 8: new pre-release options, out of scope | +| Build tooling as Appy.Configuration: Cake 6.0.0, Cake.MinVer 4.0.0, Cake.Yaml 6.0.0, YamlDotNet 16.2.0, MinVer 2.3.0, `.sln` kept; `build.cake` builds the `config.yml` projects one by one | Same pipeline across repos; MinVer 2.3.0 keeps versioning unchanged | Traversal `src/build.csproj`: not adopted yet. MinVer 8: new pre-release options, out of scope | | CI installs only the SDK in `global.json` | SDK 10 builds the `net8.0` target from reference packs; tests run on `net10.0`; the Cake, MinVer and gpr tools roll forward | Also install 8.0.x (as Appy.Configuration does): not needed | | Package validation against 1.4.0 | Catches accidental API breaks; only the dropped TFMs are suppressed (PKV006) | None; Appy.Configuration has no validation | | `MinVerMinimumMajorMinor` 2.0 (MSBuild and `build.cake`) | The master push that follows the merge publishes a preview. Without this it is `1.4.1-preview`, carrying breaking changes. Cake computes the package path, so both must agree | Skip it and accept one misleading preview | @@ -37,9 +37,8 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` `TunnelVisionLabs.ReferenceAssemblyAnnotator`, `coverlet.collector`, `XunitXml.TestLogger`) and the `Version="$(...)"` attributes in the test csproj. Test: same 6 tests pass. The run reports a non-zero count. -- [x] 3. `chore(build): upgrade cake to 6.0.0 with traversal build`. Update `dotnet-tools.json`, - `build.cake` (addins, traversal branch), `global.json` `msbuild-sdks` (Traversal 4.1.82), and add - `src/build.csproj`. `config.yml` still drives packing and publishing. +- [x] 3. `chore(build): upgrade cake to 6.0.0`. Update `dotnet-tools.json` and the `build.cake` + addins. `config.yml` still drives build, test, pack and publish (no traversal build). Test: `dotnet tool restore && dotnet cake` is green. `.artifacts/` holds 3 nupkgs with `lib/net8.0` and `lib/net10.0` only. - [x] 4. `ci: build and publish with .NET 10 SDK`. In `ci.yaml` and `publish.yaml`, move to @@ -77,11 +76,10 @@ move `PackageValidationBaselineVersion` to 2.0.0 and delete the `CompatibilitySu ## Key Files ``` -global.json # SDK 10 + Traversal SDK +global.json # SDK 10 dotnet-tools.json # Cake 6 build.cake # Cake pipeline, MinVer settings config.yml # projects to build, test and pack -src/build.csproj # traversal project (new) src/Directory.Build.props # package metadata src/Directory.Build.targets # package validation, MinVer settings src/*/CompatibilitySuppressions.xml # PKV006 for the dropped TFMs (new) diff --git a/global.json b/global.json index cbe7ff9..d92a294 100644 --- a/global.json +++ b/global.json @@ -2,8 +2,5 @@ "sdk": { "version": "10.0.103", "rollForward": "latestFeature" - }, - "msbuild-sdks": { - "Microsoft.Build.Traversal": "4.1.82" } } \ No newline at end of file diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 4ea0d24..fb4e920 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -1,5 +1,5 @@ - + true 1.4.0 diff --git a/src/build.csproj b/src/build.csproj deleted file mode 100644 index 101d66b..0000000 --- a/src/build.csproj +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file From 1bdc58aedd8fd09a98edd21e5db1c53afdf7f9fe Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Wed, 30 Sep 2026 17:47:34 +0100 Subject: [PATCH 16/23] chore(build): migrate the solution to slnx --- .editorconfig | 5 +-- .gitignore | 2 -- AGENTS.md | 4 +-- CLAUDE.md | 2 +- docs/plans/001-net10-migration.md | 6 ++-- src/Appy.Spatial.GeoJSON.slnx | 22 ++++++++++++ src/Appy.Spatial.Geojson.sln | 58 ------------------------------- 7 files changed, 30 insertions(+), 69 deletions(-) create mode 100644 src/Appy.Spatial.GeoJSON.slnx delete mode 100644 src/Appy.Spatial.Geojson.sln diff --git a/.editorconfig b/.editorconfig index 380d16d..2668794 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,13 +8,10 @@ indent_size = 4 insert_final_newline = false trim_trailing_whitespace = true -[*.sln] -indent_style = tab - [*.{csproj,vbproj,vcxproj,vcxproj.filters}] indent_size = 2 -[*.{xml,config,props,targets,nuspec,ruleset}] +[*.{xml,config,props,targets,nuspec,ruleset,slnx}] indent_size = 2 [*.{yml,yaml}] diff --git a/.gitignore b/.gitignore index 286d5f7..4d0e373 100644 --- a/.gitignore +++ b/.gitignore @@ -21,7 +21,6 @@ dotnet-install.sh* .vs/ .vscode/ launchSettings.json -*.sln.ide/ # Rider src/.idea/**/workspace.xml @@ -41,7 +40,6 @@ src/.idea/**/uiDesigner.xml # User-specific files *.suo *.user -*.sln.docstates *.userprefs *.GhostDoc.xml *StyleCop.Cache diff --git a/AGENTS.md b/AGENTS.md index b5156e7..c9d5ca1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,8 +20,8 @@ Architecture and CI: [docs/Architecture.md](docs/Architecture.md). ```bash dotnet tool restore # Cake, MinVer CLI, gpr dotnet cake # Default target: Clean, Build, Test, Package (.artifacts/) -dotnet test src/Appy.Spatial.Geojson.sln -dotnet test src/Appy.Spatial.Geojson.sln --filter "FullyQualifiedName~SerialisationTests.ShouldRoundTripPoint" +dotnet test src/Appy.Spatial.GeoJSON.slnx +dotnet test src/Appy.Spatial.GeoJSON.slnx --filter "FullyQualifiedName~SerialisationTests.ShouldRoundTripPoint" ``` - `build.cake` builds the projects listed in `config.yml` (`Type: Package` or `Type: Test`); add new diff --git a/CLAUDE.md b/CLAUDE.md index 62212b2..8a22ff4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,7 +7,7 @@ ```bash dotnet tool restore dotnet cake # Default: clean, build, test, pack into .artifacts/ -dotnet test src/Appy.Spatial.Geojson.sln # tests only +dotnet test src/Appy.Spatial.GeoJSON.slnx # tests only ``` Never run the `Publish` cake target or `dotnet nuget push`: publishing happens only in GitHub Actions. diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index 9d1e8f4..82a830f 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -19,7 +19,8 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` | Remove the `System.Text.Json` package | In-box on net8+; the package only served `netstandard2.0`/`net6.0` | Keep it: NU1510 pruning warning, fails the warnings-as-errors build | | `Newtonsoft.Json` **13.0.4** | Latest stable. Apps that pin a lower version directly must bump it with 2.0.0 (NU1605) | Keep 13.0.3: no advisory against it, but stays behind latest | | Tests: `xunit.v3` 3.2.2, `xunit.runner.visualstudio` 3.1.5, FluentAssertions 7.2.2, `Microsoft.NET.Test.Sdk` 18.10.1, `GitHubActionsTestLogger` 2.4.1 | xUnit v2 is in maintenance. FluentAssertions 8 needs a commercial licence. Logger 3.x and `XunitXml.TestLogger` 8.x need Microsoft.Testing.Platform 2 (CS1705 against xunit.v3 3.2.2's 1.9.1); the XML logger was unused | xUnit 2.9.3 (as in Appy.Configuration); `xunit.v3` 4.x | -| Build tooling as Appy.Configuration: Cake 6.0.0, Cake.MinVer 4.0.0, Cake.Yaml 6.0.0, YamlDotNet 16.2.0, MinVer 2.3.0, `.sln` kept; `build.cake` builds the `config.yml` projects one by one | Same pipeline across repos; MinVer 2.3.0 keeps versioning unchanged | Traversal `src/build.csproj`: not adopted yet. MinVer 8: new pre-release options, out of scope | +| Build tooling as Appy.Configuration: Cake 6.0.0, Cake.MinVer 4.0.0, Cake.Yaml 6.0.0, YamlDotNet 16.2.0, MinVer 2.3.0; `build.cake` builds the `config.yml` projects one by one | Same pipeline across repos; MinVer 2.3.0 keeps versioning unchanged | Traversal `src/build.csproj`: not adopted yet. MinVer 8: new pre-release options, out of scope | +| Solution as `src/Appy.Spatial.GeoJSON.slnx` | SDK 10 format; the name now matches the package casing | Keep the classic solution format | | CI installs only the SDK in `global.json` | SDK 10 builds the `net8.0` target from reference packs; tests run on `net10.0`; the Cake, MinVer and gpr tools roll forward | Also install 8.0.x (as Appy.Configuration does): not needed | | Package validation against 1.4.0 | Catches accidental API breaks; only the dropped TFMs are suppressed (PKV006) | None; Appy.Configuration has no validation | | `MinVerMinimumMajorMinor` 2.0 (MSBuild and `build.cake`) | The master push that follows the merge publishes a preview. Without this it is `1.4.1-preview`, carrying breaking changes. Cake computes the package path, so both must agree | Skip it and accept one misleading preview | @@ -31,7 +32,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` to `net10.0`. Remove the `netstandard2.0` shims (`Nullable` package, `PackageDownload` `Microsoft.NETCore.App.Ref`, `AnnotatedReferenceAssemblyVersion`, per-project `LangVersion`) and the `System.Text.Json` package. `PackageTags` become `NET10;NET8`. - Test: the 6 `SerialisationTests` pass on `net10.0` (`dotnet test src/Appy.Spatial.Geojson.sln`). + Test: the 6 `SerialisationTests` pass on `net10.0` (`dotnet test src/Appy.Spatial.GeoJSON.slnx`). - [x] 2. `chore(deps): move tests to xunit v3`. Update `src/Directory.Packages.props` to the test stack above. Remove unused entries (`Moq`, `MartinCostello.Logging.XUnit`, `TunnelVisionLabs.ReferenceAssemblyAnnotator`, `coverlet.collector`, `XunitXml.TestLogger`) and the @@ -84,6 +85,7 @@ src/Directory.Build.props # package metadata src/Directory.Build.targets # package validation, MinVer settings src/*/CompatibilitySuppressions.xml # PKV006 for the dropped TFMs (new) src/Directory.Packages.props # central package versions +src/Appy.Spatial.GeoJSON.slnx # solution (new, replaces the classic one) src/*/*.csproj # target frameworks .github/workflows/ci.yaml # PR build .github/workflows/publish.yaml # publish on master push or tag diff --git a/src/Appy.Spatial.GeoJSON.slnx b/src/Appy.Spatial.GeoJSON.slnx new file mode 100644 index 0000000..455fa56 --- /dev/null +++ b/src/Appy.Spatial.GeoJSON.slnx @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Appy.Spatial.Geojson.sln b/src/Appy.Spatial.Geojson.sln deleted file mode 100644 index edadb30..0000000 --- a/src/Appy.Spatial.Geojson.sln +++ /dev/null @@ -1,58 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Appy.Spatial.GeoJSON", "Appy.Spatial.GeoJSON\Appy.Spatial.GeoJSON.csproj", "{50962C2D-ADFE-423C-9DD6-3F0B8FF29D5F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Appy.Spatial.GeoJSON.Newtonsoft", "Appy.Spatial.GeoJSON.Newtonsoft\Appy.Spatial.GeoJSON.Newtonsoft.csproj", "{0256875D-1997-4B81-8E33-243B40F68B2B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Appy.Spatial.GeoJSON.TextJson", "Appy.Spatial.GeoJSON.TextJson\Appy.Spatial.GeoJSON.TextJson.csproj", "{CDFFB90F-9DE9-4EE6-B088-ABDCE0AFCE26}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1. Project", "1. Project", "{09A46B69-0EEB-4CF7-8857-BFC27F600C45}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2. Packages", "2. Packages", "{12D32EB2-3BA6-4ECC-801A-C379BBE2C34F}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "99. Tests", "99. Tests", "{F376B16D-2CBD-4D07-858E-7791A9FBAD4D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Appy.Spatial.GeoJSON.Tests", "Appy.Spatial.GeoJSON.Tests\Appy.Spatial.GeoJSON.Tests.csproj", "{886A1237-45D1-4580-9B8F-0531B5CC297B}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7F6AB84F-685C-4465-BB36-2832CB151EFF}" - ProjectSection(SolutionItems) = preProject - Directory.Build.props = Directory.Build.props - Directory.Build.targets = Directory.Build.targets - ..\build.cake = ..\build.cake - ..\config.yml = ..\config.yml - ..\dotnet-tools.json = ..\dotnet-tools.json - ..\functions.cake = ..\functions.cake - ..\global.json = ..\global.json - Directory.Packages.props = Directory.Packages.props - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {50962C2D-ADFE-423C-9DD6-3F0B8FF29D5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {50962C2D-ADFE-423C-9DD6-3F0B8FF29D5F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {50962C2D-ADFE-423C-9DD6-3F0B8FF29D5F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {50962C2D-ADFE-423C-9DD6-3F0B8FF29D5F}.Release|Any CPU.Build.0 = Release|Any CPU - {0256875D-1997-4B81-8E33-243B40F68B2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0256875D-1997-4B81-8E33-243B40F68B2B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0256875D-1997-4B81-8E33-243B40F68B2B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0256875D-1997-4B81-8E33-243B40F68B2B}.Release|Any CPU.Build.0 = Release|Any CPU - {CDFFB90F-9DE9-4EE6-B088-ABDCE0AFCE26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CDFFB90F-9DE9-4EE6-B088-ABDCE0AFCE26}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CDFFB90F-9DE9-4EE6-B088-ABDCE0AFCE26}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CDFFB90F-9DE9-4EE6-B088-ABDCE0AFCE26}.Release|Any CPU.Build.0 = Release|Any CPU - {886A1237-45D1-4580-9B8F-0531B5CC297B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {886A1237-45D1-4580-9B8F-0531B5CC297B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {886A1237-45D1-4580-9B8F-0531B5CC297B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {886A1237-45D1-4580-9B8F-0531B5CC297B}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {50962C2D-ADFE-423C-9DD6-3F0B8FF29D5F} = {09A46B69-0EEB-4CF7-8857-BFC27F600C45} - {0256875D-1997-4B81-8E33-243B40F68B2B} = {12D32EB2-3BA6-4ECC-801A-C379BBE2C34F} - {CDFFB90F-9DE9-4EE6-B088-ABDCE0AFCE26} = {12D32EB2-3BA6-4ECC-801A-C379BBE2C34F} - {886A1237-45D1-4580-9B8F-0531B5CC297B} = {F376B16D-2CBD-4D07-858E-7791A9FBAD4D} - EndGlobalSection -EndGlobal From b9b906af13ef718ba1ace092b2bdd6e7ea164319 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Thu, 1 Oct 2026 10:26:42 +0100 Subject: [PATCH 17/23] chore(build): update cake to 6.3.0 --- docs/plans/001-net10-migration.md | 6 +++--- dotnet-tools.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index 82a830f..3601506 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -19,7 +19,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` | Remove the `System.Text.Json` package | In-box on net8+; the package only served `netstandard2.0`/`net6.0` | Keep it: NU1510 pruning warning, fails the warnings-as-errors build | | `Newtonsoft.Json` **13.0.4** | Latest stable. Apps that pin a lower version directly must bump it with 2.0.0 (NU1605) | Keep 13.0.3: no advisory against it, but stays behind latest | | Tests: `xunit.v3` 3.2.2, `xunit.runner.visualstudio` 3.1.5, FluentAssertions 7.2.2, `Microsoft.NET.Test.Sdk` 18.10.1, `GitHubActionsTestLogger` 2.4.1 | xUnit v2 is in maintenance. FluentAssertions 8 needs a commercial licence. Logger 3.x and `XunitXml.TestLogger` 8.x need Microsoft.Testing.Platform 2 (CS1705 against xunit.v3 3.2.2's 1.9.1); the XML logger was unused | xUnit 2.9.3 (as in Appy.Configuration); `xunit.v3` 4.x | -| Build tooling as Appy.Configuration: Cake 6.0.0, Cake.MinVer 4.0.0, Cake.Yaml 6.0.0, YamlDotNet 16.2.0, MinVer 2.3.0; `build.cake` builds the `config.yml` projects one by one | Same pipeline across repos; MinVer 2.3.0 keeps versioning unchanged | Traversal `src/build.csproj`: not adopted yet. MinVer 8: new pre-release options, out of scope | +| Build tooling as Appy.Configuration: Cake 6.3.0, Cake.MinVer 4.0.0, Cake.Yaml 6.0.0, YamlDotNet 16.2.0, MinVer 2.3.0; `build.cake` builds the `config.yml` projects one by one | Same pipeline across repos; MinVer 2.3.0 keeps versioning unchanged | Traversal `src/build.csproj`: not adopted yet. MinVer 8: new pre-release options, out of scope | | Solution as `src/Appy.Spatial.GeoJSON.slnx` | SDK 10 format; the name now matches the package casing | Keep the classic solution format | | CI installs only the SDK in `global.json` | SDK 10 builds the `net8.0` target from reference packs; tests run on `net10.0`; the Cake, MinVer and gpr tools roll forward | Also install 8.0.x (as Appy.Configuration does): not needed | | Package validation against 1.4.0 | Catches accidental API breaks; only the dropped TFMs are suppressed (PKV006) | None; Appy.Configuration has no validation | @@ -38,7 +38,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` `TunnelVisionLabs.ReferenceAssemblyAnnotator`, `coverlet.collector`, `XunitXml.TestLogger`) and the `Version="$(...)"` attributes in the test csproj. Test: same 6 tests pass. The run reports a non-zero count. -- [x] 3. `chore(build): upgrade cake to 6.0.0`. Update `dotnet-tools.json` and the `build.cake` +- [x] 3. `chore(build): upgrade cake to 6.0.0`, then 6.3.0. Update `dotnet-tools.json` and the `build.cake` addins. `config.yml` still drives build, test, pack and publish (no traversal build). Test: `dotnet tool restore && dotnet cake` is green. `.artifacts/` holds 3 nupkgs with `lib/net8.0` and `lib/net10.0` only. @@ -78,7 +78,7 @@ move `PackageValidationBaselineVersion` to 2.0.0 and delete the `CompatibilitySu ``` global.json # SDK 10 -dotnet-tools.json # Cake 6 +dotnet-tools.json # Cake 6.3.0 build.cake # Cake pipeline, MinVer settings config.yml # projects to build, test and pack src/Directory.Build.props # package metadata diff --git a/dotnet-tools.json b/dotnet-tools.json index 60f01ea..507eff5 100644 --- a/dotnet-tools.json +++ b/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "cake.tool": { - "version": "6.0.0", + "version": "6.3.0", "commands": [ "dotnet-cake" ] From 88559f46736aa51438bd5a76d9ff2be48c4c5b8d Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Thu, 1 Oct 2026 11:18:44 +0100 Subject: [PATCH 18/23] ci: hash the tool and package manifests in the cache key --- .github/workflows/ci.yaml | 4 ++-- .github/workflows/publish.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d4b9188..a037a62 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -22,7 +22,7 @@ jobs: uses: actions/cache@v5 with: path: ${{ env.NUGET_PACKAGES }} - key: ${{ runner.os }}-nuget-${{ hashFiles('.config/dotnet-tools.json', '**/packages.lock.json') }} + key: ${{ runner.os }}-nuget-${{ hashFiles('dotnet-tools.json', 'src/Directory.Packages.props') }} restore-keys: ${{ runner.os }}-nuget- - name: Setup .NET SDK (global.json) @@ -61,7 +61,7 @@ jobs: uses: actions/cache@v5 with: path: ${{ env.NUGET_PACKAGES }} - key: ${{ runner.os }}-nuget-${{ hashFiles('.config/dotnet-tools.json', '**/packages.lock.json') }} + key: ${{ runner.os }}-nuget-${{ hashFiles('dotnet-tools.json', 'src/Directory.Packages.props') }} restore-keys: ${{ runner.os }}-nuget- - name: Setup .NET SDK (global.json) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 482be12..d8f0aef 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -29,7 +29,7 @@ jobs: uses: actions/cache@v5 with: path: ${{ env.NUGET_PACKAGES }} - key: ${{ runner.os }}-nuget-${{ hashFiles('.config/dotnet-tools.json', '**/packages.lock.json') }} + key: ${{ runner.os }}-nuget-${{ hashFiles('dotnet-tools.json', 'src/Directory.Packages.props') }} restore-keys: ${{ runner.os }}-nuget- - name: Setup .NET SDK (global.json) From bb11a525d41b84d73b61fb19e37e1f2ed85e5b27 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Thu, 1 Oct 2026 11:18:44 +0100 Subject: [PATCH 19/23] test: run the tests on net8.0 too --- .github/workflows/ci.yaml | 10 ++++++++-- .github/workflows/publish.yaml | 5 ++++- .../Appy.Spatial.GeoJSON.Tests.csproj | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a037a62..b511f7d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -25,8 +25,11 @@ jobs: key: ${{ runner.os }}-nuget-${{ hashFiles('dotnet-tools.json', 'src/Directory.Packages.props') }} restore-keys: ${{ runner.os }}-nuget- - - name: Setup .NET SDK (global.json) + - name: Setup .NET SDK (global.json + .NET 8 for tests) uses: actions/setup-dotnet@v5 + with: + global-json-file: global.json + dotnet-version: 8.0.x - name: Integration Tests shell: bash @@ -64,8 +67,11 @@ jobs: key: ${{ runner.os }}-nuget-${{ hashFiles('dotnet-tools.json', 'src/Directory.Packages.props') }} restore-keys: ${{ runner.os }}-nuget- - - name: Setup .NET SDK (global.json) + - name: Setup .NET SDK (global.json + .NET 8 for tests) uses: actions/setup-dotnet@v5 + with: + global-json-file: global.json + dotnet-version: 8.0.x - name: Integration Tests shell: bash diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index d8f0aef..144de40 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -32,8 +32,11 @@ jobs: key: ${{ runner.os }}-nuget-${{ hashFiles('dotnet-tools.json', 'src/Directory.Packages.props') }} restore-keys: ${{ runner.os }}-nuget- - - name: Setup .NET SDK (global.json) + - name: Setup .NET SDK (global.json + .NET 8 for tests) uses: actions/setup-dotnet@v5 + with: + global-json-file: global.json + dotnet-version: 8.0.x - name: Publish shell: bash diff --git a/src/Appy.Spatial.GeoJSON.Tests/Appy.Spatial.GeoJSON.Tests.csproj b/src/Appy.Spatial.GeoJSON.Tests/Appy.Spatial.GeoJSON.Tests.csproj index 651aadc..24e3a9c 100644 --- a/src/Appy.Spatial.GeoJSON.Tests/Appy.Spatial.GeoJSON.Tests.csproj +++ b/src/Appy.Spatial.GeoJSON.Tests/Appy.Spatial.GeoJSON.Tests.csproj @@ -1,7 +1,7 @@ - net10.0 + net10.0;net8.0 Exe false From ec54c06c09170369c3ca02866256014eee0472c2 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Thu, 1 Oct 2026 11:18:44 +0100 Subject: [PATCH 20/23] build: restore from nuget.org only --- nuget.config | 7 +++++++ src/Directory.Build.props | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 nuget.config diff --git a/nuget.config b/nuget.config new file mode 100644 index 0000000..4d736c1 --- /dev/null +++ b/nuget.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/Directory.Build.props b/src/Directory.Build.props index a3cf9c0..52246c3 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -28,7 +28,7 @@ - 1571;1572;1573;1574;1591;NU1507 + 1571;1572;1573;1574;1591 From 9e7f4d2555b5de4ced8c9537faa7338623d6d1ac Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Thu, 1 Oct 2026 11:19:39 +0100 Subject: [PATCH 21/23] chore(deps): drop the Source Link package --- src/Directory.Build.props | 1 - src/Directory.Packages.props | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 52246c3..8f4f386 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -39,7 +39,6 @@ - diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 86d6888..0141114 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -5,7 +5,6 @@ - From 7655451023961af3b06a0f2e3b2cd99010ee6981 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Thu, 1 Oct 2026 11:19:54 +0100 Subject: [PATCH 22/23] docs(plan): apply review comments --- AGENTS.md | 9 ++++++--- docs/plans/001-net10-migration.md | 14 ++++++++------ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index c9d5ca1..c07f064 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -34,12 +34,15 @@ dotnet test src/Appy.Spatial.GeoJSON.slnx --filter "FullyQualifiedName~Serialisa - **Central package management**: versions live in `src/Directory.Packages.props`; `PackageReference` items carry no `Version`. Framework-specific versions use a `Condition` on `$(TargetFramework)`. -- **Shared metadata**: package info, SourceLink and MinVer are in `src/Directory.Build.props`. +- **Shared metadata**: package info, Source Link settings (built into the SDK) and MinVer are in + `src/Directory.Build.props`. - **Versioning**: MinVer derives the version from git tags (`1.4.0`). No version is stored in files. - **Package validation**: `dotnet pack` checks each package against the last release (`PackageValidationBaselineVersion` in `src/Directory.Build.targets`). API breaks fail the build. -- **Tests**: xUnit + FluentAssertions. Every geometry round-trips through both serializers, as the - base type and the concrete type, bare and inside a `Feature`. Keep both converter packages in step. +- **Tests**: xUnit v3 + FluentAssertions, run on `net10.0` and `net8.0`. Every geometry round-trips + through both serializers, as the base type and the concrete type, bare and inside a `Feature`. + Keep both converter packages in step. +- **Package source**: `nuget.config` restores from nuget.org only. - **Target frameworks** are set per `.csproj`; the SDK is pinned in `global.json`. - **Style**: `.editorconfig` (4 spaces, 2 for XML/JSON/YAML, CRLF). File-scoped namespaces. - **Public repo**: no secrets, internal hostnames or private feed URLs in code, docs or commits. diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index 3601506..15e5f7a 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -5,8 +5,8 @@ ## Summary -Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, `net6.0` and -`netstandard2.0`, and bring the Cake build, GitHub Actions and test stack in line with +Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net6.0` and `netstandard2.0`, +and bring the Cake build, GitHub Actions and test stack in line with [Appy.Configuration](https://github.com/YellowLineParking/Appy.Configuration). Released as **2.0.0**. No public API change. @@ -14,14 +14,15 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` | Decision | Context | Alternatives Considered | |----------|---------|------------------------| -| Libraries `net10.0;net8.0`, tests `net10.0` | The two LTS releases. `net9.0` apps resolve the `net8.0` asset; `net6.0` is out of support | Also `net9.0`: no API gain. Keep `netstandard2.0`: keeps the nullable shim and the System.Text.Json package for no current need | +| Libraries `net10.0;net8.0`, tests `net10.0;net8.0` | The two LTS releases. `net9.0` apps resolve the `net8.0` asset; `net6.0` is out of support. Tests run on both because `net8.0` uses the in-box System.Text.Json 8 | Also `net9.0`: no API gain. Keep `netstandard2.0`: keeps the nullable shim and the System.Text.Json package for no current need | | Version **2.0.0** | Dropping `netstandard2.0` ends .NET Framework and pre-net8 support: breaking under SemVer. Those users stay on 1.4.x | Minor bump (Appy.Configuration used 1.2.0 for the same drop): hides the break | | Remove the `System.Text.Json` package | In-box on net8+; the package only served `netstandard2.0`/`net6.0` | Keep it: NU1510 pruning warning, fails the warnings-as-errors build | | `Newtonsoft.Json` **13.0.4** | Latest stable. Apps that pin a lower version directly must bump it with 2.0.0 (NU1605) | Keep 13.0.3: no advisory against it, but stays behind latest | | Tests: `xunit.v3` 3.2.2, `xunit.runner.visualstudio` 3.1.5, FluentAssertions 7.2.2, `Microsoft.NET.Test.Sdk` 18.10.1, `GitHubActionsTestLogger` 2.4.1 | xUnit v2 is in maintenance. FluentAssertions 8 needs a commercial licence. Logger 3.x and `XunitXml.TestLogger` 8.x need Microsoft.Testing.Platform 2 (CS1705 against xunit.v3 3.2.2's 1.9.1); the XML logger was unused | xUnit 2.9.3 (as in Appy.Configuration); `xunit.v3` 4.x | -| Build tooling as Appy.Configuration: Cake 6.3.0, Cake.MinVer 4.0.0, Cake.Yaml 6.0.0, YamlDotNet 16.2.0, MinVer 2.3.0; `build.cake` builds the `config.yml` projects one by one | Same pipeline across repos; MinVer 2.3.0 keeps versioning unchanged | Traversal `src/build.csproj`: not adopted yet. MinVer 8: new pre-release options, out of scope | +| Build tooling as Appy.Configuration: Cake 6.3.0, Cake.MinVer 4.0.0, Cake.Yaml 6.0.0, YamlDotNet 16.2.0, MinVer 2.3.0; Source Link from the SDK (no `Microsoft.SourceLink.GitHub` package); `build.cake` builds the `config.yml` projects one by one | Same pipeline across repos; MinVer 2.3.0 keeps versioning unchanged | Traversal `src/build.csproj`: not adopted yet. MinVer 8: new pre-release options, out of scope | | Solution as `src/Appy.Spatial.GeoJSON.slnx` | SDK 10 format; the name now matches the package casing | Keep the classic solution format | -| CI installs only the SDK in `global.json` | SDK 10 builds the `net8.0` target from reference packs; tests run on `net10.0`; the Cake, MinVer and gpr tools roll forward | Also install 8.0.x (as Appy.Configuration does): not needed | +| CI installs the SDK in `global.json` plus 8.0.x | SDK 10 builds both targets; 8.0.x provides the .NET 8 runtime for the `net8.0` test run; the Cake, MinVer and gpr tools roll forward | SDK 10 only: leaves the `net8.0` assets untested | +| `nuget.config` with nuget.org only | CPM raises NU1507 when a machine has several package sources; one repo-level source keeps restores reproducible | Suppress NU1507 (as Appy.Configuration does): hides where packages come from | | Package validation against 1.4.0 | Catches accidental API breaks; only the dropped TFMs are suppressed (PKV006) | None; Appy.Configuration has no validation | | `MinVerMinimumMajorMinor` 2.0 (MSBuild and `build.cake`) | The master push that follows the merge publishes a preview. Without this it is `1.4.1-preview`, carrying breaking changes. Cake computes the package path, so both must agree | Skip it and accept one misleading preview | @@ -60,7 +61,7 @@ Move the three packages to `net10.0;net8.0` on the .NET 10 SDK, drop `net9.0`, ` ## Verification -- [x] `dotnet cake` (Default target) green locally on SDK 10, warnings as errors, 6/6 tests. +- [x] `dotnet cake` (Default target) green locally on SDK 10, warnings as errors, 6/6 tests on net10.0 and net8.0. - [x] Nuspecs: TextJson has no `System.Text.Json` dependency; Newtonsoft depends on `Newtonsoft.Json` >= 13.0.4; groups only for net8.0 and net10.0. - [x] Package validation passes with only PKV006 suppressed. @@ -79,6 +80,7 @@ move `PackageValidationBaselineVersion` to 2.0.0 and delete the `CompatibilitySu ``` global.json # SDK 10 dotnet-tools.json # Cake 6.3.0 +nuget.config # nuget.org as the only package source (new) build.cake # Cake pipeline, MinVer settings config.yml # projects to build, test and pack src/Directory.Build.props # package metadata From 92f070ad89b7772355773559c1df7ad17244f590 Mon Sep 17 00:00:00 2001 From: Jorge Rodriguez Galan Date: Thu, 1 Oct 2026 11:25:34 +0100 Subject: [PATCH 23/23] docs(plan): align tasks with the net8.0 test run --- docs/plans/001-net10-migration.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/plans/001-net10-migration.md b/docs/plans/001-net10-migration.md index 15e5f7a..ea160c5 100644 --- a/docs/plans/001-net10-migration.md +++ b/docs/plans/001-net10-migration.md @@ -30,10 +30,11 @@ and bring the Cake build, GitHub Actions and test stack in line with - [x] 1. `feat(net10): target net10.0 and net8.0`. `global.json` SDK `10.0.103`, `rollForward: latestFeature`. The three library csproj files go to `net10.0;net8.0`, tests - to `net10.0`. Remove the `netstandard2.0` shims (`Nullable` package, `PackageDownload` + to `net10.0` (later `net10.0;net8.0`, from review). Remove the `netstandard2.0` shims (`Nullable` package, `PackageDownload` `Microsoft.NETCore.App.Ref`, `AnnotatedReferenceAssemblyVersion`, per-project `LangVersion`) and the `System.Text.Json` package. `PackageTags` become `NET10;NET8`. - Test: the 6 `SerialisationTests` pass on `net10.0` (`dotnet test src/Appy.Spatial.GeoJSON.slnx`). + Test: the 6 `SerialisationTests` pass on `net10.0` and `net8.0` + (`dotnet test src/Appy.Spatial.GeoJSON.slnx`). - [x] 2. `chore(deps): move tests to xunit v3`. Update `src/Directory.Packages.props` to the test stack above. Remove unused entries (`Moq`, `MartinCostello.Logging.XUnit`, `TunnelVisionLabs.ReferenceAssemblyAnnotator`, `coverlet.collector`, `XunitXml.TestLogger`) and the @@ -45,7 +46,7 @@ and bring the Cake build, GitHub Actions and test stack in line with `lib/net8.0` and `lib/net10.0` only. - [x] 4. `ci: build and publish with .NET 10 SDK`. In `ci.yaml` and `publish.yaml`, move to `actions/checkout@v6`, `actions/cache@v5` and `actions/setup-dotnet@v5`, SDK from `global.json` - only. Triggers stay as they are. + plus 8.0.x for the `net8.0` test run (from review). Triggers stay as they are. Test: PR checks green on Windows, macOS and Linux. - [x] 5. `build: validate packages against 1.4.0`. Add `EnablePackageValidation` and `PackageValidationBaselineVersion` 1.4.0 to packable projects. Pack fails first on PKV006 (the