Незалежні пайплайни CI/CD: де ламається спільна збірка
Поки сервісів п'ять, спільна збірка виглядає зручно: один файл конфігурації, один набір перевірок, один артефакт на виході.
На тридцяти сервісах та сама схема стає вузьким місцем конвеєра — правка в одному модулі запускає повну перезбірку й ставить у чергу релізи команд, які нічого не змінювали.
Причина зазвичай у відсутності графа залежностей. Тригер спрацьовує на будь-який коміт, кеш залежностей спільний і інвалідується повністю, а блокуючі перевірки — лінтери, тести, перевірка вразливостей — проганяються по всьому репозиторію, хоча змінився один сервіс. Спільний тег образу погіршує картину: перезбирати доводиться й сусідів, які від правки не залежать.
Далі вмикається ефект черги. Час збірки зростає лінійно від кількості сервісів, а не від обсягу зміни, тому очікування вільних виконавців стає головною статтею простою.
Команди починають накопичувати правки в один великий реліз, відкат зачіпає одразу кілька сервісів, а зворотний зв'язок щодо якості приходить через години замість хвилин.
Розбираємо, як це закривається незалежними пайплайнами CI/CD: у кожного сервісу свій набір тригерів, ізольований кеш, власний артефакт і зрозуміла зона відповідальності за результат.
Що дає розділення збірки: швидкість, ізоляція, передбачуваність
Коли збірка одна на всі сервіси, будь-яка зміна в спільній бібліотеці тягне перезбірку всього дерева. Час зростає лінійно від кількості сервісів, а черга на спільних складальних агентах стає вузьким місцем: розробник чекає на результат довше, ніж пише код.
Незалежні конвеєри розривають цей зв'язок — сервіс збирається й перевіряється тільки тоді, коли змінювався його код або його залежності.
Ізоляція відмов — ефект, який помічають найраніше. Помилка в тестах одного сервісу більше не блокує випуск інших: збірка падає у своїй гілці, решта йдуть далі.
Клас інцидентів «упав один — стали всі» зникає, а межі відмови видно по кожному сервісу, а не тонуть у спільному журналі.
Повторне використання залежностей дає прискорення без втрати строгості.
Кеш шарів і артефактів прив'язується до хешу маніфесту: якщо склад залежностей не змінювався, крок установлення пропускається й береться готовий результат — час збірки скорочується з десятків хвилин до одиниць, і тим сильніше, чим більше сервісів використовують спільний набір бібліотек.
Швидкий відкат релізу — наслідок того самого розділення. Кожен сервіс випускається й відкочується своєю версією артефакту: повернення до попереднього образу не потребує перезбірки сусідів і не тягне чужі зміни.
У GitLab CI це виражається в правилах запуску за шляхами й окремих середовищах на сервіс; та сама модель відтворювана на будь-якому зрілому інструменті збірки.
У сумі зростає частота релізів: випуск перестає бути подією для всієї команди й стає рутинною операцією окремого сервісу.
Способи організації пайплайнів: порівняння варіантів
Модель організації конвеєрів CI/CD обирають не за розміром команди, а за тим, наскільки сервіси розходяться за стеком збірки, частотою релізів і вимогами до ізоляції.
Межі конвеєрів збігаються з межами відповідальності: чим автономніша команда, тим дорожчий спільний конвеєр у супроводі.
У монорепозиторії ті самі моделі дають різний компроміс. Спільний конвеєр збирає все на кожен коміт, шаблонний залишає єдиний стандарт етапів при своїх тригерах у сервісу, роздільні конвеєри дають незалежний випуск, але вимагають дисципліни під час правок у спільних бібліотеках.
| Варіант | Коли підходить | Обмеження підходу |
|---|---|---|
| Спільний конвеєр | 3-5 сервісів з однотипним стеком і спільним ритмом релізів | Правка одного етапу зачіпає всі сервіси; збій збірки блокує решту |
| Шаблонний конвеєр з успадкуванням | Десятки сервісів, єдиний стандарт перевірок і різні тригери | Зворотна сумісність шаблону: руйнівна зміна етапу вимагає міграції всіх спадкоємців |
| Окремий конвеєр на сервіс | Автономні команди, різні стеки, незалежний випуск | Дублювання описів етапів; розходження версій перевірок між сервісами |
| Монорепозиторій з відбором заторкнутих сервісів | Багато сервісів в одному репозиторії, часті спільні правки | Потрібен точний розбір графа залежностей: помилка дає пропущений реліз або зайві збірки |
Що перевірити перед вибором
Практичний критерій — вартість зміни: скільки сервісів зачепить правка одного етапу. Якщо відповідь «усі», час переходити від спільного конвеєра до шаблону або роздільних конвеєрів.
Порядок робіт: від аудиту конвеєрів до передачі команді
Розділення спільного конвеєра на незалежні пайплайни починають не з правки конфігурації, а з інвентаризації: поки не видно, що саме запускається на кожен коміт і що з цього справді залежить від зміненого коду, будь-які зміни дають випадковий результат.
Нижче — послідовність, у якій ризики знімаються по одному, а команда отримує робочу схему, а не набір файлів.
- Аудит конвеєрів. Збираємо список збірок, тригерів і стадій, вимірюємо час кожної з них і знаходимо блоки, які дублюються в усіх сервісах. На виході — картина, де збірка простоює в очікуванні чужого результату.
- Схема залежностей. Фіксуємо, які сервіси пов'язані спільними бібліотеками, схемами даних та образами. Позначаємо зв'язки, які зобов'язані викликати перезбірку, і ті, що можна розірвати без ризику.
- Проєктування роздільних конвеєрів. Кожному сервісу — свій набір стадій і свій тригер; повторювані кроки виносимо в перевикористовувані шаблони, щоб нова служба підключалася коротким описом.
- Налаштування середовищ. Розводимо середовища, кеш і артефакти так, щоб збірка одного сервісу не залежала від середовища сусідів; доступи видаємо за принципом мінімально необхідних.
- Перевірка збірки на релізі. Проганяємо схему на реальних випусках: паралельні збірки, відкат на попередню версію, поведінка при падінні однієї зі служб. Переконуємося, що ізольований збій не зупиняє решту.
- Передача документації. Віддаємо схеми конвеєрів, описи залежностей, регламент додавання сервісу й порядок правок, проводимо розбір із командою. Супровід далі йде без нашої участі.
Що залишається в репозиторії: конфігурації, схеми, регламенти
Інфраструктура, описана лише в головах інженерів, живе до першої відпустки або переходу автора на інший проєкт.
Тому незалежні пайплайни CI/CD ми фіксуємо як код у репозиторії: описи збірок, схеми середовищ і регламенти лежать поряд із сервісом і змінюються через рев'ю, а не за домовленістю в чаті. Після здачі замовник отримує повний комплект артефактів.
- Описи збірок. Декларативні конфігурації по кожному сервісу: стадії, кеш залежностей, умови запуску. Новий сервіс підключається копіюванням шаблону, а не налаштуванням з нуля.
- Схеми середовищ. Що де живе: середовища розробки, передпродакшену й продакшену, які гілки в них потрапляють, де зберігаються секрети й як вони ротуються.
- Політики доступу. Ролі для розробників, чергових і відповідальних за випуск: хто запускає збірку, хто викладає в прод, де потрібне підтвердження другого інженера.
- Регламент випуску релізу. Порядок кроків від прогону тестів до продакшену, точки відкату й критерії, за яких випуск зупиняється автоматично.
- Інструкції для чергових. Що перевірити при падінні збірки, як відкотити сервіс до попереднього образу, кому ескалювати — тексти, за якими можна діяти вночі без автора коду.
- Пам'ятка з підключення нового сервісу. Покроковий список: які файли додати, які політики розширити, як переконатися, що новий пайплайн не зачепив сусідні.
Усе це зберігається в тій самій системі контролю версій, що й код, — комплект оновлюється разом із проєктом, а не застаріває окремо від нього.
Кейс: як роздільні конвеєри прискорили релізи у 8 разів
У клієнта — платформа Фінансовий сервіс із 14 сервісів в одному репозиторії. Правка в одному модулі запускала спільний конвеєр: він збирав, тестував і публікував усе, включно із сервісами, яких зміни не торкалися.
Черга збірок займала машини на години, а реліз ішов єдиним пакетом — викотити одну правку окремо було не можна.
Що показували метрики до
Повний прогін тривав близько 48 хвилин, а якщо попереду стояли чужі збірки — очікування розтягувалося до 3-4 годин. Релізне вікно відкривалося раз на два тижні, і термінова правка чекала на нього разом з іншими.
Частка успішних випусків трималася на 62%: одна зламана перевірка в будь-якому сервісі блокувала весь пакет, тому відкочували реліз цілком.
Що змінили
Рознесли спільний конвеєр на незалежні: запуск за зміненими шляхами піднімає збірку тільки для заторкнутих сервісів, тести й артефакти версіонуються по кожному окремо. Спільні бібліотеки винесли в окремі перевірки, які проганяються лише при їхній правці. Додали роздільні середовища й автоматичний відкат на попередній артефакт сервісу.
Збірка вкладається в 6 хвилин, очікування в черзі — хвилини. Реліз будь-якого сервісу йде в день готовності, частка успішних випусків зросла до 94%, а відновлення після збою скоротилося з 40 хвилин до 7: відкат зачіпає один сервіс, а не всю платформу.
Що робити, якщо конвеєр уже зібрано в один спільний?
Спільний конвеєр на всі сервіси — типова точка зростання: правка одного кроку перезапускає збірку всіх репозиторіїв, а падіння на спільному етапі блокує релізи команд, які нічого не змінювали. Переписати все відразу не можна — це зупинка постачання. Тому перехід роблять шарами й тримають спільний конвеєр робочим до останнього сервісу.
Спочатку зі спільного опису виносять базову частину: установлення залежностей, перевірки, публікацію артефакту, шаблони розгортання. Спільний конвеєр стає тонкою обгорткою над нею й продовжує збирати все як раніше, а сервісний файл уже посилається на ту саму базу.
Зворотна сумісність збірок зберігається: імена артефактів, теги образів і змінні середовища не змінюються, тому відкат на попередній реліз залишається можливим.
Далі сервіси переводять по одному, починаючи з того, що релізиться найчастіше й слабше пов'язаний з іншими. Новий незалежний пайплайн CI/CD спрацьовує тільки на зміни у своєму репозиторії, старий обслуговує решту.
Перші прогони йдуть паралельно: артефакти й результати перевірок порівнюють, розходження розбирають до вимкнення попередньої схеми.
Заморозка релізів потрібна локально: правки в спільну частину на час перемикання сервісу не вносять, інакше міграція й звичайні зміни конфліктують. Постачання команд при цьому не зупиняють — вікно стосується лише спільної обв'язки.
Секрети, доступи до реєстру образів і права на середовища переносять заздалегідь, щоб сервісний конвеєр отримав рівно той самий обсяг доступу.
У системах виду GitLab CI і подібних опис конвеєра лежить у репозиторії, тому перехід зводиться до перенесення файлу й підключення спільних шаблонів, без переробки складального середовища.
Коли переведено останній сервіс, спільний файл видаляють: реліз кожного сервісу більше не залежить від сусідів.
Часті технічні сумніви щодо роздільних збірок
Незалежні пайплайни CI/CD піднімають у замовників одні й ті самі інженерні питання — не про «чи зможете», а про поведінку на їхній кодовій базі та в їхній команді.
Що робити зі спільними бібліотеками, від яких залежать майже всі сервіси?
Публікуємо спільний модуль як версіонований артефакт: сервіс фіксує конкретну версію, а не «останню». Оновлення бібліотеки перестає бути одночасним релізом — кожен сервіс переходить своїм конвеєром, коли готовий; сумісність тримають контрактні тести.
Чи потрібен окремий стенд тестування під кожен сервіс?
Ні: базові середовища спільні, а під гілку піднімається тимчасове — живе від першого коміту до злиття й видаляється само. Зовнішні залежності підмінюються заглушками з описаними відповідями, тому перевірки відтворювані й черга за одним стендом не збирається.
Налаштування збірок не роз'їдуться по сервісах?
Кроки збірки, перевірок і публікації винесені в перевикористовувані шаблони: конфігурація сервісу описує лише свої відмінності. Правка шаблону застосовується до всіх одразу, а розходження видно під час злиття, не в момент релізу.
Що з підтримкою після передачі?
Віддаємо конфігурації, схеми залежностей і регламент: як додати крок, як відкотити реліз, що робити при падінні перевірок. Ваші інженери розбирають це на живих збірках і далі змінюють їх самі.
Обговоримо задачу: розберемо конвеєри й повернемося з планом
Щоб повернутися з планом переведення сервісів на незалежні конвеєри, а не із загальними міркуваннями, нам потрібен доступ до вашої картини світу: репозиторії, середовища й розуміння, які сервіси критичні для бізнесу. Розбір займає одну зустріч, після неї ми збираємо схему й рахуємо обсяг робіт по кожному сервісу.
Що знадобиться від вас для старту:
- доступи до репозиторіїв — на читання гілок, історії збірок і правил захисту гілок, щоб відновити поточні регламенти, а не переписувати їх навмання;
- перелік сервісів із пріоритетами — що переводимо першим, що пов'язане з іншими спільними релізами й потребує узгодженого порядку;
- схема середовищ — скільки контурів, чим відрізняються їхні конфігурації, які є залежності від зовнішніх систем і баз даних;
- опис поточного шляху коду до продакшену — де зараз ручні кроки, які перевірки вже є і на якому етапі найчастіше ламається випуск;
- доступи до сховищ образів, конфігурацій і секретів на читання — розширені права видамо пізніше, за узгодженим планом і з обмеженням у часі;
- контактна особа з боку розробки й експлуатації — з ким узгоджувати зміни в правилах збірки та порядок відкату.
За підсумками обговорення ви отримаєте карту конвеєрів по сервісах, цільову схему середовищ і поетапний план переведення — від пілотного сервісу до решти. Опишіть задачу: повернемося з оцінкою обсягу робіт і планом.







