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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ MAJOR.MINOR.PATCH
```
Version numbers are centrally managed through project build metadata so assemblies, future packages, and releases can share a consistent version identity.

See [ADR-0003: Record Release Surface and Distribution Strategy](0003-record-release-surface-and-distribution-strategy.md), for the current versioning and release strategy.

## Citation

Citation metadata is available in [CITATION.cff](CITATION.cff). GitHub can use this file to generate citation formats from the repository sidebar.
Expand Down
168 changes: 168 additions & 0 deletions docs/adr/0003-record-release-surface-and-distribution-strategy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# ADR-0003: Record Release Surface and Distribution Strategy

## Status

Accepted

## Context

The template is being prepared for a future `v1.0.0` release. After `1.0.0`, version numbers need to communicate compatibility expectations for developers who install, clone, scaffold, or maintain applications from the template.

This ADR records the release-readiness decisions needed before that stable release:

- What parts of the template are part of the SemVer public surface.
- How future changes should be classified as MAJOR, MINOR, or PATCH.
- Whether the stable distribution model is package installation or clone-and-modify.
- Which API versioning scheme is the default.
- Which container base image strategy the template follows.
- How repository metadata should cross-link related public works.

## Decision

Use this ADR as the release-readiness decision record for SemVer, template distribution, API versioning, container image strategy, and repository metadata cross-linking.

### Semantic Versioning Public Surface

The public SemVer surface includes template behavior that consumers are expected to rely on after `v1.0.0`:

- Generated project and folder layout.
- Template identity, short name, parameters, symbols, and source-name replacement behavior.
- Documented configuration key names and documented default values.
- Default API route conventions and API versioning behavior.
- Default middleware ordering and documented pipeline extension points.
- Documented container build and tag conventions.
- Public or protected class signatures documented for use by generated applications.
- Published documentation, release notes, and repository metadata that describe release behavior.

Internal implementation details remain changeable unless they are documented as extension points, generated into consumer applications, or required by customization guidance.

### Change Classification

Use the following rules after `v1.0.0`.

| Area | MAJOR | MINOR | PATCH |
|:---|:---|:---|:---|
| Scaffolded project layout | Rename, remove, or relocate generated projects, folders, files, namespaces, or startup entry points in a breaking way. | Add optional projects, examples, folders, or files without breaking existing assumptions. | Correct comments, formatting, documentation, or non-breaking file contents. |
| Template parameters and symbols | Rename, remove, invert, or materially change parameters, symbols, short names, or source-name replacement behavior. | Add optional parameters or symbols with safe defaults. | Fix parameter descriptions, constraints, or packaging metadata without behavior changes. |
| Configuration key names and defaults | Rename or remove documented keys, change value types, or change defaults in a way that materially changes runtime behavior. | Add optional keys, supported values, or provider-specific settings with compatible defaults. | Correct examples, validation messages, docs, or comments without changing documented behavior. |
| Default API route conventions | Change or remove documented route templates, default API version behavior, or canonical versioning conventions. | Add optional route forms, endpoint examples, or supported API versions while preserving existing routes. | Fix route docs, examples, or tests without changing route behavior. |
| Default middleware ordering | Reorder, remove, or replace documented middleware in a way that changes routing, error-handling, forwarded-header, or authorization behavior. | Add optional middleware or new documented extension points without breaking the existing order. | Fix ordering docs, tests, or narrow bugs while preserving the documented pipeline contract. |
| Container image tag conventions | Rename, remove, or redefine documented image names, tag forms, exposed ports, or supported runtime image family. | Add supported tags, image variants, or examples while preserving documented defaults. | Rebuild against compatible patch images or fix Docker docs without changing behavior. |
| Internal class signatures | Change documented public or protected signatures used by generated applications, extension points, tests, or examples in a breaking way. | Add optional overloads, extension methods, or helpers without breaking consumers. | Refactor private or internal details that are not documented consumer extension points. |

When a change is ambiguous, classify it by the effect on a consumer who already generated an application from the previous stable version. If their documented build, configuration, route usage, deployment script, or customization path breaks, treat the change as breaking unless a clear migration path exists.

### Template Distribution Model

The stable release direction is a published NuGet template package installable with `dotnet new install`.

Expected stable usage:

```powershell
dotnet new install <published-template-package-id>
dotnet new cdcavell-netcoreapp -n ContosoSecurityPortal
```

Clone-and-modify remains valid for source review, contribution, and preview use. Until the published package exists, documentation may continue to describe local installation from the repository root:

```powershell
dotnet new install ./
```

Documentation should clearly distinguish local preview installation from the intended stable package distribution path.

### Default API Versioning Scheme

Use URL segment API versioning as the canonical default for scaffolded API routes.

Default route convention:

```text
/api/v{version}/<resource>
```

The template also supports `X-API-Version` request header versioning as a secondary compatibility option.

Default behavior:

- Default API version: `1.0`.
- Canonical style: URL segment versioning.
- Optional compatibility style: `X-API-Version` request header.
- Assume default version when unspecified: enabled.
- Report API versions: enabled.

URL segment versioning is the default because it is visible in documentation, logs, browser testing, curl examples, and reverse proxy traces. Header versioning remains available when a consuming application prefers stable resource URLs.

### Container Base Image Strategy

Use Microsoft .NET container images with a multi-stage Dockerfile:

- `mcr.microsoft.com/dotnet/sdk:<major.minor>` for restore, build, and publish stages.
- `mcr.microsoft.com/dotnet/aspnet:<major.minor>` for the final runtime image.
- A non-root runtime user where supported by the selected .NET image.
- A documented default HTTP container port.

The documented local development image tag remains:

```text
projecttemplate-web:dev
```

If this repository later publishes reusable container images, release tags should align with repository release tags:

```text
vMAJOR.MINOR.PATCH
vMAJOR.MINOR
vMAJOR
```

Production consumers may pin image digests or use organization-approved base images in generated applications when their deployment policies require it.

### Repository Metadata Cross-Link Strategy

Repository metadata may cross-link related SSRN works when the relationship is described as related conceptual work, not as a software dependency or proof claim.

Use these relationship meanings:

- `isSupplementTo` when repository metadata points to a related conceptual paper or framework that the repository supplements as an applied software artifact.
- `isSupplementedBy` when an external paper or metadata record points back to the repository as a companion artifact.
- `references` when repository documentation explicitly cites a paper for background context.

The repository should not be described as implementing the Eden Hypothesis or ASI Backbone. It may be described as a practical software-architecture artifact that can be discussed alongside those works when the relationship is framed as conceptual, architectural, or illustrative.

## Consequences

Positive consequences:

- Future maintainers have a single release-surface reference before `v1.0.0`.
- Template consumers receive clearer compatibility expectations.
- Documentation can link to one ADR for versioning, packaging, API versioning, containers, and metadata decisions.
- Later issues can classify breaking and non-breaking work more consistently.

Trade-offs and risks:

- The ADR creates a stronger maintenance obligation after `v1.0.0`.
- Documentation can make otherwise internal details part of the practical public surface.
- Package distribution is the intended stable direction, but local installation remains necessary until package publishing is implemented.
- Supporting both URL segment and header API versioning requires documentation clarity.
- Container tag guidance may need revision if the repository later publishes official images.

## Alternatives Considered

- Treat the repository as clone-and-modify only: simpler, but weaker as a reusable template release.
- Record separate ADRs for each decision: more granular, but harder to use for the consolidated `v1.0.0` readiness decision set.
- Defer SemVer classification until package publication: avoids early commitment, but leaves readiness work without a decision baseline.
- Use header-only API versioning: keeps URLs stable, but makes examples and troubleshooting less obvious.
- Use custom container base images immediately: possible for specific organizations, but too opinionated for a public template baseline.
- Avoid SSRN/repository metadata cross-linking entirely: safest from an overclaiming perspective, but less useful for artifact discovery when the relationship is carefully bounded.

## Related References

- [Issue #140](https://github.com/cdcavell/NetCoreApplicationTemplate/issues/140)
- [Issue #138](https://github.com/cdcavell/NetCoreApplicationTemplate/issues/138)
- [`docs/articles/template-packaging.md`](../articles/template-packaging.md)
- [`docs/articles/api-versioning.md`](../articles/api-versioning.md)
- [`docs/articles/docker.md`](../articles/docker.md)
- [`docs/articles/deployment.md`](../articles/deployment.md)
- [`README.md`](https://github.com/cdcavell/NetCoreApplicationTemplate/blob/main/README.md)
- [`CITATION.cff`](https://github.com/cdcavell/NetCoreApplicationTemplate/blob/main/CITATION.cff)
1 change: 1 addition & 0 deletions docs/adr/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,4 @@ When an ADR is superseded, keep the original file and add a link to the replacin
|:---|:---|:---|
| [0001](0001-use-structured-serilog-logging.md) | Use structured Serilog logging | Accepted |
| [0002](0002-use-centralized-application-middleware-pipeline.md) | Use centralized application middleware pipeline | Accepted |
| [0003](0003-record-release-surface-and-distribution-strategy.md) | Record Release Surface and Distribution Strategy | Accepted |
3 changes: 3 additions & 0 deletions docs/adr/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@

- name: Use Centralized Application Middleware Pipeline
href: 0002-use-centralized-application-middleware-pipeline.md

- name: Record Release Surface and Distribution Strategy
href: 0003-record-release-surface-and-distribution-strategy.md
17 changes: 16 additions & 1 deletion docs/articles/api-versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,28 @@ public sealed class ExampleController : ControllerBase
}
```
If an endpoint should also support header-based versioning without the version in the URL, add an unversioned route as well.
```charp
```csharp
[Route("api/example")]
```

## Response Headers

When `ReportApiVersions` is enabled, responses include API version headers that help clients discover supported and deprecated versions.

## Release Compatibility

URL segment versioning is the canonical API versioning strategy for the template. The default route convention is:

```text
/api/v{version}/<resource>
```

Header-based versioning with `X-API-Version` remains available as a secondary compatibility option for applications that need stable resource URLs.

After the `v1.0.0` release, changes to documented API route conventions, default API version behavior, or the canonical versioning strategy should be reviewed as release-surface changes. Removing or changing documented route conventions may require a major version. Adding compatible route forms or additional supported API versions may be treated as minor version work.

See [ADR-0003: Record Release Surface and Distribution Strategy](../adr/0003-record-release-surface-and-distribution-strategy.md) for the release-surface decision.

## Production Guidance

For production APIs:
Expand All @@ -68,3 +82,4 @@ For production APIs:
- Keep old API versions available long enough for client migration.
- Document deprecated versions before removing them.
- Add tests for each supported API version.

4 changes: 3 additions & 1 deletion docs/articles/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ This article provides initial deployment guidance for applications created from

The template includes production-oriented defaults for middleware ordering, forwarded headers, security headers, rate limiting, health checks, structured logging, error handling, authentication foundations, and EF Core data access. These defaults are intended to provide a safe baseline, but every deployment environment should still be reviewed before production use.

See [ADR-0003: Record Release Surface and Distribution Strategy](../adr/0003-record-release-surface-and-distribution-strategy.md) for the release-surface decision.

## Deployment Review Areas

Before deploying an application created from this template, review the following areas:
Expand Down Expand Up @@ -217,4 +219,4 @@ Use this checklist before production release:
[ ] Confirm error responses do not expose sensitive implementation details.
```

Deployment readiness is environment-specific. Treat this article as a starting checklist, not a replacement for organization-specific production review.
Deployment readiness is environment-specific. Treat this article as a starting checklist, not a replacement for organization-specific production review.
18 changes: 18 additions & 0 deletions docs/articles/docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,23 @@ docker compose logs projecttemplate.web
```
The request should complete successfully, and forwarded header handling should not break normal local routing.

## Container Image Strategy

The application uses Microsoft .NET container images with a multi-stage Dockerfile. The SDK image is used for restore, build, and publish steps. The ASP.NET runtime image is used for the final application image.

The local development image tag is:

```text
projecttemplate-web:dev
```

This tag is intended for local development and testing. It is not a published production image contract.

Applications generated from the template may adapt the Dockerfile for production deployment. Production consumers may pin image digests, use organization-approved base images, or apply additional hardening based on their deployment requirements.

After the `v1.0.0` release, changes to documented image names, tag conventions, exposed ports, or runtime image strategy should be reviewed as release-surface changes.

See [ADR-0003: Record Release Surface and Distribution Strategy](../adr/0003-record-release-surface-and-distribution-strategy.md) for the release-surface decision.

## Notes
Do not commit generated SQLite databases, local logs, container volumes, secrets, or environment-specific credentials.
19 changes: 19 additions & 0 deletions docs/articles/template-packaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,22 @@ cd ContosoSecurityPortal
dotnet build
dotnet test
```

## Distribution Direction

The current scaffold supports local installation from the repository root. This is useful for development, validation, and preview use while the template is still being finalized.

The intended stable distribution model is a published NuGet template package installable with `dotnet new install`.

Future stable usage is expected to follow this pattern:

```powershell
dotnet new install <published-template-package-id>
dotnet new cdcavell-netcoreapp -n ContosoSecurityPortal
```

Clone-and-modify remains valid for source review, contribution, and direct customization. However, after package publishing is available, the NuGet template package should be treated as the primary stable distribution path for normal template consumers.

After the `v1.0.0` release, changes to the template short name, package identity, template parameters, symbols, or source-name replacement behavior should be reviewed as release-surface changes.

See [ADR-0003: Record Release Surface and Distribution Strategy](../adr/0003-record-release-surface-and-distribution-strategy.md) for the release-surface decision.