Как организовать ваше двухслойное приложение в монорепозитории

В Renuo мы начали с 2016 года с разработки приложений на Rails и Angular2. Эти две технологии отлично работают вместе, если вы хотите разработать SPA.

Есть некоторые моменты, которые, тем не менее, мы до сих пор не решили, и которые постоянно раздражают меня.

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

Поддержите 2 репозитория git, получите 2 запроса на слияние, почувствуйте двойную боль

Мы храним каждый слой в отдельном репозитории git, и, даже если это кажется идеальной разумной идеей, она приносит много проблем:

Если я внесу изменения, например, во Frontend и Backend, их нельзя будет объединить, потому что они зависят друг от друга.

Ситуация очень проста: представьте, что вы меняете свой API и вместо того, чтобы возвращать атрибут createdAt, вы теперь возвращаете атрибут createdOn. Шаги будут такими:

  1. Создайте новую версию API, в которой вы возвращаете новый атрибут и сохраняете старый в предыдущей версии.
  2. Сделать запрос на слияние
  3. Обзор кода
  4. Развертывать
  5. Измените Frontend, чтобы использовать новую версию API
  6. Сделать запрос на слияние
  7. Проверка кода
  8. Развертывать
  9. Удалите старую версию API из Backend
  10. Сделать запрос на слияние
  11. Проверка кода
  12. Развертывать

Но мы не разрабатываем общедоступный API, и наш Backend используется только нашим Frontend, поэтому мы можем упростить процесс:

  1. Заменить атрибут в Backend
  2. Открытый запрос на извлечение
  3. Проверка кода (НЕ ОБЪЕДИНЯЙТЕСЬ!)
  4. Заменить атрибут в Frontend
  5. Открытый запрос на извлечение
  6. Проверка кода (НЕ ОБЪЕДИНЯЙТЕСЬ!)
  7. Быстро нажмите кнопку слияния на обоих Pull Request и разверните новую версию как Backend, так и Frontend.

Вы начинаете чувствовать боль 😏.

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

В итоге вы получите следующее:

Мы не можем проводить приемочные испытания

Провести приемочные испытания очень сложно. Если вы рассмотрите ситуацию, описанную в предыдущем абзаце, вы можете представить, что приемочные тесты должны использовать правильную ветку из каждого репозитория. Итак, если у меня есть ветка feature/3000 на Frontend (для которой также требуется ветка feature/3000 на Backend), как мне провести приемочные тесты? Против какой ветви? Может быть, у вас есть решение. Мы этого не делаем.

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

Команда разделена на Frontend и Backend

Гораздо проще разделить вашу команду на людей, занимающихся Frontend и Backend. Это плохо.

Наше предложение: одно репозиторий git, чтобы управлять ими всеми

После некоторого расследования я обнаружил это слово: monorepo и понял, что многие люди уже перечислили многие из ваших преимуществ.

Для конкретного примера перейдите по этой ссылке и посмотрите репозиторий и соответствующую конфигурацию Travis.

Я предлагаю разместить как серверную часть, так и интерфейсную часть в одном репозитории Git. Просто и глупо.

Вы сразу получите множество преимуществ:

  1. Вы можете снова проводить приемочные испытания!
  2. Вы можете обновить свои API с помощью одного запроса на слияние, одного обзора кода и одного развертывания.
  3. Вы заставите людей из Frontend разрабатывать также Backend часть.
  4. Вы заставите Backend людей разрабатывать также и Frontend часть.
  5. Вы можете скачать и настроить свой проект за один шаг
  6. Вы по-прежнему можете работать над каждым проектом отдельно
  7. Вы можете запускать как Backend, так и Frontend в одной команде (проверьте репозиторий на наличие очень простой конфигурации Foreman).
  8. Вы по-прежнему можете развертывать каждый проект отдельно (вас может заинтересовать этот небольшой фрагмент bash:
if [ `git diff — name-only HEAD~..HEAD backend | wc -l` -gt 0 ];

который сообщит вам, внесла ли последняя фиксация какие-либо изменения в ваш Backend.

Я хочу сделать это сейчас

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

Заключение

Использование Monorepo - вполне разумный и правильный подход при разработке одного или нескольких приложений, строго связанных друг с другом.

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