name: CI on: push: branches: [master, main] pull_request: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: check: name: Lint, Typen, Tests, Build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 cache: npm - run: npm ci - name: Lint run: npm run lint - name: Typecheck run: npm run typecheck # Fängt die Abweichung, die `tsc` nicht sehen kann: lib/types.ts wird von # Hand gepflegt, eine Migration mit einer neuen Spalte lässt sie also # stillschweigend veralten. - name: Schema/Typen-Abgleich run: npm run types:check - name: Unit- und Komponententests run: npm test # Ohne Umgebungsvariablen: seit dem Wegfall der Browser-Anbindung wird # zur Bauzeit nichts mehr aus der Umgebung gelesen, und das Abbild ist # für jede Umgebung dasselbe. - name: Build run: npm run build migrationen: name: Migrationen auf leerer Datenbank runs-on: ubuntu-latest # Derselbe Stand wie im Betrieb. Ein eigener Dienst statt einer fremden # Plattform — die Datenbank gehört seit dem Umzug zum Projekt. services: postgres: image: postgres:17-alpine env: POSTGRES_PASSWORD: ci POSTGRES_DB: alpenwerk ports: - 5432:5432 options: >- --health-cmd "pg_isready -U postgres" --health-interval 5s --health-timeout 5s --health-retries 20 env: MIGRATE_DATABASE_URL: postgresql://postgres:ci@postgres:5432/alpenwerk DATABASE_SSL: "false" steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 cache: npm - run: npm ci # Das Abbild des Runners bringt keinen Postgres-Client mit; der # Schritt darunter ruft aber psql. Ohne das bricht er mit # "psql: command not found" ab, bevor die erste Datei laeuft. - name: psql bereitstellen run: | apt-get update -qq apt-get install -y -qq --no-install-recommends postgresql-client psql --version # Was das Schema von der Umgebung erwartet: die Anwendungsrolle ohne # BYPASSRLS, zwei Erweiterungen und die Attrappe des `auth`-Schemas, ohne # die sich die Migrationen von Juni 2026 nicht abspielen lassen. - name: Rollen, Erweiterungen, auth-Attrappe env: PGPASSWORD: ci APP_DB_PASSWORD: ci-anwendungsrolle run: | for f in deploy/db-init/*.sql; do echo "── $f" psql -v ON_ERROR_STOP=1 -h postgres -U postgres -d alpenwerk -f "$f" done # Der eigentliche Zweck dieses Jobs: jede Migration muss sich auf einer # leeren Datenbank abspielen lassen. Eine, die das nicht kann, fällt hier # auf — und nicht beim Wiederherstellen einer Sicherung oder beim # Aufsetzen einer neuen Umgebung. - name: Migrationen einspielen run: node scripts/migrate.mjs # Zweiter Lauf: die Buchführung muss greifen. Meldet er etwas anderes als # „nichts anzuwenden", verbucht der Läufer nicht richtig — und ein # Ausrollen spielte Migrationen doppelt ein. - name: Zweiter Lauf ist ein Nichts run: | ausgabe=$(node scripts/migrate.mjs) echo "$ausgabe" echo "$ausgabe" | grep -q "^Nichts anzuwenden" \ || { echo "Der zweite Lauf wollte erneut anwenden — die Buchführung greift nicht."; exit 1; } # Die Integrationstests brauchen einen befüllten Bestand; der Seed lag # in der abgelösten Umgebung und ist noch nicht nachgezogen (siehe # README, offene Punkte). Bis dahin laufen sie gegen eine erreichbare # Datenbank von Hand, nicht hier.