Как мы тестируем и разворачиваем наш код, разбив его на многократно используемые фрагменты?


9

Мы начали с одного разработчика и одного репозитория SVN, содержащего весь наш код:

^/foo/trunk/module-a
^/foo/trunk/module-b
^/foo/trunk/module-b/submodule-b1
^/foo/trunk/website1

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

Желая модулировать кодовую базу и ожидая, что мы вскоре перейдем к git (и прочитав где-то, что git не любит svn mega-repos), мы перешли к гораздо более детальной структуре:

^/module-a/trunk/
^/module-b/trunk/
^/module-b/trunk/sumbmodule-b1
^/earlier-sub-sub-sub-module-c/trunk
etc. (about 120 such modules)

Это было концептуально здорово. Более модульный код, намного более быстрые тестовые наборы, более легкое документирование и т. Д. Мы открыли некоторые из наших более общих компонентов и сделали все модули готовыми к установке (используя их pip install -e .для установки в developmentvirtualenv).

Мы создали ^/srv/trunkрепозиторий, содержащий структуру папок среды выполнения, т.е. ^/srv/trunk/libдля модулей, /srv/trunk/srcдля остатков ^/foo/trunk, ^/srv/trunk/wwwдля веб-сайтов и т. д.

И наконец (взяв идею из перформанса, с которым я работал очень давно [ https://www.perforce.com/perforce/r12.1/manuals/cmdref/client.html] ), мы создали «vcs- «Получить текстовый файл», в котором перечислены все соответствующие репозитории и где их следует извлечь в среду разработки, и соответствующую команду для этого. Например, строка vcs-fetc:

svn srv/lib/module-a ^/module-a/trunk

вызовет либо (первый раз)

cd /srv/lib && svn co ^/module-a/trunk module-a

или (потом)

cd /srv/lib/module-a && svn up

и аналогично для репозиториев github (как наших собственных, так и измененных / неизмененных пакетов поставщиков).

Мы использовали тот же процесс vcs-fetch для создания производственной среды, но мы быстро обнаруживаем, что у нас нет способа узнать, какая версия использовалась в prod после выполнения vcs-fetch.

С мега-репо мы могли просто записать номер ревизии, прежде чем обновлять prod из транка, и вернуться назад было просто svn -r nnn up .. С кодом как в SVN, так и в Git (и один модуль в HG) - и ~ 120 репозиториев, не очевидно, как это сделать ..

Сегодня я читаю http://12factor.net/ , и первый фактор - это «Одна кодовая база», поэтому мне также интересно, ухожу ли я с правильного пути?

У меня была одна идея - создать сценарий развертывания, который бы создавал pip-устанавливаемые колеса «развертывания» и «связывал» их вместе в requirements.txtфайл. Развертывание будет включать создание нового virtualenv, установку pip-файла require.txt со списком колес развертывания и переключение активного virtualenv. Возврат к предыдущему будет просто включать переключение virtualenv обратно (но если мы не хотим вечно хранить virtualenvs, это не позволит нам вернуться к любому моменту времени - в моем опыте, который никогда не был необходим).

В этот момент мне интересно, иду ли я в неправильном направлении, или я просто недостаточно далеко зашел по правильному пути? (все, что я читаю, говорит о «вашем приложении», и я не знаю, как это приводит к запуску 14 сайтов с одной и той же кодовой базой ...)


Могу ли я предположить, что отдельные компоненты сейчас разрабатываются разными командами с разными циклами разработки? Если это так, то разрыв хранилища в любом случае неизбежен. Несмотря на то, что с помощью git вы бы разместили теги синхронизированных выпусков для основных стабильных конфигураций. Взгляните на инструмент репо Google. Попытка сопоставить версии разработки с помощью интегрированных метаданных практически бесполезна. Соединение приложения через pip также вполне законно.
Ext3h

Если вы включите оценки KLOC (1000 строк кода) и байтовые показатели кода, мы можем легко получить представление о размере, например «2000 строк кода. Исходный код 50 килобайт». или "40 KLOC, 2 ГБ XML". , Кажется, что вам нужно просто перейти на git, и git имеет функции импорта. Вы можете начать с чтения Git Book .
Никлас

1
@ Programmer400 кодовая база: .py 670 клок, .js: 135kloc, .less: 25kloc, .html: 130kloc. Такой большой, но не огромный. Из того, что я прочитал, git не очень нравятся репо такого размера, так что я думаю, нам придется разделить репо на более мелкие, прежде чем перейти на git ..?
Thebjorn

Ответы:


2

Похоже, вы пропустили ветви (или, скорее, «теги» или «выпустить» ветви).

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

Это упрощает ветвление, даже если нет никаких изменений, поэтому каждый модуль сохраняет один и тот же номер выпуска, однако вашим пакетам OSS может не понравиться ветвление без изменений, поэтому следующая лучшая вещь - сохранить скрипт зависимостей - так, версия 5 вашего продукта требует OSS модуль X v2 и так далее.

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

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


1

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

Я все за то, чтобы разделить их на некотором уровне детализации, особенно если у вас несколько команд и разные циклы выпуска, как упоминает @ Ext3h.

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


Используйте подмодули git. С помощью субмодулей вы можете хранить каждый модуль в отдельном git-репо, аналогично настройке svn, а также тому, о чем вы думаете. Затем вы связываете эти модули с корневым проектом, который будет содержать ссылку на соответствующий коммит каждого подмодуля, для каждого из его собственных коммитов.

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

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

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


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

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

Есть и другие системы; Я создал довольно большой проект, используя слегка настроенную версию Apache Ivy как инструмент для упаковки и публикации каждого модуля, а также собрал их вместе для окончательного проекта. Ivy также хранит манифест со списком всех версий всех модулей, на которые вы ссылаетесь, если вам потребуется заново создать настройку позже.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.