Files
craftvia/.gitea/workflows/ci.yml
T
msolarczekandClaude Opus 5 cadaedc6cc L10b Betrieb & Aufräumen: Deploy – craftvia-worker, CI-Testjob, DEPLOY.md, Certvia-Doku archiviert
- 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>
2026-09-14 18:19:19 +02:00

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