Template Packaging
This repository includes a dotnet new template scaffold and a NuGet template package project.
The scaffold can be installed locally from source for development, or packed into a .nupkg and installed through the same package-based flow expected for consumers.
Package-based validation is preferred because it verifies the actual distribution artifact instead of only the repository working tree.
Template Identity
| Field | Value |
|---|---|
| Template short name | netcoreapp-template |
| Template package ID | CDCavell.NetCoreApplicationTemplate |
| Source replacement token | ProjectTemplate |
| Current package version | 1.0.1 |
Consumer Scaffold Boundaries
The scaffolded output intentionally includes:
- Source projects under
src/. - Baseline tests under
tests/. - Docker support files.
LICENSE.txt.ASSETS-LICENSES.md.- A consumer-oriented
README.mdgenerated from.template.content/README.md.
The scaffolded output intentionally excludes repository-maintainer content such as:
.github/workflow and issue-template files..template.config/and.template.content/authoring files.- DocFX documentation source and ADRs.
- Changelog, citation, contribution, security, and release-management files.
- Repository maintainer badges and release instructions.
Golden Scaffold Manifest
The approved default scaffold surface is tracked in eng/scaffold-manifest.default.json.
The manifest is validated by eng/Validate-ScaffoldManifest.ps1 after CI packs the template package, installs the generated .nupkg, and scaffolds the default ContosoSecurityPortal project.
The manifest check fails when:
- An expected consumer file is missing.
- An expected consumer directory is missing.
- An unexpected root-level file is generated.
- A maintainer-only path such as
.github/,.template.config/,.template.content/,docs/,eng/,CHANGELOG.md,CITATION.cff,CONTRIBUTING.md,RELEASE.md, orSECURITY.mdappears in the scaffolded output. - The generated consumer README contains repository maintainer content such as workflow badges or the current-release block.
The manifest intentionally allows recursive content under src/, tests/, and scripts/ because those folders are part of the consumer scaffold surface. Root-level additions should be added to expectedFiles only when they are intended public scaffold files.
Validate a Generated Scaffold Locally
After packing and installing the template package, generate the default scaffold:
dotnet new netcoreapp-template -n ContosoSecurityPortal --output ./artifacts/scaffold/ContosoSecurityPortal
Validate the scaffold against the checked-in manifest:
./eng/Validate-ScaffoldManifest.ps1 -ScaffoldRoot ./artifacts/scaffold/ContosoSecurityPortal
Intentionally Update the Manifest
When the public scaffold surface intentionally changes, regenerate the scaffold from the packed .nupkg, inspect the generated output, and then refresh the manifest:
./eng/Validate-ScaffoldManifest.ps1 -ScaffoldRoot ./artifacts/scaffold/ContosoSecurityPortal -Generate
Review the manifest diff carefully before committing. Changes to root-level files, maintainer-only exclusions, template source boundaries, README content checks, or public scaffold folders should be treated as release-surface changes before v1.0.0.
Pack the Template Package
From the repository root:
dotnet pack ./NetCoreApplicationTemplate.Template.csproj --configuration Release --output ./artifacts/template-package
Install the Template Package
dotnet new install ./artifacts/template-package/CDCavell.NetCoreApplicationTemplate.1.0.1.nupkg
Create a New Project from the Template
From a separate working directory:
dotnet new netcoreapp-template -n ContosoSecurityPortal
Use a project name that is also a valid C# identifier, such as ContosoSecurityPortal. Dotted project names require additional template symbol handling so namespace replacement and type-name replacement can be handled separately.
This creates a new project using ContosoSecurityPortal as the replacement name for the source template namespace and project prefix.
Template Options
The template intentionally exposes a small set of stable options for common scaffold variants.
| Option | Default | Supported values | Description |
|---|---|---|---|
--authProvider |
cookie |
cookie, none |
Selects the generated authentication baseline. Use cookie for the default cookie-authentication-ready baseline or none to generate the application with application authentication disabled by default. |
--dbProvider |
sqlite |
sqlite, sqlserver, none |
Selects the generated data access mode. Use sqlite for the default local development configuration, sqlserver for the SQL Server provider configuration, or none to generate the application with EF Core data access disabled. |
--skipRestore |
false |
true, false |
Skips the post-create NuGet restore action when set to true. |
Example non-default scaffold:
dotnet new netcoreapp-template `
--name ContosoNoAuthSqlServer `
--authProvider none `
--dbProvider sqlserver
All supported variants preserve the template's core infrastructure guardrails, including structured logging, centralized error handling, health checks, security headers, rate limiting, and safe defaults.
Authentication-disabled variant
The --authProvider none option generates the application with ProjectTemplate:Authentication:Enabled and ProjectTemplate:Authentication:Cookie:Enabled set to false.
The application still includes the authentication and authorization infrastructure so consumers can enable or replace authentication later. Test cases that intentionally exercise protected endpoints may enable test authentication through in-memory test configuration.
Data-access-disabled variant
The --dbProvider none option generates the application with ProjectTemplate:DataAccess:Provider set to None.
When data access is disabled, EF Core application data access services are not registered, including ApplicationDbContext, IDbContextFactory<ApplicationDbContext>, and EF-backed services that require ApplicationDbContext.
This mode is appropriate for lightweight applications, workers, external modules, or services that use a separate persistence strategy.
Restore, Build, and Test the Generated Project
cd ContosoSecurityPortal
dotnet restore
dotnet build --configuration Release
dotnet test --configuration Release
Update the Installed Template
Install the newer package version:
dotnet new install <path-or-package-id-for-new-version>
The .NET SDK updates the installed template package when the package identity matches and the new package version is higher.
Uninstall the Template
dotnet new uninstall CDCavell.NetCoreApplicationTemplate
Local Repository Install
For local authoring and quick iteration, the template can still be installed from the repository root.
On Windows:
dotnet new install .\
On Linux or macOS:
dotnet new install ./
Then generate from a separate working directory:
dotnet new netcoreapp-template -n ContosoSecurityPortal
Local repository install is useful during template development, but package-based install should remain the primary validation path before release.
CI Smoke Test
The CI workflow packs the template package, installs the generated .nupkg, scaffolds a new project with dotnet new netcoreapp-template, validates the scaffolded output against the golden manifest, builds the generated output, runs generated tests, and uninstalls the template package.
The smoke test runs on Linux, Windows, and macOS so path handling and package install behavior are validated across supported runner environments.
On Linux runners, CI also validates the Docker consumer path from the generated scaffolded output. This Docker smoke test builds the generated Docker image, validates docker compose config, starts the generated Compose application, verifies /health/live, captures Compose logs for diagnostics, and tears down the Compose stack during cleanup.
Docker runtime validation is intentionally limited to Linux runners. The goal is to prove that Docker files emitted by the template are usable by a generated consumer project, not to certify Docker host behavior across every operating system.
Distribution Direction
The stable distribution model is a published NuGet template package installable with dotnet new install.
Stable usage follows this pattern:
dotnet new install CDCavell.NetCoreApplicationTemplate
dotnet new netcoreapp-template -n ContosoSecurityPortal
Clone-and-modify remains valid for source review, contribution, and direct customization. However, the NuGet template package is 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 for the release-surface decision.