mirror of
https://github.com/complexcaresolutions/cms.c2sgmbh.git
synced 2026-03-17 15:04:14 +00:00
feat: add automatic schema sync to deployment workflow
- Add drizzle.production.config.ts for schema synchronization - Add scripts/sync-schema.sh for manual schema sync - Update deploy-production.sh to run drizzle-kit push after migrations - Document schema sync workflow in DEPLOYMENT_STRATEGY.md - Update CLAUDE.md with schema sync commands This prevents schema drift between DEV and PROD by automatically syncing the database schema (especially payload_locked_documents_rels) during deployment. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
283151a9d4
commit
9e433315e5
5 changed files with 210 additions and 1 deletions
42
CLAUDE.md
42
CLAUDE.md
|
|
@ -245,6 +245,10 @@ pnpm build
|
||||||
pnpm payload migrate:create
|
pnpm payload migrate:create
|
||||||
pnpm payload migrate
|
pnpm payload migrate
|
||||||
|
|
||||||
|
# Schema-Sync (wichtig nach Collection-Änderungen!)
|
||||||
|
./scripts/sync-schema.sh --dry-run # Zeigt Änderungen
|
||||||
|
./scripts/sync-schema.sh # Führt Sync aus
|
||||||
|
|
||||||
# ImportMap nach Plugin-Änderungen
|
# ImportMap nach Plugin-Änderungen
|
||||||
pnpm payload generate:importmap
|
pnpm payload generate:importmap
|
||||||
|
|
||||||
|
|
@ -277,6 +281,12 @@ scripts/backup/setup-backup.sh # Backup-System einricht
|
||||||
3. `pm2 restart payload`
|
3. `pm2 restart payload`
|
||||||
4. Testen unter https://pl.porwoll.tech/admin
|
4. Testen unter https://pl.porwoll.tech/admin
|
||||||
|
|
||||||
|
### Bei Collection/Global-Änderungen (zusätzlich)
|
||||||
|
|
||||||
|
1. `pnpm payload migrate:create` - Migration erstellen
|
||||||
|
2. `git add src/migrations/` - Migration committen
|
||||||
|
3. Auf PROD nach Deployment: `./scripts/sync-schema.sh` wird automatisch ausgeführt
|
||||||
|
|
||||||
## Bekannte Besonderheiten
|
## Bekannte Besonderheiten
|
||||||
|
|
||||||
- **ES Modules:** package.json hat `"type": "module"`, daher PM2 Config als `.cjs`
|
- **ES Modules:** package.json hat `"type": "module"`, daher PM2 Config als `.cjs`
|
||||||
|
|
@ -1009,12 +1019,44 @@ Automatisches Deployment auf Staging-Server bei Push auf `develop`:
|
||||||
**GitHub Secret erforderlich:**
|
**GitHub Secret erforderlich:**
|
||||||
- `STAGING_SSH_KEY` - SSH Private Key für `payload@37.24.237.181`
|
- `STAGING_SSH_KEY` - SSH Private Key für `payload@37.24.237.181`
|
||||||
|
|
||||||
|
### deploy-production.yml (Production Deployment)
|
||||||
|
Manuelles Deployment auf Production-Server (Hetzner 3) bei workflow_dispatch:
|
||||||
|
|
||||||
|
| Feature | Beschreibung |
|
||||||
|
|---------|--------------|
|
||||||
|
| Pre-flight Checks | Überprüft Branch-Status und Migrationen |
|
||||||
|
| Pre-deployment Tests | Optional, Lint + Unit Tests |
|
||||||
|
| Database Backup | Automatisches Backup vor Deployment |
|
||||||
|
| Health Check | Verifiziert erfolgreiche Deployment |
|
||||||
|
| Auto-Rollback | Bei fehlgeschlagenem Health Check |
|
||||||
|
|
||||||
|
**Manuelles Production-Deployment:**
|
||||||
|
```bash
|
||||||
|
# Via GitHub Actions (empfohlen)
|
||||||
|
gh workflow run deploy-production.yml
|
||||||
|
|
||||||
|
# Auf dem Production-Server (Hetzner 3)
|
||||||
|
ssh payload@162.55.85.18
|
||||||
|
./scripts/deploy-production.sh
|
||||||
|
|
||||||
|
# Mit Optionen
|
||||||
|
./scripts/deploy-production.sh -y # Ohne Bestätigung
|
||||||
|
./scripts/deploy-production.sh --skip-backup # Ohne Backup
|
||||||
|
./scripts/deploy-production.sh --rollback # Rollback zur vorherigen Version
|
||||||
|
./scripts/deploy-production.sh --dry-run # Zeigt was passieren würde
|
||||||
|
```
|
||||||
|
|
||||||
|
**GitHub Secrets erforderlich:**
|
||||||
|
- `STAGING_SSH_KEY` - SSH Private Key für sv-payload
|
||||||
|
- `PRODUCTION_SSH_KEY` - SSH Private Key für Hetzner 3
|
||||||
|
|
||||||
## Dokumentation
|
## Dokumentation
|
||||||
|
|
||||||
### Hauptdokumentation
|
### Hauptdokumentation
|
||||||
- `CLAUDE.md` - Diese Datei (Projekt-Übersicht für AI-Assistenten)
|
- `CLAUDE.md` - Diese Datei (Projekt-Übersicht für AI-Assistenten)
|
||||||
- `docs/INFRASTRUCTURE.md` - Infrastruktur-Übersicht (Dev + Prod)
|
- `docs/INFRASTRUCTURE.md` - Infrastruktur-Übersicht (Dev + Prod)
|
||||||
- `docs/DEPLOYMENT.md` - Deployment-Prozess & Checklisten
|
- `docs/DEPLOYMENT.md` - Deployment-Prozess & Checklisten
|
||||||
|
- `docs/DEPLOYMENT_STRATEGY.md` - Vollständige Deployment-Strategie (Dev → Prod)
|
||||||
- `docs/PROJECT_STATUS.md` - Aktueller Projektstatus & Roadmap
|
- `docs/PROJECT_STATUS.md` - Aktueller Projektstatus & Roadmap
|
||||||
- `docs/STAGING-DEPLOYMENT.md` - Staging Deployment Workflow
|
- `docs/STAGING-DEPLOYMENT.md` - Staging Deployment Workflow
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,49 @@ Diese Strategie gewährleistet fehlerfreie Deployments von der Development-Umgeb
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Schema-Synchronisation
|
||||||
|
|
||||||
|
### Problem: Schema-Drift
|
||||||
|
|
||||||
|
Wenn neue Collections oder Globals auf DEV hinzugefügt werden, muss die PROD-Datenbank
|
||||||
|
entsprechend aktualisiert werden. Besonders die `payload_locked_documents_rels` Tabelle
|
||||||
|
benötigt für jede Collection eine eigene `*_id` Spalte.
|
||||||
|
|
||||||
|
### Automatische Synchronisation (im Deploy-Script)
|
||||||
|
|
||||||
|
Das Deploy-Script führt automatisch `drizzle-kit push` aus:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Im deploy-production.sh:
|
||||||
|
pnpm payload migrate # Payload-Migrationen
|
||||||
|
pnpm exec drizzle-kit push --force # Schema-Sync
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manuelle Schema-Synchronisation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Auf dem Server:
|
||||||
|
cd ~/payload-cms
|
||||||
|
|
||||||
|
# Dry-Run (zeigt was sich ändern würde)
|
||||||
|
./scripts/sync-schema.sh --dry-run
|
||||||
|
|
||||||
|
# Schema synchronisieren
|
||||||
|
./scripts/sync-schema.sh
|
||||||
|
|
||||||
|
# Oder mit --force für CI/Automation
|
||||||
|
./scripts/sync-schema.sh --force
|
||||||
|
```
|
||||||
|
|
||||||
|
### Best Practices
|
||||||
|
|
||||||
|
1. **Nach Collection-Änderungen:** `pnpm payload migrate:create` auf DEV ausführen
|
||||||
|
2. **Migrations committen:** `git add src/migrations/`
|
||||||
|
3. **Schema-Datei prüfen:** `src/payload-generated-schema.ts` sollte aktuell sein
|
||||||
|
4. **Vor Deployment testen:** `./scripts/sync-schema.sh --dry-run` auf PROD
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Rollback-Strategie
|
## Rollback-Strategie
|
||||||
|
|
||||||
### Automatischer Rollback (GitHub Actions)
|
### Automatischer Rollback (GitHub Actions)
|
||||||
|
|
|
||||||
20
drizzle.production.config.ts
Normal file
20
drizzle.production.config.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { defineConfig } from 'drizzle-kit'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drizzle config for production schema sync.
|
||||||
|
* Used by deploy script to push schema changes directly to database.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* DATABASE_URI="postgresql://..." pnpm exec drizzle-kit push --config=drizzle.production.config.ts
|
||||||
|
*/
|
||||||
|
export default defineConfig({
|
||||||
|
schema: './src/payload-generated-schema.ts',
|
||||||
|
out: './drizzle',
|
||||||
|
dialect: 'postgresql',
|
||||||
|
dbCredentials: {
|
||||||
|
url: process.env.DATABASE_URI || '',
|
||||||
|
},
|
||||||
|
// Safe mode - will prompt for destructive changes
|
||||||
|
strict: true,
|
||||||
|
verbose: true,
|
||||||
|
})
|
||||||
|
|
@ -250,10 +250,14 @@ log "Installing dependencies..."
|
||||||
pnpm install --frozen-lockfile
|
pnpm install --frozen-lockfile
|
||||||
success "Dependencies installed"
|
success "Dependencies installed"
|
||||||
|
|
||||||
# Step 5: Run migrations
|
# Step 5: Run migrations and schema sync
|
||||||
if [ "$SKIP_MIGRATIONS" = false ]; then
|
if [ "$SKIP_MIGRATIONS" = false ]; then
|
||||||
log "Running database migrations..."
|
log "Running database migrations..."
|
||||||
pnpm payload migrate || warn "No migrations to run or migration failed"
|
pnpm payload migrate || warn "No migrations to run or migration failed"
|
||||||
|
|
||||||
|
log "Syncing database schema with drizzle-kit..."
|
||||||
|
# Use drizzle-kit push to ensure schema is in sync (handles payload_locked_documents_rels etc.)
|
||||||
|
pnpm exec drizzle-kit push --config=drizzle.production.config.ts --force 2>/dev/null || warn "drizzle-kit push skipped or failed"
|
||||||
else
|
else
|
||||||
warn "Skipping migrations (--skip-migrations)"
|
warn "Skipping migrations (--skip-migrations)"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
100
scripts/sync-schema.sh
Executable file
100
scripts/sync-schema.sh
Executable file
|
|
@ -0,0 +1,100 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Schema Sync Script
|
||||||
|
# =============================================================================
|
||||||
|
# Synchronizes the database schema with the Payload-generated schema.
|
||||||
|
# Use this after adding new Collections/Globals to ensure the database
|
||||||
|
# has all required tables and columns.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./scripts/sync-schema.sh # Interactive mode
|
||||||
|
# ./scripts/sync-schema.sh --force # Non-interactive (for CI/automation)
|
||||||
|
# ./scripts/sync-schema.sh --dry-run # Show what would change
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
FORCE=false
|
||||||
|
DRY_RUN=false
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
case $arg in
|
||||||
|
--force|-f)
|
||||||
|
FORCE=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--dry-run|-n)
|
||||||
|
DRY_RUN=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
head -15 "$0" | tail -12
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Determine environment
|
||||||
|
if [ -f "/home/payload/payload-cms/.env" ]; then
|
||||||
|
source /home/payload/payload-cms/.env 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
PROJECT_DIR="${PROJECT_DIR:-/home/payload/payload-cms}"
|
||||||
|
cd "$PROJECT_DIR"
|
||||||
|
|
||||||
|
echo -e "${BLUE}=============================================="
|
||||||
|
echo -e " Database Schema Sync"
|
||||||
|
echo -e "==============================================${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check if schema file exists
|
||||||
|
if [ ! -f "src/payload-generated-schema.ts" ]; then
|
||||||
|
echo -e "${YELLOW}Generating schema file...${NC}"
|
||||||
|
pnpm payload generate:db-schema 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "src/payload-generated-schema.ts" ]; then
|
||||||
|
echo -e "${RED}Error: Could not find or generate schema file${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Dry run mode
|
||||||
|
if [ "$DRY_RUN" = true ]; then
|
||||||
|
echo -e "${YELLOW}[DRY RUN] Showing what would change:${NC}"
|
||||||
|
echo ""
|
||||||
|
pnpm exec drizzle-kit push --config=drizzle.production.config.ts --dry-run 2>&1 || true
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Interactive confirmation
|
||||||
|
if [ "$FORCE" != true ]; then
|
||||||
|
echo -e "${YELLOW}This will sync the database schema with the code.${NC}"
|
||||||
|
echo "Database: $DATABASE_URI"
|
||||||
|
echo ""
|
||||||
|
read -p "Continue? (y/n) " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "Aborted."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run schema sync
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}Running drizzle-kit push...${NC}"
|
||||||
|
pnpm exec drizzle-kit push --config=drizzle.production.config.ts --force
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}Schema sync complete!${NC}"
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo " 1. Restart Payload: pm2 restart payload"
|
||||||
|
echo " 2. Test the admin panel"
|
||||||
Loading…
Reference in a new issue