CI/CD
| CI | непрерывная интеграция |
|---|---|
| CD | непрерывная поставка (delivery) или развёртывание (deployment) |
| Истоки | экстремальное программирование (конец 1990-х) |
| Ключевые тексты | Мартин Фаулер «Continuous Integration» (2000), Хамбл и Фарли «Continuous Delivery» (2010) |
| Инструменты | GitHub Actions, GitLab CI, Jenkins, CircleCI, Argo CD |
| Метрики | DORA (частота развёртываний, время выполнения изменений, доля неудачных изменений, время восстановления) |
CI/CD — набор практик автоматизации, при котором каждое изменение кода автоматически собирается, проверяется и доводится до пользователей. CI (Continuous Integration, непрерывная интеграция) — разработчики часто вливают изменения в общую ветку, и каждое вливание запускает сборку и тесты. CD — либо Continuous Delivery (непрерывная поставка: любая проверенная версия готова к выкладке одной кнопкой), либо Continuous Deployment (непрерывное развёртывание: каждое изменение, прошедшее проверки, выкладывается в продакшен автоматически).
Цель — короткий и надёжный путь от коммита до работающего продукта: ошибки находятся через минуты после появления, а выкладка становится рутинной операцией, а не рискованным событием раз в квартал.
История
Термин «непрерывная интеграция» употребил Грейди Буч в 1991 году, а практикой его сделало экстремальное программирование Кента Бека в конце 1990-х. Широкую известность принесла статья Мартина Фаулера «Continuous Integration» (2000, с последующими редакциями).[1] Инструменты появились тогда же: CruiseControl (2001), Hudson (2005), который в 2011 году после конфликта с Oracle продолжил развиваться как Jenkins.[6]
В 2010 году Джез Хамбл и Дэвид Фарли выпустили книгу «Continuous Delivery», описавшую конвейер развёртывания (deployment pipeline).[2] В 2010-х CI переехала в облака и в сами платформы хостинга кода: Travis CI, CircleCI, GitLab CI, а с 2019 года — GitHub Actions.
Конвейер
Конвейер (pipeline) — последовательность этапов, которые проходит каждое изменение:
| Этап | Что происходит |
|---|---|
| Триггер | push в ветку, открытие pull request, тег, расписание |
| Сборка | установка зависимостей, компиляция, сборка образа по Dockerfile |
| Статические проверки | линтеры, форматирование, проверка типов, поиск секретов и уязвимостей |
| Тесты | модульные, интеграционные, сквозные |
| Публикация артефакта | образ в реестр, пакет, бинарник с версией |
| Развёртывание | тестовое окружение → продакшен |
| Проверка после выкладки | смоук-тесты, мониторинг, автоматический откат |
Если любой этап падает, конвейер останавливается, а автор изменения получает уведомление. Важный принцип — артефакт собирается один раз и без изменений проходит все окружения: в продакшен попадает ровно то, что тестировали.
Пример
Конвейер GitHub Actions для проекта на Python:[4]
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v6
- run: uv sync --locked
- run: uv run ruff check .
- run: uv run pytest --maxfail=1
deploy:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- run: ./scripts/deploy.sh
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
В GitLab CI аналогичное описание хранится в файле .gitlab-ci.yml со стадиями stages.[5] Конвейер — такой же код, как приложение: он версионируется в Git и проходит ревью.
Стратегии развёртывания
- Rolling update — экземпляры заменяются новыми по очереди; так по умолчанию обновляет Kubernetes.
- Blue-green — новая версия поднимается рядом со старой, и трафик переключается целиком; откат — переключение обратно.
- Canary — новая версия сначала получает небольшую долю трафика; при росте ошибок выкладка останавливается.
- Флаги функций — код выкладывается выключенным и включается для части пользователей независимо от развёртывания.
Инфраструктуру, в которую идёт выкладка, тоже описывают кодом и меняют через конвейер — см. Infrastructure as Code. В подходе GitOps желаемое состояние кластера хранится в репозитории, а агенты вроде Argo CD или Flux синхронизируют с ним кластер.
Как измерять
Исследовательская программа DORA выделила четыре ключевые метрики эффективности поставки:[3]
- Частота развёртываний — как часто изменения попадают в продакшен.
- Время выполнения изменений (lead time) — от коммита до продакшена.
- Доля неудачных изменений — какой процент выкладок требует исправления или отката.
- Время восстановления после неудачного развёртывания.
Исследования DORA показывают, что скорость и стабильность не противоречат друг другу: команды, выкладывающие чаще и меньшими порциями, как правило, реже ломают продакшен.
Хорошие практики
- Быстрый конвейер: проверки pull request должны укладываться в минуты; медленные тесты распараллеливают и кэшируют зависимости.
- Сломанная основная ветка — главный приоритет команды.
- Секреты — только в хранилище секретов CI, а не в репозитории; права токенов развёртывания — минимальные.
- Нестабильные (flaky) тесты чинить или изолировать: иначе к красным сборкам привыкают и перестают их замечать.
- Версии релизов — по правилам семантического версионирования.