CI/CD с GitHub Actions
Автоматизация проверок и деплоя при пуше.
Базовый workflow
.github/workflows/ci.yml:
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npx tsc --noEmit
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'npm'
- run: npm ci
- run: npm run build
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
AUTH_SECRET: ${{ secrets.AUTH_SECRET }}
Секреты
Settings → Secrets and variables → Actions.
DATABASE_URL
AUTH_SECRET
VERCEL_TOKEN
Доступны как ${{ secrets.NAME }}.
Деплой на Vercel
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'
Деплой на VPS через SSH
name: Deploy to VPS
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy via SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /var/www/my-app
git pull
docker compose build
docker compose up -d
docker compose exec -T app npx prisma migrate deploy
Docker build и push
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:latest
env:
REGISTRY: ghcr.io
Затем на сервере:
docker pull ghcr.io/user/repo:latest
docker compose up -d
Матрица версий
strategy:
matrix:
node: [20, 22]
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
Кеш
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
Или через cache: 'npm' в setup-node.
Тесты
- run: npm test
- run: npm run test:e2e
env:
DATABASE_URL: ${{ secrets.TEST_DATABASE_URL }}
Условные шаги
- name: Deploy
if: github.ref == 'refs/heads/main'
run: vercel --prod
Только для main.
Preview для PR
- name: Deploy Preview
if: github.event_name == 'pull_request'
run: vercel
Уведомления
- name: Notify
if: failure()
uses: slackapi/slack-github-action@v1
with:
payload: |
{"text": "Deploy failed for ${{ github.repository }}"}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
Best practices
- Кешируй
node_modulesи.next/cache - Запускай линтер и типы до сборки
- Используй
npm ci, а неnpm install - Секреты — только через GitHub Secrets
- Preview-деплой для PR
- Уведомления при падении
Итоги
- GitHub Actions для CI/CD
- Секреты через Settings
- Деплой на Vercel, VPS, Docker
- Кеш для скорости
- Условные шаги
- Уведомления о падениях