Обновление локального пакета nuget при событии после сборки

У меня есть локальный репозиторий библиотеки nuget отдельно как для моих личных, так и для работы с повторными библиотеками классов.

Я создал некоторые пакеты nuget для библиотек, которые больше не находятся в разработке. Я сделал это только для них, потому что я не знаю, как их автоматически обновлять, как только мой проект будет создан.

Я понял, что вся работа выполняется командой nuget с командной строкой Visual Studio. Поэтому я могу легко выполнить нужную мне работу (конечно, я бы прекрасно знал команды, а я нет!)

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

В сборке проекта:

  • копирование DLL проекта в определенную папку (папка lib пакета nuget)
  • обновление файла nuspec для новой версии файла (мой проект увеличивает версию файла при каждой сборке)
  • создание нового файла nupkg с новой версией файла

Фил Хаак показывает часть этой функции, но, насколько я могу судить, это все еще прототип.

Итак, мое требование - это выше. Кто-нибудь еще это сделал?

Ответ 1

Джереми Скиннер написал сообщение в блоге о том, как он выполняет автоматические сборки пакетов и загружает их в галерею NuGet. Я думаю, что это соответствует вашим требованиям.

В основном он использует MsBuild для применения версии (с помощью задачи MsBuild Community Extensions UpdateXml) в файл nuspec и вызывает nuget.exe для упакуйте его.

Ответ 2

Выбранное решение выглядит так, как будто оно работает, но похоже, что есть более простое решение для ваших требований.

Вы можете создать файл nuspec, который будет считывать данные из метаданных проекта. Вам нужно сделать это один раз с помощью этой команды:

C:\<Path to project>\nuget spec

Это создает "токены" в spec файле, который будет заменен метаданными проекта при создании пакета nuget. Сюда входит версия файла. Вы захотите заменить и потому, что все проекты технически предполагают их.

Более подробную информацию можно найти здесь: http://docs.nuget.org/docs/creating-packages/Creating-and-Publishing-a-Package#From_a_project

Тогда...

Для проектов .Net Framework (old-school), в вашем проекте Post build events вы можете сделать это:

nuget pack "$(ProjectPath)"  
xcopy "$(TargetDir)*.nupkg" "<path where you are hosting your local nuget repo>" /C /Y

(предполагая, что nuget.exe доступен в вашей системе PATH).

Для проектов .Net Core и Standard, nuget не может их упаковывать (см. https://github.com/NuGet/Home/issues/4491), Вместо этого используйте это как шаг после сборки:

dotnet pack "$(ProjectPath)" --no-build --include-source --include-symbols --output "<path where you are hosting your local nuget repo>"

Конечно, вы можете настроить параметры в соответствии с вашими потребностями. См. https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-pack?tabs=netcore2x для параметров dotnet pack.

Ответ 3

На тот случай, если кто-то другой (например, я) столкнется с этим древним вопросом - в нынешнюю эпоху (VS2017, SDK/формат NugetReference/.NET Core/.NET Standard/многоцелевые проекты), где создание пакета NuGet является опцией в Свойства проекта - так, должен быть решен только вопрос локального репозитория:

Если у вас есть проект с одной целью, чтобы скопировать файл .nupkg в локальный репозиторий NuGet, добавьте событие Post-build (Свойства проекта> События сборки> Командная строка события после сборки):

xcopy $ (TargetDir) *. nupkg [путь к локальному репозиторию nuget]/s

Подобно:

xcopy $ (TargetDir) *. nupkg G:\imbVelesOpenSource\LocalNuGet\imbVelesSecondGeneration \/s


Если у вас многоцелевой проект, скопируйте файл .nupkg в локальный репозиторий NuGet: добавьте событие после сборки (Свойства проекта> События сборки> Командная строка события после сборки):

xcopy $ (TargetDir).. *. nupkg [путь к вашему локальному репозиторию nuget]/s

Подобно:

xcopy $ (TargetDir).. *. nupkg G:\imbVelesOpenSource\LocalNuGet\imbVelesSecondGeneration \/s


Обновление: забудьте о событиях после сборки, есть более чистый способ (подход xcopy работает странно для многоцелевых проектов), просто добавьте это в XML проекта:

  <Target Name="CopyPackage" AfterTargets="Pack">
    <Copy SourceFiles="$(OutputPath)$(PackageId).$(PackageVersion).nupkg" DestinationFolder="G:\imbVelesOpenSource\LocalNuGet\imbVelesSecondGeneration\" />
  </Target>

Ответ 4

Недавно я опубликовал решение для этого, которое фактически создает/обновляет файлы nuspec во время сборки, поэтому не нужно делать это вручную, а затем создает файлы nupkg.

Все, что вам нужно будет добавить, это событие после сборки для копирования пакетов в их место назначения (или добавление его в качестве дополнительного этапа для моего решения).

Здесь вы можете найти статью с здесь, и исходный код + двоичный файл здесь.

Ответ 5

В последнем формате пакета nuget с использованием тегов "PackageReference" вы можете использовать следующее простое событие postbuild в вашем csproj для обновления файла nuspec с последними зависимостями.

  <Target Name="AfterBuild">
     <WriteLinesToFile File="dependencies.xml" Overwrite="true" Lines=""/>
     <WriteLinesToFile File="dependencies.xml" Overwrite="false" Lines="&lt;dependencies&gt;"/>
     <WriteLinesToFile File="dependencies.xml" Overwrite="false" Lines="&lt;dependency id=&quot;%(PackageReference.Identity)&quot; version=&quot;%(PackageReference.Version)&quot; /&gt;" />
     <WriteLinesToFile File="dependencies.xml" Overwrite="false" Lines="&lt;/dependencies &gt;"/>
     <Exec Command="powershell -NonInteractive -executionpolicy Unrestricted -command &quot;$xml = [xml] (Get-Content Project.nuspec); $xml.package.metadata.RemoveChild($xml.package.metadata.dependencies); $dependencies = [xml](Get-Content dependencies.xml); $xml.Package.Metadata.AppendChild($xml.ImportNode($dependencies.Dependencies, $true)); $xml.Save('Project.nuspec')&quot;"/>
     <Delete Files="dependencies.xml" />
  </Target>

Единственным условием для этого является то, что у вас есть файл nuspec с остальными метаданными, упомянутыми в каталоге проекта. Вот пример файла nuspec:

<?xml version="1.0"?>
<package>
   <metadata>
      <id>Package Id</id>
      <version>1.0.0</version>
      <authors>Author name</authors>
      <owners>Owner name</owners>
      <description>Description</description>
      <contentFiles>
         <files include="**/content.zip" buildAction="None" copyToOutput="true" flatten="false" />
      </contentFiles>
      <dependencies>
      </dependencies>
   </metadata>
   <files>
      <file src="bin\Release\Project.dll" target="lib\net462" />
      <file src="bin\Release\Project.pdb" target="lib\net462" />
      <file src="bin\Release\file.zip" target="Content" />
   </files>
</package>