Files
metascraper/doc/DEPLOYMENT.md
2025-11-23 14:25:09 +03:00

13 KiB
Raw Blame History

MetaScraper Deployment Guide

📦 Package Publishing

Preparation Checklist

Before publishing, ensure:

  • All tests pass: npm test
  • Code is properly documented
  • Version number follows semantic versioning
  • CHANGELOG.md is updated
  • Package.json is complete and accurate
  • License file is present
  • README.md is up to date

Version Management

Semantic Versioning

# Patch version (bug fixes)
npm version patch

# Minor version (new features, backward compatible)
npm version minor

# Major version (breaking changes)
npm version major

Version Numbering Rules

  • MAJOR: Breaking changes (API changes, Node.js version requirements)
  • MINOR: New features (new Turkish patterns, performance improvements)
  • PATCH: Bug fixes (error handling, small fixes)

Package.json Configuration

{
  "name": "flixscaper",
  "version": "1.0.0",
  "description": "Netflix meta veri scraper.",
  "type": "module",
  "main": "src/index.js",
  "exports": {
    ".": "./src/index.js",
    "./parser": "./src/parser.js",
    "./headless": "./src/headless.js"
  },
  "files": [
    "src/",
    "README.md",
    "LICENSE",
    "CHANGELOG.md"
  ],
  "engines": {
    "node": ">=18"
  },
  "keywords": [
    "netflix",
    "scraper",
    "metadata",
    "turkish",
    "flixscaper"
  ],
  "repository": {
    "type": "git",
    "url": "https://github.com/username/flixscaper.git"
  }
}

Publishing Process

1. Local Testing

# Test package locally
npm pack

# Install in test project
npm install ./flixscaper-1.0.0.tgz

# Test functionality
node -e "import { scraperNetflix } from 'flixscaper'; console.log('Import successful')"

2. NPM Registry Publishing

# Login to npm
npm login

# Publish to public registry
npm publish

# Publish with beta tag
npm publish --tag beta

# Publish dry run
npm publish --dry-run

3. Private Registry Publishing

# Publish to private registry
npm publish --registry https://registry.yourcompany.com

# Configure default registry
npm config set registry https://registry.yourcompany.com

🏗️ Build & Distribution

Source Distribution

MetaScraper is distributed as source code with minimal processing:

# Files included in distribution
src/
├── index.js     # Main entry point
├── parser.js    # HTML parsing logic
├── headless.js  # Playwright integration
└── polyfill.js  # Node.js compatibility

# Documentation files
README.md
LICENSE
CHANGELOG.md

# Configuration files
package.json

Browser/Node.js Compatibility

Node.js Support Matrix

Node.js Version Support Status Notes
18.x Full Support Requires polyfill
20.x Full Support Polyfill optional
22.x Full Support Native support
16.x Not Supported Use older version or upgrade
<16.x Not Supported Major compatibility issues

Compatibility Layer

// src/polyfill.js - Automatic compatibility handling
import { Blob } from 'node:buffer';

// Only apply polyfill if needed
if (typeof globalThis.File === 'undefined') {
  class PolyfillFile extends Blob {
    constructor(parts, name, options = {}) {
      super(parts, options);
      this.name = String(name);
      this.lastModified = options.lastModified ?? Date.now();
    }
  }
  globalThis.File = PolyfillFile;
}

globalThis.Blob = globalThis.Blob || Blob;

🔄 Continuous Integration/Deployment

GitHub Actions Workflow

# .github/workflows/deploy.yml
name: Deploy Package

on:
  push:
    tags:
      - 'v*'
  release:
    types: [published]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18.x, 20.x, 22.x]

    steps:
    - uses: actions/checkout@v3

    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'
        registry-url: 'https://registry.npmjs.org'

    - name: Install dependencies
      run: npm ci

    - name: Run tests
      run: npm test

    - name: Run linting
      run: npm run lint

    - name: Check build
      run: npm pack

  publish:
    needs: test
    runs-on: ubuntu-latest
    if: github.event_name == 'release' || startsWith(github.ref, 'refs/tags/')

    steps:
    - uses: actions/checkout@v3

    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '20.x'
        cache: 'npm'
        registry-url: 'https://registry.npmjs.org'

    - name: Install dependencies
      run: npm ci

    - name: Build package
      run: npm pack

    - name: Publish to NPM
      run: npm publish
      env:
        NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

Automated Testing Pipeline

# .github/workflows/test.yml
name: Test Suite

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18.x, 20.x, 22.x]
        os: [ubuntu-latest, windows-latest, macos-latest]

    steps:
    - uses: actions/checkout@v3

    - name: Setup Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'

    - name: Install dependencies
      run: npm ci

    - name: Install Playwright (if needed)
      run: npx playwright install chromium

    - name: Run tests
      run: npm test -- --coverage

    - name: Upload coverage
      uses: codecov/codecov-action@v3

🐳 Docker Deployment

Dockerfile

# Dockerfile
FROM node:18-alpine

WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm ci --only=production

# Copy source code
COPY src/ ./src/

# Create non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S flixscaper -u 1001

# Change ownership
RUN chown -R flixscaper:nodejs /app
USER flixscaper

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD node -e "import('flixscaper').then(() => process.exit(0)).catch(() => process.exit(1))"

EXPOSE 3000

CMD ["node", "-e", "import('flixscaper').then(m => console.log('MetaScraper ready'))"]

Docker Compose

# docker-compose.yml
version: '3.8'

services:
  flixscaper:
    build: .
    container_name: flixscaper
    environment:
      - NODE_ENV=production
    volumes:
      - ./logs:/app/logs
    restart: unless-stopped

  flixscaper-test:
    build: .
    container_name: flixscaper-test
    command: npm test
    environment:
      - NODE_ENV=test
    volumes:
      - .:/app
      - /app/node_modules

Building Docker Images

# Build image
docker build -t flixscaper:latest .

# Build with specific version
docker build -t flixscaper:1.0.0 .

# Run container
docker run --rm flixscaper:latest node -e "
  import('flixscaper').then(async (m) => {
    const result = await m.scraperNetflix('https://www.netflix.com/title/80189685');
    console.log(result);
  })
"

🔒 Security Considerations

Package Security

Dependency Scanning

# Audit dependencies for vulnerabilities
npm audit

# Fix vulnerabilities
npm audit fix

# Generate security report
npm audit --json > security-report.json

Secure Publishing

# Use 2FA for npm account
npm profile enable-2fa

# Check package contents before publishing
npm pack --dry-run

# Verify no sensitive files included
tar -tzf flixscaper-*.tgz | grep -E "(key|secret|password|token)" || echo "No sensitive files found"

Runtime Security

Input Validation

// Ensure all inputs are validated
function validateInput(url, options = {}) {
  if (!url || typeof url !== 'string') {
    throw new Error('Invalid URL provided');
  }

  // Validate URL format
  try {
    new URL(url);
  } catch {
    throw new Error('Invalid URL format');
  }

  // Sanitize options
  const safeOptions = {
    headless: Boolean(options.headless),
    timeoutMs: Math.max(1000, Math.min(60000, Number(options.timeoutMs) || 15000)),
    userAgent: typeof options.userAgent === 'string' ? options.userAgent : undefined
  };

  return safeOptions;
}

Network Security

// Secure request configuration
const secureHeaders = {
  'User-Agent': userAgent || DEFAULT_USER_AGENT,
  'Accept': 'text/html,application/xhtml+xml',
  'Accept-Language': 'en-US,en;q=0.9',
  'Cache-Control': 'no-cache',
  'Pragma': 'no-cache'
};

// Rate limiting consideration
const requestDelay = 1000; // 1 second between requests

📊 Monitoring & Analytics

Usage Analytics

Basic Metrics Collection

// Optional analytics (user consent required)
function trackUsage(url, options, success, duration) {
  if (!options.analytics) return;

  const metrics = {
    timestamp: Date.now(),
    url: url.replace(/\/title\/\d+/, '/title/XXXXXX'), // Anonymize
    headless: options.headless,
    success: success,
    duration: duration,
    nodeVersion: process.version,
    version: require('./package.json').version
  };

  // Send to analytics service (optional)
  // analytics.track('flixscaper_usage', metrics);
}

Error Tracking

function trackError(error, context) {
  const errorInfo = {
    message: error.message,
    stack: error.stack,
    context: context,
    timestamp: Date.now(),
    nodeVersion: process.version
  };

  // Log for debugging
  console.error('MetaScraper Error:', errorInfo);

  // Optional: Send to error tracking service
  // errorTracker.captureException(error, { extra: context });
}

Performance Monitoring

// Performance metrics
class PerformanceMonitor {
  constructor() {
    this.metrics = {
      totalRequests: 0,
      successfulRequests: 0,
      averageResponseTime: 0,
      errorCounts: {}
    };
  }

  recordRequest(duration, success, error = null) {
    this.metrics.totalRequests++;

    if (success) {
      this.metrics.successfulRequests++;
    } else {
      this.metrics.errorCounts[error?.message] =
        (this.metrics.errorCounts[error?.message] || 0) + 1;
    }

    // Update average response time
    this.metrics.averageResponseTime =
      (this.metrics.averageResponseTime * (this.metrics.totalRequests - 1) + duration)
      / this.metrics.totalRequests;
  }

  getMetrics() {
    return {
      ...this.metrics,
      successRate: (this.metrics.successfulRequests / this.metrics.totalRequests) * 100
    };
  }
}

🔄 Version Management

Release Process

1. Development Release

# Create feature branch
git checkout -b feature/new-patterns

# Implement changes
# Add tests
# Update documentation

# Create development release
npm version prerelease --preid=dev
git push --tags
npm publish --tag dev

2. Production Release

# Merge to main
git checkout main
git merge develop

# Update version
npm version minor  # or patch/major

# Create GitHub release
gh release create v1.1.0 --generate-notes

# Publish to npm
npm publish

3. Hotfix Release

# Create hotfix branch from main
git checkout -b hotfix/critical-bug

# Fix issue
npm version patch

# Publish immediately
npm publish --tag latest

# Merge back to develop
git checkout develop
git merge main
git checkout main
git merge hotfix/critical-bug

Changelog Management

# CHANGELOG.md

## [1.1.0] - 2025-11-23

### Added
- New Turkish UI pattern: "yeni başlık"
- Performance monitoring API
- Docker support

### Fixed
- Memory leak in Playwright cleanup
- URL validation for Turkish Netflix domains

### Changed
- Improved error messages in Turkish
- Updated Node.js compatibility matrix

### Deprecated
- Support for Node.js 16.x (will be removed in 2.0.0)

## [1.0.1] - 2025-11-20

### Fixed
- Critical bug in title cleaning
- Missing year extraction for movies

🌐 Distribution Channels

NPM Registry

// package.json - publishing configuration
{
  "publishConfig": {
    "access": "public",
    "registry": "https://registry.npmjs.org"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/username/flixscaper.git"
  },
  "bugs": {
    "url": "https://github.com/username/flixscaper/issues"
  },
  "homepage": "https://github.com/username/flixscaper#readme"
}

CDN Distribution

// For browser usage (future enhancement)
// Available via CDN:
// https://cdn.jsdelivr.net/npm/flixscaper/dist/flixscaper.min.js

import('https://cdn.jsdelivr.net/npm/flixscaper@latest/dist/flixscaper.min.js')
  .then(module => {
    const { scraperNetflix } = module;
    // Use in browser
  });

Private Distribution

# For enterprise/internal distribution
npm config set @company:registry https://npm.company.com

# Publish to private registry
npm publish --registry https://npm.company.com

# Install from private registry
npm install @company/flixscaper

Deployment guide last updated: 2025-11-23