- docker-compose.coolify(.prebuilt).yml: Service craftvia-worker (Target worker, Chromium, shm_size 1gb, gleiche Härtung), Craftvia-Variablen für app und worker. - Dockerfile: worker-Stage mit HOME=/home/app (Chromium-Profil für non-root); lokaler docker build der Targets runner und worker erfolgreich, PDF-Erzeugung im Image geprüft. - .env.example/.env.prod.example/.env.coolify.example: alle Craftvia-Variablen inkl. RLS, KI-Provider, PDF_CHROMIUM_PATH, OFFLINE_MAX_DAYS, API_RATE_LIMIT_*, AI_GENERATION_RETENTION_DAYS, AI_MONTHLY_TOKEN_LIMIT. - CI (.github, .gitea): Job gate mit Postgres (pgvector) und Redis als Service: migrate deploy, seed, Passwort für craftvia_app, tsc, lint, build, npm run test. - docs/craftvia/DEPLOY.md (aus den Certvia-Deploy-Docs abgeleitet): Architektur, Domains, Secrets, Worker, Migrationen, RLS-Aktivierung, Backup/Restore, KI, Rate Limits, Aufbewahrung, Smoke, Update/Rollback. build-and-push-images.sh baut craftvia-worker. - Certvia-/ISMS-Dokumente aus docs/ nach docs/_certvia-archiv/ (mit README); Verweise in README.md und Skript-Kommentaren angepasst. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
169 lines
6.5 KiB
YAML
169 lines
6.5 KiB
YAML
# CI-Pipeline (Gitea Actions — GitHub-Actions-kompatibel).
|
|
#
|
|
# WICHTIG: Braucht einen aktivierten Gitea-Actions-Runner (Gitea ->
|
|
# Settings -> Actions -> Runners). Ohne registrierten Runner wird dieser Workflow
|
|
# NICHT ausgeführt (er schlägt nicht fehl, er läuft schlicht nicht an).
|
|
# Inhaltlich identisch zu .github/workflows/ci.yml (Spiegel für Nicht-Gitea-Remotes).
|
|
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: ["main", "dev", "dev-*"]
|
|
pull_request:
|
|
branches: ["main", "dev", "dev-*"]
|
|
|
|
jobs:
|
|
# Vollständiges Qualitäts-Gate (= `npm run gate`) gegen echte Infrastruktur:
|
|
# Postgres 16 mit pgvector + Redis als Service-Container. Garage/S3 wird bewusst
|
|
# weggelassen: der Storage-Adapter fällt ohne S3_* auf den Stub zurück, S3-abhängige
|
|
# Prüfungen (test-garage-storage, Byte-Abruf in test-einsatz-sync/test-berichte-pdf)
|
|
# überspringen sich. Ohne SMTP_HOST überspringt test-mail den echten Versand, ohne
|
|
# ANTHROPIC_API_KEY/TRANSCRIPTION_API_KEY die Live-KI-Tests. test-berichte-pdf
|
|
# überspringt sich, wenn im Runner-Image kein Chromium/Chrome startbar ist.
|
|
gate:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 60
|
|
services:
|
|
postgres:
|
|
image: pgvector/pgvector:0.8.0-pg16
|
|
env:
|
|
POSTGRES_USER: craftvia
|
|
POSTGRES_PASSWORD: craftvia
|
|
POSTGRES_DB: craftvia
|
|
options: >-
|
|
--health-cmd "pg_isready -U craftvia"
|
|
--health-interval 5s
|
|
--health-timeout 5s
|
|
--health-retries 20
|
|
redis:
|
|
image: redis:7.4.2-alpine
|
|
options: >-
|
|
--health-cmd "redis-cli ping"
|
|
--health-interval 5s
|
|
--health-timeout 5s
|
|
--health-retries 20
|
|
# Nur CI-Dummywerte (keine echten Secrets). Gitea act_runner führt den Job in einem
|
|
# Container im selben Netz wie die Services aus → Hostnamen = Service-Namen
|
|
# (postgres/redis), NICHT localhost. Läuft der Runner im Host-Modus
|
|
# (Label ubuntu-latest:host), Hosts auf localhost umstellen und ports: ergänzen.
|
|
env:
|
|
DATABASE_URL: "postgresql://craftvia:craftvia@postgres:5432/craftvia?schema=public"
|
|
# RLS-Test (scripts/test-rls-enforcement.ts): RLS_ENFORCED bleibt aus, der Test schaltet
|
|
# selbst scharf. RLS_TEST_REQUIRED=true macht aus dem Skip einen harten Fehler.
|
|
RLS_DATABASE_URL: "postgresql://craftvia_app:craftvia_app_ci@postgres:5432/craftvia?schema=public"
|
|
RLS_TEST_REQUIRED: "true"
|
|
REDIS_URL: "redis://redis:6379"
|
|
AUTH_SECRET: "ci-dummy-auth-secret-0000000000000000"
|
|
AUTH_URL: "http://localhost:3000"
|
|
APP_BASE_URL: "http://localhost:3000"
|
|
PASSWORD_PEPPER: "0000000000000000000000000000000000000000000000000000000000000abc"
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Node 22 einrichten
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22.14.0"
|
|
|
|
# npm 11 pinnen: Das committete Lockfile wurde mit npm 11 erzeugt; node 22.14
|
|
# bringt npm 10.9.2 mit, das next@16.2.12 -> @swc/helpers anders auflöst und
|
|
# `npm ci` sonst mit "out of sync" abbricht (siehe Dockerfile).
|
|
- name: npm 11 pinnen
|
|
run: npm i -g npm@11.19.0
|
|
|
|
- name: Abhängigkeiten installieren (Lockfile bindend)
|
|
run: npm ci --include=optional --no-audit --no-fund
|
|
|
|
- name: Prisma Client generieren
|
|
run: npx prisma generate
|
|
|
|
- name: Migrationen anwenden
|
|
run: npx prisma migrate deploy
|
|
|
|
- name: Demo-Seed
|
|
run: npx prisma db seed
|
|
|
|
# Die Baseline-Migration legt craftvia_app NOLOGIN an; das Passwort ist ein Betriebs-
|
|
# Secret und wird nie migriert. Für den RLS-Test hier ein CI-Dummy-Passwort setzen
|
|
# (über die Prisma-Config-Datasource, damit kein psql-Client im Runner nötig ist).
|
|
- name: RLS-Rolle craftvia_app mit LOGIN versehen
|
|
run: echo "ALTER ROLE craftvia_app WITH LOGIN PASSWORD 'craftvia_app_ci';" | npx prisma db execute --stdin
|
|
|
|
- name: Typprüfung (tsc --noEmit)
|
|
run: npx tsc --noEmit
|
|
|
|
- name: Lint
|
|
run: npm run lint
|
|
|
|
- name: Build
|
|
run: npm run build
|
|
|
|
- name: Tests (scripts/test-*.ts)
|
|
run: npm run test
|
|
|
|
audit:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Node 22 einrichten
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22.14.0"
|
|
|
|
- name: npm 11 pinnen
|
|
run: npm i -g npm@11.19.0
|
|
|
|
- name: Abhängigkeiten installieren
|
|
run: npm ci --include=optional --no-audit --no-fund
|
|
|
|
# HARTES Gate: nur Produktions-Abhängigkeiten, ab "high" bricht der Build.
|
|
# Bewusst --omit=dev, weil die bekannten High-Findings (F-12) in der
|
|
# Build-/Lint-Toolchain (devDependencies) liegen und die Auslieferung nicht
|
|
# gefährden. Der Produktionsbaum ist aktuell frei von high/critical -> grün.
|
|
- name: npm audit (Gate, prod-only, high+)
|
|
run: npm audit --omit=dev --audit-level=high
|
|
|
|
# INFORMATIV: voller Lauf inkl. devDependencies. Bricht den Build NICHT
|
|
# (continue-on-error), macht die dev-only-Befunde aber im Log sichtbar.
|
|
- name: npm audit (informativ, voller Baum)
|
|
continue-on-error: true
|
|
run: npm audit --audit-level=high
|
|
|
|
sbom:
|
|
# Optionaler Schritt: erzeugt eine Software Bill of Materials (CycloneDX) und
|
|
# legt sie als Build-Artefakt ab. Für Supply-Chain-Nachvollziehbarkeit (F-11).
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Node 22 einrichten
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22.14.0"
|
|
|
|
- name: npm 11 pinnen
|
|
run: npm i -g npm@11.19.0
|
|
|
|
- name: Abhängigkeiten installieren
|
|
run: npm ci --include=optional --no-audit --no-fund
|
|
|
|
# Hinweis: `npm sbom` validiert den installierten Baum streng. Solange das
|
|
# Lockfile die @swc/helpers-Inkonsistenz trägt (siehe Dockerfile / Folgeänderung
|
|
# der Dependency-Lane), bricht der Schritt mit ESBOMPROBLEMS ab — daher
|
|
# continue-on-error. Alternative ohne npm-Baum-Validierung: Syft gegen das
|
|
# gebaute Image (siehe docs/_certvia-archiv/DEPLOY-PROD-CONTABO.md, Abschnitt SBOM).
|
|
- name: SBOM erzeugen (CycloneDX)
|
|
continue-on-error: true
|
|
run: npm sbom --sbom-format cyclonedx --omit dev > sbom.cyclonedx.json
|
|
|
|
- name: SBOM als Artefakt ablegen
|
|
continue-on-error: true
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: sbom-cyclonedx
|
|
path: sbom.cyclonedx.json
|