Как использовать Nuget для внутренней разработки предприятия?

Мы используем Nuget для нашей внутренней разработки, чтобы мы могли делиться кодами между командами. Мы сталкиваемся с проблемами, однако, когда один человек работает над кодом, который будет развернут в нескольких пакетах nuget одновременно. Например,

A зависит от B, зависящего от C.

A, B и C имеют свои артефакты, выдвинутые Nuget, и то, как мы управляем зависимостями между A, B и C. Мы обнаружили, что если разработчик хочет внести изменения в C и быстро увидеть те изменения, которые отражены в A, они должны пройти следующий процесс.

  • Внесите изменения в C.
  • Нажать изменение до git
  • CI подбирает изменения в C и строит и развертывает новый пакет nuget.
  • Перейдите в B и обновите ссылку на C, используя команду пакета обновления nuget.
  • Нажмите на изменение в файле packages.config до git
  • CI берет изменения в B и строит и развертывает новый пакет nuget для B
  • Теперь откройте A и измените ссылку на пакет обновлений B и nuget.
  • Сделайте изменения в A, чтобы идти вместе с изменениями в B (и транзитивно C)

Это кажется чрезвычайно болезненным и вызывает у некоторых наших разработчиков вопрос о выборе Nuget для нашего внутреннего кода. Каждому по-прежнему нравится использовать внешние пакеты.

Есть ли какой-нибудь лучший рабочий процесс для внутреннего использования Nuget?

Ответ 1

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

  • Существует внутренний репозиторий NuGet, в котором хранятся все опубликованные пакеты для компании. Этот репозиторий - это всего лишь общий каталог на одном из наших серверов.
  • Каждый разработчик может иметь (но не обязательно) один или несколько каталогов на своей собственной машине, которая служит локальным репозиторием пакетов NuGet. Используя специфическую для пользователя конфигурацию NuGet разработчик может контролировать, в каком порядке NuGet ищет через репозитории пакетов для поиска пакетов.

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <packageRestore>
        <add key="enabled" value="True" />
      </packageRestore>
      <packageSources>
        <add key="Dev" value="D:\dev\testpackages" />
        <add key="Company" value="<UNC_ADDRESS_COMPANY_REPOSITORY>" />
        <add key="NuGet official package source" value="https://nuget.org/api/v2/" />
      </packageSources>
      <disabledPackageSources />
      <activePackageSource>
        <add key="All" value="(Aggregate source)" />
      </activePackageSource>
    </configuration>
    
  • Все решения имеют автоматическое восстановление пакетов, поэтому нам не нужно фиксировать пакеты в нашей системе управления версиями.

  • Разработчики управляют только 3 из 4 номеров версий, например. если версия <MAJOR>.<MINOR>.<BUILD>.<REVISION>, то разработчики могут изменять только основные, второстепенные и строковые номера, номер версии устанавливается равным 0, кроме как в сборках, выполняемых сервером сборки, где это номер сборки сборки. Это важно, потому что это означает, что для данной версии, состоящей из основного, младшего и строкового номера, сервер сборки всегда будет производить более высокий номер версии. Это снова означает, что NuGet предпочтет взять версию пакета из репозитория пакета компании (который получает пакеты только через сервер сборки).

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

  • Внесите изменения в базовую библиотеку (A). Обновите версию (A), если необходимо.
  • Запустите MsBuild script для создания двоичных файлов и создания пакетов NuGet (A)
  • Скопируйте новые пакеты NuGet в репозиторий пакетов на локальном компьютере.
  • В зависимом проекте (B) обновление до новых пакетов (A), которые были только что помещены в репозиторий локального машинного пакета (который должен иметь более высокую версию, чем те, которые доступны в общем репозитории компании, или NuGet. орг)
  • Внесите изменения в (B).

Если для (A) требуется больше изменений, повторите шаги 1,2 и 3, а затем удалите пакет (A) из рабочего каталога (B). В следующий раз при запуске сборки NuGet пойдет искать определенную версию (A), найдет ее в локальном репозитории и вернет обратно. Обратите внимание, что кеш NuGet может нарушить этот процесс некоторое время, хотя похоже, что NuGet не может кэшировать пакеты, которые поступают с одного и того же компьютера (?).

Как только изменения завершены, мы:

  • Зафиксируйте изменения в (A). Сервер сборки запустит сборку интеграции, чтобы убедиться, что все работает.
  • Сообщите серверу сборки запустить сборку релизов, которая создает двоичные файлы и подталкивает пакеты NuGet к общедоступному репозиторию NuGet.
  • В (B) обновите до последней версии (A) (которая должна иметь более высокий номер версии, чем тестовый пакет, потому что тестовый пакет должен иметь версию abc0, а новая версия в общем репозитории компании должна be abc где > 0
  • Зафиксируйте изменения в (B). Подождите, пока сервер сборки завершит тесты интеграции.
  • Сообщите серверу сборки, чтобы запустить сборку выпуска для (B).

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

  • Внесите изменения в базовую библиотеку (A). При необходимости обновите версию (A).
  • Создание двоичных файлов
  • Скопируйте двоичные файлы в место, где NuGet распаковывает пакет (A) для проекта (B) (например, c:\mysource\projectB\packages\ProjectA.1.2.3.4)
  • Внесите необходимые изменения в проект (B)

Процесс фиксации по-прежнему остается прежним, сначала необходимо выполнить проект (A), а в проекте (B) необходимо обновить ссылку NuGet (A).

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

Ответ 2

Здесь у вас есть два варианта:

  • Запустите экземпляр Галерея NuGet в вашей организации. Это код, который запускает nuget.org
  • Получить лицензию на Artifactory Pro, которая имеет встроенную поддержку Nuget и выступает в качестве репозитория Nuget.

Я использовал оба, и # 1 - разумный выбор для начала, но NuGet Galley оптимизирован и разработан для nuget.org, а не на месте или в корпоративном использовании, поэтому такие вещи, как удаление пакетов, - это боль (hand- требуется свернутый SQL-запрос).

Я бы сказал, что вы должны заплатить (низкий) лицензионный сбор за Artifactory Pro - это отличный продукт, и команда JFrog действительно заинтересована и включена.

Вы не должны использовать nuget.org для внутренних/корпоративных пакетов; nuget.org предназначен для сторонних/открытых исходных библиотек, а не для внутренних зависимостей сборки.

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

EDIT 2. Чтобы ускорить рабочий процесс изменения кода для разработчика, вы можете использовать nuget.exe (клиент командной строки) и использовать доступные для командной строки сборки, чтобы вы могли настроить таргетинг на "Сборка разработчика". Затем в вашей сборке "разработчик" (в отличие от сборки CI) вы указываете -Source как локальный путь (например, nuget install B -Source C:\Code\B), когда вы хотите вытащить обновленный B в качестве зависимости и построить против этого; аналогично для C или других локальных, недавно обновленных пакетов. Затем, когда A, B и C все строят отлично, вы можете git push все из них (в порядке обратной зависимости) и позволить CI делать свою работу.

Однако, вы также должны задать вопрос о том, действительно ли ваше разделение пакетов действительно подходит, если вам нужно часто делать это "танцевать", поскольку это говорит о том, что весь код должен быть в одном пакете или возможно разделенные по разным строкам в отдельных пакетах. Ключевая особенность четко определенного пакета заключается в том, что он не должен вызывать волновые эффекты для других пакетов, конечно, если вы эффективно используете Semantic Versioning.

Редактировать 3 Некоторые пояснения, запрошенные marcelo-oliveira: "доступные для командной строки сборки" - это сборки, которые могут выполняться целиком из командной строки без использования Visual Studio, обычно с помощью пакетных файлов. "Конструкция разработчика" представляет собой сборку, которую разработчик запускает со своей рабочей станции, в отличие от сборки CI, которая выполняется на сервере CI (обе сборки должны быть по существу одинаковыми).

Ответ 3

Если A, B и C находятся под тем же самым решением, вы можете создавать пакеты NuGet для них в одной сборке.

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

Если A, B и C преднамеренно находятся под разными решениями, например. A находится под инфраструктурным решением, а B находится под решением продукта, тогда единственное, что у меня есть для вас, - это определить, что ваши CI-сборки выполняются при проверке, а не периодически.


Edit:

Другой вариант - создать на своем сервере NuGet push-пакеты пакеты предварительного выпуска (например, версия 1.0.0-альфа) на локальных сборках, таким образом разработчики могут экспериментировать с пакетом до создания релиз версии.

Ответ 4

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

Единственный способ, которым я вижу, что Nuget - любая помощь, - это когда компоненты, код или артефакты, которыми вы делитесь между командами/проектами, являются стабильными и имеют собственный цикл выпуска, который отличается от цикла выпуска проекта. Для ваших потребностей Nuget - это излишество. У вас может быть более высокая производительность, связанная со всеми такими проектами в рамках одного и того же решения. Структура вашего решения должна включать три проекта A, B и C в качестве зависимых проектов, на которые ссылаются внутри страны, где требуется.