← Назад к вопросам
Как устроен pipeline проекта?
2.0 Middle🔥 201 комментариев
#DevOps и инфраструктура#Тестирование
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как устроен pipeline проекта?
Pipeline — это автоматизированный процесс от кода к production. Я описываю типичный pipeline современного Node.js проекта, который я создаю.
Архитектура pipeline
Разработчик пишет код
↓
Git push на remote
↓
GitHub Actions (CI)
↓
├─ Checkout code
├─ Setup Node.js
├─ npm install
├─ npm run lint (ESLint, Prettier)
├─ npm run test (Unit + Integration)
├─ npm run build (TypeScript compile)
└─ npm run coverage (>90% required)
↓
Проходит CI? → Pull Request
↓
Code Review
↓
Прошёл review?
↓
Merge в main branch
↓
GitHub Actions (CD)
↓
├─ Build Docker image
├─ Push to Docker Registry
├─ Deploy to staging
└─ Run E2E tests
↓
Развёртывание в production
↓
Докu (git push dokku main)
Шаг 1: Git Workflow
# Разработчик создаёт feature branch
git checkout -b feature/add-auth
# Делает коммиты
git commit -m "feat: add JWT authentication"
git commit -m "test: add auth tests"
# Пушит на GitHub
git push origin feature/add-auth
# Создаёт Pull Request (PR)
# GitHub автоматически запускает CI
Шаг 2: GitHub Actions CI
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15-alpine
env:
POSTGRES_PASSWORD: test
POSTGRES_DB: testdb
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7-alpine
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
steps:
# Получить код
- uses: actions/checkout@v3
# Установить Node.js
- uses: actions/setup-node@v3
with:
node-version: '20'
cache: 'npm'
# Установить зависимости
- run: npm ci # --ci вместо install для CI
# Линтинг
- name: Lint
run: npm run lint
# TypeScript compilation check
- name: Type Check
run: npm run build
# Unit + Integration тесты
- name: Tests
run: npm run test -- --coverage
env:
DATABASE_URL: postgresql://postgres:test@localhost/testdb
REDIS_URL: redis://localhost:6379
# Проверка coverage
- name: Upload Coverage
uses: codecov/codecov-action@v3
with:
files: ./coverage/lcov.info
fail_ci_if_error: true
min_coverage_percentage: 90
# Build production
- name: Build Production
run: npm run build
Шаг 3: Code Review
Когда CI пройдён:
PR статус: ✓ All checks passed
Теперь нужен code review от коллег:
1. Senior разработчик читает код
2. Ищет:
- Логические ошибки
- Security issues
- Performance проблемы
- Нарушение архитектуры
- Читаемость
3. Оставляет комментарии
4. Либо approves, либо requests changes
Шаг 4: Merge в main
# После одобрения
git merge feature/add-auth
git push origin main
# GitHub Actions автоматически запускает CD
Шаг 5: GitHub Actions CD
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# Авторизация в Docker Registry
- uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Build Docker image
- uses: docker/build-push-action@v4
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository }}:latest
ghcr.io/${{ github.repository }}:${{ github.sha }}
# Deploy to staging
- name: Deploy to Staging
run: |
ssh -i ${{ secrets.STAGING_SSH_KEY }} user@staging.example.com
docker pull ghcr.io/${{ github.repository }}:latest
docker-compose -f docker-compose.staging.yml up -d
# E2E tests на staging
- name: E2E Tests
run: npm run test:e2e -- --baseURL https://staging.example.com
# Если всё ок, deploy to production
- name: Deploy to Production
if: success()
run: |
ssh -i ${{ secrets.PROD_SSH_KEY }} user@prod.example.com
docker pull ghcr.io/${{ github.repository }}:latest
docker-compose -f docker-compose.prod.yml up -d
# Smoke tests
- name: Smoke Tests
run: |
curl -f https://api.example.com/health || exit 1
curl -f https://api.example.com/api/v1/status || exit 1
Шаг 6: Docker контейнеризация
# Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine
WORKDIR /app
# Только production зависимости
COPY package*.json ./
RUN npm ci --only=production
# Скопировать build
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/migrations ./migrations
EXPOSE 3000
CMD ["node", "dist/index.js"]
# docker-compose.yml
version: '3.8'
services:
api:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:pass@postgres:5432/db
- REDIS_URL=redis://redis:6379
depends_on:
- postgres
- redis
postgres:
image: postgres:15-alpine
environment:
- POSTGRES_PASSWORD=secure_password
- POSTGRES_DB=myapp
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
volumes:
postgres_data:
redis_data:
Шаг 7: Монитринг и Логирование
// src/observability/logger.ts
import pino from 'pino';
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV,
tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,
});
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
transport: {
target: 'pino-pretty',
options: {
colorize: true,
singleLine: false
}
}
});
// Использование
export function logError(err: Error, context?: any) {
logger.error({ err, context });
Sentry.captureException(err);
}
export function logInfo(message: string, data?: any) {
logger.info({ message, ...data });
}
Шаг 8: Докку (для финального развёртывания)
# Настройка Dokku
ssh user@prod.example.com
dokku apps:create myapp
dokku config:set myapp NODE_ENV=production DATABASE_URL="..." REDIS_URL="..."
# Разработчик локально
git remote add dokku dokku@prod.example.com:myapp
# Push на production
git push dokku main # Dokku автоматически:
# 1. Получит код
# 2. Запустит Docker build
# 3. Запустит тесты
# 4. Запустит миграции
# 5. Развернёт приложение
# 6. Перезагрузит nginx
Полный flow от коммита до production
1. Разработчик пишет код (20 минут)
↓
2. git commit & git push (1 минута)
↓
3. GitHub Actions запускает CI (5 минут)
- Lint
- Tests
- Build
- Coverage check
↓
4. Если CI passed → Notification в Slack
↓
5. Code Review (30 минут - несколько часов)
↓
6. Merge в main (1 минута)
↓
7. GitHub Actions запускает CD (15 минут)
- Docker build
- Deploy to staging
- E2E tests
- Deploy to production
↓
8. Smoke tests & Monitoring (ongoing)
↓
9. Пользователи видят новый функционал
Мониторинг pipeline
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'nodejs_app'
static_configs:
- targets: ['localhost:3000/metrics']
# Алерты в Grafana
- alert: HighErrorRate
expr: rate(http_requests_errors[5m]) > 0.05
for: 5m
annotations:
summary: "High error rate detected"
action: "Check logs in Sentry"
Чеклист успешного pipeline
- Все коммиты проходят CI проверки
- Code review обязателен перед merge
- Coverage >= 90%
- Линтинг проходит без ошибок
- Тесты выполняются быстро (< 10 минут)
- Deployment автоматизирован
- Миграции БД выполняются автоматически
- Есть staging для тестирования
- E2E тесты на staging
- Мониторинг production
- Логирование и алерты
- Откат возможен при необходимости
Вывод: хороший pipeline — это автоматизированный путь от кода к production, который предотвращает ошибки и обеспечивает быстрое развёртывание.