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 などのオプションのプロパティを設定することもできます。

注意

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

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

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

パッケージの NuGet.org ページに表示される、パッケージの省略可能な説明は、.csproj ファイルで使用されている <description></description> から取得されるか、または .nuspec ファイル$description を経由して取得されます。

"description" フィールドの例は、.NET パッケージ用の .csproj ファイルの次の XML テキストに示されています。

<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://docs.microsoft.com/en-us/azure/storage/
      Microsoft Azure Storage REST API Reference - https://docs.microsoft.com/en-us/rest/api/storageservices/
      REST API Reference for Blob Service - https://docs.microsoft.com/en-us/rest/api/storageservices/blob-service-rest-api
    </Description>
  </PropertyGroup>
</Project>

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

パッケージ識別子とバージョン番号は、パッケージに含まれる正確なコードを一意に識別するため、プロジェクトの中で最も重要な 2 つの値です。

パッケージ識別子のベスト プラクティス:

  • 一意性:この識別子は、nuget.org 全体で、あるいはパッケージをホストするギャラリー全体で一意になる必要があります。 識別子を決める前に、該当するギャラリーを検索し、その名前が既に使用されていないか確認してください。 競合を避けるために、Contoso. のように、識別子の最初の部分に会社の名前を使用することが適しているパターンです。
  • 名前空間のような名前:.NET の名前空間に似たパターンに従います。ハイフンの代わりにドット表記を使います。 たとえば、Contoso-Utility-UsefulStuffContoso_Utility_UsefulStuff ではなく Contoso.Utility.UsefulStuff を使用します。 パッケージ識別子がコードで使用される名前空間と一致すれば、利用者にとっても便利です。
  • サンプル パッケージ:別のパッケージの使用方法を示すサンプル コードのパッケージを生成する場合、Contoso.Utility.UsefulStuff.Sample のように、識別子にサフィックスとして .Sample を付けます。 (サンプル パッケージは、もちろん、他のパッケージに依存します。)サンプル パッケージを作成する場合は、<IncludeAssets> 内で contentFiles 値を使用します。 content フォルダーで、\Samples\Contoso.Utility.UsefulStuff.Sample のように、\Samples\<identifier> という名前のフォルダーにサンプル コードを配置します。

パッケージ バージョンのベスト プラクティス:

  • これは厳密には必須ではありませんが、一般的にはプロジェクト (またはアセンブリ) と一致するようにパッケージのバージョンを設定します。 パッケージを単一のアセンブリに限定する場合に、これはシンプルな方法です。 概して、NuGet 自体は依存関係の解決時、パッケージ バージョンを使います。アセンブリ バージョンではありません。
  • 非標準のバージョン スキーマを使用するとき、「パッケージのバージョン管理」で説明するように、NuGet バージョン管理ルールを検討してください。 NuGet は、ほぼ semver 2 に準拠しています。

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

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

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

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

    <ItemGroup>
      <!-- ... -->
      <PackageReference Include="NuGet.Build.Tasks.Pack" Version="5.2.0"/>
      <!-- ... -->
    </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 を実行した場合、これにより、パック化可能なソリューション内のすべてのプロジェクトがパックされます ( プロパティは true に設定されます)。

注意

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

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

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

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

重要

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

次の手順

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

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

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