[DTP-Worker 20260802_170601] Sprint 8 · buffer · run_ci.sh : -h|--help + en-tête --static honnête (UX du lanceur, PAS un gate #5)

Deux vraies aspérités d'UX sur le lanceur run_ci.sh (miroir local du gate),
reproduites avant fix :
- `--help`/`-h` échouait « option inconnue » exit 2 alors qu'un bloc d'usage
  riche dormait dans l'en-tête → ajout usage() branché AVANT résolution git
  (aide marche hors checkout : exit 0 ; vrai run hors git reste exit 3),
  codes de sortie documentés (0/1/2/3).
- en mode --static l'en-tête annonçait « 30 jobs = 7 gates + 23 suites »
  alors que seuls 7 gates tournent → récap « 7 PASS » contredisait l'en-tête ;
  en-tête rendu mode-conscient (« 7 gates seuls, 23 suites ignorées »).
- message d'option inconnue + ci/README.md alignés (ajout --help).

Toutes les valeurs restent DÉRIVÉES de gate.needs (#6, zéro compte figé).
Zéro nouveau module · zéro gate ajouté (#5) : run_ci.sh reste un lanceur
(racine ∉ ci/*.sh, hors gate.needs, INV-B). Vérif : --help exit 0 in+hors git ·
--bogus exit 2 · check_docs/check_readme_claims/guard_constraints verts ·
run_ci.sh plein → 30 PASS · 0 FAIL · 0 SKIP.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Code DTP Worker
2026-08-02 17:11:19 +00:00
parent 59eb4dcb7c
commit 68f8c1a718
3 changed files with 59 additions and 2 deletions
+30
View File
@@ -1632,3 +1632,33 @@ commande touchant au VPS.
- **Action** : ajout d'une 3e ligne à la table + sous-section dédiée décrivant `run_ci.sh` **avec exactitude** : outillage local (confort dev), **PAS un gate** (CLAUDE.md #5 · aucun `ci/*.sh`, hors `gate.needs`, racine ∉ `ci/` donc hors invariant INV-B), liste de checks **dérivée** de `gate.needs` (zéro liste en dur → zéro dérive), décompte imprimé à l'exécution (#6). Aligné sur la mémoire `local-ci-runner`. - **Action** : ajout d'une 3e ligne à la table + sous-section dédiée décrivant `run_ci.sh` **avec exactitude** : outillage local (confort dev), **PAS un gate** (CLAUDE.md #5 · aucun `ci/*.sh`, hors `gate.needs`, racine ∉ `ci/` donc hors invariant INV-B), liste de checks **dérivée** de `gate.needs` (zéro liste en dur → zéro dérive), décompte imprimé à l'exécution (#6). Aligné sur la mémoire `local-ci-runner`.
- **Zéro nouveau module · zéro gate ajouté** (#5). Seul changement = prose de fiche. - **Zéro nouveau module · zéro gate ajouté** (#5). Seul changement = prose de fiche.
- **Vérif** : `check_docs.sh` valide le nouveau lien `../../run_ci.sh` (HARD) → vert · `guard_constraints.sh` vert · `run_ci.sh` → **30 PASS · 0 FAIL · 0 SKIP**. - **Vérif** : `check_docs.sh` valide le nouveau lien `../../run_ci.sh` (HARD) → vert · `guard_constraints.sh` vert · `run_ci.sh` → **30 PASS · 0 FAIL · 0 SKIP**.
## Session `20260802_170601` · Sprint 8 · buffer · DevOps — `run_ci.sh` : `-h|--help` + en-tête `--static` honnête (UX du lanceur, PAS un gate #5)
**Contexte** — Série buffer Sprint 8, tout vert (`run_ci.sh` → 30 PASS). L'outil
`run_ci.sh` (miroir local du gate, mémoire `local-ci-runner`) était fonctionnellement
complet mais avait **2 vraies aspérités d'UX**, reproduites avant correction :
1. `run_ci.sh --help` (et `-h`) échouait en « option inconnue » + exit 2, alors qu'un
bloc d'usage riche dormait dans l'en-tête du script, jamais surfacé — la convention
`--help` la plus universelle manquait.
2. En mode `--static`, l'en-tête annonçait toujours « **30 jobs = 7 gates + 23 suites** »
alors que seuls les 7 gates s'exécutent → le récap final « **7 PASS** » **contredisait**
l'en-tête (vert honnête mais message trompeur).
**Action** (édition de l'outil `run_ci.sh` uniquement + accord doc) :
- Ajout d'une fonction `usage()` (heredoc) et branchement `-h|--help` **AVANT** la
résolution git → l'aide marche même hors checkout (vérifié : exit 0 depuis `/tmp`),
alors qu'un vrai run hors git reste exit 3. Codes de sortie documentés (0/1/2/3).
- En-tête d'exécution rendu **mode-conscient** : en `--static`, affiche
« 30 jobs · mode --static → 7 gates ci/*.sh seuls (23 suites ignorées) » — plus de
contradiction avec le récap. Le mode plein est inchangé.
- Message d'option inconnue et bloc d'usage `ci/README.md` mis à jour (ajout `--help`).
- **Toutes les valeurs restent DÉRIVÉES** de `gate.needs` (`n_jobs/n_gates/n_suites`) —
aucune liste ni compte figé introduit (#6). **Zéro nouveau module · zéro gate ajouté**
(#5) : `run_ci.sh` demeure un lanceur (racine ∉ `ci/*.sh`, hors `gate.needs`, INV-B).
**Vérif** — `--help`/`-h` → exit 0 (dans + hors git) · `--bogus` → exit 2 · en-tête
`--static` désormais « 7 gates seuls » cohérent avec « 7 PASS » · `--list` inchangé
(30 jobs) · `check_docs` · `check_readme_claims` · `guard_constraints` verts ·
`run_ci.sh` (plein) → **30 PASS · 0 FAIL · 0 SKIP**. Arbre propre avant édition.
Aucune commande touchant au VPS.
+1
View File
@@ -34,6 +34,7 @@ Avant de committer, reproduire l'intégralité du gate de merge en une commande
bash run_ci.sh # tout gate.needs (7 gates statiques + 23 suites de module) bash run_ci.sh # tout gate.needs (7 gates statiques + 23 suites de module)
bash run_ci.sh --static # seulement les 7 gates ci/*.sh (rapide) bash run_ci.sh --static # seulement les 7 gates ci/*.sh (rapide)
bash run_ci.sh --list # liste les jobs qui seraient lancés, sans exécuter bash run_ci.sh --list # liste les jobs qui seraient lancés, sans exécuter
bash run_ci.sh --help # aide + codes de sortie (0 vert · 1 échec · 2 option · 3 hors git)
``` ```
`run_ci.sh` n'a **aucune liste en dur** : il DÉRIVE l'ensemble des checks depuis `run_ci.sh` n'a **aucune liste en dur** : il DÉRIVE l'ensemble des checks depuis
+27 -1
View File
@@ -36,12 +36,34 @@
# bash run_ci.sh # exécute tout gate.needs (miroir CI complet) # bash run_ci.sh # exécute tout gate.needs (miroir CI complet)
# bash run_ci.sh --static # seulement les gates statiques ci/*.sh (rapide) # bash run_ci.sh --static # seulement les gates statiques ci/*.sh (rapide)
# bash run_ci.sh --list # liste les jobs qui SERAIENT lancés, sans exécuter # bash run_ci.sh --list # liste les jobs qui SERAIENT lancés, sans exécuter
# bash run_ci.sh --help # affiche cette aide et sort
# #
# Sortie : une ligne PASS/FAIL par job + un récapitulatif. Code de sortie 0 ssi # Sortie : une ligne PASS/FAIL par job + un récapitulatif. Code de sortie 0 ssi
# tous les jobs passent (identique à la sémantique du gate de merge). # tous les jobs passent (identique à la sémantique du gate de merge).
# ============================================================================ # ============================================================================
set -uo pipefail set -uo pipefail
usage() {
cat <<'EOF'
run_ci.sh · miroir LOCAL du gate CI (dérivé de gate.needs, sans liste en dur).
Rejoue en une commande, sans runner ni réseau, l'ensemble de checks que le gate
de merge Gitea Actions agrège.
Usage :
bash run_ci.sh exécute tout gate.needs (miroir CI complet)
bash run_ci.sh --static seulement les gates statiques ci/*.sh (rapide)
bash run_ci.sh --list liste les jobs qui SERAIENT lancés, sans exécuter
bash run_ci.sh --help affiche cette aide et sort
Sortie : une ligne PASS/FAIL par job + un récapitulatif.
Code de sortie : 0 ssi tous les jobs passent · 1 si un job échoue ·
2 option inconnue · 3 hors checkout git / ci.yml illisible.
EOF
}
# --- aide : disponible AVANT toute résolution git (n'exige aucun checkout) ---
case "${1:-}" in -h|--help) usage; exit 0 ;; esac
# --- racine du dépôt (marche depuis n'importe quel sous-dossier) ------------- # --- racine du dépôt (marche depuis n'importe quel sous-dossier) -------------
ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || { ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || {
echo "run_ci.sh : hors d'un checkout git — impossible de localiser ci.yml." >&2 echo "run_ci.sh : hors d'un checkout git — impossible de localiser ci.yml." >&2
@@ -56,7 +78,7 @@ case "${1:-}" in
--static) MODE="static" ;; --static) MODE="static" ;;
--list) MODE="list" ;; --list) MODE="list" ;;
"") MODE="all" ;; "") MODE="all" ;;
*) echo "run_ci.sh : option inconnue « $1 » (attendu : --static | --list)" >&2; exit 2 ;; *) echo "run_ci.sh : option inconnue « $1 » (attendu : --static | --list | --help)" >&2; exit 2 ;;
esac esac
# --- parse ci.yml : gate.needs (ordre) + par job {working-directory, run} ---- # --- parse ci.yml : gate.needs (ordre) + par job {working-directory, run} ----
@@ -115,7 +137,11 @@ LOGDIR="$(mktemp -d)"
trap 'rm -rf "$LOGDIR"' EXIT trap 'rm -rf "$LOGDIR"' EXIT
pass=0; fail=0; skip=0; failed_jobs=() pass=0; fail=0; skip=0; failed_jobs=()
echo "run_ci.sh · miroir du gate CI (mode=$MODE) · $(git rev-parse --short HEAD 2>/dev/null || echo '?')" echo "run_ci.sh · miroir du gate CI (mode=$MODE) · $(git rev-parse --short HEAD 2>/dev/null || echo '?')"
if [ "$MODE" = "static" ]; then
echo "gate.needs dérivé : $n_jobs jobs · mode --static → $n_gates gates ci/*.sh seuls ($n_suites suites de module ignorées)"
else
echo "gate.needs dérivé : $n_jobs jobs = $n_gates gates ci/*.sh + $n_suites suites de module" echo "gate.needs dérivé : $n_jobs jobs = $n_gates gates ci/*.sh + $n_suites suites de module"
fi
echo "------------------------------------------------------------------------" echo "------------------------------------------------------------------------"
for row in "${ROWS[@]}"; do for row in "${ROWS[@]}"; do
IFS=$'\t' read -r job wd cmd <<<"$row" IFS=$'\t' read -r job wd cmd <<<"$row"