Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,14 @@ swaggerdiff snapshot --assembly ./bin/Release/net8.0/MyApi.dll

| Option | Default | Description |
|--------|---------|-------------|
| `--project` | auto-discover | Path to a `.csproj` file. If omitted, finds the single `.csproj` in the current directory |
| `--assembly` | — | Direct path to a built DLL. Overrides `--project` and skips the build step |
| `--project` | auto-discover | Path to one or more `.csproj` files. Repeat for multiple projects |
| `--assembly` | — | Direct path to a built DLL. Overrides `--project` and skips the build step (single project only) |
| `-c`, `--configuration` | `Debug` | Build configuration (used with `--project`) |
| `--no-build` | `false` | Skip the build step (assumes the project was already built) |
| `--output` | `Docs/Versions` | Directory where snapshots are written |
| `--output` | `Docs/Versions` | Directory where snapshots are written (relative to each project directory) |
| `--doc-name` | `v1` | Swagger document name passed to `ISwaggerProvider.GetSwagger()` |
| `--exclude` | — | Project names to exclude from auto-discovery (without `.csproj`). Repeat for multiple |
| `--exclude-dir` | — | Directory names to exclude from auto-discovery. Repeat for multiple |

The command will:

Expand All @@ -183,6 +185,35 @@ The command will:
4. **Compare** with the latest existing snapshot (normalizing away the `info.version` field).
5. If the API surface has changed, **write a new timestamped file** (e.g. `doc_20250612143022.json`). If nothing changed, print "No API changes detected" and exit cleanly.

### Multiple projects

When run from a solution directory (or any directory without a single `.csproj`), the tool automatically discovers all ASP.NET Core web projects by scanning up to 2 levels deep for `.csproj` files with `Sdk="Microsoft.NET.Sdk.Web"`.

```bash
# From the solution root — discovers and snapshots all web API projects
swaggerdiff snapshot

# Explicit multi-project
swaggerdiff snapshot \
--project ./src/AdminApi/AdminApi.csproj \
--project ./src/TenantApi/TenantApi.csproj

# Auto-discover but skip specific projects or directories
swaggerdiff snapshot --exclude MyApi.Tests --exclude-dir tests
```

Each project's snapshots are written to `Docs/Versions/` relative to that project's own directory:

```
src/
ServiceOneApi/
Docs/Versions/doc_20250612143022.json
ServiceTwoApi/
Docs/Versions/doc_20250612143022.json
```

The tool skips `bin/`, `obj/`, `.git/`, and other well-known non-project directories automatically.

### Dry-run mode — skipping external dependencies

When the CLI tool loads your application to generate a snapshot, your `Program.cs` entry point runs in full. This means any startup code that connects to external services (secret vaults, databases, message brokers, etc.) will execute and may fail if those services are unreachable.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
Expand Down Expand Up @@ -46,7 +47,7 @@ public static WebApplication UseSwaggerDiff(this WebApplication app)
{
var versions = service.GetAvailableVersions();
return Results.Ok(new { isSuccess = true, data = versions });
}).ExcludeFromDescription();
}).ExcludeFromDescription().AllowAnonymous();

app.MapPost("/api-docs/compare", async (ApiDiffRequest request, SwaggerDiffService service) =>
{
Expand All @@ -55,7 +56,7 @@ public static WebApplication UseSwaggerDiff(this WebApplication app)
return result == null
? Results.Ok(new { isSuccess = false, message = "Failed to retrieve the diff." })
: Results.Ok(new { isSuccess = true, data = result });
}).ExcludeFromDescription();
}).ExcludeFromDescription().AllowAnonymous();

// Serve the Swagger Diff UI
app.Map(options.RoutePrefix, swaggerDiffApp =>
Expand Down
Loading