Создание пакета NuGet с помощью MSBuild

При создании пакета NuGet из кода вы формируете компонент, которым можно поделиться с любым количеством разработчиков для совместного использования. В этой статье описывается, как создать пакет с помощью MSBuild. MSBuild предустанавливается с каждой рабочей нагрузкой Visual Studio, содержащей NuGet. Кроме того, можно использовать MSBuild через dotnet CLI с помощью команды dotnet msbuild.

Для проектов .NET Core и .NET Standard с форматом в стиле пакета SDK и других проектов в таком стиле NuGet использует сведения в файле проекта напрямую для создания пакета. Для проекта в стиле, отличном от SDK, который использует <PackageReference>, NuGet также использует файл проекта для создания пакета.

Проекты в стиле SDK имеют функциональные возможности пакетирования по умолчанию. Для проектов PackageReference в стиле, отличном от SDK, необходимо добавить пакет NuGet.Build.Tasks.Pack в зависимости проекта. Подробные сведения о целевых объектах пакета MSBuild см. в разделе Пакет NuGet и восстановление в качестве целевых объектов MSBuild.

Команда, создающая пакет (msbuild -t:pack) функционально эквивалентна dotnet pack.

Внимание

Эта статья применяется к проектам в стиле SDK (обычно это проекты .NET Core и .NET Standard), а также к проектам в других стилях, использующим PackageReference.

Задание свойств

Для создания пакета необходимы следующие свойства:

  • PackageId — идентификатор пакета, который должен быть уникальным в пределах коллекции, содержащей пакет. Если не задано, по умолчанию используется значение AssemblyName.
  • Version —определенный номер версии в формате основной_номер.дополнительный_номер.исправление[-суффикс], где -суффикс указывает на предварительные версии. По умолчанию используется значение 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>

Можно также задать дополнительные свойства, такие как Title, PackageDescription и PackageTags (см. подробнее об использовании целевых объектов пакета MSBuild, управлении ресурсами зависимостей и использовании свойств метаданных NuGet).

Примечание.

Если пакет будет общедоступным, обратите особое внимание на свойство PackageTags, так как теги помогают найти ваш пакет и понять его назначение.

Подробные сведения об объявлении зависимостей и указании номеров версий см. в разделе Ссылки на пакеты в файлах проекта и Управление версиями пакетов. Доступ к ресурсам зависимостей в пакете можно также предоставлять напрямую с помощью атрибутов <IncludeAssets> и <ExcludeAssets>. См. подробнее об управлении ресурсами зависимостей.

Добавление необязательного поля описания

Необязательное описание пакета отображается на вкладке README страницы nuget.org пакета. Описание извлекает из <Description> файла проекта или $description в nuspec-файле.

В следующем примере показан Description файл CSPROJ для пакета .NET:

<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.UsefulStuff вместо Contoso-Utility-UsefulStuff или Contoso_Utility_UsefulStuff. Это также полезно для потребителей, если вы соответствуете идентификатору пакета с пространством имен, который использует код.

  • Если вы создаете пакет примера кода, демонстрирующий использование другого пакета , добавьте .Sample его к идентификатору, как показано в Contoso.Utility.UsefulStuff.Sample.

    Пример пакета зависит от исходного пакета. При создании примера пакета добавьте <IncludeAssets>contentFiles значение. В папке содержимого упорядочение примера кода в папке с именем \Samples\<identifier>, например \Samples\Contoso.Utility.UsefulStuff.Sample.

Чтобы задать версию пакета, выполните следующие рекомендации.

  • Как правило, задайте версию пакета для соответствия версии проекта или сборки, хотя это не обязательно. Сопоставление версии просто при ограничении пакета на одну сборку. Сам NuGet относится к версиям пакетов при разрешении зависимостей, а не версий сборок.

  • Если вы используете нестандартную схему версий, обязательно рассмотрите правила управления версиями NuGet, как описано в разделе "Управление версиями пакетов". NuGet в основном соответствует семантической версии 2.0.0.

Примечание.

Дополнительные сведения о разрешении зависимостей см. в разделе "Разрешение зависимостей" с помощью PackageReference. Сведения, которые помогут вам понять управление версиями, см. в этой серии записей блога:

Добавление пакета NuGet.Build.Tasks.Pack

Если вы используете MSBuild с проектом в стиле, отличном от SDK, и PackageReference, добавьте пакет NuGet.Build.Tasks.Pack в проект.

  1. Откройте файл проекта и добавьте следующее после элемента <PropertyGroup>:

    <ItemGroup>
      <!-- ... -->
      <PackageReference Include="NuGet.Build.Tasks.Pack" Version="6.7.0" PrivateAssets="all" />
      <!-- ... -->
    </ItemGroup>
    
  2. Откройте командную строку разработчика (в поле поиска введите Командная строка разработчика).

    В общем случае следует запустить Командную строку разработчика для Visual Studio из меню Пуск, так как в этом случае настраиваются все необходимые пути для MSBuild.

  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).

Примечание.

При автоматическом создании пакета время на упаковку увеличивает время сборки проекта.

Тестирование установки пакета

Перед публикацией пакета, как правило, необходимо протестировать процесс его установки в проекте. Это позволяет убедиться в том, что все необходимые файлы помещаются в нужные места.

Установку можно протестировать вручную в Visual Studio или в командной строке, выполнив стандартную процедуру установки пакета.

Внимание

Пакеты не изменяются. Если вы устраните проблему, измените содержимое пакета и снова выполните упаковку, при повторном тестировании вы все равно будете использовать старую версию пакета до тех пор, пока не будет очищена папка глобальных пакетов. Это особенно важно при тестировании пакетов, которые не используют уникальную метку предварительной версии при каждой сборке.

Next Steps

Создав пакет, то есть файл .nupkg, вы можете опубликовать его в любой коллекции на ваш выбор, как описано в разделе Публикация пакета.

Вы также можете расширить возможности пакета или обеспечить поддержку других сценариев, как описано в следующих разделах:

Наконец, существуют дополнительные типы пакетов, о которых нужно знать: