Kit enthält drei GitHub Actions Workflows, die den gesamten Weg von der Code-Änderung bis zum Production Deployment automatisieren. Jeder Push führt Typprüfung, Linting, Unit-Tests und E2E-Smoke-Tests aus. Merges auf
master lösen ein vollständiges Deployment auf Vercel aus.Workflow-Übersicht
| Workflow | Datei | Auslöser | Zweck |
|---|---|---|---|
| Deploy to Production | deploy.yml | Push auf master, manuell | Vollständige Test-Suite + Vercel Deployment |
| Test | test.yml | PRs auf master, Push auf develop | Quality Gate für Pull Requests |
| Full E2E Suite | e2e-full.yml | Täglich um 2 Uhr UTC, manuell | Umfassendes nächtliches Regressions-Testing |
Alle drei Workflows verwenden Turborepo Remote Caching, um Builds über Runs hinweg zu beschleunigen. Cache-Treffer können die Build-Zeiten um 50-70% reduzieren.
Production Deployment Workflow
Der
deploy.yml-Workflow ist deine Production-Pipeline. Er läuft bei jedem Push auf master und kann auch manuell über den GitHub Actions Tab ausgelöst werden.Pipeline-Struktur
Der Workflow hat zwei sequenzielle Jobs:
test (Job 1) deploy (Job 2)
├── Install dependencies ├── Install dependencies
├── Validate customer files ├── Check required secrets
├── Setup test database ├── Pull Vercel environment
├── Generate Prisma client ├── Build with Vercel CLI
├── Type checking ├── Deploy to production
├── Linting ├── Comment on commit
├── Unit tests └── Create deployment status
├── Build application
└── E2E smoke tests
Der Deploy-Job läuft nur, wenn alle Tests bestehen. Das stellt sicher, dass fehlerhafter Code niemals Production erreicht.
Test-Job
Der Test-Job läuft gegen eine echte PostgreSQL-Datenbank mit der pgvector-Erweiterung (entspricht deinem Production Supabase-Setup):
deploy.yml — Test Job with PostgreSQL Service
test:
name: Run Tests
runs-on: ubuntu-latest
services:
postgres:
image: pgvector/pgvector:pg15
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: testdb
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: 10.15.1
Der PostgreSQL-Service-Container verwendet
pgvector/pgvector:pg15, das die gleiche Vektor-Erweiterung bietet, die du in Production für RAG-Features verwendest. Das stellt sicher, dass Datenbankabfragen mit Vektoroperationen gegen echtes PostgreSQL-Verhalten getestet werden.Kundendatei-Validierung
Bevor Tests ausgeführt werden, prüft der Workflow, ob automatisch generierte Kundendateien aktuell sind:
deploy.yml — Customer File Validation (env.test)
- name: Validate customer .env.test is up-to-date
run: |
echo "Validating customer .env.test generation..."
# Check if generated file exists
if [ ! -f "apps/boilerplate/.env.test" ]; then
echo "❌ Error: apps/boilerplate/.env.test does not exist"
echo "This file should be generated and committed to git"
echo "Run: cd apps/boilerplate && pnpm generate:env-test"
exit 1
fi
# Compare files (must be identical - no transformations)
if ! diff -q .env.test apps/boilerplate/.env.test > /dev/null 2>&1; then
echo "❌ Error: apps/boilerplate/.env.test is outdated"
echo ""
echo "The root .env.test was updated but the generated customer version wasn't."
echo "Please run: cd apps/boilerplate && pnpm generate:env-test"
echo "Then commit the updated apps/boilerplate/.env.test"
echo ""
echo "Differences:"
diff .env.test apps/boilerplate/.env.test || true
exit 1
fi
echo "✅ Customer .env.test is up-to-date"
Die Validierung prüft vier kundenkritische Dateikategorien:
| Validierung | Was geprüft wird |
|---|---|
.env.test | Test-Umgebungsvorlage stimmt mit Root überein |
CLAUDE.md | Generierte Kunden-CLAUDE.md ist aktuell |
.gitignore | Monorepo-Muster in der Standalone-Version entfernt |
docs/ | Generierte Docs haben keine Monorepo-Pfad-Referenzen |
Falls eine Validierung fehlschlägt, beendet der Workflow mit einer klaren Fehlermeldung, die erklärt, welche Datei neu generiert werden muss, und dem genauen Befehl dazu.
Deploy-Job
Nachdem die Tests bestanden haben, baut der Deploy-Job die Anwendung und deployt sie auf Vercel:
deploy.yml — Vercel Build and Deploy
deploy:
name: Deploy to Vercel
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check Required Secrets
run: |
echo "Checking for required secrets..."
if [ -z "${{ secrets.VERCEL_TOKEN }}" ]; then
echo "❌ Error: VERCEL_TOKEN secret is not set"
echo "Please add VERCEL_TOKEN to your GitHub repository secrets"
echo "See docs/DEPLOYMENT_SETUP.md for instructions"
exit 1
fi
if [ -z "${{ secrets.VERCEL_ORG_ID }}" ]; then
echo "❌ Error: VERCEL_ORG_ID secret is not set"
echo "Please add VERCEL_ORG_ID to your GitHub repository secrets"
echo "Required value: team_Bgh9zp308TcrlrYLqGmuGLHN"
exit 1
fi
if [ -z "${{ secrets.VERCEL_PROJECT_ID }}" ]; then
echo "❌ Error: VERCEL_PROJECT_ID secret is not set"
echo "Please add VERCEL_PROJECT_ID to your GitHub repository secrets"
echo "Required value: prj_jf8vKRszL6Xt7IF8EwqxzfnwRXsl"
exit 1
fi
echo "✅ All required secrets are configured"
- uses: pnpm/action-setup@v3
with:
version: 10.15.1
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Install Vercel CLI
run: pnpm add -g vercel@latest
- name: Pull Vercel Environment Information
run: |
echo "Pulling Vercel environment configuration..."
vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
echo "✅ Successfully pulled Vercel configuration"
- name: Build Project Artifacts
run: |
echo "Building boilerplate app for production..."
vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
echo "✅ Build completed successfully"
- name: Deploy to Vercel
id: deploy
run: |
echo "Deploying to Vercel production..."
# --archive=tgz compresses files before upload to avoid rate limits (>5000 files)
DEPLOYMENT_URL=$(vercel deploy --prebuilt --prod --archive=tgz --token=${{ secrets.VERCEL_TOKEN }})
echo "deployment-url=$DEPLOYMENT_URL" >> $GITHUB_OUTPUT
echo "✅ Successfully deployed to: $DEPLOYMENT_URL"
Wichtige Implementierungsdetails:
vercel pulllädt die Umgebungskonfiguration von Vercel herunter und stellt sicher, dass der Build dieselben Variablen wie Production verwendetvercel build --prodbaut die Anwendung lokal in CI (schneller als das Bauen auf Vercels Servern)--archive=tgzkomprimiert die Build-Ausgabe vor dem Upload. Das ist entscheidend für Monorepo-Projekte mit 5.000+ Dateien — ohne diese Option können Vercels API-Rate-Limits zu Upload-Fehlern führen- Commit-Kommentare bieten direkte Links zur Deployment-URL für schnelle Überprüfung
Erforderliche GitHub Secrets
Konfiguriere diese Secrets in deinem GitHub-Repository unter Settings > Secrets and variables > Actions:
| Secret | Zweck | Wo zu finden |
|---|---|---|
VERCEL_TOKEN | Authentifiziert Vercel CLI | Vercel Dashboard > Settings > Tokens |
VERCEL_ORG_ID | Identifiziert dein Vercel-Team | Vercel Dashboard > Settings > General |
VERCEL_PROJECT_ID | Identifiziert dein Vercel-Projekt | Vercel Dashboard > Project Settings > General |
TURBO_TOKEN | Turborepo Remote Cache Auth | vercel.com/account/tokens |
TURBO_TEAM | Turborepo Team-Bezeichner | Dein Vercel Team Slug |
Der Deploy-Job prüft auf
VERCEL_TOKEN, VERCEL_ORG_ID und VERCEL_PROJECT_ID, bevor er das Deployment versucht. Fehlt eines dieser Secrets, tritt ein expliziter Fehler mit Anweisungen zum Setzen auf.PR-Validierungs-Workflow
Der
test.yml-Workflow läuft bei jedem Pull Request auf master und bei Pushes auf develop. Er fungiert als Quality Gate — PRs können nicht gemergt werden, bis alle Checks bestehen.PR-Pipeline-Struktur
test (Single Job)
├── Install dependencies
├── Setup PostgreSQL + pgvector
├── Generate Prisma client
├── Push database schema
├── Type checking
├── Linting
├── Unit tests
├── Validate customer files
├── E2E smoke tests
└── Upload test artifacts
Test-Artefakt-Upload
Nach jedem Durchlauf lädt der Workflow Test-Ergebnisse mit 30-tägiger Aufbewahrung hoch:
test.yml — Artifact Upload
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: |
coverage/
playwright-report/
retention-days: 30
Artefakte umfassen:
coverage/— Code-Coverage-Berichte von Vitest (HTML, JSON, Text)playwright-report/— E2E-Testergebnisse mit Screenshots und Traces
Lade diese aus dem Bereich Actions > Artifacts in GitHub herunter, wenn du Fehler debuggst.
Nächtliche E2E-Suite
Der
e2e-full.yml-Workflow führt die vollständige E2E-Test-Suite täglich um 2:00 Uhr UTC aus. Das erkennt Regressionen, die Smoke-Tests möglicherweise verpassen.Was ausgeführt wird
e2e-full.yml — Schedule and Trigger
name: Full E2E Test Suite
on:
# Run daily at 2:00 AM UTC
schedule:
- cron: '0 2 * * *'
# Allow manual trigger
workflow_dispatch:
| Aspekt | Wert |
|---|---|
| Zeitplan | Täglich um 2:00 Uhr UTC |
| Tests | Vollständige Suite auf Chromium |
| Timeout | 30 Minuten |
| Quality Gates | Typprüfung + Lint + Unit-Tests + vollständige E2E |
Automatische Issue-Erstellung
Wenn die nächtliche Suite fehlschlägt, erstellt der Workflow automatisch ein GitHub Issue mit den Fehlerdetails:
e2e-full.yml — Auto-Create Issue on Failure
- name: Create issue on failure
if: failure()
uses: actions/github-script@v7
with:
script: |
const title = '🔴 Full E2E Test Suite Failed';
const body = `
The scheduled full E2E test suite has failed.
**Workflow Run:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
**Triggered by:** ${{ github.event_name }}
**Branch:** ${{ github.ref_name }}
**Commit:** ${{ github.sha }}
Please review the test results and fix the failing tests.
[View Playwright Report](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
`;
// Check if there's already an open issue
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'e2e-test-failure'
});
if (issues.data.length === 0) {
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: body,
labels: ['e2e-test-failure', 'automated']
});
}
Das Issue enthält:
- Direkten Link zum fehlgeschlagenen Workflow-Durchlauf
- Branch und Commit-SHA zum Debuggen
- Link zum Playwright-Report-Artefakt
- Labels (
e2e-test-failure,automated) zum Filtern
Es wird nur ein Issue erstellt — falls bereits ein offenes Issue mit dem Label
e2e-test-failure existiert, überspringt der Workflow die Erstellung, um Duplikate zu vermeiden.Du kannst die vollständige E2E-Suite auf Abruf über den Actions-Tab mit der Schaltfläche Run workflow ausführen. Das ist nützlich vor größeren Releases oder nach erheblichem Refactoring.
Quality Gates Zusammenfassung
Jeder Code-Pfad muss diese Gates passieren, bevor er Production erreicht:
| Gate | Workflow | Blockiert |
|---|---|---|
| TypeScript-Kompilierung | deploy.yml, test.yml | Typfehler |
| ESLint | deploy.yml, test.yml | Code-Qualitätsverstöße |
| Unit-Tests (800+) | deploy.yml, test.yml | Logik-Regressionen |
| E2E-Smoke-Tests (19) | deploy.yml, test.yml | Kritische Flow-Fehler |
| Kundendatei-Validierung | deploy.yml, test.yml | Veraltete generierte Dateien |
| Vollständige E2E-Suite (186) | e2e-full.yml | Umfassende Regressionen |
Turborepo Remote Caching
Alle Workflows verwenden Turborepo Remote Caching, um Build-Artefakte über CI-Runs hinweg zu teilen. Das wird über zwei Umgebungsvariablen konfiguriert:
yaml
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
Wenn ein vorheriger Durchlauf denselben Code bereits gebaut hat, lädt Turborepo das gecachte Ergebnis herunter, anstatt neu zu bauen. Das bringt die größten Einsparungen bei:
- Typprüfung — TypeScript-Kompilierungsergebnisse werden gecacht
- Linting — ESLint-Ergebnisse werden gecacht
- Building — Next.js-Build-Ausgabe wird gecacht
Typische Cache-Trefferquoten liegen bei 60-80% für PR-Validierungs-Workflows. Production Deploys bauen meist alles neu, da sie nach Merges ausgeführt werden, die neuen Code einbringen.
Eigene Workflow-Schritte hinzufügen
Um eigene Schritte zur Pipeline hinzuzufügen, bearbeite die Workflow-Dateien in
.github/workflows/. Häufige Ergänzungen:Lighthouse-Audit hinzufügen
yaml
- name: Run Lighthouse CI
uses: treosh/lighthouse-ci-action@v11
with:
urls: |
${{ steps.deploy.outputs.deployment-url }}
budgetPath: ./lighthouse-budget.json
uploadArtifacts: true
Datenbank-Migration hinzufügen
yaml
- name: Run database migrations
run: pnpm --filter=@nextsaasai/boilerplate prisma migrate deploy
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
Slack-Benachrichtigung hinzufügen
yaml
- name: Notify Slack
if: success()
uses: slackapi/slack-github-action@v1
with:
payload: |
{"text": "Deployed to production: ${{ steps.deploy.outputs.deployment-url }}"}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
Fehlerbehebung
Tests bestehen lokal, schlagen aber in CI fehl
Die häufigsten Ursachen sind:
- Fehlende Umgebungsvariablen — CI verwendet
apps/boilerplate/.env.test, während lokalapps/boilerplate/.env.localverwendet wird. Stelle sicher, dass alle für Tests benötigten Variablen in.env.testvorhanden sind - Timing-Probleme — CI-Runner sind langsamer als lokale Maschinen. Falls Tests fest codierte Timeouts verwenden, erhöhe diese oder nutze Playwrights eingebaute
waitFor-Muster - Datenbankzustand — CI pusht ein frisches Schema mit
prisma db push. Stelle sicher, dass deine Tests nicht von Seed-Daten abhängen, die nur lokal existieren
Cache-bedingte Build-Fehler
Falls ein Build nach einem Dependency-Update mit unerwarteten Fehlern fehlschlägt:
bash
# In deinem Workflow, vor install hinzufügen:
- name: Clear Turborepo cache
run: pnpm turbo run build --force
Das umgeht den Remote-Cache für einen einzelnen Durchlauf. Falls der Build erfolgreich ist, war der alte Cache veraltet.
Deployment erfolgreich, aber Website zeigt Fehler
- Prüfe, ob alle Umgebungsvariablen im Production-Scope von Vercel gesetzt sind
- Vergewissere dich, dass Datenbank-Migrationen angewendet wurden:
prisma migrate deploy - Prüfe die Vercel Functions-Logs auf Laufzeitfehler