Siphonight ed623b786b Docs + process (web v1.6.0) : CHANGELOG, doc §4/§8/§11, garde de parité check.sh §3.bis
- check.sh : NOUVELLE étape 3.bis — garde de PARITÉ du portage
  Android↔web (si le dépôt Android voisin existe) : les symboles clés
  des features partagées (moteur prolongation, chip, avertissement)
  sont vérifiés des DEUX côtés — attrape un portage incomplet.
- Doc : arbre §4, suite lab-trajectory-model (§8), scénario E2E (§8),
  leçons #12 étendue (LABX) et #14 (parité) (§11).
- CHANGELOG web : entrée [1.6.0] (séparé du CHANGELOG Android).
- README : statut web v1.6.0, 140 tests verts.
2026-09-12 23:51:20 +02:00

183 lines
7.3 KiB
Bash

#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────────────
# check.sh — vérifications de l'app web (pré-commit / pré-push / pré-release).
#
# 1. node --check sur chaque module ES (syntaxe) — attrape les typos avant
# même de charger l'app dans un navigateur ;
# 2. présence des fichiers critiques (index.html, asset PK, CSS, changelog) ;
# 3. cohérence i18n : clés FR/EN synchronisées + clés référencées existantes
# (leçon Android §12 : une string manquante s'affiche brute) ;
# 4. tests unitaires Node (node --test) ;
# 5. E2E navigateur (si playwright est installé — npm i + npx playwright
# install firefox, cf docs/DEVELOPPEMENT.md §Tests) ;
# 6. smoke HTTP (--with-serve : serveur + curl des ressources clés).
#
# Mode RELEASE (--release) : ajoute les vérifications OBLIGATOIRES avant une
# release (cf docs/DEVELOPPEMENT.md §10) —
# 7. cohérence de la version : WEB_VERSION == section `## [X.Y.Z]` de
# docs/CHANGELOG.md == tag annoté `vX.Y.Z` existant (le bump de version
# jamais commité côté Android, bug #46, ne doit pas se reproduire ici) ;
# 8. arbre git propre (tout commité avant publication) ;
# 9. test conteneur RÉEL (scripts/container-test.sh — build/run durci/
# headers/gzip/MIME/E2E contre le conteneur) si un daemon Docker est
# joignable, ignoré sinon (à lancer sur l'hôte qui a Docker).
#
# Usage : bash scripts/check.sh [--with-serve] [--release]
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail
cd "$(dirname "$0")/.." # racine du dépôt
fail=0
RELEASE=false
for arg in "$@"; do
[[ "$arg" == "--release" ]] && RELEASE=1
done
echo "── 1. Syntaxe des modules (node --check) ──"
while IFS= read -r f; do
if ! node --check "$f" 2>/tmp/hrt-check.err; then
echo "✗ $f"
cat /tmp/hrt-check.err
fail=1
fi
done < <(find js -name '*.js' -type f | sort)
echo " tous les modules de js/ sont syntaxiquement valides"
echo "── 2. Fichiers critiques ──"
for f in index.html css/style.css assets/pk_profiles.json docs/CHANGELOG.md \
js/ui/app.js js/pk/pk-engine.js; do
if [[ ! -f "$f" ]]; then
echo "✗ manquant : $f"
fail=1
fi
done
echo " fichiers critiques présents"
echo "── 3. Cohérence i18n FR/EN ──"
# Vérifie : (a) chaque clé de EN existe dans FR et inversement ;
# (b) chaque clé utilisée par t('...') dans js/ existe dans EN et FR.
# (leçon Android §12 : une string manquante s'affiche brute — et FR/EN
# désynchronisés = UI mi-anglaise mi-française)
if ! node scripts/i18n-check.mjs; then
echo "✗ clés i18n manquantes (voir ci-dessus)"
fail=1
fi
echo "── 3.bis Garde de PARITÉ du portage Android ↔ web (soft) ──"
# v1.6.0 (leçon de la session « Prolonger ») : le web est un PORTAGE fidèle
# de l'Android — quand les deux dépôts sont côte à côte (layout standard,
# cf docs/DEVELOPPEMENT.md §3), on vérifie que les symboles CLÉS des
# dernières features partagées existent des DEUX côtés. Attrape le portage
# incomplet (ex. modèle porté mais pas l'UI, ou clés i18n Android sans
# miroir web). Soft : si le dépôt Android voisin est absent (clone web
# isolé, CI), la garde est ignorée avec un message.
ANDROID_DIR="$(dirname "$PWD")/HormoneTrack"
if [[ -d "$ANDROID_DIR" ]]; then
parity=1
check_pair() { # <desc> <fichier-android:pattern> <fichier-web:pattern>
local desc="$1" andro="$2" web="$3"
local af="${andro%%:*}" ap="${andro#*:}"
local wf="${web%%:*}" wp="${web#*:}"
if grep -qE "$ap" "$ANDROID_DIR/$af" 2>/dev/null \
&& grep -qE "$wp" "$wf" 2>/dev/null; then
echo " ✓ $desc"
else
echo "✗ PARITÉ rompue : $desc (Android: $ANDROID_DIR/$af =~ $ap ; web: $wf =~ $wp)"
parity=0
fi
}
# Le modèle de prolongation doit exister des deux côtés (v1.6.0)
check_pair "prolongation tracé labs : moteur" \
"app/src/main/java/com/hormonetrack/pk/LabTrajectoryModel.kt:extensionHorizonEndMs" \
"js/pk/lab-trajectory-model.js:extensionHorizonEndMs"
check_pair "prolongation tracé labs : UI (chip)" \
"app/src/main/res/values/strings.xml:show_lab_track_extend" \
"js/util/i18n.js:show_lab_track_extend"
check_pair "prolongation tracé labs : avertissement" \
"app/src/main/res/values/strings.xml:lab_track_extend_warning" \
"js/util/i18n.js:lab_track_extend_warning"
[[ $parity -eq 1 ]] || fail=1
else
echo " (ignoré : dépôt Android voisin absent — $ANDROID_DIR)"
fi
echo "── 4. Tests unitaires ──"
if ! node --test tests/ 2>&1 | tail -6; then
fail=1
fi
echo "── 5. E2E navigateur (si playwright installé) ──"
if [[ -d node_modules/playwright-core && -d "$HOME/Library/Caches/ms-playwright" ]]; then
if ! node scripts/e2e.mjs 8989; then
fail=1
fi
else
echo " (ignoré : playwright non installé — npm i && npx playwright install firefox)"
fi
if [[ "${1:-}" == "--with-serve" ]]; then
echo "── 6. Smoke HTTP ──"
python3 scripts/serve.py --port 8971 >/tmp/hrt-serve.log 2>&1 &
SRV=$!
sleep 1.5
for path in / /css/style.css /assets/pk_profiles.json /js/ui/app.js /docs/CHANGELOG.md; do
code=$(curl -s -o /dev/null -w '%{http_code}' "http://127.0.0.1:8971${path}")
if [[ "$code" != "200" ]]; then
echo "✗ ${path} → HTTP ${code}"
fail=1
else
echo " 200 ${path}"
fi
done
kill $SRV 2>/dev/null || true
wait $SRV 2>/dev/null || true
fi
if [[ "$RELEASE" == "1" ]]; then
echo "── 7. Cohérence de la version (release) ──"
ver=$(node --input-type=module -e "
import { WEB_VERSION } from './js/ui/settings.js';
process.stdout.write(WEB_VERSION);")
verGrep=$(echo "$ver" | sed 's/\./\\./g') # 1.4.10 → 1\.4\.10 pour grep -E
if grep -qE "^## \\[$verGrep\\]" docs/CHANGELOG.md; then
echo " WEB_VERSION = $ver ; section [$ver] présente dans docs/CHANGELOG.md"
else
echo "✗ WEB_VERSION ($ver) n'a pas de section correspondante dans docs/CHANGELOG.md"
fail=1
fi
# Le bump de version jamais commité (bug Android #46) ne doit pas se
# reproduire : la release est faite SUR un tag qui existe.
if git rev-parse -q --verify "refs/tags/v$ver" >/dev/null 2>&1; then
echo " tag v$ver présent"
else
echo "✗ tag v$ver ABSENT — créer et pousser le tag avant la release (leçon Android #46)"
fail=1
fi
echo "── 8. Arbre git propre avant publication ──"
if [[ -n "$(git status --porcelain)" ]]; then
echo "✗ working tree sale — tout committer avant la release"
git status --short | head -5
fail=1
else
echo " working tree propre"
fi
echo "── 9. Test conteneur RÉEL (si daemon Docker joignable) ──"
if docker info --format x >/dev/null 2>&1; then
if ! bash scripts/container-test.sh 8975; then
fail=1
fi
else
echo " (ignoré : aucun daemon Docker ici — lancer sur l'hôte cible :"
echo " bash scripts/container-test.sh ; cf docs/DEVELOPPEMENT.md §10)"
fi
fi
if [[ $fail -eq 0 ]]; then
echo "✓ CHECK OK"
else
echo "✗ CHECK FAILED"
exit 1
fi