222 lines
8.0 KiB
Markdown
222 lines
8.0 KiB
Markdown
# ROADMAP — CI (Gitea Actions Synology) + Ancrages (aliases build-time)
|
||
|
||
But : permettre à un successeur de reprendre sans rien deviner.
|
||
Ce document décrit :
|
||
- l’état stable actuel (baseline)
|
||
- les invariants à ne pas casser
|
||
- les prochaines étapes “mission principale” (ancrages primaires robustes + CI durable)
|
||
- la méthode de debug rapide
|
||
|
||
---
|
||
|
||
## 0) État actuel (baseline VALIDÉE)
|
||
|
||
### CI (Gitea Actions)
|
||
- ✅ Job dans un container Node 22 (conforme `engines`)
|
||
- ✅ Checkout **sans actions GitHub**, depuis `workflow/event.json`
|
||
- ✅ Zéro `apt-get` dans le workflow
|
||
- ✅ `npm ci` + build + tests anchors + validation schema aliases
|
||
- ✅ Injection d’aliases au postbuild confirmée en logs
|
||
|
||
### Runner (DS220+)
|
||
- ✅ `container.network: host` dans `/data/config.yaml` du runner
|
||
- ✅ `NODE_OPTIONS=--dns-result-order=ipv4first` passé aux containers de job
|
||
- ✅ `--add-host=gitea.archicratie.trans-hands.synology.me:192.168.1.20`
|
||
|
||
Raison : le DNS du bridge Docker (127.0.0.11) est instable sur cette infra → EAI_AGAIN / ESERVFAIL (npm, debian).
|
||
|
||
Référence : `docs/CI-BASELINE.md` + `docs/CI-WORKFLOW.md` + `docs/HANDOFF-SESSION.md`.
|
||
|
||
---
|
||
|
||
## 1) Invariants (NE PAS “optimiser”)
|
||
|
||
Ces points sont des garde-fous. Si on les retire, on revient aux mêmes pannes.
|
||
|
||
1) Runner :
|
||
- garder `container.network: host` (tant que l’infra DNS bridge n’est pas corrigée)
|
||
- garder `-e NODE_OPTIONS=--dns-result-order=ipv4first`
|
||
|
||
2) Workflow :
|
||
- ne pas réintroduire `apt-get`
|
||
- ne pas dépendre de `actions/checkout@...`
|
||
- garder un container Node 22 tant que `package.json engines` impose `>=22 <23`
|
||
|
||
3) Ancrages :
|
||
- le fichier canonique : `src/anchors/anchor-aliases.json`
|
||
- injection build-time : `scripts/inject-anchor-aliases.mjs`
|
||
- test anchors : `scripts/check-anchors.mjs`
|
||
- validation schema aliases : `scripts/check-anchor-aliases.mjs`
|
||
|
||
---
|
||
|
||
## 2) Mission principale (raccrochage)
|
||
|
||
Objectif “métier” :
|
||
- préserver les liens profonds (ancrages) malgré l’édition (déplacements, insertions, corrections)
|
||
- éviter les résolutions “par index” (fragiles)
|
||
- rendre la migration d’ancrages **déterministe, versionnée, testée**
|
||
|
||
Traduction technique :
|
||
- quand un `newId` remplace un `oldId`, on versionne `oldId -> newId` **par page**
|
||
- au build, on injecte un alias DOM invisible portant l’ancien `id` avant l’élément ciblé
|
||
|
||
---
|
||
|
||
## 3) Prochains jalons (ordre recommandé)
|
||
|
||
### Jalons A — Verrouillage qualité (court terme, “béton”)
|
||
A1) CI : prouver l’injection (pas seulement “build ok”)
|
||
- ajouter un test qui parcourt `src/anchors/anchor-aliases.json` et vérifie dans `dist/<route>/index.html` :
|
||
- présence de `<span id="oldId" ...>`
|
||
- présence de l’élément `id="newId"`
|
||
- et idéalement : alias placé “juste avant” la cible (proximité)
|
||
|
||
A2) CI : interdire les IDs en double (risque SEO/DOM)
|
||
- dans les pages `dist`, détecter les doublons d’attribut `id="..."`
|
||
|
||
A3) CI : artefacts / logs actionnables
|
||
- quand un test échoue : afficher `route`, `oldId`, `newId`, extrait HTML et ligne
|
||
|
||
### Jalons B — Ergonomie éditeur (moyen terme)
|
||
B1) `apply-ticket.mjs` : renforcer le mode `--alias`
|
||
- si un paragraphe est remplacé : écrire l’alias automatiquement
|
||
- si conflit : message clair “oldId déjà mappé / newId introuvable”
|
||
|
||
B2) `check-anchors.mjs` : suggestion d’aliases
|
||
- lorsqu’il détecte “removed X / added Y” avec même préfixe `p-8-...`
|
||
- générer une proposition, option `--write-aliases` (ou sortie patch)
|
||
|
||
### Jalons C — Robustesse long terme (ops)
|
||
C1) Runner : réduire le risque “host network”
|
||
- isoler le runner sur LAN (réseau dédié/pare-feu)
|
||
- limiter les labels/queues aux repos nécessaires
|
||
- documenter comment restaurer `/data/config.yaml`
|
||
|
||
C2) Versionner les décisions
|
||
- tout changement CI/runner : documenté dans `docs/` + commit (pas de “magic fix” non tracé)
|
||
|
||
---
|
||
|
||
## 4) Procédure standard (dev -> PR -> merge)
|
||
|
||
### Ajouter/modifier du contenu
|
||
1) modifier les sources (docx/import etc.)
|
||
2) si des IDs de paragraphes changent :
|
||
- appliquer `scripts/apply-ticket.mjs --alias` si possible
|
||
- sinon éditer `src/anchors/anchor-aliases.json` (par route)
|
||
|
||
### Vérifier en local
|
||
- `npm test`
|
||
- ou au minimum :
|
||
- `npm run build`
|
||
- vérifier injection : `grep -n "para-alias" dist/<route>/index.html`
|
||
|
||
### PR & merge
|
||
- une PR = un ticket logique
|
||
- CI doit passer
|
||
- merge seulement quand anchors + aliases sont cohérents
|
||
|
||
---
|
||
|
||
## 5) Debug express (quand ça casse)
|
||
|
||
### CI échoue “DNS / npm”
|
||
Symptômes typiques :
|
||
- `EAI_AGAIN`, `ESERVFAIL`, `Temporary failure resolving`
|
||
Actions :
|
||
1) vérifier runner config : `/data/config.yaml` contient bien `network: host`
|
||
2) vérifier job container : logs montrent `network="host"`
|
||
3) smoke test NAS :
|
||
- `docker run --rm --network host mcr.microsoft.com/devcontainers/javascript-node:22-bookworm bash -lc "npm ping --registry=https://registry.npmjs.org"`
|
||
|
||
### CI échoue “EBADENGINE”
|
||
- Node pas 22 → corriger l’image du job (Node 22)
|
||
|
||
### CI échoue “MODULE_NOT_FOUND scripts/...”
|
||
- fichier non commité
|
||
- `git status --porcelain` puis `git add/commit/push`
|
||
|
||
### Injection d’alias absente
|
||
- vérifier que `postbuild` appelle bien `inject-anchor-aliases.mjs`
|
||
- vérifier que `src/anchors/anchor-aliases.json` respecte le schéma (par route)
|
||
|
||
---
|
||
|
||
## 6) Définition de “DONE” (quand on peut dire “mission accomplie”)
|
||
|
||
1) CI stable sur 30+ runs consécutifs (push + PR + merge)
|
||
2) Toute modification de paragraphes qui casse des anchors produit :
|
||
- soit un alias automatique via tooling
|
||
- soit un échec CI explicite (avec patch proposé)
|
||
3) Aliases injectés testés (preuve dans dist) + pas de doublons d’IDs
|
||
4) Documentation à jour (baseline + décisions + procédures)
|
||
|
||
---
|
||
|
||
## P2 — UX / Front “lecture outillée” (verrouillé)
|
||
- [x] Scroll unique dans le panneau gauche (TOC global + local).
|
||
- [x] Bandeau H1/H2/H3 aligné au reading + offsets d’ancres cohérents.
|
||
- [x] Boucle “Proposer” rétablie : modal 2 étapes (type + category) puis ouverture Gitea en nouvel onglet.
|
||
- [x] Bookmarks + reprise de lecture + citation copiable.
|
||
- [x] Procédure de diagnostic (terminal + dist + DevTools Firefox).
|
||
|
||
______________________________________
|
||
|
||
Dernière mise à jour : 2026-01-29
|
||
|
||
---
|
||
|
||
## ✅ Réalisé (socle solide)
|
||
|
||
### A) Ancrages stables (anti-casse)
|
||
- Aliasing d’ancres à la build (déterministe) :
|
||
- mapping versionné (ex: `docs/anchor-aliases.json`)
|
||
- injection dans `dist/**/index.html` via `scripts/inject-anchor-aliases.mjs`
|
||
- Audit dist : détection des IDs dupliqués (sans faux positifs JS/CSS) via `scripts/audit-dist.mjs`
|
||
- Vérification “aliases réellement présents dans dist” via `scripts/verify-anchor-aliases-in-dist.mjs`
|
||
|
||
### B) Qualité CI
|
||
- Suite de tests `npm test` (build + audit + anchors + inline JS)
|
||
|
||
### C) ✅ Production DS220+ (DSM 7.3) — Blue/Green
|
||
- Build Astro en image Docker (Node Debian) + runtime Nginx statique
|
||
- 2 slots :
|
||
- `web_blue` → 127.0.0.1:8081
|
||
- `web_green` → 127.0.0.1:8082
|
||
- Reverse Proxy DSM :
|
||
- bascule port 8081/8082 = bascule prod (rollback ~10s)
|
||
- Variables `PUBLIC_GITEA_*` injectées au build → “Proposer” fonctionne end-to-end
|
||
- Smoke test + healthcheck opérationnels
|
||
|
||
Docs :
|
||
- `DEPLOY_PROD_SYNOLOGY_DS220.md`
|
||
- `OPS_COCKPIT.md`
|
||
|
||
---
|
||
|
||
## ⏭️ Prochaines actions “futées” (à très forte valeur)
|
||
|
||
### 1) Automatiser le cycle blue/green (sans complexifier)
|
||
- Script `scripts/deploy-slot.sh green` :
|
||
- build --no-cache
|
||
- up --force-recreate
|
||
- smoke + health
|
||
- imprime “OK pour bascule DSM vers 8082”
|
||
- Script `scripts/which-live.sh` :
|
||
- compare 8081/8082 avec le domaine public
|
||
|
||
### 2) Durcir l’hygiène “transfert macOS → NAS”
|
||
- `.dockerignore` contre `PaxHeader/`, `._*`, `.DS_Store`
|
||
- (optionnel) script `scripts/clean-macos-artifacts.sh`
|
||
|
||
### 3) Observabilité minimale
|
||
- page “/healthz” (statique) ou check `/pagefind/pagefind.js`
|
||
- journalisation Nginx : garder 2–3 jours, rotation simple (optionnel)
|
||
|
||
### 4) Sécurité reverse proxy
|
||
- confirmer headers (HSTS si voulu, CSP si nécessaire)
|
||
- s’assurer que 8081/8082 restent local-only (127.0.0.1)
|
||
|
||
Fin.
|