mirror of
https://github.com/IliesAllali/parenthese.git
synced 2026-11-06 23:32:08 +00:00
Le conteneur web relayait l'API vers `api:4000`, écrit en dur. Sur un réseau partagé entre plusieurs applications (Umbrel), ce nom peut appartenir à une autre. L'adresse vient maintenant de API_UPSTREAM, `api:4000` par défaut : rien ne change pour les installations existantes. L'image tout-en-un garde sa propre configuration. La CI lance un second front qui joint l'API par le nom de son conteneur et repasse le test de fumée. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
249 lines
7.8 KiB
YAML
249 lines
7.8 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@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.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@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.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@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.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-url "$DATABASE_URL" --to-schema-datamodel 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
|
|
|
|
# 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
|
|
|
|
- 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
|