CI/CD и GitHub Actions: workflow, secrets, тесты и деплой на практике (Node.js, Python, Docker)
Максимально понятное объяснение CI/CD и GitHub Actions с примерами: workflow/job/step, запускаем тесты и линтеры, подключаем secrets, собираем Docker и деплоим на сервер. Подходит для джунов и для реальных проектов.
CI/CD на практике: GitHub + GitHub Actions простыми словами
Если коротко: CI/CD — это когда рутинную работу делает машина, а не ты. Коммиты проверяются автоматически, сборка не забывается, деплой не ломается «вручную в пятницу вечером».
А теперь — спокойно, по шагам и без магии.
Что вообще такое CI и CD
CI — Continuous Integration (непрерывная интеграция)
CI — это процесс, при котором каждое изменение кода автоматически проверяется.
Обычно CI делает следующее:
- забирает код из репозитория
- ставит зависимости
- запускает тесты
- проверяет линтеры
- сообщает: «всё ок» или «сломал — чини»
💡 Главная идея CI:
Ошибки нужно ловить сразу, а не через неделю в проде.
CD — Continuous Delivery / Continuous Deployment
CD — это логическое продолжение CI.
- Continuous Delivery — код готов к деплою всегда, но выкладка по кнопке
- Continuous Deployment — код автоматически уезжает на сервер после успешных проверок
Проще говоря:
- CI — «код жив?»
- CD — «код поехал»
Почему GitHub Actions — это удобно
GitHub — это не только репозиторий. Внутри него есть GitHub Actions — встроенная система CI/CD.
Плюсы:
- не нужен отдельный Jenkins / GitLab Runner
- YAML лежит рядом с кодом
- бесплатный лимит для публичных репозиториев
- огромная экосистема готовых action-ов
Минусы тоже есть, но для 90% проектов — это идеальный старт.
Базовая терминология (без заумных слов)
| Термин | Что это значит |
|---|---|
| workflow | сценарий CI/CD |
| job | отдельная задача внутри workflow |
| step | конкретный шаг (команда) |
| runner | машина, где всё выполняется |
| action | готовый блок действий |
Где живёт CI/CD в репозитории
GitHub Actions всегда лежат здесь:
.github/
└── workflows/
└── ci.yml
Название файла любое, главное — расширение .yml.
Самый простой CI: проверка кода
Начнём с минимального, но рабочего примера.
Пример: CI для Node.js проекта
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Забираем код
uses: actions/checkout@v4
- name: Устанавливаем Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Устанавливаем зависимости
run: npm ci
- name: Запускаем тесты
run: npm test
Разберём этот файл по-человечески
name
name: CI
Название workflow — просто для удобства в интерфейсе GitHub.
on — когда запускать
on:
push:
branches: [main]
pull_request:
Это означает:
- при каждом пуше в
main - при каждом pull request
💡 Совет: CI обязан запускаться на PR — иначе смысл теряется.
jobs
jobs:
build:
Workflow может состоять из нескольких job-ов.
Здесь job один — build.
runs-on
runs-on: ubuntu-latest
GitHub даёт виртуальную машину с Ubuntu.
Есть ещё windows-latest и macos-latest.
steps
Steps — это пошаговый сценарий:
- забрать код
- поставить окружение
- выполнить команды
actions/checkout
uses: actions/checkout@v4
Без этого шага кода просто не будет. Это обязательный минимум.
actions/setup-node
uses: actions/setup-node@v4
Ставит Node.js нужной версии. Аналоги есть для Python, PHP, Java, Go.
npm ci vs npm install
Используем npm ci, потому что:
- быстрее
- строго по
package-lock.json - идеально для CI
CI для Python (пример)
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r requirements.txt
- run: pytest
Просто. Читаемо. Без шаманства.
Добавляем линтеры
CI без линтеров — это полдела.
Пример:
- name: Lint
run: npm run lint
Или для Python:
- run: ruff check .
Docker в CI/CD
Если проект использует Docker, добавляем сборку образа:
- name: Build Docker image
run: docker build -t myapp:latest .
- name: Run tests in container
run: docker run --rm myapp:latest npm test
💡 Совет: используй Docker Hub или GitHub Container Registry для хранения образов.
CI ≠ CD: добавляем деплой
Теперь самое интересное — автоматическая выкладка.
Пример: деплой по SSH
- name: Deploy
run: |
ssh user@server "cd /var/www/app && git pull && npm run build"
❗ Но так делать нельзя, если:
- нет ключей
- нет secrets
- нет ограничений по веткам
Secrets — как не спалить пароли
GitHub даёт Secrets:
- Settings → Secrets and variables → Actions
- Добавляем
SSH_PRIVATE_KEY,SERVER_HOSTи т.д.
Использование:
env:
SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
💡 Правило:
Никогда не храни пароли в YAML. Никогда.
Деплой только из main
if: github.ref == 'refs/heads/main'
Так ты не уронишь прод случайным пушем из фичи.
Типичная схема CI/CD проекта
- PR → CI
- CI зелёный → merge
- merge в main → CI
- CI успешен → CD
- CD выкатил код
Всё. Никакой магии.
Частые ошибки новичков
- ❌ CI запускается только вручную
- ❌ Нет проверки PR
- ❌ Всё в одном step
- ❌ Пароли в YAML
- ❌ Деплой без условий
- ❌ Нет логов
Хорошая практика
- ✔ Разделяй CI и CD
- ✔ Минимум логики в YAML
- ✔ Проверки обязательны
- ✔ Деплой только из main
- ✔ Secrets — только через GitHub
- ✔ Логи читаемы
Когда GitHub Actions — не лучший выбор
Честно:
- очень сложная оркестрация
- кастомные runner-ы
- тяжёлые enterprise-процессы
Тогда смотри в сторону GitLab CI или Jenkins. Но для старта, пет-проектов и малого бизнеса — GitHub Actions более чем достаточно.
Итог
CI/CD — это не «модно», а необходимость.
GitHub Actions позволяет:
-
автоматизировать проверки
-
убрать человеческий фактор
-
ускорить релизы
-
спать спокойнее
-
Если CI нет — ты тестировщик
-
Если CD нет — ты деплойщик
-
Если есть оба — ты инженер 😏



Комментарии