CI/CD: інтеграція, доставка, розгортання
Зміст
Уяви команду з десяти розробників, де кожен два тижні пише свою фічу у власній гілці й ні з ким не зливається. За два тижні всі одночасно намагаються влити код у спільну — і починається те, що індустрія назвала інтеграційним пеклом (integration hell): на пів дня, «а в мене локально працювало», , який не збирається, тести, які ніхто не запускав, і ніхто не знає, чия саме зміна все зламала. Реліз, який планували на п'ятницю, з'їжджає на наступний тиждень. CI/CD — це відповідь індустрії на цей біль: не героїчно інтегруватися раз на спринт, а робити це маленькими порціями щодня й одразу автоматично перевіряти.
Для AQA ця тема — не «щось про девопсів». (pipeline) — це середовище, у якому живуть твої автотести: вони запускаються там на кожен , там падають з незрозумілих причин, там стають гейтом, що блокує реліз. А плутанина між CI, CD і пайплайном одразу видає рівень: хто не розрізняє їх, той не розуміє, що саме блокує його реліз і хто це полагодить. Тож розберемо механізм, а не визначення з вікіпедії.
«Інтеграційне пекло» і навіщо CI
Чому інтеграція взагалі болить? Бо що довше дві гілки розходяться, то більше між ними накопичується прихованих несумісностей: конфлікти в одних файлах, мовчазні логічні конфлікти в різних (мій код і твій код окремо коректні, а разом ламають фічу), розбіжність залежностей. Складність інтеграції росте не лінійно, а різко — і вибухає саме тоді, коли часу вже немає.
Безперервна інтеграція (continuous integration, CI) розвертає цю логіку: якщо інтегруватися боляче — роби це якнайчастіше, доки порція змін маленька. Кожен розробник щодня (а то й кілька разів на день) зливає свою роботу у спільну магістраль (trunk), і на кожне таке злиття автоматика збирає проєкт і ганяє тести. Дрібний конфлікт видно й лагодиться за хвилини, а не за пів дня наприкінці спринту.
Ключова думка теми: CI — це передусім практика (дисципліна команди), а не інструмент. Можна поставити Jenkins чи GitHub Actions і не мати ніякого CI, якщо всі сидять по своїх гілках тижнями. І навпаки: суть CI — часте злиття в спільну гілку плюс автоматична перевірка кожного злиття. Інструмент лише автоматизує те, що команда й так вирішила робити.
Три звички, без яких CI не працює:
- Часті дрібні коміти в спільну гілку — не «велика фіча раз на два тижні», а маленькі порції щодня. Це прямо пов'язано з trunk-based development (див. розділ Pull Request і стратегії гілкування).
- Автоматична перевірка на кожен коміт — білд і тести запускає машина, не людина за настроєм.
- Зелена магістраль понад усе. Якщо перевірка червона — це стоп-сигнал: спільна гілка зламана, і команда лагодить її раніше, ніж додає нове. «Не зупиняй конвеєр із дефектом» — той самий принцип, що на реальному складальному конвеєрі.
Continuous Integration: як це виглядає механічно
Механіка проста й однакова майже всюди. Розробник робить git push (або відкриває Pull Request). CI-сервер помічає цю подію, бере свіжий код, у чистому середовищі збирає проєкт, проганяє тести й повертає статус: зелено або червоно. Статус видно прямо в Pull Request — червоний чек блокує злиття, зелений дозволяє.
Що дає ця петля на практиці:
- ловить машина за хвилини після коміту, а не тестувальник за тиждень перед релізом.
- «В мене локально працювало» більше не аргумент: збірка йде в чистому, відтворюваному середовищі, однаковому для всіх (звідси природний перехід до — див. Docker і тестові середовища).
- Історія перевірок прив'язана до комітів: видно, який саме коміт зробив магістраль червоною.
Тут і живуть твої автотести. У CI прогін відрізняється від локального: headless-браузер, інші ресурси агента, інші таймінги — і тест, зелений у тебе на машині, у CI може миготіти. Це окрема велика тема (див. Автотести в CI: стабільність і дебаг), але вже тут важливо засвоїти: нестабільний (flaky) тест руйнує весь сенс CI. Якщо пайплайн падає «через раз» без причини, команда перестає довіряти червоному кольору й починає його ігнорувати — а тоді гейт не гейт.
CI vs Continuous Delivery vs Continuous Deployment
Це найчастіше плутане місце, бо обидва CD — і Delivery, і Deployment — скорочуються однаково. Розберемо по межах відповідальності. Уяви пайплайн: коміт → білд → тести → готовий артефакт → на staging → деплой на prod. Три практики покривають різні відрізки цього пайплайна.
- Continuous Integration (CI) відповідає за відрізок від коміту до готового артефакта: інтегрувати, зібрати, протестувати. На виході — перевірена збірка. Куди й коли її котити — уже поза CI.
- Безперервна доставка (continuous delivery) розширює пайплайн далі: кожна зелена збірка автоматично доводиться до стану «готова до релізу» — прогнана через усі стадії, розгорнута на staging, залишилося тільки натиснути кнопку. Рішення коли котити на prod ухвалює людина. Тобто prod-деплой — за один клік, але клік свідомий.
- Безперервне розгортання (continuous deployment) прибирає й цю кнопку: кожна збірка, що пройшла всі перевірки, автоматично їде на prod без ручного апруву. Людина в петлю релізу вже не вмикається — її роль перенесена в автоматичні гейти й моніторинг.
Головний водорозділ між двома CD — наявність ручного апруву перед prod. Continuous Delivery = «завжди готові релізнути одним кліком, але вирішує людина». Continuous Deployment = «релізимо самі, без кліку». Друге вимагає значно зрілішого автоматизованого : раз людина не дивиться перед prod, то весь захист — це перевірки в пайплайні (і сильна з можливістю швидкого rollback, див. Середовища, деплой і релізи).
| Практика | Що автоматизовано | Хто вирішує «котимо на prod» |
|---|---|---|
| Continuous Integration | Злиття, білд, тести | Реліз узагалі поза скоупом |
| Continuous Delivery | Усе аж до staging; prod — за одну дію | Людина (свідомий клік) |
| Continuous Deployment | Усе, включно з prod | Ніхто — автоматика, якщо перевірки зелені |
Практична підказка на співбесіду: якщо тебе просять «в двох словах» — CI про інтеграцію коду, Delivery про готовність релізу будь-коли, Deployment про автоматичний реліз без людини. Continuous Delivery — обов'язкова Continuous Deployment, але не навпаки.
Пайплайн як конвеєр якості
Пайплайн — це автоматизована послідовність стадій, які код проходить від коміту до (потенційно) продакшену. Правильна ментальна модель — конвеєр контролю якості: на кожній станції стоїть перевірка, і деталь їде далі, лише якщо станцію пройдено. Не пройшов lint — далі не поїхав; впав unit-тест — до e2e справа не дійшла.
Чому саме конвеєр, а не «купа перевірок». Порядок стадій вибирають за принципом fail fast — «впасти якомога раніше й дешевше»: спершу найшвидші й найдешевші перевірки, потім повільні й дорогі.
Логіка тут економічна: немає сенсу тримати агента пів години на e2e, якщо код не проходить навіть перевірку типів — цю помилку треба показати автору за секунди. Порядок «lint → типи → unit → integration → e2e» прямо лягає на (широка дешева основа знизу, вузький дорогий верх). Це і є конвеєр якості: кожна стадія — фільтр, а разом вони не пускають дефект далі по трубі.
Детальну будову — стадії, , тригери, артефакти джобів — розбирає окрема глава Будова пайплайна. А те, яка стадія має блокувати злиття і що ганяти на PR проти nightly, — це стратегія якості в пайплайні, канон теми — Стратегія якості в пайплайні. Тут важливий сам : не «набір скриптів», а впорядкована черга гейтів.
Білд і артефакт
Два слова, які junior часто вживає навмання. Розведемо їх.
Білд (build) — це процес перетворення вихідного коду в форму, придатну до запуску чи розгортання. Для компільованих мов це буквально компіляція. Для веб-стека «збірка» теж є, хоч JavaScript і не компілюється в машинний код: встановити залежності, перевірити типи TypeScript, зібрати й мінімізувати бандл (Vite/webpack/esbuild), проставити хеші у назви файлів для cache busting (механіку версіонування ассетів дивись у главі Кешування). Білд — це дія, процес.
Артефакт (artifact) — це результат білда: незмінний пакет, готовий до розгортання. Залежно від проєкту це зібраний бандл, Docker-образ, .jar, .zip, набір статичних файлів. Ключова властивість — незмінність.
Головний принцип, який варто винести: build once, deploy many — «зібрати один раз, розгорнути багато разів». Артефакт збирають раз, а потім той самий незмінний артефакт просувають середовищами: staging → prod. Не перезбирають окремо під кожне середовище. Чому це критично саме для QA:
- Ти тестуєш на staging той самий байт-у-байт артефакт, що поїде в prod. Якби під prod робили нову збірку, твоє тестування staging нічого б не гарантувало — у prod могла б заїхати інша збірка.
- Артефакт трасується до конкретного коміту й версії. Зловив баг у prod — знаєш точну збірку й точний коміт, звідки вона зросла.
- Різницю поведінки між середовищами треба шукати не в коді (він той самий), а в конфігурації та даних (див. Секрети та конфігурація в CI).
Звідси й межа між білдом і деплоєм: білд виробляє артефакт, деплой ставить готовий артефакт у середовище. Це різні дії, і плутати їх — типова помилка новачка.
Shift-left і швидкий фідбек
(shift-left) — це принцип «пересувати перевірки якості якомога раніше на часовій осі проєкту» (уліво, ближче до написання коду). Основа тут — відома крива вартості дефекту: чим пізніше знайдено баг, тим дорожче його виправити (детально — у розділі основ тестування). Баг, спійманий на коміті, коштує кількох хвилин; той самий баг у проді — інциденту, hotfix-у й репутації.
CI — це головний технічний механізм shift-left: він переносить прогін тестів із «фази тестування наприкінці» на «кожен коміт». Тестування перестає бути окремим етапом після розробки й вплітається в саму розробку.
Але shift-left працює лише за умови швидкого зворотного зв'язку (fast feedback). Уся цінність CI тримається на швидкості петлі «закомітив → дізнався результат». Якщо пайплайн іде дві години або миготить — петля розривається: люди перестають чекати результату, накопичують зміни великими пачками, зливаються рідше — і ти повертаєшся в те саме інтеграційне пекло, тільки з логотипом CI-системи згори. Тому швидкість і стабільність пайплайна — це не «зручність», а умова, за якої CI взагалі має сенс. (Питання спільного володіння автотестами й shift-left з боку автоматизації — окрема тема в розділі стратегії автоматизації.)
Місце QA в CI/CD-культурі
Найважливіший зсув, який приносить CI/CD, — якість не «пришивають» наприкінці, її вбудовують у пайплайн. Стара модель «розробники накодили → кинули QA через паркан → QA потиць руками → підписали реліз» у безперервній доставці не працює: релізів забагато й вони автоматичні. Роль QA не зникає — вона стає роллю стюарда автоматизованої .
Що QA реально робить у CI/CD-культурі:
- Пише й володіє автоперевірками в пайплайні — тими самими тестами, що стоять гейтами на кожному коміті.
- Визначає — які перевірки блокують злиття, а які лише інформують; де e2e має бути блокувальним, а де винесеним у nightly (канон — Стратегія якості в пайплайні).
- падіння — червоний пайплайн це баг продукту, баг тесту чи інфраструктура? Це щоденна робота AQA, і плутати ці три причини дорого (див. Автотести в CI).
- Тримає вартою довіри — бо, повторимо, один хронічно flaky тест знецінює весь гейт: команда починає ігнорувати червоне.
- Рев'ює тестовий код у Pull Request нарівні з продуктовим — тести теж код, який гниє й ламається.
Головна теза для співбесіди: у зрілій CI/CD-культурі якість — відповідальність усієї команди, але QA — це та людина, що проєктує й доглядає автоматизований механізм, який цю якість стереже. Це перехід від «тестувальника, що клікає» до інженера, що володіє захисною сіткою релізу.
Типові помилки
- «У нас є Jenkins, отже у нас CI» — виглядає як CI, а насправді інструмент ≠ практика. Якщо гілки живуть тижнями й зливаються рідко, ніякий сервер не робить це безперервною інтеграцією. CI — це дисципліна частого злиття, автоматика лише її обслуговує.
- «Continuous Delivery і Continuous Deployment — те саме» — виглядає однаково (обидва CD), а насправді різниця в одному: чи є ручний апрув перед prod. Delivery — людина тисне кнопку; Deployment — кнопки немає.
- «Білд і деплой — одне й те саме» — виглядає як один крок, а насправді білд виробляє артефакт, деплой ставить готовий артефакт у середовище. Артефакт збирають раз, деплоять багато разів.
- «Зелений пайплайн = можна релізити» — виглядає як гарантія, а насправді зелене означає лише «перевірки, які ми написали, пройшли». Тонка сюїта чи flaky-тести дають зелене на дірявому . Зелений колір рівно настільки цінний, наскільки чесні перевірки за ним.
- «Впав пайплайн — просто зроблю ретрай» — виглядає як швидке рішення, а насправді маскує flaky-тест або реальну регресію. «Ретраїв і позеленіло» — це не полагоджено, це відкладено; звичка так робити вбиває довіру до гейта.
- «CI/CD — робота девопсів, не QA» — виглядає як чужа зона, а насправді саме гейти якості, тріаж падінь і здоров'я тестової сюїти — пряма відповідальність QA. Девопс володіє інфраструктурою, QA — вмістом перевірок.
Підсумок
- CI — це практика, а не інструмент: часте злиття дрібних змін у спільну гілку плюс автоматичний білд і тести на кожне злиття. Народилася вона з «інтеграційного пекла» — болю рідкісної інтеграції великих гілок.
- CI → Delivery → Deployment — це розширення того самого пайплайна. CI доводить до артефакта; Continuous Delivery — до «готово релізити одним кліком людини»; Continuous Deployment — до автоматичного prod без кліку. Різниця двох CD — ручний апрув перед prod.
- Пайплайн — конвеєр якості з fail-fast порядком: дешеві швидкі перевірки спершу, дорогі повільні потім; кожна стадія — фільтр, що не пускає дефект далі.
- Артефакт збирають раз і просувають середовищами незмінним (build once, deploy many): тестуєш на staging рівно те, що поїде в prod.
- CI — головний механізм shift-left, а його цінність тримається на швидкому й стабільному фідбеку. У CI/CD-культурі QA не гейт наприкінці, а стюард автоматизованої страхувальної сітки.
Можливі питання
- «Чим CI відрізняється від CD?» — класика-пастка через подвійне «CD». Сильна відповідь одразу розводить Continuous Delivery і Continuous Deployment і називає водорозділ — ручний апрув перед prod. Інтерв'юер перевіряє, чи не каша в голові.
- «Що таке CI своїми словами?» — тут дивляться, чи скажеш «часте злиття + автоматична перевірка на кожен коміт» і чи згадаєш, що це практика, а не просто «сервер, що ганяє тести». Згадка про «інтеграційне пекло» як причину — сильний плюс.
- «Що таке пайплайн і в якому порядку йдуть стадії?» — очікують fail-fast: lint/типи → unit → integration → e2e, і пояснення чому саме так (дешеве й швидке раніше).
- «Різниця між білдом і деплоєм? Що таке артефакт?» — перевіряють, чи розумієш build once, deploy many і чому важливо тестувати той самий артефакт, що піде в prod.
- «Де роль QA у CI/CD?» — слабка відповідь: «QA тестує в кінці». Сильна: QA володіє гейтами якості, тріажить падіння, тримає сюїту стабільною, рев'ює тестовий код — якість вбудована в пайплайн, а не пришита наприкінці.
- «Що таке shift-left?» — очікують зв'язку з вартістю дефекту й з CI як механізмом раннього виявлення, а не просто переклад слова.
Джерела
«Інтеграційне пекло» і навіщо CI
- Martin Fowler — Continuous Integration — ключовий принцип «Everyone Commits To the Mainline Every Day» і порогова вимога «no code sits on a branch longer than a few hours»; зламаний білд має пріоритет: «nobody has a higher priority task than fixing the build».
- Trunk Based Development — кількісна форма тієї самої дисципліни: усі комітять у trunk щонайменше раз на 24 години, а понад «пару розробників» потрібен білд-сервер.
- GitHub Docs — About continuous integration — механізми вигоди: частіші коміти виявляють помилки раніше, зменшують обсяг коду для дебагу й спрощують злиття.
Continuous Integration: як це виглядає механічно
- GitHub Docs — About continuous integration — петля цілком: CI-сервер сам дивиться на нові коміти, збирає й тестує, а результат кожного тесту віддається в pull request; зелений прогін робить зміни готовими до рецензії, а не апрувнутими.
- GitLab CI/CD documentation — той самий цикл із боку GitLab: зміни безперервно збирають, тестують, розгортають і моніторять, і це зменшує шанс писати новий код поверх зламаної версії.
CI vs Continuous Delivery vs Continuous Deployment
- Martin Fowler — Continuous Integration — усі три означення в одному абзаці й залежність між ними: «Continuous Delivery just assures that this is possible (and is thus a pre-requisite for Continuous Deployment)».
- continuousdelivery.com (Jez Humble, David Farley) — CD як здатність доводити зміни в продакшен безпечно й на вимогу; ключове слово означення —
ability, а не стадія пайплайна. - ISTQB CTFL Syllabus v4.0, §2.1.4 — CI, CD і continuous deployment зазвичай реалізуються як частина автоматизованого DevOps-пайплайна.
- GitLab CI/CD documentation — стадії задають порядок виконання, джоби описують задачі в межах стадії, а у файлі задають залежності й умови запуску.
- Martin Fowler — The Practical Test Pyramid — форма, на яку лягає порядок стадій: широка дешева основа знизу, вузький дорогий верх.
- Jenkins Pipeline Documentation — CD-пайплайн складається з двох частин: надійна й повторювана збірка і проведення того самого білда через стадії тестування й розгортання.
- continuousdelivery.com (Jez Humble, David Farley) — інваріант «код завжди у стані, придатному до розгортання», з якого й росте просування готового артефакта середовищами. Принципу «build once, deploy many» на самому сайті немає — він живе в однойменній книзі, і в цій главі поданий як наша практика, а не як цитата звідси.
- ISTQB CTFL Syllabus v4.0, §2.1.4 — CI просуває shift-left у тестуванні, підштовхуючи віддавати код разом із компонентними тестами й ; межа названа прямо: ручне тестування все одно буде потрібне.
- Martin Fowler — Continuous Integration — «Keep the Build Fast» разом із XP-орієнтиром десятихвилинного білда: цінність петлі тримається на швидкості фідбеку.
- ISTQB CTFL Syllabus v4.0, §2.1.4 — DevOps як організаційний підхід із культурним зсувом і рівноцінністю функцій; автоматизація зменшує потребу в повторюваному ручному тестуванні, але не скасовує його.
- continuousdelivery.com (Jez Humble, David Farley) — коли регресії знаходяться за хвилини, команда звільняється для , юзабіліті, продуктивності й безпеки.
- GitHub Docs — About continuous integration — що саме ганяють у пайплайні: лінтери, перевірки безпеки, покриття коду, функціональні тести й власні перевірки команди.
Що таке «інтеграційне пекло» і чому саме воно породило CI?
Це ситуація, коли команда довго не зливає код: кожен тижнями сидить у власній гілці, а наприкінці всі разом намагаються влити роботу в спільну . Що довше гілки розходяться, то більше між ними накопичується несумісностей — і явних (той самий файл правили двоє), і тихих логічних (два окремо коректні шматки разом ламають фічу), і розбіжностей у залежностях. Складність такого злиття росте не лінійно, а різко, і вибухає рівно тоді, коли до релізу лишаються дні. Безперервна інтеграція (continuous integration, CI) перевертає логіку: якщо інтегруватися боляче — роби це часто, поки порція змін дрібна, і тоді конфлікт видно й лагодиться за хвилини. Тобто CI народилася не як технологія, а як відповідь на конкретний організаційний біль.
CI — це інструмент чи практика? Чому це питання не чіпляння до слів?
CI — передусім практика, дисципліна команди, а не сервер, який ти встановив. Можна підняти GitHub Actions чи Jenkins і не мати ніякого CI, якщо всі далі сидять по гілках тижнями й зливаються раз на спринт. І навпаки: суть CI — часте злиття в спільну магістраль плюс автоматична перевірка кожного злиття, а інструмент лише автоматизує те, що команда й так вирішила робити. На співбесіді ця відповідь одразу відрізняє того, хто розуміє механізм, від того, хто завчив назви систем. Слабка відповідь звучить як «CI — це коли стоїть Jenkins, що ганяє тести».
Розкажи своїми словами, що таке безперервна інтеграція.
Два стовпи: розробники часто (щодня чи кілька разів на день) зливають дрібні порції змін у спільну гілку, і на кожне таке злиття автоматика збирає проєкт та проганяє тести. Мета — тримати спільну гілку в робочому стані постійно, а не «доводити її до пуття» перед релізом. Сильна відповідь додає причину — «інтеграційне пекло» рідкісного злиття великих гілок — і наголошує, що це практика, а не просто «машина, яка запускає тести». Ще один маркер зрілості: згадка про trunk-based development як спосіб життя, що робить часте злиття можливим. Слабка відповідь зупиняється на «сервер збирає код».
Які звички команди роблять CI справді робочим?
Перша — часті дрібні в спільну гілку замість великої фічі раз на два тижні. Друга — автоматична перевірка ( плюс тести) на кожен коміт, яку запускає машина, а не людина за настроєм. Третя, і найнедооціненіша — «зелена магістраль понад усе»: якщо перевірка червона, спільна гілка вважається зламаною, і команда лагодить її раніше, ніж додає нове. Це той самий принцип, що на реальному складальному конвеєрі — не пускай далі деталь із дефектом. Без третьої звички CI перетворюється на декорацію: червоне накопичується, ніхто його не чинить, гейт втрачає сенс.
Опиши механіку одного прогону CI від пуша до статусу.
Розробник робить git push або відкриває Pull Request — CI-сервер помічає цю подію. Він бере свіжий код, у чистому відтворюваному середовищі збирає проєкт, проганяє тести й повертає статус: зелено або червоно. Статус видно прямо в Pull Request — червоний чек блокує злиття, зелений дозволяє. Головна цінність цієї петлі — ловить машина за хвилини після коміту, а не тестувальник за тиждень перед релізом, і «в мене локально працювало» перестає бути аргументом, бо збірка йде в однаковому для всіх середовищі. Історія перевірок прив'язана до комітів, тож видно, який саме коміт зробив магістраль червоною.
Чим CI відрізняється від CD?
Це класична пастка через подвійне «CD»: обидва Continuous Delivery і Continuous Deployment скорочуються однаково, тому сильна відповідь одразу їх розводить. CI відповідає за відрізок від коміту до готового артефакта: інтегрувати, зібрати, протестувати — на виході перевірена збірка. Обидва CD — про те, що з цим артефактом робити далі: доводити його до релізу. Continuous Delivery тримає кожну зелену збірку готовою до релізу «в один клік», а рішення котити на prod ухвалює людина. Continuous Deployment прибирає й цей клік: кожна збірка, що пройшла всі перевірки, їде на prod автоматично. Водорозділ між двома CD — наявність ручного апруву перед prod.
У чому конкретно різниця між Continuous Delivery і Continuous Deployment?
Різниця рівно в одному: чи є людина в петлі релізу перед продакшеном. При Continuous Delivery автоматично доводить збірку до стану «готово релізити» — прогнано через усі стадії, розгорнуто на staging, — але саму кнопку «на prod» тисне людина у свідомий момент. При Continuous Deployment кнопки немає: пройшли всі гейти — збірка поїхала на prod сама. Друге вимагає значно зрілішого автоматизованого , бо ніхто не дивиться на збірку перед prod очима — весь захист переноситься в перевірки пайплайна, і швидкий rollback. Тому Continuous Deployment без сильної автоматизації якості — це не швидкість, а рулетка.
Чи можна мати Continuous Deployment без Continuous Delivery?
Ні — Continuous Delivery це обов'язкова , а не навпаки. Щоб релізити на prod автоматично без людини, спершу треба вміти стабільно доводити кожну збірку до стану «готова до релізу»: пройдена через усі стадії, розгорнута на staging, перевірена автоматичними гейтами. Continuous Deployment лише знімає останній ручний клік із уже налагодженого Continuous Delivery. Спроба «зразу автоматичний prod» без цієї бази означає, що збірки їдуть у прод, не будучи гарантовано готовими — а це прямий шлях до інцидентів. Тому послідовність завжди CI → Delivery → Deployment, і перескочити середню ланку не вийде.
Що таке пайплайн і чому його називають конвеєром якості?
Пайплайн (pipeline) — це автоматизована послідовність стадій, які код проходить від коміту до потенційного продакшену. Правильна ментальна модель — конвеєр контролю якості: на кожній станції стоїть перевірка, і деталь їде далі, лише якщо станцію пройдено. Не пройшов lint — далі не поїхав; впав unit-тест — до e2e справа взагалі не дійшла. Тобто це не «купа скриптів, які запускаються», а впорядкована черга гейтів, кожен з яких — фільтр, що не пускає дефект далі по трубі. Для AQA це ще й середовище, у якому живуть автотести: там вони запускаються на кожен коміт і там стають блокувальним гейтом.
У якому порядку йдуть стадії пайплайна і чому саме так?
Типовий порядок — lint і перевірка типів, потім unit-тести, потім integration/API, і аж наприкінці e2e. Принцип за цим — fail fast: спершу найшвидші й найдешевші перевірки, потім повільні й дорогі. Логіка суто економічна — немає сенсу тримати агента пів години на e2e, якщо код не проходить навіть перевірку типів; цю помилку треба показати автору за секунди, а не за десятки хвилин. Порядок прямо лягає на : широка дешева основа знизу, вузький дорогий верх. Сильна відповідь на співбесіді називає не лише послідовність, а й це «чому»: раннє падіння економить час і гроші та дає автору швидкий фідбек.
Чим білд відрізняється від артефакта?
Білд (build) — це дія, процес перетворення вихідного коду в форму, придатну до запуску: для компільованих мов це компіляція, для веб-стека — встановити залежності, перевірити типи, зібрати й мінімізувати бандл, проставити хеші в назви файлів. Артефакт (artifact) — це результат білда: незмінний пакет, готовий до розгортання (зібраний бандл, Docker-, .jar, .zip, набір статичних файлів). Ключова властивість артефакта — незмінність. Звідси й межа з : білд виробляє артефакт, а деплой ставить готовий артефакт у середовище — це різні дії. Плутати «білд» і «деплой» як один крок — типова помилка новачка.
Що означає принцип build once, deploy many і чому він критичний саме для QA?
Він означає «зібрати один раз, розгорнути багато разів»: артефакт збирають раз, а далі той самий незмінний артефакт просувають середовищами staging → prod, не перезбираючи окремо під кожне. Для QA це фундамент довіри до тестування: на staging ти перевіряєш той самий байт-у-байт артефакт, що поїде в prod, тож твоє тестування staging реально щось гарантує. Якби під prod робили нову збірку, у прод могла б заїхати інша збірка, і перевірка staging нічого не варта. Друга перевага — : артефакт прив'язаний до конкретного коміту й версії, тож зловивши баг у prod, ти знаєш точну збірку й точний коміт. Практичний висновок: різницю поведінки між середовищами треба шукати не в коді (він той самий), а в конфігурації та даних.
Що таке shift-left і як CI з ним пов'язаний?
(shift-left) — це принцип пересувати перевірки якості якомога раніше на часовій осі проєкту, ближче до написання коду. Основа — крива вартості дефекту: чим пізніше знайдено баг, тим дорожче його виправити; баг на коміті коштує кількох хвилин, той самий баг у проді — інциденту й hotfix-у. CI — головний технічний механізм shift-left: він переносить прогін тестів із окремої «фази тестування наприкінці» на кожен коміт, і тестування вплітається в саму розробку. Сильна відповідь пов'язує термін саме з вартістю дефекту й з CI як інструментом раннього виявлення, а не просто перекладає слово «зсув». Слабка — «shift-left це коли тестуємо раніше», без пояснення механізму й вигоди.
Чому швидкість і стабільність пайплайна — це умова, а не зручність?
Уся цінність CI тримається на швидкості петлі «закомітив → дізнався результат». Якщо пайплайн іде дві години або миготить без причини, петля зворотного зв'язку розривається: люди перестають чекати результату, накопичують зміни великими пачками, зливаються рідше — і команда повертається в те саме інтеграційне пекло, тільки тепер із логотипом CI-системи згори. Тобто повільний чи нестабільний пайплайн не просто дратує — він знищує сам сенс безперервної інтеграції. Тому швидкість (fail-fast порядок стадій) і стабільність (боротьба з flaky) — це не косметика, а умова, за якої CI взагалі працює. Для AQA це прямий обов'язок: тримати швидкою й надійною.
Чому один flaky-тест здатний знецінити весь пайплайн?
Flaky-тест падає «через раз» без зміни коду, і саме ця непередбачуваність отруює гейт. Коли пайплайн червоніє випадково, команда поступово перестає довіряти червоному кольору й починає його ігнорувати — ретраїть , не читаючи причину. А щойно червоне стало «нормальним», гейт перестав бути гейтом: наступного разу за випадковим червоним сховається справжня регресія, і її пропустять. Тобто шкода не в самому падінні, а в підриві довіри до сигналу. Тому тримати сюїту вартою довіри — пряма робота QA: один хронічно нестабільний тест дорожчий, ніж відсутній.
Чому «зелений пайплайн» не завжди означає «можна релізити»?
Бо зелене означає лише «перевірки, які ми написали, пройшли» — не «продукт справний». Тонка сюїта з дірявим чи набір flaky-тестів дадуть зелене на функціоналі, який насправді зламаний, просто його ніхто не перевіряє. Зелений колір рівно настільки цінний, наскільки чесні й повні перевірки за ним. Тому за зеленим гейтом мусить стояти продумана стратегія якості: що саме блокує злиття, яке покриття вважається достатнім, які свідомо лишили поза автоматикою. Сприймати зелене як залізну гарантію релізу — типова помилка, яка присипляє пильність.
Чому звичка «впав пайплайн — просто зроблю ретрай» небезпечна?
Бо не лагодить причину, а маскує її. За випадковим падінням стоїть або flaky-тест, або реальна регресія, що спрацювала на конкретних таймінгах — і «ретраїв, позеленіло» означає не «полагоджено», а «відкладено до наступного разу». Гірше те, що звичка ретраїти вбиває довіру до гейта: команда привчається не читати червоне, а клікати «retry», і одного дня за цим retry проскочить справжній баг. Правильна реакція на червоне — розібратися, чому впало, і завести це у три категорії: баг продукту, баг тесту чи інфраструктура. падінь — щоденна робота AQA, і підміняти його кнопкою ретраю дорого коштує.
Де місце QA у зрілій CI/CD-культурі?
Слабка відповідь — «QA тестує наприкінці». Сильна — якість не пришивають наприкінці, її вбудовують у пайплайн, а QA стає стюардом цієї автоматизованої . Конкретно QA пише й володіє автоперевірками в пайплайні, визначає (що блокує злиття, а що лише інформує; де e2e блокувальний, а де винесений у nightly), тріажить падіння (продукт / тест / інфраструктура), тримає сюїту вартою довіри й рев'ює тестовий код у Pull Request нарівні з продуктовим. У цій моделі якість — відповідальність усієї команди, але саме QA проєктує й доглядає механізм, який цю якість стереже. Це перехід від «тестувальника, що клікає» до інженера, що володіє захисною сіткою релізу: девопс володіє інфраструктурою, QA — вмістом перевірок.
Три ситуації, у яких CI/CD перестає бути теорією й стає щоденною роботою AQA: червоного за таблицею причин, читання fail-fast пайплайна в GitHub Actions і рішення, який гейт куди поставити, та розбір «на staging працювало, на prod ні» через призму build once, deploy many. Скрізь — що дивитися й чому.
Кейс 1. Червоний пайплайн: тріаж за три категорії
Пайплайн упав на PR, і перша реакція новачка — клікнути «Re-run jobs». Це найгірше, що можна зробити: не каже, що сталося, а лише відкладає діагноз. Червоне падіння завжди розкладають у три категорії — баг продукту, баг тесту, інфраструктура — бо лікуються вони по-різному, і плутати їх дорого.
| Симптом у логах CI | Найімовірніша категорія | Перший крок діагностики |
|---|---|---|
| Асерт впав на конкретному кроці, стабільно відтворюється локально | Баг продукту або тесту | Відтворити крок вручну; якщо продукт поводиться не так, як каже асерт — баг продукту |
| Зелено локально, червоно лише в CI, падіння «плаває» | Баг тесту (flaky) або гонка | Перезапустити той самий коміт кілька разів; нестабільність підтверджує flaky |
ECONNREFUSED, таймаути на підйомі сервісу, 502/503 від застосунку | Інфраструктура/середовище | Перевірити, чи середовище й залежності взагалі піднялися до тестів |
| Падіння одразу після оновлення залежностей або конфігу CI | Інфраструктура/конфіг | Порівняти з попереднім зеленим прогоном: що змінилось поза продуктовим кодом |
Що дивитися й чому:
- Стабільність відтворення — головний розділювач. Падіння, що чесно повторюється на тому самому , — це або продукту, або зламаний . Падіння, що «через раз», — майже завжди flaky-тест чи гонка, і його не можна «полагодити ретраєм»: позеленіло — значить, відклали, а не полагодили.
5xxвід застосунку в момент прогону — окремий діагноз. Масові502/503одразу після частіше означають, що середовище ще прогрівається, ніж баг продукту; спершу переконайся, що застосунок піднявся, а вже потім заводь дефект.- Локально зелено, у CI червоно — не привід звинувачувати CI. Прогін у CI йде в headless-браузері, з іншими ресурсами й таймінгами, тож нестабільність вилазить саме там. Це не «поламаний CI», а тест, який спирався на удачу локальної машини.
- Тріаж — це відповідальність QA, а не девопса. Девопс володіє інфраструктурою, але рішення «це баг продукту / тесту / середовища» ухвалює той, хто розуміє вміст перевірок.
Кейс 2. Fail-fast пайплайн у GitHub Actions і місце e2e-гейта
Порядок стадій у пайплайні — не косметика, а економіка: дешеве й швидке має падати першим, поки автор ще за клавіатурою. У GitHub Actions цей порядок задають залежності needs — не стартує, поки не позеленів попередній.
name: ci
on: [pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run lint && npm run typecheck # секунди
unit:
needs: lint # не запуститься, поки lint червоний
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run test:unit # секунди-хвилини
e2e:
needs: unit # найдорожча стадія — остання
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npx playwright test --project=chromium # десятки хвилин
Ту саму e2e- можна не тримати блокувальною на кожному PR, а винести важку її частину в nightly — окремий запуск за розкладом:
name: nightly-e2e
on:
schedule:
- cron: '0 2 * * *' # щоночі о 02:00 — повний регрес, усі браузери
jobs:
full-e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npx playwright test # усі проєкти, довгий хвіст сценаріїв
Що дивитися й чому:
needs— це і є fail-fast. Якщоlintчервоний,unitіe2eнавіть не стартують: агент не витрачає пів години на e2e для коду, що не проходить перевірку типів. Помилку автор бачить за секунди, а не наприкінці.- Порядок повторює . Багато дешевих unit знизу, кілька дорогих e2e зверху — це не випадковість, а той самий принцип «широка дешева основа, вузький дорогий верх», перенесений у пайплайн.
- Рішення «блокувати чи винести в nightly» — стратегія якості, і його ухвалює QA. Швидкий -e2e тримають гейтом на PR; повний регрес по всіх браузерах ганяють уночі, щоб не гальмувати кожен коміт. Це компроміс між швидкістю фідбека й повнотою .
- Зелений цієї сюїти каже рівно те, що написано. Якщо на PR блокує лише смоук-набір, «зелено» не означає «повний регрес пройдено» — воно означає «пройшли ті перевірки, що на гейті». Плутати одне з іншим — присипляти пильність.
Кейс 3. «На staging працювало, на prod зламалось»: build once, deploy many на практиці
Фіча відпрацювала на staging, а в prod одразу після релізу — помилка. Перша думка новачка — «код у prod інший». Якщо процес побудований правильно, це майже завжди хибний слід: артефакт зібрали раз і той самий незмінний просунули staging → prod, тож код там байт-у-байт однаковий. Отже, шукати треба не в коді, а в конфігурації та даних.
Щоб зняти саме питання «а чи справді там той самий артефакт», перед прогоном сюїти корисно мати версії — застосунок віддає свою збірку, а тест звіряє її з очікуваною:
import { test, expect } from '@playwright/test';
test('на середовищі крутиться очікувана збірка', async ({ request }) => {
// застосунок віддає свій build/commit, наприклад, у /healthz або /version
const res = await request.get(`${process.env.BASE_URL}/version`);
expect(res.status()).toBe(200);
const { commit } = await res.json();
// очікувану версію передаємо з CI (SHA артефакта, що деплоївся)
expect(commit, 'на середовищі стара збірка — деплой не доїхав').toBe(process.env.EXPECTED_SHA);
});
Якщо версія збіглася, а поведінка все одно різна — розбір іде за таблицею відмінностей середовищ:
| Джерело різниці | Приклад | Де перевіряти |
|---|---|---|
| Конфігурація / змінні оточення | Інший API-URL, вимкнений фіча-флаг, інший рівень логів | Секрети й конфіг середовища, не код |
| Дані | На staging тестова фікстура, у prod реальні дані з edge cases | Стан бази, вхідні дані конкретного користувача |
| Зовнішні залежності | Платіжний шлюз у sandbox проти бойового | Інтеграції, доступні саме цьому середовищу |
| Масштаб / навантаження | Гонки й таймаути вилазять лише під prod-трафіком | Метрики, конкурентність, ліміти |
Конкурентність (concurrency) в останньому рядку — це скільки запитів застосунок обслуговує водночас; не плутай її з паралельністю, тобто одночасним прогоном незалежних тестів.
Що дивитися й чому:
- Незмінність артефакта — це те, що робить тестування staging осмисленим. Ти перевіряєш той самий байт, що поїде в prod; якби під prod робили нову збірку, перевірка staging нічого б не гарантувала.
- Оракул версії відсікає найдешевшу гіпотезу першою. Половина «загадкових» різниць між середовищами — це банально не доїхав деплой: у prod ще стара збірка. Звіривши SHA, ти або підтверджуєш це за секунди, або чесно виключаєш і йдеш далі.
- до коміту економить години. Артефакт прив'язаний до конкретної версії, тож зловивши баг у prod, ти знаєш точну збірку й точний коміт, звідки вона зросла, — не треба гадати «а що ж там задеплоєно».
- Різницю шукай у конфізі й даних, а не в коді. Це прямий наслідок build once, deploy many: код той самий за побудовою, тож усе, що відрізняється, живе в оточенні середовища.
Інтеграційне пекло і суть CI
- Можу пояснити «інтеграційне пекло»: що довше розходяться, то різкіше (нелінійно) росте складність злиття, і вибух припадає на дедлайн.
- Знаю головну тезу: CI — це практика й дисципліна команди, а не інструмент; Jenkins сам по собі ще не CI.
- Можу назвати три звички робочого CI: часті дрібні в спільну гілку, автоперевірка на кожен коміт, «зелена магістраль понад усе».
- Розумію правило «не пускай далі деталь із дефектом»: червона магістраль — стоп-сигнал, її лагодять раніше, ніж додають нове.
Механіка і роль автотестів
- Можу описати петлю: push/PR → CI бере свіжий код → чисте середовище → → тести → статус green/red у Pull Request.
- Розумію, чому «в мене локально працювало» перестає бути аргументом: збірка йде у відтворюваному, однаковому для всіх середовищі.
- Можу пояснити, чому один flaky-тест руйнує весь сенс CI: команда перестає довіряти червоному й починає його ігнорувати.
CI vs Delivery vs Deployment
- Можу розмежувати відрізки : CI — від коміту до артефакта; Delivery — до «готово релізити одним кліком»; Deployment — до автоматичного prod.
- Знаю водорозділ двох CD: наявність ручного апруву перед prod (Delivery — людина тисне кнопку; Deployment — кнопки немає).
- Розумію, що Continuous Delivery — обов'язкова Continuous Deployment, але не навпаки.
Пайплайн як конвеєр якості
- Розумію пайплайн як конвеєр : кожна стадія — гейт, деталь їде далі лише пройшовши станцію.
- Знаю fail-fast порядок стадій: lint/типи → unit → integration/API → e2e, і можу пояснити чому (дешеве й швидке раніше).
Білд і артефакт
- Можу розвести білд (дія, процес збірки) і артефакт (результат: незмінний пакет, готовий до розгортання).
- Знаю ключову властивість артефакта — незмінність, і межу з : білд виробляє артефакт, деплой ставить його в середовище.
- Розумію принцип build once, deploy many: один артефакт просувають середовищами, а не перезбирають під кожне.
- Можу пояснити, чому це критично для QA: на staging тестую той самий байт-у-байт артефакт, що поїде в prod.
Shift-left і роль QA
- Можу пояснити shift-left через криву вартості дефекту: чим пізніше знайдено баг, тим дорожче виправити.
- Розумію, що CI — головний технічний механізм shift-left: тести переносяться з «фази наприкінці» на кожен коміт.
- Можу назвати обов'язки QA у CI/CD: володіння автоперевірками, визначення гейтів, падінь, здоров'я , рев'ю тестового коду в PR.
- Розумію тезу «зелений пайплайн ≠ можна релізити»: зелене означає лише, що написані перевірки пройшли, не що продукт справний.
Квіз
Перед стартом
- Питань: 15
- Поріг «зараховано»: ≥70% правильних відповідей.
- Результат впливає на прогрес; завалені питання підуть у чергу повторення.
- Квіз впливає на компліт теми: тема стає «пройдено», лише коли прочитано теорію І квіз складено на ≥70%.
Питання
Що таке «інтеграційне пекло» (integration hell)?
