CI (continuous integration) — «непрерывная интеграция»: каждый коммит автоматически собирается и прогоняет тесты, чтобы поломку поймать сразу, а не через неделю. CD (continuous delivery/deployment) — автоматическая выкатка проверенной сборки на серверы. Вместе они образуют пайплайн: коммит → сборка → тесты → деплой. Код едет не сразу на боевой сервер, а через окружения — dev, stage, prod, — где каждое следующее ближе к реальности. Если на проде что-то сломалось, есть откат (rollback) — вернуть прошлую рабочую версию. Для аналитика это значит: фичу принимают на конкретном окружении (обычно stage), критерии приёмки — это по сути ручная проверка поверх автотестов, а «выкатили на prod» и «готово» — разные события.
Однажды разработчик написал в чат «выкатил, готово», я закрыл задачу — а через час посыпались жалобы. Оказалось, он выкатил на stage, а я понял «на prod»; и даже на проде фича была включена под фиче-флагом для одного процента пользователей. Мы говорили об одном слове «выкатил», подразумевая три разные вещи. С тех пор я не закрываю задачу, пока не пойму ровно: на каком окружении это живёт, видят ли это реальные пользователи и где я могу это потрогать. CI/CD — это не «дела разработки», это карта, по которой ваша фича доезжает до людей, и аналитику надо уметь её читать.
Что такое CI: ловить поломки рано
Continuous integration, «непрерывная интеграция», решает старую боль. Раньше каждый разработчик неделями писал свой кусок в одиночку, а потом все разом сливали код вместе — и наступал «ад интеграции»: куски не стыковались, всё ломалось, разбираться было некому. CI переворачивает это: код вливают в общую ветку часто, маленькими порциями, и на каждый такой коммит автоматика делает две вещи — собирает проект (проверяет, что он вообще компилируется и складывается в работающее приложение) и прогоняет тесты.
Смысл — поймать поломку в тот момент, когда её дёшево чинить. Сломал тест своим коммитом — узнал об этом через пять минут, пока помнишь, что делал, а не через две недели на сборке релиза, когда уже всё перемешалось. Зелёные тесты — едем дальше, красные — коммит не проходит, чини.
Что такое CD: выкатывать часто и безопасно
Continuous delivery/deployment — это про то, что происходит с проверенной сборкой дальше. Аббревиатура одна, а смыслов два, и их полезно различать:
- Continuous delivery — сборка автоматически доводится до состояния «готова к выкатке», но нажать кнопку «выложить на прод» решает человек. Автоматика всё подготовила, финальное «да» — за людьми.
- Continuous deployment — даже эту кнопку нажимает автоматика: прошли тесты — выкатилось на прод само, без участия человека. Так умеют зрелые команды с хорошим покрытием тестами.
Зачем вообще автоматизировать выкатку: чтобы выкатывать часто и мелко. Когда релиз — это редкое страшное событие раз в месяц с сотней изменений, любая поломка ищется в этой сотне. Когда выкатка происходит по десять раз в день мелкими порциями, сломавшее изменение всегда свежее и очевидное. Парадокс, который CI/CD сделал нормой: чем чаще выкатываешь, тем безопаснее.
Пайплайн на пальцах
Пайплайн — это конвейер стадий, через которые код проходит от коммита до прода. Каждая стадия — ворота: не прошёл, конвейер останавливается, дальше код не едет.
flowchart LR C["Коммит"] --> B["Сборка"] B --> T["Тесты"] T --> S["Деплой на stage"] S --> A["Приёмка"] A --> P["Деплой на prod"]
На схеме код проходит конвейер слева направо. Разработчик делает коммит — пайплайн запускается сам. Сначала сборка: проект собирается в работающее приложение. Потом тесты: автоматика прогоняет проверки, и если хоть одна красная — конвейер встал, до прода ничего не доедет. Дальше деплой на stage — сборку выкладывают на тестовое окружение, максимально похожее на боевое. Там фичу проверяет человек — это стадия приёмки, ваша зона. И только когда приёмка пройдена — деплой на prod, на боевой сервер, который видят реальные пользователи. Суть конвейера: каждая стадия — это ворота, и плохое изменение отсеивается на ближайших к коммиту воротах, далеко от живых людей.
Зачем несколько окружений
Окружение (environment) — это отдельная копия системы со своими серверами и базой. Их обычно несколько, и каждое следующее ближе к реальности:
| Окружение | Для кого | Данные | Кто смотрит |
|---|---|---|---|
| dev | разработка | мусорные, ломать не жалко | разработчики |
| stage | проверка перед боем | близкие к боевым | аналитики, QA, заказчик |
| prod | боевой | настоящие, пользовательские | реальные пользователи |
Зачем городить три копии вместо одной: чтобы проверять изменения там, где ошибка ничего не стоит. На dev разработчик ломает и чинит на ходу — данные мусорные, всем плевать. На stage система настроена как боевая, данные похожи на реальные, и тут фичу принимают перед выкаткой — это репетиция прода. И только prod видят настоящие пользователи с настоящими деньгами. Идея та же, что у пайплайна: чем ближе к живым людям, тем строже фильтр. Та же логика «отдельных контуров для разных стадий» всплывает, когда меняешь контракт API без поломки старых клиентов — про это есть запись про версионирование API. А одинаковость самих окружений на практике обеспечивают контейнеры: через все стадии едет одна и та же запечатанная коробка.
Первый вопрос аналитика к любой фиче
«На каком окружении это смотреть?» Если задачу зовут на приёмку, а вы не знаете, где живёт фича, — вы рискуете проверять старую версию на проде вместо новой на stage и принять не то. Привыкните держать в голове три ответа: где это сейчас, что там за данные, кто это уже видит. Без них приёмка — гадание.
Откат: кнопка «как было»
Даже идеальный пайплайн не ловит всё — иногда поломка вылезает только на проде, на реальной нагрузке и реальных данных. На этот случай есть откат (rollback): вернуть предыдущую рабочую версию, чтобы прекратить боль здесь и сейчас, а разбираться в причинах уже спокойно.
Почему это важно понимать аналитику: откат — это часть нормального процесса, а не катастрофа. Хороший пайплайн делает откат быстрым и дешёвым (одна команда — и вернулись), и именно возможность мгновенно откатиться позволяет командам не бояться выкатывать часто. Если откат дорогой и страшный, выкатки становятся редкими и большими — и всё ломается ровно так, как описано выше.
Фиче-флаги: выкатить не значит включить
Есть приём, который окончательно разводит понятия «код на проде» и «фича работает у пользователей»: фиче-флаг (feature flag) — переключатель, который включает или выключает функциональность без новой выкатки. Код фичи уже лежит на проде, но спрятан за флагом; флаг включают отдельно — сразу всем, или одному проценту пользователей, или только внутренним сотрудникам. Это позволяет выкатить рискованную фичу заранее и «открыть» её постепенно, наблюдая, не сломалось ли что. И откат превращается в выключение флага — мгновенно, без пайплайна.
Что меняется для аналитика
Главное, что CI/CD добавляет в вашу работу, — это понимание, что «выкатили» и «готово» — разные события, и между ними иногда пропасть. Код может быть на проде, но спрятан за флагом; фича может быть включена, но на одном проценте; задача может быть «выкачена на stage», что вообще не про живых пользователей. Закрывать задачу по слову «выкатил» — путь к недоразумениям вроде того, с которого начался этот текст.
Второе: приёмка живёт на конкретном окружении, обычно на stage. Ваши критерии готовности (Definition of Done) — это, по сути, ручная проверка поверх автотестов: тесты подтвердили, что код не сломан технически, а вы подтверждаете, что он делает то, что задумано по бизнесу. Полезно, чтобы критерии приёмки были сформулированы так, чтобы их можно было однозначно проверить на stage, — тогда «принято» становится фактом, а не мнением.
Тесты не заменяют приёмку
Зелёный пайплайн означает «код собрался и автотесты прошли» — не «фича сделана правильно». Автотест проверяет то, что в него заложили; он не знает, что заказчик имел в виду под «удобной фильтрацией». Поэтому ручная приёмка аналитиком — отдельный обязательный шаг, а не дублирование того, что уже сделала автоматика. Зелёные тесты — необходимое условие, но не достаточное.
Откуда это взялось
Практику continuous integration популяризировал Мартин Фаулер и движение экстремального программирования (XP) в начале 2000-х — как ответ на «ад интеграции», когда разработчики неделями не сливали код и потом мучительно его стыковали. В 2010 году Джез Хамбл и Дэвид Фарли выпустили книгу «Continuous Delivery», которая оформила идею автоматического конвейера до прода в стройную дисциплину. Примерно тогда же выросло движение DevOps — сближение разработки (Dev) и эксплуатации (Ops), которые исторически жили в разных мирах и воевали: одни хотели выкатывать чаще, другие — чтобы ничего не падало. CI/CD стал техническим воплощением их примирения: автоматизировать выкатку так, чтобы частые релизы были не риском, а нормой.
Частые вопросы
Чем CI отличается от CD?
CI (continuous integration) — про то, что происходит с кодом сразу после коммита: его автоматически собирают и прогоняют тесты, чтобы поймать поломку рано. CD (continuous delivery/deployment) — про то, что происходит дальше: проверенную сборку автоматически готовят к выкатке и выкатывают на серверы. При delivery финальную кнопку «на прод» нажимает человек, при deployment — автоматика сама. CI отвечает за «код не сломан», CD — за «код доехал до пользователей».
Зачем нужно несколько окружений?
Чтобы проверять изменения там, где ошибка ничего не стоит, и пускать на боевой сервер только проверенное. На dev разработчики ломают и чинят на мусорных данных. На stage система настроена как боевая, и там фичу принимают аналитики и заказчик — это репетиция прода. И только prod с настоящими данными видят реальные пользователи. Логика — фильтр, который становится строже по мере приближения к живым людям.
Почему «выкатили на прод» не значит «готово»?
Потому что код может быть на проде, но спрятан за фиче-флагом и недоступен пользователям; или включён, но на одном проценте аудитории; или фича технически работает, но не прошла приёмку аналитика. Зелёный пайплайн подтверждает только, что код собрался и автотесты прошли, — не что фича делает то, что задумано по бизнесу. Поэтому ручная приёмка на stage остаётся отдельным обязательным шагом, а закрывать задачу стоит, точно понимая, где фича живёт и кто её видит.