Введение: Почему CI/CD критичен для TypeScript проектов
Современная разработка на TypeScript требует не только качественного кода, но и надежного процесса его доставки пользователям. Ручной запуск тестов, сборка и деплой — это не только рутина, но и источник ошибок. CI/CD (Continuous Integration / Continuous Deployment) решает эту проблему, автоматизируя каждый этап.
В этой статье мы разберем, как настроить полноценный CI/CD пайплайн для TypeScript проекта с помощью GitHub Actions. Вы узнаете, как автоматизировать линтинг, тестирование, сборку и развертывание вашего приложения, сэкономив часы рабочего времени.
Статья написана для платформы PythonLib, но все примеры и концепции применимы к любому TypeScript проекту. Мы будем использовать TypeScript 5.x и Node.js 20.
Основная часть: Пошаговая настройка CI/CD
1. Структура проекта и подготовка
Прежде чем писать workflow, убедитесь, что ваш проект TypeScript правильно настроен. Вот минимальная структура:
my-typescript-app/
├── src/
│ └── index.ts
├── tests/
│ └── index.test.ts
├── package.json
├── tsconfig.json
├── .eslintrc.json
└── .github/
└── workflows/
└── ci.yml
Важно: в package.json должны быть прописаны скрипты для тестирования и сборки.
{
"name": "my-typescript-app",
"version": "1.0.0",
"scripts": {
"build": "tsc",
"test": "jest",
"lint": "eslint src/**/*.ts",
"start": "node dist/index.js"
},
"devDependencies": {
"typescript": "^5.3.0",
"jest": "^29.7.0",
"@types/jest": "^29.5.0",
"ts-jest": "^29.1.0",
"eslint": "^8.50.0"
}
}
Убедитесь, что tsconfig.json включает корректный outDir (например, "./dist") и strict режим.
2. Создание GitHub Actions workflow
GitHub Actions работает на основе YAML-файлов в директории .github/workflows/. Создайте файл ci.yml со следующим содержимым:
name: CI/CD Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x, 20.x]
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Lint code
run: npm run lint
- name: Build project
run: npm run build
- name: Run tests
run: npm test
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-${{ matrix.node-version }}
path: dist/
Разбор ключевых моментов:
- on: Workflow запускается на push и pull request в ветки main и develop.
- matrix: Тестируем на двух версиях Node.js (18 и 20) для совместимости.
- npm ci: Чистая установка зависимостей (быстрее и надежнее, чем npm install).
- upload-artifact: Сохраняем собранные файлы для последующего деплоя.
3. Добавление этапа деплоя
После успешной сборки и тестирования можно автоматически развернуть приложение. Рассмотрим деплой на GitHub Pages (для статических сайтов) и на VPS через SSH.
Вариант A: Деплой на GitHub Pages
deploy:
needs: build-and-test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/download-artifact@v4
with:
name: build-20.x
path: dist/
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
Вариант B: Деплой на VPS через SSH
deploy:
needs: build-and-test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/download-artifact@v4
with:
name: build-20.x
path: dist/
- name: Deploy to VPS
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 }}
Для работы с SSH необходимо добавить секреты в репозиторий: Settings → Secrets and variables → Actions. Добавьте SSH_PRIVATE_KEY, REMOTE_HOST, REMOTE_USER, REMOTE_TARGET.
4. Оптимизация и лучшие практики
Чтобы ваш CI/CD был быстрым и надежным, следуйте этим рекомендациям:
- Кэширование зависимостей: Используйте
actions/setup-nodeс параметромcache: 'npm'— это сократит время установки пакетов на 70%. - Параллельные джобы: Разделите линтинг, тестирование и сборку на отдельные джобы, если проект большой. Запускайте их параллельно.
- Условные триггеры: Не запускайте полный пайплайн на каждый коммит. Используйте
paths-ignoreдля документации и конфигов. - Уведомления: Добавьте отправку сообщений в Slack или Telegram при падении билда.
# Пример оптимизированного workflow с кэшированием
- name: Cache node modules
uses: actions/cache@v3
id: cache
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-