Монорепозиторії: будь ласка, треба

Монорепозиторії: будь ласка, треба

Переклад статті підготовлений для студентів курсу «DevOps практики та інструменти» у освітньому проекті OTUS.

Ви повинні вибрати монорепозиторій, тому що поведінка, якій він сприяє у ваших командах, - це прозорість і колективна відповідальність, особливо при зростанні команд. У будь-якому випадку вам доведеться вкладатися в інструментарій, але завжди краще, коли стандартна поведінка — це поведінка, яку ви хочете бачити у своїх командах.

Чому ми говоримо про це?

Метт Кляйн (Matt Klein) написав статтю «Monorepos: Please don't!»  (прим. перекладача: переклад на хабрі «Монорепозиторії: будь ласка, не треба»). Мені подобається Метт, я думаю, що він дуже розумний, і ви повинні прочитати його думку. Спочатку він опублікував опитування у твіттері:

Монорепозиторії: будь ласка, треба

Переклад:
Цього новорічного дня я посперечаюсь про те, наскільки безглузді монорепозиторії. 2019 рік розпочався непомітно. На кшталт цього я пропоную вам опитування. Хто більші фанатики? Прихильники:
- Монорепозиторія
- Іржа
- Неправильне опитування / і ті, і ті

Моя відповідь була: «Я буквально обидві ці людини». Замість того щоб говорити про те, який Rust наркотик, давайте розберемося, чому я думаю, що він помиляється щодо монорепозиторіїв. Трохи про себе. Я технічний директор Chef Software. У нас близько 100 інженерів, кодова база, що налічує близько 11–12 років, та 4 основні продукти. Частина цього коду знаходиться в полірепозиторії (моя стартова позиція), частина монорепозиторії (моя поточна позиція).

Перш ніж я почну: кожен аргумент, який я тут наводжу, буде застосовано до репозиторій обох видів. На мою думку, немає жодних технічних причин, з яких ви повинні вибрати той чи інший тип репозиторію. Ви можете змусити працювати будь-який підхід. Я радий поговорити про це, але мене не цікавлять штучні технічні причини, через які одне перевершує інше.

Я згоден з першою частиною погляду Метта:

Тому що на великому масштабі монорепозиторій буде вирішувати ті самі проблеми, які вирішує і полірепозиторій, але при цьому провокуючи вас до сильної зв'язності вашого коду і вимагаючи неймовірних зусиль зі збільшення масштабованості вашої системи контролю версій.

Вам належить вирішити однакові проблеми незалежно від того ви оберете ви монорепозиторій або полірепозиторій. Як ви випускаєте релізи? Який у вас підхід до оновлень? Зворотня сумісність? Перехресні залежності проектів? Які архітектурні стилі є прийнятними? Як ви керуєте своєю інфраструктурою складання та тестування? Список нескінченний. І ви вирішуватимете їх у міру того, як ростете. Безкоштовного сиру немає.

Я думаю, що аргумент Метта схожий на погляди, які поділяють багато інженерів (і менеджерів), яких я поважаю. Це відбувається з погляду інженера, що працює над компонентом, або команди, що працює над компонентом. Ви чуєте такі речі, як:

  • Кодова база громіздка — мені не потрібен весь цей мотлох.
  • Це складніше тестувати, тому що я повинен перевірити весь цей мотлох, який мені не потрібен.
  • Складніше працювати із зовнішніми залежностями.
  • Мені потрібні свої віртуальні системи керування версіями.

Безперечно, всі ці пункти є обґрунтованими. Це відбувається в обох випадках — у полірепозиторії я маю свій мотлох, крім того, який потрібен для складання… Мені може знадобитися ще й інший мотлох. Тому я «просто» створюю інструменти, які роблять чекають всього проекту. Або я створюю фальшивий монорепозиторій з підмодулями. Ми могли б ходити весь день навколо це. Але я думаю, що аргумент Метта пропускає основну причину, яку я досить сильно перевернув на користь монорепозиторію:

Він провокує спілкування та показує проблеми

Коли ми поділяємо репозиторії, ми де-факто створюємо проблему координації та прозорості. Це відповідає тому, як ми думаємо про команди (особливо тому, як думають про них окремі учасники): ми відповідаємо за певний компонент. Ми працюємо у відносній ізоляції. Кордони фіксуються на моїй команді та компоненті (-ах), над якими ми працюємо.

При ускладненні архітектури одна команда не може більше керувати нею поодинці. Дуже небагато інженерів тримають всю систему в голові. Допустимо, ви керуєте загальним компонентом A, який використовується командами B, C та D. Команда A проводить рефакторинг, покращує API, а також змінює внутрішню реалізацію. В результаті зміни є несумісними. Яку пораду ви дасте?

  • Знайти усі місця, де використовується старий API.
  • Чи є місця, де не можна використовувати новий API?
  • Чи можете ви виправити та протестувати інші компоненти, щоб переконатися, що вони не зламаються?
  • Чи можуть ці команди перевірити ваші зміни зараз?

Зауважте, що ці питання не залежать від типу репозиторію. Вам потрібно буде знайти команди B, C та D. Вам потрібно буде поговорити з ними, з'ясувати час, зрозуміти їхні пріоритети. Принаймні, ми сподіваємося, що ви це зробите.

Насправді, ніхто не хоче займатися цим. Це набагато менш цікаво, ніж просто виправлення чортового API. Все це людське та заплутане. У полірепозиторії ви можете просто внести зміни, дати рев'ю тим, хто працює над цим компонентом (ймовірно, не B, C або D), і рухатися далі. Команди B, C і D можуть поки що просто залишатися на своїй поточній версії. Вони оновляться, коли розуміють вашу геніальність!

У монорепозиторії відповідальність зсувається за умовчанням. Команда A змінює свій компонент і, якщо не виявить обережності, негайно ламає B, C і D. Це призводить до того, що B, C і D з'являються біля дверей A, дивуючись чому команда A зламала збірку. Це вчить тому, що вони не можуть пропустити мій список вище. Вони повинні говорити, що вони збираються робити. Чи можуть B, C та D рухатися? Що, якщо B і C можуть, але D був тісно пов'язаний із побічним ефектом поведінки старого алгоритму?

Потім ми повинні поговорити про те, як ми вийдемо з цієї ситуації:

  1. Підтримка кількох внутрішніх API, при цьому старий алгоритм буде позначений застарілим, поки D не зможе припинити його використання.
  2. Підтримка кількох версій релізів, одна зі старим інтерфейсом, одна з новим.
  3. Затримка релізу змін A доти, доки одночасно B, C і D не зможуть прийняти його.

Допустимо, ми вибрали 1, кілька API. У цьому випадку у нас є два шматки коду. Старий та новий. Досить зручно у деяких ситуаціях. Ми повертаємо старий код назад, помічаємо застарілим (deprecated) і погоджуємо графік його видалення з командою D. Фактично ідентично полі і монорепозитория.

Для релізу кількох версій нам потрібна гілка. Тепер у нас є два компоненти – А1 та А2. Команди B та C використовують A2, а D використовує A1. Нам потрібно, щоб кожен компонент був готовий до релізу, тому що, перш ніж D зможе рухатися далі, можуть знадобитися оновлення безпеки та виправлення інших помилок. У полірепозиторії ми можемо сховати це у довгоживучій гілці, яка почувається добре. У монорепозиторії ми примусово створюємо код у новому модулі. Команді D все ще доведеться вносити зміни до «старого» компонента. Кожен може побачити вартість, яку ми тут платимо — у нас тепер удвічі більше за код, і будь-які виправлення помилок, які застосовуються до A1 і A2, повинні застосовуватися для них обох. З підходом використання гілок у полірепозиторії це приховано за cherry-pick. Ми вважаємо вартість як меншу, бо там нема дублювання. З практичної точки зору, вартість однакова: ви створюватимете, випускатимете і підтримуватимете дві, в основному ідентичні, бази коду доти, доки не зможете видалити одну з них. Різниця в тому, що у монорепозиторія цей біль прямий і він на увазі. Це ще гірше і це добре.

Зрештою, ми дісталися третього пункту. Затримка релізу. Можливо, що зміни, внесені А, покращать життя команди А. Важливо, але не терміново. Чи можемо ми просто затримати? У полірепозиторії ми підштовхуємо це до закріплення артефакту. Звичайно, ми говоримо про цю команду D. Просто залишайтеся на старій версії, поки не наздоженете! Це налаштовує на гру в труса. Команда A продовжує працювати над своїм компонентом, ігноруючи той факт, що команда D використовує більш застарілу версію (це проблема команди D, вони дурні). Тим часом, команда D говорить погано про необережне ставлення команди A до стабільності коду, якщо вони взагалі говорять про це. Минають місяці. Нарешті, команда D вирішує поглянути на можливість оновлення, але змін A стало тільки більше. Команда А ледве пам'ятає, коли і як вони зламали D. Оновлення більш болісне і займе більше часу. Що відправляє його далі вниз стеком пріоритетів. До того дня, поки у нас не виникне проблема безпеки в А, що змушує нас робити гілку. Команда A повинна повернутись назад у часі, знайти момент, коли D був стабільним, виправити там проблему і зробити його готовим до релізу. Це де-факто вибір, який роблять люди, і він, безумовно, найгірший. Здається, це добре як для команди A, так і для D, поки ми можемо ігнорувати один одного.

У монорепозиторії третій – справді не варіант. Ви змушені справлятися із ситуацією одним із двох способів. Вам необхідно бачити витрати наявності двох релізних гілок. Навчитися захищати себе від оновлень, що ламають зворотну сумісність. Але головне: вам не уникнути складної розмови.

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

Так, ви можете створити інструменти, які намагатимуться вирішити проблему полірепозиторіїв. Але мій досвід навчання безперервної поставки (continuous delivery) і автоматизації на великих підприємствах говорить мені таке: поведінка за умовчанням без використання додаткових інструментів — це поведінка, яку ви очікуєте бачити. Поведінка полірепозиторію за умовчанням — ізоляція, ото й увесь сенс. Поведінка монорепозиторія за умовчанням - це загальна відповідальність і прозорість, отож і весь зміст. В обох випадках я збираюся створити інструмент, який дозволить згладити гострі кути. Як керівник, я вибиратиму монорепозиторій щоразу, бо інструменти мають зміцнювати культуру, яку я хочу, а культура виходить із крихітних рішень та щоденної роботи команди.

Тільки зареєстровані користувачі можуть брати участь в опитуванні. Увійдіть, будь ласка.

Хто більші фанатики? Прихильники:

  • Монорепозиторія

  • Іржа

  • Неправильне опитування / і ті, і ті

Проголосували 33 користувачів. Утрималися 13 користувачів.

Джерело: habr.com

Додати коментар або відгук