template-authoring について
既存プロジェクトを基にカスタム `dotnet new` テンプレートを作成・検証するスキルです。プロジェクト設定やパッケージ情報を引き継ぎ、生成物をローカルで試します。
主な機能
- 01プロジェクトからテンプレート設定を作成
- 02`template.json` を検証
- 03プロジェクトとパッケージ設定を維持
- 04パラメーター、条件、後処理を設定
- 05生成物をインストールしてビルド
活用シーン
- 01.csproj を再利用可能なテンプレートにする
- 02公開前にテンプレート設定を確認
- 03NuGet テンプレートパッケージを作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dotnet/ skills --skill template-authoringインストール後、Claude Code で/template-authoringを入力して読み込まれたか確認します。
詳細
テンプレートの作成
このスキルは、エージェントがカスタムの dotnet new テンプレートを作成し、検証できるよう支援します。既存のプロジェクトからテンプレートを作成する手順を案内し、公開前に template.json に作成上の問題がないか検証します。
使用する場面
- 既存の .csproj から再利用可能なテンプレートを作成したい場合
- 公開前に、作成中の template.json を検証したい場合
.template.config/template.jsonを一から設定したい場合- NuGet で配布するテンプレートをパッケージ化したい場合
使用しない場面
- 既存のテンプレートを探したり使用したりしたい場合 —
template-discoveryまたはtemplate-instantiationに案内してください - テンプレート作成とは無関係な MSBuild の問題がある場合 —
dotnet-msbuildプラグインに案内してください
入力
| 入力 | 必須 | 説明 |
|---|---|---|
| ソースプロジェクトのパス | 作成時 | テンプレートのソースとして使う .csproj のパス |
| template.json のパス | 検証時 | 検証する既存の template.json のパス |
| テンプレート名 | 作成時 | テンプレートの人間が読みやすい名前 |
| 短縮名 | 推奨 | dotnet new <shortname> で使用する短縮名 |
ワークフロー
回答を左右するルール
次の構造をそのまま使用してください。他のテンプレート機能のフィールドを独自に追加しないでください。
依頼された成果物を提示してください。 ユーザーが「見せて」「書いて」「内容を教えて」と言った場合は、ファイルにも書き込んでいても、最終回答に完全な JSON/XML を含めてください。ユーザーのテンプレートを作成する代わりに、このスキルの SKILL.md やプラグインのドキュメントを編集してはいけません。ファイルの作成または変更は、ユーザーがそれを依頼し、対象のテンプレート/プロジェクトが存在する場合にのみ行ってください。
| 要件 | 正しい構造 | 決して使用しないもの |
|---|---|---|
.csproj 内の条件付き XML | 完全な要素を囲む と などの XML コメント | XML が無効になる、単独の #if 行 |
| 生成されたプロジェクトの復元 | 復元アクション 210D431B-A78B-4D2F-B762-4ED3E3EA9025。primaryOutputs、またはソーステンプレートのパス/glob を含む args.files を使用 | 復元アクションでの executable などのスクリプト実行フィールド |
| SDK ホストに限定 | args が { "hostname": "dotnetcli" } を含む配列である host 制約。オプションの version でホスト/CLI のバージョンを制限 | 要件がアクティブな SDK のバージョンである場合に host の version を使うこと、無効なホスト ID dotnet-cli、または無関係な pattern/value フィールド |
| アクティブな SDK バージョンの制限 | args に NuGet のバージョン/範囲文字列を指定する sdk-version 制約 | テンプレートが本当に必要とする場合を除き、マシン固有の完全一致パッチバージョン |
| CPM の維持 | 生成される PackageReference 項目のバージョン指定を省略し、テンプレートを自己完結型にする場合は、パッケージを所有する Directory.Packages.props を含める | インラインの Version 属性を追加すること |
| テンプレートのパッケージ化 | <PackageType>Template</PackageType> を指定し、テンプレートのコンテンツを content/ 以下にパッケージ化する pack プロジェクト | 依頼されたプロジェクトファイルを提示せず、構成だけを説明すること |
ステップ 1:既存のプロジェクトからひな形を作成する
ソース .csproj を分析し、.template.config/template.json を作成します。
- デフォルトでは、元のプロジェクトを変更せずに保持したまま、専用のテンプレートソースディレクトリにソースプロジェクトをコピーします。元のプロジェクトを直接変更するのは、その配置をユーザーが明示的に指定した場合のみです。
- テンプレートソースディレクトリ内に
.template.configを作成します。 identity(逆 DNS 形式)、name、shortName、sourceName(置換対象のプロジェクト名)、classifications、tagsを指定してtemplate.jsonを生成します。- ソースから引き継ぎます。汎用の
dotnet newテンプレートでは誤りが頻発するため、元の.csprojからそれぞれ引き継がれていることを確認します。- SDK の種類 —
Microsoft.NET.Sdk、Microsoft.NET.Sdk.Web、Microsoft.NET.Sdk.Workerなど - アナライザー/パッケージ参照のメタデータ —
PrivateAssets、IncludeAssets、ExcludeAssets OutputTypeとその他の主要なプロパティ —TreatWarningsAsErrors、Nullable、LangVersion- CPM への参加 —
Directory.Packages.propsが存在する場合、インラインのVersion属性を使用しない - カスタムビルドの props/targets と
Directory.Build.propsの規約 - リポジトリの規約 — フォルダー構成、命名、
global.jsonによる SDK の固定
- SDK の種類 —
最小限の例:
{
"$schema": "http://json.schemastore.org/template",
"author": "MyOrg",
"classifications": ["Library"],
"identity": "MyOrg.Templates.MyLib",
"name": "My Library Template",
"shortName": "mylib",
"sourceName": "MyLib",
"tags": { "language": "C#", "type": "project" }
}
必須の出力 — 最小限のひな形だけで終わらせないでください。 実際のソースプロジェクトに対応する完全な .template.config/template.json を記述し、続けて短い 規約を保持したことの確認 を出力して、何も黙って省略されていないことをユーザーが確認できるようにします。この引き継ぎこそがスキルの価値のすべてです。これらを失う汎用の dotnet new テンプレートではなく、手書きのひな形を作る理由はそこにあります。
ソース .csproj の設定 | 引き継ぎ済み? | 方法 |
|---|---|---|
SDK(Microsoft.NET.Sdk.*) | ✅ | テンプレートの内容である .csproj が同じ SDK を使用 |
TreatWarningsAsErrors/Nullable/LangVersion | ✅ | テンプレートの .csproj にそのまま保持 |
PackageReference の PrivateAssets/IncludeAssets/ExcludeAssets | ✅ | 各参照のメタデータを保持 |
CPM(Directory.Packages.props が存在) | ✅ | ManagePackageVersionsCentrally を有効なまま保持し、インラインの Version 属性を出力しない |
意図的に省略した行には、理由を添えて ⚠️ を付けます。省略を明示しないままにしてはいけません。
ステップ 2:template.json を検証する
生成した template.json を template-validation スキルで検証します(必須フィールド、identity の形式、予約済みの shortName との競合、パラメーターのデータ型、事後アクション、制約、タグなど、すべてのルールを管理しています)。
検証項目の概要:
- 必須フィールド —
identity、name、shortNameを指定する必要があります。 - shortName の競合 —
dotnet newのサブコマンドと重複する名前は避けてください。インストール済み SDK のdotnet new --helpにあるCommands:セクションから正確な一覧を取得し、ハードコードしないでください(バージョンによって変わる可能性があります)。現在の SDK における例としては、install、uninstall、update、list、search、details、createがあります。dotnet new <name>が同じ名前のサブコマンドとして解析されるため、競合が発生します。build、run、test、publishなどのトップレベルのdotnet動詞は競合しません。dotnet new listを実行し、その名前がすでに使用されていないことを確認してください。 - パラメーター、事後アクション、タグ — 有効なデータ型の一覧を含む完全なルールについては、template-validation を参照してください。
ステップ 3: テンプレートを改良する
検証結果とユーザーの要件に基づいて、次のことを行います。
-
パラメーターを追加する — 適切な型(string、bool、choice)、既定値、説明を付けます
-
条件付きコンテンツを追加する — ファイル種別で有効な構文を使用します。XML では、裸のプリプロセッサ行ではなく、 XML コメント内のテンプレートディレクティブを使用します。
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" /> -
ポストアクションを構成する — ソリューションの追加、復元、カスタムスクリプト用に設定します
-
制約を設定する — テンプレートがサポートする SDK やワークロードを制限します
-
分類を追加する — 検出しやすいように分類とタグを付けます
復元ポストアクションでは、プロジェクトのパスがわかっている場合は primaryOutputs を優先します。
"primaryOutputs": [{ "path": "MyProject.csproj" }],
"postActions": [{
"description": "Restore NuGet packages.",
"manualInstructions": [{ "text": "Run 'dotnet restore'." }],
"actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025",
"continueOnError": true
}]
args.files が必要な場合、そのパスは名前変更の前にソーステンプレートと照合されます。たとえば
"files": ["**/*.csproj"] のようになります。この違いについて説明してください。
ステップ 4: テンプレートをローカルでテストする
既存プロジェクトからの作成リクエストの場合、このステップは任意ではなく必須です。
作成したテンプレートをインストールし、ドライランを実行し、一時出力フォルダーにインスタンス化し、
生成されたプロジェクトをビルドします。観測した各結果を報告してください。template.json だけを調べても、
再利用可能なテンプレートが動作することは証明できません。
dotnet new install ./path/to/template/root
dotnet new mylib --name TestProject --dry-run
dotnet new mylib --name TestProject --output ./test-output
dotnet build ./test-output/TestProject
パッケージ化が要求された場合は、ディレクトリツリーだけでなく、完全な pack プロジェクトを含めてください。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageId>Contoso.ProjectTemplates</PackageId>
<PackageType>Template</PackageType>
<TargetFramework>net8.0</TargetFramework>
<IncludeBuildOutput>false</IncludeBuildOutput>
<NoWarn>$(NoWarn);NU5128</NoWarn>
</PropertyGroup>
<ItemGroup>
<Compile Remove="**\*" />
<Content Include="templates\**\*" Pack="true" PackagePath="content\" />
</ItemGroup>
</Project>
pack プロジェクトのターゲットフレームワークは、コンテンツのみのパッケージ化プロジェクトにのみ適用されます。
templates/ 内のプロジェクトのターゲットを変更するものではありません。パッケージ化プロジェクト自体が
新しいビルド機能を使用していない限り、広く利用可能なサポート対象のフレームワークを優先してください。
セルフコンテインドな CPM テンプレートの場合、パッケージ化された Directory.Packages.props には
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> を含める必要があり、バージョン指定のない
すべての PackageReference には、対応する PackageVersion が必要です。props ファイルは、意図した生成先
リポジトリのルートに置いてください。参照方法が変わる位置のプロジェクトの近くに重複して置かないでください。
検証
-
template.jsonが手動検証にエラーゼロで合格する - テンプレートの identity と shortName が一意で意味がある
- すべてのパラメーターに説明と適切な既定値がある
- テンプレートをインストール、ドライラン、インスタンス化できる
- 作成されたプロジェクトが
dotnet buildでクリーンにビルドできる - 条件付きコンテンツがすべてのパラメーターの組み合わせで正しい出力を生成する
- XML テンプレートディレクティブが XML コメントで囲まれており、生成されたプロジェクトがパースできる
- ホスト制約は
args[].hostnameを使用し、復元アクションはprimaryOutputsまたはargs.filesを使用している
よくある落とし穴
| 落とし穴 | 解決策 |
|---|---|
| identity の形式の問題 | 逆 DNS 形式(例: MyOrg.Templates.WebApi)を使用します。スペースや特殊文字は避けてください。 |
| shortName が CLI コマンドと競合する | dotnet new のサブコマンドと一致する名前は避けてください。実際のセットは dotnet new --help から読み取り、ハードコードしないでください(例として挙げられるもの: install、uninstall、update、list、search、details、create)。build/run/test/publish のようなトップレベルの動詞は問題ありません。名前がすでに使われているかどうかは dotnet new list を実行して確認してください。 |
| パラメーターの説明が不足している | 検出しやすいように、すべてのパラメーターに description と displayName を付けてください。 |
| すべてのパラメーターの組み合わせをテストしていない | 異なるパラメーター値で dotnet new <template> --dry-run を使用し、条件付きコンテンツが正しく動作することを確認してください。 |
| テンプレート内のハードコードされたバージョン | プロジェクト名には sourceName 置換を使用し、フレームワークバージョンのパラメーター化を検討してください。 |
| classifications を設定していない | テンプレートの検出のために、適切な classifications(例: ["Web", "API"])を追加してください。 |
| 別の制約やポストアクションのフィールドを再利用している | 正確なスキーマに従ってください。host.args[].hostname や、run-script のフィールドではなく復元の args.files を使用します。 |
詳細情報
- dotnet new 用のカスタムテンプレート — 公式の作成ガイド
- template.json リファレンス — スキーマの完全なリファレンス
- Template Engine Wiki — テンプレートエンジンの内部構造