Независимое управление версиями пакетов в моно-репо - PullRequest
0 голосов
/ 21 ноября 2018

Мы только начали работать над чем-то, что, возможно, лучше всего описать как «открытый» фреймворк для всей компании.Наш основной язык - C #, и мы используем Jenkins и ProGet для создания и обмена nuget-пакетами.Мы начали помещать все (и я действительно имею в виду все. Один модуль имеет как минимум три репозитория) в собственном Git-репо.Мы подумали, что это было бы хорошей идеей, поскольку мы можем создавать версии и публиковать все по отдельности, но это приводит к очень раздражающему рабочему процессу, если вы хотите вносить изменения в несколько репозиториев с зависимостями.

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

Репозиторий CoreFx является хорошим примером того, чего мы пытаемся достичь.Один репо, который приводит к множеству отдельных пакетов.Когда я создаю это локально, для всех пакетов существует один номер версии, но когда я смотрю на доступные версии пакетов на nuget.org, кажется, что версии для каждого пакета.Например, System.Diagnostics.DiagnosticsSource имеет версию 4.5.1, но ссылается на System.Diagnostics.Debug версию 4.3.0.

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

Кто-нибудь знает, как это достигается с помощью проекта corefx, или есть другие предложения, как это можно сделать?

1 Ответ

0 голосов
/ 21 ноября 2018

Как моноро, так и очень много репо имеют преимущества ;Одним из примеров преимуществ множества небольших репозиториев является то, что вы легко можете git tag конкретную версию отдельного пакета.Делать то же самое в монорепо иногда более неудобно.

Но если то, что вы выпускаете , является скорее "набором связанных пакетов", то, возможно, это не плохая идея в конце концов:у вас может быть один файл .bat или .ps1, который собирает все пакеты NuGet для вашего хранилища и соответственно устанавливает номер версии.Как и этот пример (скрипт Powershell)

Ссылки / зависимости, о которых вы говорите (System.Diagnostics.DiagnosticsSource версия 4.5.1 в зависимости от System.Diagnostics.Debug версия 4.3.0), становятся отдельными <dependency> теги в .nuspec пакета «потребление» (например, System.Diagnostics.DiagnosticsSource в данном случае.) Здесь вы можете выбрать две основные стратегии:

  • Всегда поднимать все версии <dependency>, чтобы"обновление одного обновляет все" пакеты.Иногда это то, что вы хотите, и тогда вы должны это сделать.
  • Будьте более детализированы: обновляйте зависимость только тогда, когда вы действительно используете какую-то более новую / обновленную функциональность.Например, когда пакет-потребитель использует метод, который существует только в конкретной версии зависимости.

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

.NET-специфические проблемы

Предположим, у меня есть проект A и проект B, который имеет ссылку на A и что оба находятся втот же репозиторий.Также у меня есть решение Visual Studio для проекта B, которое содержит ссылку на проект проекта A.

Теперь я внес изменения в проект B и увеличиваю его версию, не увеличивая версию проекта A. Я нажимаюмои изменения и Дженкинс делает чистую проверку репо и создает решение, создавая оба пакета, но пакет А теперь имеет ту же версию, что и в предыдущей сборке, и его нельзя отправить в ленту новостей

Это действительно интересная проблема.Некоторые потенциальные обходные пути:

  • Пусть Jenkins обнаружит / определит разницу между изменениями и только формирует пакеты для частей дерева, которые изменились.Возможно выполнимо , но, возможно, не очень легко;требует некоторой логики в вашем .ps1 скрипте.Пожалуй, самое изящное решение, которое я могу придумать.

  • Делать нажатия NuGet, которые терпят неудачу из-за того, что «версия уже существует», не является фатальной ошибкой.Т.е. обнаружите, когда вы запускаете nuget push, если вы получаете эту конкретную ошибку (очень важная деталь!), И игнорируйте ее.Вы определенно не хотите игнорировать все ошибки в nuget push, а только эти конкретные.Менее элегантный, но все же полностью автоматический.

  • Сделайте высвобождение пакетов полуавтоматическим вместо полностью автоматического процесса.Настройте одно или несколько заданий в Jenkins, где вы вручную «нажимаете кнопку», когда должна быть выпущена новая версия пакета, возможно, с аргументом задания, говорящим «какой пакет выпустить» (может быть выпадающим в Jenkins, поэтому никто не можетвводить имя вручную.) Возможно, звучит немного ручно по своей природе, но эта опция дает вам, как команде, максимальный уровень контроля над тем, какие пакеты отправляются и когда.

Дополнительная литература

(о монорепосах в целом, не относящихся конкретно к случаю CoreFx, о котором вы упомянули. Тем не менее, может предоставить ценную информацию.)

...