# CI CD And Automation

> Автоматизирует настройку конвейера CI/CD. Используй при настройке или изменении конвейеров сборки и выкатки. Используй, когда нужно автоматизировать ворота качества, настроить прогон тестов в CI или выстроить стратегии выкатки.

- Skill: `aleksandr-litvinenko/ci-cd-and-automation` (Agent Skill)
- Install (CLI): `npx skillmds@latest add aleksandr-litvinenko/ci-cd-and-automation`
- Raw SKILL.md: https://api.skillmd.com/api/skills/aleksandr-litvinenko/ci-cd-and-automation/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: Aleksandr-Litvinenko (https://skillmd.com/u/aleksandr-litvinenko)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/aleksandr-litvinenko/ci-cd-and-automation

---


# CI/CD и автоматизация

## Обзор

Автоматизируй ворота качества так, чтобы ни одно изменение не доехало до продакшна, не пройдя тесты, линтер, проверку типов и сборку. CI/CD — это механизм принуждения для всех остальных скиллов: он ловит то, что упускают люди и агенты, и делает это одинаково на каждом изменении.

**Сдвиг влево:** лови проблемы как можно раньше в конвейере. Баг, пойманный линтером, стоит минуты; тот же баг, пойманный в продакшне, стоит часы. Двигай проверки вверх по потоку: статический анализ до тестов, тесты до стенда, стенд до продакшна.

**Быстрее — значит безопаснее:** меньшие порции и более частые релизы снижают риск, а не повышают его. Выкатку с 3 изменениями отлаживать проще, чем с 30. Частые релизы формируют доверие к самому процессу релиза.

## Когда применять

- Настраиваешь конвейер CI нового проекта
- Добавляешь или меняешь автоматические проверки
- Настраиваешь конвейеры выкатки
- Когда изменение должно запускать автоматическую проверку
- Разбираешься с падениями CI

## Конвейер ворот качества

Каждое изменение проходит эти ворота до вливания:

```
Открыт пулл-реквест
    │
    ▼
┌──────────────────────┐
│   ЛИНТЕР              │  eslint, prettier
│   ↓ прошло            │
│   ПРОВЕРКА ТИПОВ      │  tsc --noEmit
│   ↓ прошло            │
│   ЮНИТ-ТЕСТЫ          │  jest/vitest
│   ↓ прошло            │
│   СБОРКА              │  npm run build
│   ↓ прошло            │
│   ИНТЕГРАЦИОННЫЕ      │  тесты API/БД
│   ↓ прошло            │
│   СКВОЗНЫЕ (опция)    │  Playwright/Cypress
│   ↓ прошло            │
│   АУДИТ БЕЗОПАСНОСТИ  │  npm audit
│   ↓ прошло            │
│   РАЗМЕР БАНДЛА       │  проверка bundlesize
└──────────────────────┘
    │
    ▼
  Готово к ревью
```

**Ни одни ворота нельзя пропустить.** Если падает линтер — чини код, а не отключай правило. Если падает тест — чини код, а не пропускай тест.

## Настройка GitHub Actions

### Базовый конвейер CI

```yaml
# .github/workflows/ci.yml
name: CI

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Lint
        run: npm run lint

      - name: Type check
        run: npx tsc --noEmit

      - name: Test
        run: npm test -- --coverage

      - name: Build
        run: npm run build

      - name: Security audit
        run: npm audit --audit-level=high
```

### С интеграционными тестами на базе данных

```yaml
  integration:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_DB: testdb
          POSTGRES_USER: ci_user
          POSTGRES_PASSWORD: ${{ secrets.CI_DB_PASSWORD }}
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'
      - run: npm ci
      - name: Run migrations
        run: npx prisma migrate deploy
        env:
          DATABASE_URL: postgresql://ci_user:${{ secrets.CI_DB_PASSWORD }}@localhost:5432/testdb
      - name: Integration tests
        run: npm run test:integration
        env:
          DATABASE_URL: postgresql://ci_user:${{ secrets.CI_DB_PASSWORD }}@localhost:5432/testdb
```

> **Замечание:** даже для тестовых баз, живущих только в CI, храни учётные данные в GitHub Secrets, а не зашивай значения. Это формирует правильную привычку и предотвращает случайное переиспользование тестовых учётных данных в других местах.

### Сквозные тесты

```yaml
  e2e:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'
      - run: npm ci
      - name: Install Playwright
        run: npx playwright install --with-deps chromium
      - name: Build
        run: npm run build
      - name: Run E2E tests
        run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report
          path: playwright-report/
```

## Возврат падений CI агентам

Сила CI в связке с AI-агентами — это петля обратной связи. Когда CI падает:

```
CI упал
    │
    ▼
Скопировать вывод падения
    │
    ▼
Отдать агенту:
«Конвейер CI упал с такой ошибкой:
[вставить конкретную ошибку]
Устрани проблему и проверь локально, прежде чем пушить снова.»
    │
    ▼
Агент чинит → пушит → CI прогоняется снова
```

**Ключевые паттерны:**

```
Падение линтера  → Агент запускает `npm run lint --fix` и коммитит
Ошибка типов     → Агент читает место ошибки и правит тип
Падение теста    → Агент следует скиллу debugging-and-error-recovery
Ошибка сборки    → Агент проверяет конфигурацию и зависимости
```

## Стратегии выкатки

### Предварительные выкатки

Каждый пулл-реквест получает предварительную выкатку для ручной проверки:

```yaml
# Предварительная выкатка на PR (Vercel/Netlify и подобные)
deploy-preview:
  runs-on: ubuntu-latest
  if: github.event_name == 'pull_request'
  steps:
    - uses: actions/checkout@v4
    - name: Deploy preview
      run: npx vercel --token=${{ secrets.VERCEL_TOKEN }}
```

### Фича-флаги

Фича-флаги отделяют выкатку от релиза. Выкатывай незаконченную или рискованную функциональность под флагами, чтобы иметь возможность:

- **Выкатить код, не включая его.** Влить в main рано, включить, когда готов.
- **Откатиться без повторной выкатки.** Выключить флаг вместо отката кода.
- **Проверить на канарейке.** Включить для 1% пользователей, потом 10%, потом 100%.
- **Проводить A/B-тесты.** Сравнить поведение с функциональностью и без неё.

```typescript
// Простой паттерн фича-флага
if (featureFlags.isEnabled('new-checkout-flow', { userId })) {
  return renderNewCheckout();
}
return renderLegacyCheckout();
```

**Жизненный цикл флага:** создать → включить для тестирования → канарейка → полная выкатка → удалить флаг и мёртвый код. Флаги, живущие вечно, становятся техническим долгом: назначай дату уборки при создании.

### Поэтапные выкатки

```
PR влит в main
    │
    ▼
  Выкатка на стенд (автоматически)
    │ Ручная проверка
    ▼
  Выкатка в продакшн (по ручному запуску или автоматически после стенда)
    │
    ▼
  Наблюдение за ошибками (окно 15 минут)
    │
    ├── Обнаружены ошибки → откат
    └── Чисто → готово
```

### План отката

Любая выкатка должна быть обратимой:

```yaml
# Рабочий процесс ручного отката
name: Rollback
on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to rollback to'
        required: true

jobs:
  rollback:
    runs-on: ubuntu-latest
    steps:
      - name: Rollback deployment
        run: |
          # Выкатить указанную предыдущую версию
          npx vercel rollback ${{ inputs.version }}
```

## Управление окружениями

```
.env.example        → Коммитится (шаблон для разработчиков)
.env                → НЕ коммитится (локальная разработка)
.env.test           → Коммитится (тестовое окружение, без настоящих секретов)
Секреты CI          → Хранятся в GitHub Secrets / хранилище секретов
Продакшн-секреты    → Хранятся в платформе выкатки / хранилище секретов
```

В CI никогда не должно быть продакшн-секретов. Используй отдельные секреты для тестирования в CI.

## Автоматизация за пределами CI

### Dependabot / Renovate

```yaml
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: npm
    directory: /
    schedule:
      interval: weekly
    open-pull-requests-limit: 5
```

### Роль дежурного по сборке

Назначь ответственного за то, чтобы CI оставался зелёным. Когда сборка ломается, задача дежурного — починить или откатить, а не задача того, чьё изменение сломало. Это не даёт сломанным сборкам накапливаться, пока все считают, что починит кто-то другой.

### Проверки на пулл-реквестах

- **Обязательные ревью:** минимум 1 одобрение до вливания
- **Обязательные статусные проверки:** CI должен пройти до вливания
- **Защита ветки:** никаких force-push в main
- **Автослияние:** если все проверки прошли и есть одобрение, вливать автоматически

## Оптимизация CI

Когда конвейер превышает 10 минут, применяй эти стратегии в порядке отдачи:

```
Медленный конвейер CI?
├── Кешируй зависимости
│   └── Используй actions/cache или опцию cache в setup-node для node_modules
├── Запускай задания параллельно
│   └── Раздели линтер, проверку типов, тесты и сборку на отдельные параллельные задания
├── Гоняй только то, что изменилось
│   └── Используй фильтры по путям, чтобы пропускать несвязанные задания (например, сквозные тесты на PR только с документацией)
├── Используй матричные сборки
│   └── Разбей набор тестов на шарды по нескольким раннерам
├── Оптимизируй набор тестов
│   └── Убери медленные тесты с критичного пути, гоняй их по расписанию
└── Возьми раннеры помощнее
    └── Более крупные раннеры GitHub или свои для сборок, тяжёлых по CPU
```

**Пример: кеширование и параллельность**
```yaml
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '22', cache: 'npm' }
      - run: npm ci
      - run: npm run lint

  typecheck:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '22', cache: 'npm' }
      - run: npm ci
      - run: npx tsc --noEmit

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '22', cache: 'npm' }
      - run: npm ci
      - run: npm test -- --coverage
```

## Типовые самооправдания

| Самооправдание | Как на самом деле |
|---|---|
| «CI слишком медленный» | Оптимизируй конвейер (см. «Оптимизация CI»), а не пропускай его. Пятиминутный конвейер предотвращает часы отладки. |
| «Изменение пустяковое, CI можно пропустить» | Пустяковые изменения ломают сборки. Для пустяковых изменений CI и так быстрый. |
| «Тест мигающий, просто перезапусти» | Мигающие тесты маскируют настоящие баги и тратят время всех. Устрани мигание. |
| «Добавим CI потом» | Проекты без CI накапливают сломанные состояния. Настрой в первый же день. |
| «Ручного тестирования достаточно» | Ручное тестирование не масштабируется и невоспроизводимо. Автоматизируй то, что можно. |

## Тревожные признаки

- В проекте нет конвейера CI
- Падения CI игнорируются или заглушаются
- Тесты отключены в CI, чтобы конвейер прошёл
- Выкатки в продакшн без проверки на стенде
- Нет механизма отката
- Секреты хранятся в коде или конфигах CI (а не в менеджере секретов)
- Долгое время прогона CI без всяких попыток оптимизации

## Проверка

После настройки или изменения CI:

- [ ] Все ворота качества на месте (линтер, типы, тесты, сборка, аудит)
- [ ] Конвейер запускается на каждом пулл-реквесте и пуше в main
- [ ] Падения блокируют вливание (защита ветки настроена)
- [ ] Результаты CI возвращаются в цикл разработки
- [ ] Секреты хранятся в менеджере секретов, а не в коде
- [ ] У выкатки есть механизм отката
- [ ] Конвейер укладывается в 10 минут для набора тестов

