Что такое CI/CD на самом деле
CI собирает и тестирует каждый push на чистой машине, чтобы поломки интеграции всплывали за минуты. CD держит артефакт всегда готовым к релизу: continuous delivery отгружает кнопкой, continuous deployment авто-отгружает каждый зелёный commit.
Два разработчика расходятся на спринт. Один рефакторит модуль авторизации, другой добавляет фичу, которая его вызывает. У обоих «работает на моей машине». В пятницу они мёржатся к релизу — и ничего не собирается: сигнатура функции изменилась, ключ конфига переименован, а тест, который ни разу не бежал на общей машине, красный уже несколько дней. Они теряют вечер на интеграционную археологию. CI существует, чтобы сделать такую пятницу невозможной: каждый push автоматически собирается и тестируется на чистой машине, поэтому конфликт всплывает за минуты во вторник, а не в панике в пятницу.
CI: каждый push собран и протестирован на чистой машине
Continuous Integration — это практика частого вливания работы всех в общий мейнлайн (в идеале много раз в день) с автоматической сборкой и тестированием каждой интеграции в момент, когда она приземляется. Ключевое слово — автоматически. Человек, гоняющий тесты «когда вспомнит», — это не CI; сервер, который собирает и тестирует каждый push без исключений, — это CI.
Механизм — это петля. Ты пушишь commit. Свежая, чистая машина забирает именно этот commit, ставит зависимости с нуля, компилирует или бандлит код и прогоняет набор тестов. Через минуты ты получаешь вердикт: зелёный (интегрировалось чисто) или красный (что-то сломалось). Поскольку всё бежит на чистой машине без остатков состояния с твоего ноутбука, это лекарство от «работает на моей машине» — если там собирается и проходит, то собирается и проходит у всех, потому что там — нейтральная почва, в которой артефакту на самом деле и предстоит жить.
Когда ты видишь, что CI-пайплайн покраснел на коммите, запушенном пять минут назад, — это и есть суть: боль дешёвая, локализованная и устранимая, пока изменение ещё у тебя в голове.
Зачем это нужно? Три причины, и все про то, чтобы ловить проблемы, пока они дёшевы. Раннее обнаружение: поломка, найденная через секунды после вызвавшего её коммита, чинится тривиально — ты точно знаешь, что изменилось. Та же поломка через две недели, погребённая под полусотней других коммитов, — уже расследование. Малые батчи: интегрировать понемногу и часто — значит, каждый мёрж несёт мало риска; большой мёрж-взрыв, который губит пятницу, заменяется десятками скучных мгновенных мёржей. Быстрая обратная связь: разработчик, который что-то сломал, узнаёт об этом за минуты, пока изменение ещё загружено в голову, а не после того, как переключился на три других задачи.
CD: delivery vs deployment (две разные «D»)
CI говорит, что код хорош. CD — про то, что происходит дальше: как довести этот хороший код до пользователей. Ловушка для джуниора в том, что «CD» означает две связанные, но разные вещи, и команды используют буквы вольно.
Continuous Delivery означает, что каждое изменение, прошедшее CI, даёт артефакт, который всегда готов к релизу, а отгрузка его в production — это осознанное человеческое решение, кнопка. Pipeline делает всю работу (сборка, тесты, упаковка, может быть, staging) и останавливается на ручном гейте подтверждения. Ты мог бы зарелизить любой зелёный commit в любой момент; ты выбираешь когда.
Continuous Deployment убирает эту кнопку: каждый commit, прошедший весь pipeline, автоматически деплоится в production, без человека в петле. Это continuous delivery плюс смелость (и покрытие тестами, и мониторинг, и способность быстро откатиться), чтобы позволить машине отгружать на зелёном.
Различие важно, потому что это выбор зрелости и риска, а не инструмента. Большинство команд держат continuous delivery — всегда готово к релизу, отгрузка кнопкой — задолго до того, как доверятся continuous deployment. Оба стоят на одном фундаменте: pipeline, которому ты доверяешь настолько, что «зелёный» действительно значит «безопасно».
▸Почему это работает
Полезная ментальная модель: CI отвечает на «интегрировалось ли это изменение, ничего не сломав?». Continuous Delivery отвечает на «готово ли это изменение к релизу, когда мы захотим?». Continuous Deployment отвечает на «а не выкатить ли его самим, автоматически?». Один pipeline, три нарастающих уровня доверия — и каждый уровень ты зарабатываешь тестами, наблюдаемостью и быстрым откатом, а не переключением флага в конфиге.
Словарь, который предполагает остальной трек
Каждый инструмент, который ты встретишь — GitHub Actions, GitLab CI/CD, CircleCI, Jenkins — это лишь разный диалект одной горстки существительных. Выучи их здесь один раз, и YAML в следующем юните будет читаться как проза:
| Термин | Что значит |
|---|---|
| Pipeline | Вся автоматическая последовательность, запускаемая событием (push, PR), от checkout до деплоя. |
| Stage (стадия) | Именованная фаза pipeline (например, build, test, deploy), которая бежит после успеха предыдущей. |
| Job (задача) | Единица работы внутри стадии (например, «прогнать юнит-тесты»). Job’ы в стадии часто бегут параллельно. |
| Runner | Машина (чистая VM или контейнер), которая реально выполняет шаги job’а. |
| Artifact | Файл, который pipeline создаёт и сохраняет — собранный бинарник, Docker-образ, отчёт тестов — чтобы передать дальше или задеплоить. |
| Gate (гейт) | Контрольная точка, которую надо пройти, прежде чем pipeline продолжится — все тесты зелёные, обязательное ревью, ручное подтверждение. |
| Environment (окружение) | Цель деплоя со своим конфигом и секретами — staging, production — куда отгружает деплой-job, привязанный к окружению. |
Эти семь терминов описывают полный жизненный цикл одного изменения: оно входит в pipeline (автоматическую последовательность от push до деплоя), проходит через stage’и, составленные из job’ов, собирается runner’ом, производит artifact, минует gate’ы и попадает в environment. Потеряй любое звено — например, gate, который никогда не срабатывает, — и у пайплайна появляется слепое пятно.
Эти инструменты — карта, а не лабиринт: GitHub Actions (workflow’ы из job’ов, бегут на GitHub-hosted runner’ах), GitLab CI/CD (стадии и job’ы в .gitlab-ci.yml), CircleCI и почтенный Jenkins — все выражают одну и ту же петлю. Выбери один, остальные — это рескины.
Культурная половина: trunk-based и зелёный main
CI наполовину инструменты, наполовину дисциплина, и дисциплину джуниоры недооценивают. Смысл интегрировать «непрерывно» теряется, если все работают на долгоживущей ветке две недели и мёржатся в конце — это просто переносит болезненный пятничный мёрж на другую пятницу. Практика, которая делает CI настоящим, — это trunk-based development (разработка от ствола: все работают почти всегда на одной главной ветке, вливая изменения часто и небольшими кусками): короткоживущие ветки (часы — день-два), вливаемые в мейнлайн (main) часто, за маленькими pull request’ами.
И нерушимое правило: держи main зелёным. Мейнлайн должен всегда быть в собираемом, проходящем тесты состоянии, потому что именно от него ответвляются все остальные и именно его continuous delivery готов отгрузить в любой момент. Красный main блокирует всю команду — никто не может доверять собственной сборке, потому что сломан фундамент. Когда pipeline становится красным, починить его (или откатить виновный commit) — приоритет команды номер один, выше новой работы. Этот социальный контракт — малые батчи, быстрые мёржи, мейнлайн, которому всегда можно доверять — и превращает кучу YAML в настоящую continuous integration.
Команда отгружает в production только после того, как человек нажмёт «Release» в pipeline, но каждый зелёный commit — в одном клике от продакшена. Какая это практика?
Маленькая команда хочет начать получать пользу от CI/CD уже на этой неделе. Какой первый ход даёт наибольший рычаг?
- 01В двух словах: что CI реально делает и почему он лечит «работает на моей машине»?
- 02В чём разница между continuous delivery и continuous deployment и почему она важна?
CI/CD — это автоматический хребет современной доставки. Continuous Integration собирает и тестирует каждый push на чистой машине в тот же миг, как он приземлился, чтобы поломки интеграции всплывали за минуты, а не на паническом релизе — он лечит «работает на моей машине», потому что чистая машина — нейтральная почва, и окупается через малые батчи, раннее обнаружение и быструю обратную связь. CD приходит в двух разновидностях, которые джуниор обязан различать: continuous delivery держит каждое изменение всегда готовым к релизу и отгружает по осознанной человеческой кнопке, а continuous deployment убирает кнопку и авто-отгружает каждый зелёный commit — тот же pipeline, на одну ступень доверия выше, заработанную тестами, мониторингом и откатом. Под всем этим лежит общий словарь — pipeline, stage, job, runner, artifact, gate, environment — который GitHub Actions, GitLab CI/CD, CircleCI и Jenkins лишь рескинят. И никакие инструменты не значат ничего без культуры: trunk-based development с короткоживущими ветками, малыми частыми мёржами и нерушимым правилом, что main остаётся зелёным, чтобы вся команда могла доверять фундаменту, от которого собирает и отгружает. Теперь, когда ты видишь красный значок пайплайна на main, — ты знаешь, что это значит: всё стоит, пока не починили, потому что сломанный фундамент заражает каждую ветку, которая на нём растёт.
Практика
Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.