# CI/CD

> Практика непрерывной интеграции (CI) и непрерывной поставки или развёртывания (CD) — автоматическая сборка, тестирование и выкладка каждого изменения кода.

Источник: https://llmdocs.ru/wiki/ci-cd/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **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](https://llmdocs.ru/wiki/gitlab-ci.md), а с 2019 года — [GitHub Actions](https://llmdocs.ru/wiki/github-actions.md).

## Конвейер

Конвейер (*pipeline*) — последовательность этапов, которые проходит каждое изменение:

| Этап | Что происходит |
|---|---|
| Триггер | push в ветку, открытие [pull request](https://llmdocs.ru/wiki/pull-request.md), тег, расписание |
| Сборка | установка зависимостей, компиляция, сборка образа по [Dockerfile](https://llmdocs.ru/wiki/dockerfile.md) |
| Статические проверки | линтеры, форматирование, проверка типов, поиск секретов и уязвимостей |
| Тесты | модульные, интеграционные, сквозные |
| Публикация артефакта | образ в [реестр](https://llmdocs.ru/wiki/container-registry.md), пакет, бинарник с версией |
| Развёртывание | тестовое окружение → продакшен |
| Проверка после выкладки | смоук-тесты, [мониторинг](https://llmdocs.ru/wiki/monitoring-alerting.md), автоматический откат |

Если любой этап падает, конвейер останавливается, а автор изменения получает уведомление. Важный принцип — **артефакт собирается один раз** и без изменений проходит все окружения: в продакшен попадает ровно то, что тестировали.

## Пример

Конвейер [GitHub Actions](https://llmdocs.ru/wiki/github-actions.md) для проекта на [Python](https://llmdocs.ru/wiki/python.md):[4]

```yaml
# .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](https://llmdocs.ru/wiki/gitlab-ci.md) аналогичное описание хранится в файле `.gitlab-ci.yml` со стадиями `stages`.[5] Конвейер — такой же код, как приложение: он версионируется в [Git](https://llmdocs.ru/wiki/git.md) и проходит ревью.

## Стратегии развёртывания

- **Rolling update** — экземпляры заменяются новыми по очереди; так по умолчанию обновляет [Kubernetes](https://llmdocs.ru/wiki/kubernetes.md).
- **Blue-green** — новая версия поднимается рядом со старой, и трафик переключается целиком; откат — переключение обратно.
- **Canary** — новая версия сначала получает небольшую долю трафика; при росте ошибок выкладка останавливается.
- **Флаги функций** — код выкладывается выключенным и включается для части пользователей независимо от развёртывания.

Инфраструктуру, в которую идёт выкладка, тоже описывают кодом и меняют через конвейер — см. [Infrastructure as Code](https://llmdocs.ru/wiki/infrastructure-as-code.md). В подходе **GitOps** желаемое состояние кластера хранится в репозитории, а агенты вроде Argo CD или Flux синхронизируют с ним кластер.

## Как измерять

Исследовательская программа DORA выделила четыре ключевые метрики эффективности поставки:[3]

1. **Частота развёртываний** — как часто изменения попадают в продакшен.
2. **Время выполнения изменений** (*lead time*) — от коммита до продакшена.
3. **Доля неудачных изменений** — какой процент выкладок требует исправления или отката.
4. **Время восстановления** после неудачного развёртывания.

Исследования DORA показывают, что скорость и стабильность не противоречат друг другу: команды, выкладывающие чаще и меньшими порциями, как правило, реже ломают продакшен.

## Хорошие практики

- Быстрый конвейер: проверки pull request должны укладываться в минуты; медленные тесты распараллеливают и кэшируют зависимости.
- Сломанная основная ветка — главный приоритет команды.
- Секреты — только в хранилище секретов CI, а не в репозитории; права токенов развёртывания — минимальные.
- Нестабильные (*flaky*) тесты чинить или изолировать: иначе к красным сборкам привыкают и перестают их замечать.
- Версии релизов — по правилам [семантического версионирования](https://llmdocs.ru/wiki/semver.md).

## См. также

- [GitHub Actions](https://llmdocs.ru/wiki/github-actions.md)
- [GitLab CI](https://llmdocs.ru/wiki/gitlab-ci.md)
- [Infrastructure as Code](https://llmdocs.ru/wiki/infrastructure-as-code.md)
- [Git](https://llmdocs.ru/wiki/git.md)
- [Мониторинг и алертинг](https://llmdocs.ru/wiki/monitoring-alerting.md)

## Источники

1. [Martin Fowler — Continuous Integration](https://martinfowler.com/articles/continuousIntegration.html)
2. [Jez Humble — Continuous Delivery](https://continuousdelivery.com/)
3. [DORA — DORA's software delivery metrics](https://dora.dev/guides/dora-metrics-four-keys/)
4. [GitHub Docs — GitHub Actions](https://docs.github.com/en/actions)
5. [GitLab Docs — CI/CD](https://docs.gitlab.com/ci/)
6. [Jenkins](https://www.jenkins.io/)
