CI/CD для TypeScript проектов: GitHub Actions от А до Я

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Почему 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 (для статических

Блоги

Рекомендаций по книгам