Files
IliesAllaliandClaude Opus 5.5 cc01059c47 Prisma 7 : pilote pg, client généré, prisma.config.ts (#164)
* Prisma 7 : client généré dans src/generated, pilote pg, prisma.config.ts

- générateur prisma-client (ESM, extension .js), compilé dans dist : plus de node_modules/.prisma à copier dans les images
- @prisma/adapter-pg, délai de connexion de 5 s comme le moteur de Prisma 6
- prisma.config.ts : adresse de la base et .env pour le CLI, sans dépendre de prisma/config à l'exécution (CLI à part dans les images)
- CI : migrate diff --from-config-datasource --to-schema
- deploy.sh : arrêt avant installation si Node est trop vieux pour Prisma 7
- remplace les PR Dependabot #135 et #137

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Prisma 7 : import du client généré dans token-revocation (#163)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 13:58:42 +01:00

259 lines
8.4 KiB
YAML

name: CI
# Tests, lint et builds des trois projets, plus une installation Docker complète testée comme un
# auto-hébergeur. Le déploiement de production (deploy-hostinger.yml) attend la réussite de ce workflow.
on:
push:
branches:
- '**'
pull_request:
permissions:
contents: read
# Un nouveau push sur la même branche annule la vérification devenue obsolète.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
frontend:
name: Frontend
runs-on: ubuntu-latest
timeout-minutes: 15
defaults:
run:
working-directory: frontend
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
with:
persist-credentials: false
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: 24
cache: npm
cache-dependency-path: frontend/package-lock.json
- name: Dépendances
run: npm ci --no-audit --no-fund
# Bloque seulement sur une faille critique d'une dépendance de production
- name: Audit des dépendances de production
run: npm audit --omit=dev --audit-level=critical
- name: Lint
run: npm run lint
- name: Tests
run: npm test
- name: Build
run: npm run build
landing:
name: Landing
runs-on: ubuntu-latest
timeout-minutes: 15
defaults:
run:
working-directory: landing
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
with:
persist-credentials: false
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: 24
cache: npm
cache-dependency-path: landing/package-lock.json
- name: Dépendances
run: npm ci --no-audit --no-fund
# Bloque seulement sur une faille critique d'une dépendance de production
- name: Audit des dépendances de production
run: npm audit --omit=dev --audit-level=critical
- name: Tests
run: npm test
# Le build ne lit que landing/ : aucune police n'est prise dans ../frontend.
- name: Build
run: npm run build
backend:
name: Backend
runs-on: ubuntu-latest
timeout-minutes: 15
defaults:
run:
working-directory: backend
# Les tests vitest remplacent Prisma par un mock et fixent leurs propres variables d'environnement :
# ils n'utilisent pas la base. Elle sert à vérifier que les migrations s'appliquent sur une base
# vide (ce que fait le premier démarrage Docker) et qu'elles reproduisent exactement schema.prisma.
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: genealogy
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres -d genealogy"
--health-interval 5s
--health-timeout 5s
--health-retries 12
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/genealogy
CHECKPOINT_DISABLE: '1'
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
with:
persist-credentials: false
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: 24
cache: npm
cache-dependency-path: backend/package-lock.json
- name: Dépendances
run: npm ci --no-audit --no-fund
# Bloque seulement sur une faille critique d'une dépendance de production
- name: Audit des dépendances de production
run: npm audit --omit=dev --audit-level=critical
- name: Client Prisma
run: npm run prisma:generate
- name: Build TypeScript
run: npm run build
- name: Migrations sur une base vide
run: npx prisma migrate deploy
- name: Schéma Prisma aligné sur les migrations
run: npx prisma migrate diff --from-config-datasource --to-schema prisma/schema.prisma --exit-code
- name: Tests
run: npm test
docker:
name: Docker (auto-hébergement)
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
with:
persist-credentials: false
- name: Fichier .env de test
run: |
set -euo pipefail
cp .env.example .env
set_env() {
if grep -q "^$1=" .env; then
sed -i "s|^$1=.*|$1=$2|" .env
else
printf '%s=%s\n' "$1" "$2" >> .env
fi
}
# Valeurs hexadécimales : sans caractère spécial, sûres dans l'URL de connexion PostgreSQL.
set_env POSTGRES_PASSWORD "$(openssl rand -hex 24)"
set_env JWT_SECRET "$(openssl rand -hex 48)"
set_env WEB_PORT 8080
set_env CORS_ORIGIN http://localhost:8080
grep -Ev '^(POSTGRES_PASSWORD|JWT_SECRET)=' .env | grep -Ev '^\s*(#|$)'
- name: Configuration compose valide
run: docker compose config --quiet
- name: Construction et démarrage
run: docker compose up -d --build --wait --wait-timeout 420
- name: Test de fumée par le port web
run: bash tools/docker-smoke.sh http://localhost:8080
# Les commandes de sauvegarde et de restauration du README, jouées pour de vrai
- name: Sauvegarde puis restauration
run: |
set -euo pipefail
bash tools/docker-restore-check.sh http://localhost:8080
bash tools/docker-smoke.sh http://localhost:8080
# Un second front qui joint l'API par le nom de son conteneur (API_UPSTREAM), comme sur Umbrel.
- name: Front avec une autre adresse d'API
run: |
WEB_IMAGE="$(docker compose config --images | grep parenthese-web)"
API_CONTAINER="$(docker compose ps -q api | xargs docker inspect -f '{{.Name}}' | tr -d /)"
docker run -d --name web-upstream --network parenthese_default -p 8081:80 \
-e API_UPSTREAM="$API_CONTAINER:4000" "$WEB_IMAGE"
sleep 3
docker exec web-upstream grep -q "http://$API_CONTAINER:4000" /etc/nginx/conf.d/default.conf
bash tools/docker-smoke.sh http://localhost:8081
- name: État et journaux en cas d'échec
if: failure()
run: |
docker compose ps -a
docker compose logs --no-color --timestamps
docker logs web-upstream || true
- name: Arrêt et suppression des volumes
if: always()
run: |
docker rm -f web-upstream || true
docker compose down -v --remove-orphans
docker-aio:
name: Docker tout-en-un (Unraid, NAS)
runs-on: ubuntu-latest
timeout-minutes: 30
env:
SMOKE_WAIT_SECONDS: 180
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
with:
persist-credentials: false
- name: Construction
run: DOCKER_BUILDKIT=1 docker build -f Dockerfile.aio -t parenthese-aio:test .
- name: Démarrage, sans aucune variable
run: docker run -d --name aio -p 8080:80 -v aio-data:/data parenthese-aio:test
- name: Test de fumée par le port web
run: bash tools/docker-smoke.sh http://localhost:8080
# Les secrets et la base de /data doivent servir tels quels au démarrage suivant (mise à jour, reboot).
- name: Redémarrage puis nouveau test
run: |
set -euo pipefail
docker restart aio
bash tools/docker-smoke.sh http://localhost:8080
docker logs aio 2>&1 | grep -c "première installation" | grep -qx 1
# Base à jour au redémarrage : pas de sauvegarde avant migration, mais pg_dump marche dans l'image
[ -z "$(docker exec aio ls -A /data/backups 2>/dev/null)" ]
[ "$(docker exec aio runuser -u postgres -- pg_dump -Fc parenthese | wc -c)" -gt 1000 ]
- name: Journaux en cas d'échec
if: failure()
run: |
docker ps -a
docker logs --timestamps aio || true
docker run --rm -v aio-data:/data busybox cat /data/postgres/postgres.log || true
- name: Arrêt et suppression du volume
if: always()
run: |
docker rm -f aio || true
docker volume rm aio-data || true