Антон Ларичев

Введение
GitHub Actions CI/CD для Node.js позволяет автоматизировать весь цикл разработки: от проверки кода до деплоя на продакшен. Настроив CI/CD пайплайн один раз, вы получаете автоматический запуск тестов, линтинг и деплой при каждом пуше или pull request.
В этой статье разберем, как создать полноценный workflow для GitHub Actions, который будет проверять качество кода с помощью ESLint, запускать тесты через Jest, собирать проект и деплоить его на сервер. Все примеры основаны на реальных конфигурациях для Node.js проектов.
Структура GitHub Actions workflow для Node.js
Каждый CI/CD пайплайн в GitHub Actions описывается YAML-файлом в директории .github/workflows/. Workflow состоит из джобов (jobs), а каждый джоб содержит шаги (steps). Для Node.js проекта типичный пайплайн включает три основных этапа: линтинг, тестирование и деплой.
Создадим файл .github/workflows/ci.yml:
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npm test
deploy:
runs-on: ubuntu-latest
needs: test
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npm run build
- name: Деплой на сервер
run: |
echo "Деплой приложения..."
Этот workflow запускается при пуше в main или develop и при pull request в main. Джобы выполняются последовательно: сначала линтинг, затем тесты, и только после успеха обоих этапов происходит деплой.
Как настроить автоматический линтинг в GitHub Actions
Линтинг помогает поддерживать единый стиль кода и находить потенциальные ошибки до того, как они попадут в основную ветку. Для Node.js проектов стандартным инструментом является ESLint.
Убедитесь, что в package.json есть скрипт для линтинга:
{
"scripts": {
"lint": "eslint . --ext .ts,.js",
"lint:fix": "eslint . --ext .ts,.js --fix"
}
}
Для более строгих проверок можно добавить параллельный запуск нескольких линтеров:
lint:
runs-on: ubuntu-latest
strategy:
matrix:
check: [eslint, prettier, typecheck]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- name: Запуск проверки
run: |
if [ "${{ matrix.check }}" = "eslint" ]; then
npm run lint
elif [ "${{ matrix.check }}" = "prettier" ]; then
npx prettier --check .
elif [ "${{ matrix.check }}" = "typecheck" ]; then
npx tsc --noEmit
fi
Матричная стратегия запускает ESLint, Prettier и проверку типов параллельно, что сокращает общее время выполнения пайплайна.
Автоматический запуск тестов в GitHub Actions
Запуск тестов при каждом пуше гарантирует, что новый код не ломает существующую функциональность. Для Node.js чаще всего используют Jest или Vitest.
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm test -- --coverage
- name: Загрузка отчета о покрытии
if: matrix.node-version == 20
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
Матрица версий Node.js позволяет проверить совместимость проекта с разными версиями рантайма. Отчет о покрытии кода загружается как артефакт и доступен во вкладке Actions на GitHub.
Как подключить базу данных к тестам
Если тесты требуют базу данных, используйте сервисные контейнеры:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: testdb
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: 20
cache: 'npm'
- run: npm ci
- run: npm test
env:
DATABASE_URL: postgresql://test:test@localhost:5432/testdb
GitHub Actions поднимет контейнер PostgreSQL перед запуском тестов и автоматически остановит его после завершения джоба.
Кэширование зависимостей для ускорения пайплайна
Кэширование node_modules существенно ускоряет CI/CD пайплайн. Параметр cache: 'npm' в actions/setup-node автоматически кэширует глобальный кэш npm на основе package-lock.json.
Для более тонкой настройки можно использовать actions/cache напрямую:
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
При попадании в кэш команда npm ci выполняется за секунды вместо минут. Это особенно заметно в проектах с большим количеством зависимостей.
Настройка автоматического деплоя Node.js приложения
Деплой должен запускаться только после успешного прохождения всех проверок и только для определенных веток. Рассмотрим деплой через SSH на VPS:
deploy:
runs-on: ubuntu-latest
needs: [lint, test]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
environment: production
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npm run build
- name: Деплой через SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /var/www/app
git pull origin main
npm ci --production
npm run build
pm2 restart app
Секреты (SSHHOST, SSHUSER, SSH_KEY) хранятся в настройках репозитория: Settings -> Secrets and variables -> Actions. Параметр environment: production позволяет настроить правила защиты окружения, включая ручное подтверждение деплоя.
Частые ошибки при настройке CI/CD пайплайна
Первая распространенная ошибка: использование npm install вместо npm ci в CI-окружении. Команда npm ci устанавливает зависимости строго по package-lock.json, что гарантирует воспроизводимость сборки.
Вторая проблема: отсутствие кэширования. Без кэша каждый запуск пайплайна скачивает все зависимости заново, что увеличивает время выполнения в несколько раз.
Третья ошибка: хранение секретов в коде. Никогда не коммитьте токены, пароли или SSH-ключи в репозиторий. Используйте GitHub Secrets для всех чувствительных данных.
Четвертая проблема: отсутствие branch protection rules. Настройте защиту основных веток, чтобы мерж был возможен только после успешного прохождения всех проверок CI.
Заключение
GitHub Actions CI/CD пайплайн для Node.js проекта с тестами, линтингом и деплоем создается за один YAML-файл и полностью автоматизирует процесс доставки кода. Настроив workflow один раз, вы получаете автоматические проверки качества кода при каждом изменении, что повышает надежность проекта и ускоряет процесс разработки.





Комментарии
0