Введение: Почему CI/CD необходим для JavaScript проектов
Разработка современного JavaScript-приложения на Node.js — это сложный процесс, который включает написание кода, тестирование, сборку и развертывание. Без автоматизации эти этапы выполняются вручную, что приводит к ошибкам, задержкам и снижению качества продукта. CI/CD (Continuous Integration / Continuous Delivery) — это практика DevOps, которая автоматизирует сборку, тестирование и развертывание кода.
GitHub Actions — это встроенный инструмент GitHub, который позволяет создавать рабочие процессы (workflows) для автоматизации задач. Он идеально подходит для JavaScript-проектов, так как поддерживает Node.js, npm, Yarn и множество популярных сервисов. В этой статье мы разберем, как настроить полноценный CI/CD пайплайн для вашего JavaScript-проекта с использованием GitHub Actions.
Вы узнаете: как запускать тесты, как собирать приложение, как деплоить на сервер или облачную платформу, и как избежать типичных ошибок.
Основы GitHub Actions для JavaScript
Что такое GitHub Actions?
GitHub Actions — это платформа для автоматизации рабочих процессов. Вы описываете последовательность шагов в YAML-файле, который помещается в репозиторий (обычно .github/workflows/main.yml). Каждый раз при наступлении события (например, push, pull request) запускается workflow.
Workflow состоит из jobs (задач), которые выполняются на runner (виртуальной машине). Для JavaScript-проектов обычно используется Ubuntu runner, предустановленный с Node.js.
Базовый workflow для Node.js
Начнем с простого workflow, который запускает тесты при каждом push или pull request. Создайте файл .github/workflows/ci.yml:
name: CI для JavaScript
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x, 18.x, 20.x]
steps:
- uses: actions/checkout@v4
- name: Использовать Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm test
- run: npm run build --if-present
Этот workflow делает следующее:
- Триггеры: запускается при push в main/develop или при pull request в main.
- Матрица версий: тестирует на Node.js 16, 18, 20 — это гарантирует совместимость.
- Кэширование:
cache: 'npm'ускоряет установку зависимостей. - Команды:
npm ci(чистая установка),npm test(тесты),npm run build(сборка, если есть).
Настройка полноценного CI/CD пайплайна
Теперь усложним задачу: добавим линтинг, проверку безопасности и автоматический деплой после успешного тестирования.
Шаг 1: Линтинг и форматирование
Добавим job для ESLint и Prettier. Это гарантирует единый стиль кода:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '18.x'
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npx prettier --check .
В package.json должны быть скрипты "lint" и "format". Пример:
{
"scripts": {
"lint": "eslint src/",
"format": "prettier --write ."
}
}
Шаг 2: Безопасность зависимостей
Используйте npm audit для проверки уязвимостей:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm audit --audit-level=high
Если аудит найдет критические уязвимости, job завершится ошибкой, и пайплайн остановится.
Шаг 3: Сборка и публикация артефактов
После успешных тестов и линтинга соберем приложение и сохраним артефакты для деплоя:
build:
needs: [test, lint, security]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '18.x'
cache: 'npm'
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: dist/
Здесь needs означает, что сборка запустится только после успешного выполнения предыдущих job.
Шаг 4: Деплой на сервер
Для деплоя на VPS или облако (например, DigitalOcean, AWS) используем SSH-действия. Пример деплоя через rsync:
deploy:
needs: [build]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/download-artifact@v4
with:
name: build-artifacts
path: dist/
- name: Деплой на сервер
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
ARGS: "-rlgoDzvc -i"
SOURCE: "dist/"
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_USER: ${{ secrets.REMOTE_USER }}
TARGET: ${{ secrets.REMOTE_TARGET }}
Важно: Все секреты (SSH-ключи, пароли) храните в Settings → Secrets and variables → Actions. Никогда не пишите их в коде!
Оптимизация и лучшие практики
Кэширование зависимостей
Без кэширования каждая сборка скачивает npm-пакеты заново, что занимает 1-3 минуты. Используйте actions/setup-node с параметром cache, как мы сделали выше. Альтернативно — отдельное кэширование ~/.npm:
- uses: actions/cache