MSBuild を使用して NuGet パッケージを作成する

自分のコードで NuGet パッケージを作成する場合、その機能をコンポーネントにパッケージ化し、数を問わず他の開発者と共有し、使用することができます。 この記事では、MSBuild を使用してパッケージを作成する方法について説明します。 MSBuild は、NuGet を含むすべての Visual Studio ワークロードにプレインストールされています。 また、dotnet CLI と dotnet msbuild を介して MSBuild を使用することもできます。

SDK スタイルの形式を使用する .NET Core および .NET Standard プロジェクト、またその他の SDK スタイルのあらゆるプロジェクトに対して、NuGet ではプロジェクト ファイルにある情報を直接使ってパッケージが作成されます。 <PackageReference> を使用する SDK スタイル以外のプロジェクトの場合、NuGet ではプロジェクト ファイルを使用してパッケージを作成することもできます。

SDK スタイルのプロジェクトには、既定でパック機能を利用できます。 SDK スタイル以外の PackageReference プロジェクトでは、プロジェクトの依存関係に NuGet.Build.Tasks.Pack パッケージを追加する必要があります。 MSBuild パック ターゲットの詳細については、「MSBuild ターゲットとしての NuGet の pack と restore」を参照してください。

パッケージ (msbuild -t:pack) を作成するコマンドは、dotnet pack と機能的に同等です。

重要

このトピックは、SDK スタイルのプロジェクト (通常は、.NET Core プロジェクトと .NET Standard プロジェクト)、および PackageReference を使った SDK スタイル以外のプロジェクトを対象としています。

プロパティの設定

次のプロパティは、パッケージを作成するために必要です。

  • PackageId、パッケージの識別子。パッケージをホストするギャラリー全体で一意にする必要があります。 指定しない場合は、既定値の AssemblyName が使用されます。
  • VersionMajor.Minor.Patch[-Suffix] という形式の特別なバージョン番号。-Suffix によってプレリリース版を識別します。 指定しない場合は、既定値は 1.0.0 です。
  • ホスト (nuget.org など) に表示されるパッケージ タイトル。
  • Authors、作成者と所有者の情報。 指定しない場合は、既定値の AssemblyName が使用されます。
  • Company、会社名。 指定しない場合は、既定値の AssemblyName が使用されます。

さらに、PackageReference を使用する非 SDK 形式のプロジェクトをパックする場合は、次のものが必要です。

  • PackageOutputPath、パックの呼び出し時に生成されるパッケージの出力フォルダー。

Visual Studio では、プロジェクトのプロパティにこれらの値を設定できます (ソリューション エクスプローラー内でプロジェクトを右クリックし、[プロパティ] を選択して、[パッケージ] タブを選択します)。 プロジェクト ファイル (.csproj) 内でこれらのプロパティを直接設定することもできます。

<PropertyGroup>
  <PackageId>ClassLibDotNetStandard</PackageId>
  <Version>1.0.0</Version>
  <Authors>your_name</Authors>
  <Company>your_company</Company>
</PropertyGroup>

重要

パッケージには、nuget.org または使用しているパッケージ ソース全体で一意になる識別子を付けてください。

次の例は、これらのプロパティを含む、シンプルかつ完全なプロジェクト ファイルを示しています。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <PackageId>ClassLibDotNetStandard</PackageId>
    <Version>1.0.0</Version>
    <Authors>your_name</Authors>
    <Company>your_company</Company>
  </PropertyGroup>
</Project>

また、MSBuild pack ターゲットに関するセクション、「依存関係アセットを制御する」、「NuGet メタデータ プロパティ」に説明されているように、TitlePackageDescriptionPackageTags などのオプションのプロパティを設定することもできます。

Note

公開用にビルドされたパッケージの場合は、PackageTagsプロパティに特に注意してください。これらのタグは他のユーザーがパッケージを検索して、パッケージの動作を理解するのに役立ちます。

依存関係の宣言とバージョン番号の指定の詳細については、「プロジェクト ファイルのパッケージ参照 (PackageReference)」と「パッケージのバージョン管理」を参照してください。 <IncludeAssets> および <ExcludeAssets> 属性を使用して、パッケージ内で直接、依存関係からアセットを表面化させることもできます。 詳しくは、「依存関係アセットを制御する」をご覧ください。

省略可能な説明フィールドを追加する

パッケージのオプションの説明は、パッケージの nuget.org ページの [README] タブに表示されます。 説明は、プロジェクト ファイルの <Description> または .nuspec ファイル$description からプルされます。

次の例は、.NET パッケージの .csproj ファイル内の Description を示しています。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <PackageId>Azure.Storage.Blobs</PackageId>
    <Version>12.4.0</Version>
    <PackageTags>Microsoft Azure Storage Blobs;Microsoft;Azure;Blobs;Blob;Storage;StorageScalable</PackageTags>
    <Description>
      This client library enables working with the Microsoft Azure Storage Blob service for storing binary and text data.
      For this release see notes - https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Azure.Storage.Blobs/README.md and https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Azure.Storage.Blobs/CHANGELOG.md
      in addition to the breaking changes https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Azure.Storage.Blobs/BreakingChanges.txt
      Microsoft Azure Storage quickstarts and tutorials - https://learn.microsoft.com/azure/storage/
      Microsoft Azure Storage REST API Reference - https://learn.microsoft.com/rest/api/storageservices/
      REST API Reference for Blob Service - https://learn.microsoft.com/rest/api/storageservices/blob-service-rest-api
    </Description>
  </PropertyGroup>
</Project>

一意のパッケージ識別子を選択してバージョン番号を設定する

パッケージ識別子とバージョン番号は、パッケージに含まれる正確なコードを一意に識別します。

パッケージ識別子を作成するには、次のベスト プラクティスに従ってください。

  • パッケージ識別子は、nuget.org とそのパッケージをホストするその他すべての場所間で一意である必要があります。 競合を避けるために、識別子の最初の部分に会社の名前を使用すると、適切なパターンになります。

  • ドット表記を使用して、.NET 名前空間のような名前付け規則に従います。 たとえば、Contoso-Utility-UsefulStuffContoso_Utility_UsefulStuff ではなく Contoso.Utility.UsefulStuff を使用します。 また、コードで使用する名前空間とパッケージ識別子を合わせると、コンシューマーにも役立ちます。

  • 別のパッケージの使用方法を示すサンプル コードのパッケージを生成する場合、Contoso.Utility.UsefulStuff.Sample のように、識別子に .Sample を付加します。

    サンプル パッケージは、元のパッケージと依存関係があります。 サンプル パッケージを作成するときに、<IncludeAssets> と値 contentFiles を追加します。 content フォルダー内の、\Samples\<identifier> というフォルダー (\Samples\Contoso.Utility.UsefulStuff.Sample など) にサンプル コードを配置します。

パッケージのバージョンを設定するには、次のベスト プラクティスに従ってください。

  • これは厳密には必須ではありませんが、一般的に、パッケージのバージョンはプロジェクトまたはアセンブリのバージョンと一致するように設定します。 パッケージを単一のアセンブリに限定する場合は、バージョンを一致させるのは簡単です。 NuGet 自体は依存関係の解決時に、アセンブリのバージョンではなくパッケージのバージョンを使います。

  • 非標準のバージョン スキームを使用するときは、「パッケージのバージョン管理」で説明するように、NuGet バージョン管理ルールを考慮してください。 NuGet は、セマンティック バージョニング 2.0.0 にほぼ準拠しています。

Note

依存関係の解決の詳細については、「PackageReference による依存関係の解決」を参照してください。 バージョン管理の理解を深めるために役立つ可能性がある情報については、こちらの一連のブログ投稿を参照してください。

NuGet.Build.Tasks.Pack パッケージを追加する

SDK スタイル以外のプロジェクトと PackageReference で MSBuild を使用している場合は、プロジェクトに NuGet.Build.Tasks.Pack パッケージを追加します。

  1. プロジェクト ファイルを開き、以下を <PropertyGroup> 要素の後に追加します。

    <ItemGroup>
      <!-- ... -->
      <PackageReference Include="NuGet.Build.Tasks.Pack" Version="6.7.0" PrivateAssets="all" />
      <!-- ... -->
    </ItemGroup>
    
  2. 開発者コマンド プロンプトを開きます (検索ボックスに「開発者コマンド プロンプト」と入力します)。

    MSBuild に必要なすべてのパスが構成されるため、通常は [スタート] メニューから Visual Studio 用開発者コマンド プロンプトを使用します。

  3. プロジェクト ファイルが含まれているフォルダーに切り替え、次のコマンドを入力して、NuGet.Build.Tasks.Pack パッケージをインストールします。

    # Uses the project file in the current folder by default
    msbuild -t:restore
    

    MSBuild の出力にビルドが正常に完了したことが示されていることを確認します。

msbuild -t:pack コマンドを実行する

プロジェクトから NuGet パッケージ (.nupkg ファイル) を作成するには、msbuild -t:pack コマンドを実行します。このコマンドではプロジェクトのビルドも自動的に行われます。

Visual Studio 用開発者コマンド プロンプトで次のコマンドを入力します。

# Uses the project file in the current folder by default
msbuild -t:pack

出力に、.nupkg ファイルへのパスが表示されます。

Microsoft (R) Build Engine version 16.1.76+g14b0a930a7 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 8/5/2019 3:09:15 PM.
Project "C:\Users\username\source\repos\ClassLib_DotNetStandard\ClassLib_DotNetStandard.csproj" on node 1 (pack target(s)).
GenerateTargetFrameworkMonikerAttribute:
Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the input files.
CoreCompile:
  ...
CopyFilesToOutputDirectory:
  Copying file from "C:\Users\username\source\repos\ClassLib_DotNetStandard\obj\Debug\netstandard2.0\ClassLib_DotNetStandard.dll" to "C:\Use
  rs\username\source\repos\ClassLib_DotNetStandard\bin\Debug\netstandard2.0\ClassLib_DotNetStandard.dll".
  ClassLib_DotNetStandard -> C:\Users\username\source\repos\ClassLib_DotNetStandard\bin\Debug\netstandard2.0\ClassLib_DotNetStandard.dll
  Copying file from "C:\Users\username\source\repos\ClassLib_DotNetStandard\obj\Debug\netstandard2.0\ClassLib_DotNetStandard.pdb" to "C:\Use
  rs\username\source\repos\ClassLib_DotNetStandard\bin\Debug\netstandard2.0\ClassLib_DotNetStandard.pdb".
GenerateNuspec:
  Successfully created package 'C:\Users\username\source\repos\ClassLib_DotNetStandard\bin\Debug\AppLogger.1.0.0.nupkg'.
Done Building Project "C:\Users\username\source\repos\ClassLib_DotNetStandard\ClassLib_DotNetStandard.csproj" (pack target(s)).

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:01.21

ビルド時に自動的にパッケージを生成する

プロジェクトのビルドまたは復元時に自動的に msbuild -t:pack を実行させるには、プロジェクト ファイルの <PropertyGroup> 内に次の行を追加します。

<GeneratePackageOnBuild>true</GeneratePackageOnBuild>

ソリューション上で msbuild -t:pack を実行した場合、これにより、パック化可能なソリューション内のすべてのプロジェクトがパックされます (<IsPackable> プロパティは true に設定されます)。

Note

パッケージを自動的に生成する場合、パックする時間によってプロジェクトのビルド時間が長くなります。

パッケージ インストールのテスト

パッケージを公開する前に、通常、パッケージをプロジェクトにインストールするプロセスをテストします。 このテストにより、必要なファイルがすべて、プロジェクト内の適切な場所に入ります。

インストールは Visual Studio またはコマンド ラインで手動テストできます。通常のパッケージ インストール手順を利用します。

重要

パッケージは不変です。 問題を修正する場合は、パッケージ内容を変更して、もう一度パックしてください。再テスト時に、グローバル パッケージのフォルダーをクリアするまでは、古いバージョンのパッケージを引き続き使用することになります。 どのビルド時でも、一意のプレリリース ラベルを使用しないパッケージをテストする場合に、これは特に該当します。

次のステップ

.nupkg ファイルとなるパッケージを作成したら、「パッケージの公開」の説明にあるように、選択したギャラリーにパッケージを公開できます。

パッケージの機能を拡張したり、次のトピックで説明するように、その他の方法で他のシナリオをサポートしたりすると便利な場合があります。

最後になりますが、次のような種類のパッケージもあります。