Введение: Почему CI/CD критически важен для TypeScript проектов
Разработка на TypeScript — это мощный инструмент, но без автоматизации процессов сборки, тестирования и развертывания вы рискуете столкнуться с человеческими ошибками, потерей времени и нестабильностью продакшена. CI/CD (Continuous Integration / Continuous Deployment) — это философия и набор практик, которые позволяют автоматизировать эти процессы. GitHub Actions — встроенный инструмент GitHub, который идеально подходит для TypeScript проектов, предоставляя гибкие, масштабируемые и бесплатные (для публичных репозиториев) пайплайны.
В этой статье мы пройдем путь от нуля до полноценного пайплайна: настроим линтинг, тестирование, сборку и автоматический деплой TypeScript-приложения. Вы узнаете, как писать эффективные YAML-конфиги, оптимизировать время выполнения и избегать типичных ошибок.
Основная часть: Пошаговое создание CI/CD пайплайна
1. Основы GitHub Actions: структура workflow
Workflow (рабочий процесс) в GitHub Actions — это набор шагов, объединенных в джобы. Он описывается в YAML-файле, который хранится в директории .github/workflows/ вашего репозитория. Базовая структура выглядит так:
name: CI/CD Pipeline for TypeScript
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
- run: npm test
Ключевые элементы:
on:— триггеры (push, pull_request).jobs:— список задач (джобов), которые выполняются параллельно или последовательно.runs-on:— операционная система для выполнения (обычноubuntu-latest).steps:— последовательность команд.usesвызывает готовые действия (actions), аrun— shell-команды.npm ci— быстрая чистая установка зависимостей поpackage-lock.json.
Этот минимальный пайплайн уже обеспечивает базовый CI: при каждом пуше или PR код будет проверен на сборку и тесты.
2. Расширенная конфигурация: линтинг, форматирование и матрица версий
Для TypeScript проектов критично поддерживать единый стиль кода. Добавим проверку линтером (eslint) и форматтером (prettier). Также используем матрицу стратегий для тестирования на нескольких версиях Node.js.
jobs:
lint-and-format:
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
- run: npm run format:check
test:
needs: lint-and-format
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
Важные моменты:
needs:— задает порядок выполнения джобов (сначала линтинг, потом тесты).strategy.matrix— позволяет запускать одну и ту же джобу с разными параметрами (версиями Node.js).- Кэширование (
cache: 'npm') ускоряет установку зависимостей. - Добавьте в
package.jsonскрипты:"lint": "eslint src/"и"format:check": "prettier --check src/".
Теперь ваш пайплайн не только проверяет код, но и гарантирует его качество и совместимость с разными версиями рантайма.
3. Сборка и публикация артефактов
После успешного тестирования часто требуется собрать итоговый JavaScript-бандл и сохранить его как артефакт для последующего деплоя. Используем actions/upload-artifact.
jobs:
build:
needs: test
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 build
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
Что здесь происходит:
- Джоба
buildзапускается только после успешного прохождения тестов. - Выполняется сборка (
npm run build), которая компилирует TypeScript в папкуdist/. - Артефакт
distзагружается в GitHub Actions и доступен для скачивания или использования в следующих джобах.
Этот шаг особенно полезен, если вы используете монорепозиторий или хотите вручную проверить собранный бандл.
4. Continuous Deployment: автоматический деплой на сервер
Финальный этап — развертывание собранного приложения. Рассмотрим два популярных сценария:
Сценарий А: Деплой на VPS/сервер через SSH
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Deploy via SSH
uses: easingthemes/ssh-deploy@v4
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 }}
Сценарий Б: Деплой на GitHub Pages (для статических