Альтернатива двоичным файлам в Subversion - PullRequest
23 голосов
/ 02 апреля 2009

Некоторые мои коллеги убеждены, что отправка артефактов сборки в хранилище Subversion - хорошая идея. Аргумент в том, что таким образом установка и обновление на тестовых машинах просты - просто "svn up"!

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

Это для кода Java, если это имеет значение. Все скомпилировано из Eclipse (без автоматических сборок PDE).

Когда я говорю добавить артефакты сборки, я имею в виду, что коммит будет выглядеть так:

"Added the new Whizbang feature"

 M src/foo/bar/Foo.java
 M bin/Foo.jar

Каждое изменение кода имеет соответствующий сгенерированный файл JAR.

Ответы [ 15 ]

24 голосов
/ 02 апреля 2009

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

Я думаю, что проблема в вашем случае заключается в том, что у вас нет надлежащих сценариев сборки. Вот почему создание двоичного файла из исходников включает в себя некоторую работу, например запуск затмения, импорт проекта, настройку classpathes и т. Д. *

Если имеются скрипты сборки, получение двоичных файлов можно выполнить с помощью команды, подобной:

svn update; ant dist

Я думаю, что самая важная причина не регистрировать двоичные файлы вместе с источником - это размер вашего репозитория. Это приведет к:

  • Большой репозиторий и, возможно, слишком мало места на системном сервере версий
  • Много трафика между сервером системы контроля версий и клиентами
  • Более длительное время обновления (представьте, что вы обновляете SVN из Интернета ...)

Другая причина может быть:

  • Исходный код легко сопоставим, поэтому многие функции системы управления версиями имеют смысл. Но вы не можете легко сравнить двоичные файлы ...

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

16 голосов
/ 02 апреля 2009

Во-первых, Subversion (и все другие в настоящее время) - это не менеджеры контроля исходного кода (я всегда думал, что SCM означает управление конфигурацией программного обеспечения), а системы контроля версий. Это означает, что они хранят изменения в материалах, которые вы храните в них, это не обязательно должен быть исходный код, это могут быть файлы изображений, растровые ресурсы, файлы конфигурации (текстовые или xml), все виды вещей. Есть только одна причина, почему встроенные двоичные файлы не должны рассматриваться как часть этого списка, и это потому, что вы можете перестроить их.

Однако подумайте, почему вы хотели бы также хранить выпущенные двоичные файлы там.

Во-первых, это система, которая помогает вам, а не рассказывает, как вы должны создавать свои приложения. Заставь компьютер работать на тебя, а не против тебя. Так что, если хранение двоичных файлов занимает много места - у вас есть сотни гигабайт дискового пространства и супер быстрые сети. Теперь нет ничего сложного в том, чтобы хранить там двоичные объекты (тогда как десять лет назад это могло быть проблемой - возможно, поэтому люди считают двоичные объекты в SCM плохой практикой).

Во-вторых, как разработчик, вам может быть удобно использовать систему для перестройки любой версии приложения, но другие, которые могут ее использовать (например, qa, test, support), могут этого не делать. Это означает, что вам понадобится альтернативная система для хранения двоичных файлов, и действительно, у вас уже есть такая система, это ваш SCM! Используйте это.

В-третьих, вы предполагаете, что можете восстановить из исходного кода. Очевидно, вы храните весь исходный код там, но вы не храните компилятор, библиотеки, sdks и все другие зависимые биты, которые требуются. Что происходит, когда кто-то приходит и спрашивает: «Можете ли вы собрать мне версию, которую мы поставили 2 года назад, у клиента есть проблема с этой версией». 2 года - это вечность, есть ли у вас тот же компилятор, который вы использовали тогда? Что происходит, когда вы проверяете весь источник только для того, чтобы обнаружить, что недавно обновленный sdk несовместим с вашим источником и дает сбой с ошибками? Вы стираете свой блок разработки и переустанавливаете все зависимости только для создания этого приложения? Можете ли вы вспомнить, какие были все зависимости?!

Последний пункт - самый важный. Чтобы сэкономить несколько килобайт дискового пространства, вы можете потратить несколько дней, если не недель боли. (И закон Сода также гласит, что любое приложение, которое вам нужно перестроить, будет тем самым, которое требовало самой непонятной, сложной для установки зависимости, от которой вы когда-либо были рады избавиться)

Так что храните двоичные файлы в своем SCM, не беспокойтесь о мелочах.

PS. мы помещаем все двоичные файлы в свои собственные каталоги 'release' для каждого проекта, затем, когда мы хотим обновить машину, мы используем специальный проект 'setup', который состоит только из svn: externals. Вы экспортируете проект установки, и все готово, поскольку он выбирает нужные вещи и помещает их в правильную структуру каталогов.

6 голосов
/ 02 апреля 2009

Сервер непрерывной интеграции, такой как Hudson , сможет архивировать артефакты сборки. Это не поможет вашему аргументу «почему нет», но, по крайней мере, это альтернатива.

5 голосов
/ 02 апреля 2009

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

Это хорошая идея для управления выпуском цели, более конкретно для:

1 / Вопрос об упаковке

Если артефакт сборки - это не только exe (или dll или ...), но также:

  • некоторые файлы конфигурации
  • некоторые скрипты для запуска / остановки / перезапуска вашего артефакта
  • некоторые sql для обновления вашей базы данных
  • некоторые источники (сжатые в файл) для облегчения отладки
  • некоторая документация (сжатый в файле javadoc)

затем хорошая идея иметь артефакт сборки и всех связанных файлов, хранящихся в VCS.
(Потому что это больше не просто вопрос «перестройки» артефакта, но также «извлечения» всех тех дополнительных файлов, которые будут запускать этот артефакт)

2 / Проблема развертывания

Предположим, вам нужно развернуть множество артефактов в разных средах (тестирование, омологация, подготовка к производству, производство).
Если:

  • вы создаете много артефактов сборки
  • эти артефакты достаточно длинные, чтобы воссоздать их с нуля

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

Но вы должны помнить:

  • 1 / вы не можете хранить каждые артефактов, которые вы делаете в VCS: все промежуточные сборки, которые вы делаете для непрерывной интеграции, должны не храниться в VCS (или в итоге у вас будет огромное хранилище со множеством бесполезных версий двоичных файлов).
    Необходимо указывать только версии, необходимые для омологации и производства.
    Для промежуточной сборки необходим внешний репозиторий (maven или общий каталог), чтобы быстро публиковать / тестировать эти сборки.

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

5 голосов
/ 02 апреля 2009

Я уверен, что есть веские аргументы против этой плохой практики

У вас неверное предположение, что фиксация "артефактов сборки" в управлении версиями - плохая идея (если вы неправильно сформулировали свой вопрос). Это не так.

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

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

Таким образом, нет причин, по которым вы должны так бояться хранить «артефакты сборки» в управлении версиями. То, что вы можете сделать, это хранить их в разных местах.

Я предлагаю разделить их следующим образом:

 ProjectName
 |--- /trunk
 |    |--- /build
 |    |    |--- /bin        <-- compilers go here
 |    |    |--- /lib        <-- libraries (*.dll, *.jar) go here
 |    |    '--- /object     <-- object files (*.class, *.jar) go here
 |    '--- /source          <-- sources (*.java) go here
 |         |--- package1    <-- sources (*.java) go here
 |         |--- package2    <-- sources (*.java) go here

Вам необходимо настроить IDE или ваши сценарии сборки для размещения объектных файлов в / ProjectName / trunk / build / object (возможно, даже воссоздать структуру каталогов в ... / source).

Таким образом, вы предоставляете своим пользователям возможность извлекать либо / ProjectName / trunk для получения полной среды сборки, либо / ProjectName / trunk / source для получения источника приложения.

В ../build/bin и ../build/lib вы должны разместить компиляторы и библиотеки, которые использовались для компиляции конечного продукта, те, которые использовались для доставки программного обеспечения пользователю. Через 5 или 10 лет они у вас будут, и в некоторых случаях вы сможете их использовать.

4 голосов
/ 02 апреля 2009

Поместить двоичные файлы в ствол или ветви определенно излишне. Помимо занимаемого пространства, как вы упомянули, это также приводит к несоответствиям между источником и двоичными файлами. Когда вы ссылаетесь на ревизию 1234, вы не хотите задаваться вопросом, означает ли это «сборка, полученная из источника в ревизии 1234, против« двоичных файлов в ревизии 1234 ». То же правило избегания несоответствий применяется к автоматически сгенерированному коду. Вы не должны указывать версию, которая может быть сгенерирована при сборке.

OTOH Я более или менее в порядке, помещая двоичные файлы в теги . Таким образом, другим проектам легко использовать двоичные файлы других проектов через svn: externals, не создавая все эти зависимости. Это также позволяет тестировщикам легко переключаться между тегами, не нуждаясь в полной среде сборки.

Чтобы получить двоичные файлы в тегах, вы можете использовать эту процедуру:

  1. проверить рабочую копию
  2. запустить скрипт сборки и оценить результаты любого теста
  3. если сборка в порядке, svn добавляет двоичные файлы
  4. вместо фиксации в сундуке или ветка, пометка прямо с вашего рабочая копия вот так: svn copy myWorkingCopyFolder myTagURL
  5. отказаться от рабочей копии, чтобы избежать случайные коммиты двоичных файлов в ствол или ветка

У нас есть tagbuild скрипт для полуавтоматизации шагов 3 и 4.

4 голосов
/ 02 апреля 2009

Двоичные файлы, особенно ваши, но и сторонние, не имеют места в инструменте контроля версий, таком как SVN.

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

Для сторонних двоичных файлов вам понадобится инструмент управления зависимостями, такой как Maven2. Затем вы можете настроить локальный репозиторий Maven для обработки всех сторонних двоичных файлов (или просто полагаться на общедоступные). Локальное хранилище также может управлять своими собственными двоичными файлами.

4 голосов
/ 02 апреля 2009

По моему опыту, хранение банок в SVN может закончиться беспорядком.
Я думаю, что лучше сохранять Jar-файлы в репозитории Maven, например Nexus .
Это также имеет то преимущество, что вы можете использовать инструмент управления зависимостями, такой как Maven или Ivy.

2 голосов
/ 02 апреля 2009

Одной из веских причин будет быстрый запуск исполняемого файла на новой машине. В частности, если среда сборки требует времени для настройки. (Загрузка компиляторов, сторонних библиотек и инструментов и т. Д.)

1 голос
/ 02 апреля 2009

Контроль версий должен иметь все, что вам нужно сделать: svn co, а затем собрать. У него не должно быть промежуточных продуктов или конечного продукта, так как это противоречит цели. Вы можете создать новый проект в SVN для результата и отдельно отразить двоичный результат (для выпусков и исправлений при необходимости).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...