Files
florian.wilde 14cc4de9b8
Pruefung / pruefung (push) Canceled after 0s
Pruefung / oberflaeche (push) Canceled after 0s
Phase 11: Freigabereife (#16)
2026-09-06 20:05:49 +00:00

185 lines
6.4 KiB
YAML

# =============================================================================
# Die Pruefung bei jedem Push.
#
# Bis Phase 10 gab es 581 Unit- und 266 E2E-Tests — und nichts, was sie
# ausfuehrte ausser einem Menschen, der daran dachte. In der Sitzung, in der
# die Kassenverwaltung entstand, haben die Tests vier echte Fehler gefunden,
# zwei davon in Code, der eine Stunde alt war. Genau das soll hier von allein
# passieren.
#
# Zwei Auftraege, bewusst getrennt:
#
# pruefung typecheck, lint und die Unit-Tests. Braucht eine Datenbank,
# weil ein Teil der Tests die Trigger und RLS gegen echtes
# Postgres prueft — mit einer Attrappe waeren sie wertlos.
#
# oberflaeche die E2E-Tests. Dauern eine Dreiviertelstunde und brauchen den
# halben Stack, deshalb laufen sie nur auf main und in Pull
# Requests, nicht bei jedem Zwischenstand auf einem Zweig.
# =============================================================================
name: Pruefung
on:
push:
branches: [main]
pull_request:
env:
# Dieselben Werte wie in .env.example. Es sind Testdaten in einem
# Wegwerf-Container; echte Geheimnisse haben in einer Pipeline nichts zu
# suchen und stehen im Betrieb in der .env.
POSTGRES_USER: florian
POSTGRES_PASSWORD: pruefung
POSTGRES_DB: florian
POSTGRES_APP_PASSWORD: pruefung_app
DATABASE_URL: postgresql://florian_app:pruefung_app@localhost:5432/florian?schema=public
DIRECT_DATABASE_URL: postgresql://florian:pruefung@localhost:5432/florian?schema=public
AUTH_SECRET: nur-fuer-die-pruefung-nicht-fuer-den-betrieb
AUTH_TRUST_HOST: "true"
APP_URL: http://localhost:3100
S3_ENDPOINT: localhost
S3_PORT: "9000"
S3_USE_SSL: "false"
S3_ACCESS_KEY: florian
S3_SECRET_KEY: pruefung_minio
S3_BUCKET: florian
REDIS_URL: redis://localhost:6379
TZ: Europe/Berlin
jobs:
pruefung:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
# Das eigene Postgres-Image statt eines fertigen: FLORIAN braucht
# PostGIS **und** pgvector, und kein oeffentliches Image bringt beides
# mit. Ein Dienst-Container mit postgres:17 wuerde die Migrationen
# durchlassen und erst bei der ersten Umkreissuche scheitern.
- name: Datenbank bauen und starten
run: |
docker build -t florian-postgres:pruefung ./docker/postgres
docker run -d --name postgres -p 5432:5432 \
-e POSTGRES_USER=$POSTGRES_USER \
-e POSTGRES_PASSWORD=$POSTGRES_PASSWORD \
-e POSTGRES_DB=$POSTGRES_DB \
-e POSTGRES_APP_PASSWORD=$POSTGRES_APP_PASSWORD \
-e POSTGRES_INITDB_ARGS="--locale-provider=icu --icu-locale=de-DE --locale=C.UTF-8 --encoding=UTF8" \
-v "$(pwd)/docker/postgres:/docker-entrypoint-initdb.d:ro" \
florian-postgres:pruefung
- name: Redis und MinIO starten
run: |
docker run -d --name redis -p 6379:6379 redis:7-alpine
docker run -d --name minio -p 9000:9000 \
-e MINIO_ROOT_USER=$S3_ACCESS_KEY \
-e MINIO_ROOT_PASSWORD=$S3_SECRET_KEY \
minio/minio:latest server /data
- run: npm ci
- name: Auf die Datenbank warten
run: |
for i in $(seq 1 60); do
docker exec postgres pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB" && exit 0
sleep 2
done
echo "Postgres kam nicht hoch:"
docker logs postgres
exit 1
- run: npx prisma generate
- run: npm run typecheck
- run: npm run lint
- name: Migrationen einspielen
run: npm run db:migrate
# Der Seed gehoert dazu: er ist selbst ein Test. Faellt eine Migration
# oder ein Standardwert um, merkt man es hier und nicht erst, wenn eine
# Wehr ihn zum ersten Mal ausfuehrt.
- name: Beispielbestand anlegen
run: npm run db:seed
- run: npm run test
- name: Aufraeumen
if: always()
run: docker rm -f postgres redis minio || true
oberflaeche:
runs-on: ubuntu-latest
# Nur wo es sich lohnt: ein voller Lauf dauert etwa 45 Minuten.
if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: Dienste starten
run: |
docker build -t florian-postgres:pruefung ./docker/postgres
docker run -d --name postgres -p 5432:5432 \
-e POSTGRES_USER=$POSTGRES_USER \
-e POSTGRES_PASSWORD=$POSTGRES_PASSWORD \
-e POSTGRES_DB=$POSTGRES_DB \
-e POSTGRES_APP_PASSWORD=$POSTGRES_APP_PASSWORD \
-e POSTGRES_INITDB_ARGS="--locale-provider=icu --icu-locale=de-DE --locale=C.UTF-8 --encoding=UTF8" \
-v "$(pwd)/docker/postgres:/docker-entrypoint-initdb.d:ro" \
florian-postgres:pruefung
docker run -d --name redis -p 6379:6379 redis:7-alpine
docker run -d --name minio -p 9000:9000 \
-e MINIO_ROOT_USER=$S3_ACCESS_KEY \
-e MINIO_ROOT_PASSWORD=$S3_SECRET_KEY \
minio/minio:latest server /data
docker run -d --name gotenberg -p 3001:3000 gotenberg/gotenberg:8
- run: npm ci
- run: npx playwright install --with-deps chromium
- name: Auf die Datenbank warten
run: |
for i in $(seq 1 60); do
docker exec postgres pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB" && exit 0
sleep 2
done
docker logs postgres
exit 1
- run: npx prisma generate
- run: npm run db:migrate
# Die E2E-Tests laufen seit Phase 8 gegen eine eigene Wehr, nicht gegen
# den Beispielbestand. Das Skript legt beide an.
- name: Testwehr anlegen
run: npm run db:test-reset
- run: npm run build
- run: npx playwright test
env:
GOTENBERG_URL: http://localhost:3001
- name: Fehlerbilder sichern
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-bericht
path: |
playwright-report/
test-results/
retention-days: 7
- name: Aufraeumen
if: always()
run: docker rm -f postgres redis minio gotenberg || true