corentin_wakdo/db/migrate.sh
Imugiii 56b26db0c1
All checks were successful
CI / auto-merge (pull_request) Successful in 4s
CI / secret-scan (pull_request) Successful in 9s
CI / php-lint (pull_request) Successful in 21s
CI / static-tests (pull_request) Successful in 42s
CI / js-tests (pull_request) Successful in 19s
chore: remplace le Makefile par un service compose wakdo-migrate (migrate + seed idempotents)
Le Makefile portait surtout des cibles mortes/trompeuses (test/test-unit/
test-integration/lint annoncaient "pas implemente" alors que les tests tournent ;
install-hooks pointait sur des fichiers absents) ; sa seule cible porteuse, `init`,
existait parce que `docker compose up` seul n'applique pas les migrations.

En deplacant migrate + seed DANS la stack, `docker compose up` devient l'unique
commande qui amene une stack complete et loginnable -> Cr 7.c.4 satisfait sans
dependance a l'outil `make`.

- db/migrate-container.sh : runner in-container (connexion par le reseau compose),
  applique db/migrations/*.sql (suivi schema_migrations) puis db/seeds/*.sql (suivi
  seeds_applied), idempotent.
- Service one-shot `wakdo-migrate` (depends_on db healthy) ; wakdo-app/web attendent
  sa completion (service_completed_successfully).
- Makefile supprime ; db/migrate.sh (hote) conserve pour l'usage manuel / --status.
- Docs realignees : README, .env.example, db/README, docker-compose, PROJECT_CONTEXT
  (`make *` -> `docker compose *`, Cr 7.b porte par les scripts Bash). Correction au
  passage : la CI/CD est Forgejo Actions (pas GitHub Actions), protections cote Forgejo.
- Journal : docs/journal/2026-06-17--makefile-to-compose-migrate.md (rationale + verif
  sur base ephemere : 2 migrations + 2 seeds, idempotent ; note de deploiement pour
  les bases deja seedees).

Verifie : docker compose config valide ; runner teste sur MariaDB ephemere (5 roles,
23 permissions, admin present) ; re-run = 0 nouveau. Aucun code PHP/JS touche.
2026-06-17 12:41:36 +00:00

70 lines
2.8 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# Wakdo - migration runner.
#
# Applique les fichiers db/migrations/*.sql dans l'ordre lexicographique,
# de maniere idempotente : une table schema_migrations enregistre les fichiers
# deja appliques, donc relancer ne rejoue que les nouvelles migrations.
#
# Cible : le service docker-compose `wakdo-db` (MariaDB). Lance depuis l'hote
# (usage manuel / `--status`, identifiants lus dans .env). Au boot de la stack,
# c'est le service `wakdo-migrate` (db/migrate-container.sh, via le reseau) qui
# applique migrations + seed automatiquement.
#
# Usage :
# bash db/migrate.sh # applique les migrations en attente
# bash db/migrate.sh --status # liste l'etat sans rien appliquer
#
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
ENV_FILE="$ROOT/.env"
CONTAINER="${WAKDO_DB_CONTAINER:-wakdo-db}"
MIGRATIONS_DIR="$ROOT/db/migrations"
[ -f "$ENV_FILE" ] || { echo "ERREUR : .env introuvable ($ENV_FILE)" >&2; exit 1; }
DB_NAME="$(grep -E '^DB_NAME=' "$ENV_FILE" | cut -d= -f2- | tr -d '[:space:]')"
DB_ROOT_PASSWORD="$(grep -E '^DB_ROOT_PASSWORD=' "$ENV_FILE" | cut -d= -f2-)"
: "${DB_NAME:?DB_NAME absent de .env}"
: "${DB_ROOT_PASSWORD:?DB_ROOT_PASSWORD absent de .env}"
# Client mariadb dans le conteneur (root : les migrations sont des operations DDL).
db() { docker exec -i "$CONTAINER" mariadb -uroot -p"$DB_ROOT_PASSWORD" "$@"; }
# Le conteneur doit etre en marche.
docker exec "$CONTAINER" true 2>/dev/null || { echo "ERREUR : conteneur $CONTAINER non demarre (docker compose up -d)" >&2; exit 1; }
# Journal des migrations appliquees.
db "$DB_NAME" -e "CREATE TABLE IF NOT EXISTS schema_migrations (
filename VARCHAR(255) NOT NULL PRIMARY KEY,
applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;"
shopt -s nullglob
files=("$MIGRATIONS_DIR"/*.sql)
[ ${#files[@]} -gt 0 ] || { echo "[migrate] aucune migration dans $MIGRATIONS_DIR"; exit 0; }
if [ "${1:-}" = "--status" ]; then
echo "[migrate] etat des migrations (base $DB_NAME) :"
for f in "${files[@]}"; do
base="$(basename "$f")"
n="$(db "$DB_NAME" -N -s -e "SELECT COUNT(*) FROM schema_migrations WHERE filename='$base';")"
[ "$n" = "0" ] && echo " PENDING $base" || echo " applied $base"
done
exit 0
fi
applied=0
for f in "${files[@]}"; do
base="$(basename "$f")"
n="$(db "$DB_NAME" -N -s -e "SELECT COUNT(*) FROM schema_migrations WHERE filename='$base';")"
if [ "$n" = "0" ]; then
echo "[migrate] application de $base ..."
db "$DB_NAME" < "$f"
db "$DB_NAME" -e "INSERT INTO schema_migrations (filename) VALUES ('$base');"
applied=$((applied + 1))
else
echo "[migrate] $base deja applique, ignore"
fi
done
echo "[migrate] termine ($applied nouvelle(s) migration(s) appliquee(s))."