diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..89045f8 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,65 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Overview + +NSchema.Build is the build/release pipeline tool for NSchema, written as a .NET 10 console +app. It orchestrates `dotnet` CLI steps (clean, format, restore, build, test, pack) and the +release process (versioning, changelog, git tag, GitHub release, NuGet publish). It is run +both locally and from CI, and is also packaged/published as the `NSchema.Build` NuGet package. + +## Commands + +Run the pipeline locally from the repo root: + +```bash +# CI build pipeline (clean → format → extract → version → changelog → restore → build → test) +dotnet run --project src/NSchema.Build/NSchema.Build.csproj -- build + +# Full release pipeline (adds pack → tag → GitHub release → NuGet publish) +dotnet run --project src/NSchema.Build/NSchema.Build.csproj -- deploy +``` + +Plain `dotnet build` / `dotnet test` work too, but there is no test project yet — `Steps/Test.cs` +just invokes `dotnet test`. `TreatWarningsAsErrors` is on, so warnings fail the build. + +Configuration comes from `appsettings.json` under the `Build` section, overridable via +environment variables using the `Build__` convention (e.g. `Build__ProjectFile`, +`Build__SkipVersion`). See `.github/workflows/cicd.yml` for the CI invocation. + +## Architecture + +The app is built on the **Hamelin** pipeline framework. `Program.cs` is the whole entry point: +it sets up DI, binds + validates `BuildOptions`, and dispatches the first CLI arg (`build` / +`deploy`) to an ordered chain of `.UseStep()` calls. To change what a pipeline does, edit the +step chain in `Program.cs`; to change *how* a stage behaves, edit the corresponding step. + +- **Steps** (`Steps/`) — each implements `Hamelin.IPipelineStep` with a single `Run(...)` + method and a `[DisplayName]`. They are registered automatically via + `AddStepsFromAssemblyContaining()`, so a new step just needs to be a class in the + assembly and then added to a chain in `Program.cs`. Dependencies (logger, options, command + runner, pipeline context) are constructor-injected. + +- **State passing** — steps share data through `IPipelineContext.State` (typed get/set), not + return values. `ExtractProject` parses the csproj and `context.State.Set(projectInfo)`; + later steps (`Version`, `Changelog`, etc.) call `context.State.Get()`. The same + context exposes `FileSystem` for file access. + +- **Shelling out** — all external commands go through `ICommandRunner` + (`CliWrapCommandRunner`, backed by CliWrap). Steps never call `Process` directly; inject + `ICommandRunner` and call `commands.Run("dotnet", [...], ct)`. + +- **Skip flags** — `Version` and `Changelog` honor `SkipVersion` / `SkipChangelog` on + `BuildOptions` (CI sets these to `true` since NSchema.Build versions itself manually). + +- **NuGet integration** — `Version` uses the `NuGet.Protocol` API directly against the feed + to guard that the project's version is new and strictly greater than the latest published + version. `NuGetLoggerAdapter` bridges NuGet's `ILogger` to `Microsoft.Extensions.Logging`. + +## Conventions + +- Central package management: all versions live in `Directory.Packages.props`; + `` entries in the csproj carry **no** `Version` attribute. +- `BuildOptions` is validated at startup (`ValidateOnStart`) — required config keys must be + present or the app fails fast before any step runs. \ No newline at end of file diff --git a/src/NSchema.Build/Program.cs b/src/NSchema.Build/Program.cs index 2bf9deb..8e3fe3d 100644 --- a/src/NSchema.Build/Program.cs +++ b/src/NSchema.Build/Program.cs @@ -35,6 +35,13 @@ .UseStep() .UseStep() .RunWithExitCode(), + ["verify"] => pipeline + .UseStep() + .UseStep() + .UseStep() + .UseStep() + .UseStep() + .RunWithExitCode(), ["deploy"] => pipeline .UseStep() .UseStep() @@ -53,6 +60,6 @@ static int Help() { - Console.Error.WriteLine("Usage: nschema-build "); + Console.Error.WriteLine("Usage: nschema-build "); return 1; }