683 lines
14 KiB
Markdown
683 lines
14 KiB
Markdown
# START-HERE — Archicratie / Édition Web (v3)
|
||
> Onboarding + exploitation “nickel chrome” (DEV → Gitea → CI → Release → Blue/Green → Edge/SSO → localhost auto-sync)
|
||
|
||
## 0) TL;DR (la règle d’or)
|
||
|
||
- **Gitea = source canonique**.
|
||
- **`main` est protégée** : toute modification passe par **branche → PR → CI → merge**.
|
||
- **Le NAS n’est pas la source** : si un hotfix est fait sur NAS, il doit être **backporté immédiatement** via PR.
|
||
- **Le site est statique Astro** : la prod sert du HTML via nginx ; l’accès est contrôlé au niveau reverse-proxy (Traefik + Authelia).
|
||
- **Le localhost automatique n’est pas le repo de dev** : il tourne depuis un **worktree dédié**, synchronisé sur `origin/main`.
|
||
|
||
---
|
||
|
||
## 1) Architecture mentale (ultra simple)
|
||
|
||
- **DEV canonique (Mac Studio)** : édition, dev, tests, commits, pushes
|
||
- **Gitea** : dépôt canonique, PR, CI, workflows éditoriaux
|
||
- **NAS (DS220+)** : déploiement blue/green
|
||
- `web_blue` → staging upstream → `127.0.0.1:8081`
|
||
- `web_green` → live upstream → `127.0.0.1:8082`
|
||
- **Edge (Traefik)** : routage des hosts
|
||
- `staging.archicratie...` → 8081
|
||
- `archicratie...` → 8082
|
||
- **Authelia** devant, via middleware `chain-auth@file`
|
||
- **Localhost auto-sync**
|
||
- un **repo canonique de développement**
|
||
- un **worktree localhost miroir de `origin/main`**
|
||
- un **agent de sync**
|
||
- un **agent Astro**
|
||
|
||
---
|
||
|
||
## 2) Répertoires & conventions (repo)
|
||
|
||
### 2.1 Contenu canon (édition)
|
||
|
||
- `src/content/**` : contenu MD / MDX canon
|
||
- `src/pages/**` : routes Astro
|
||
- `src/components/**` : composants UI
|
||
- `src/layouts/**` : layouts
|
||
- `src/styles/**` : CSS global
|
||
|
||
### 2.2 Annotations (pré-Édition “tickets”)
|
||
|
||
- `src/annotations/<workKey>/<slug>.yml`
|
||
- Exemple :
|
||
`src/annotations/archicrat-ia/prologue.yml`
|
||
|
||
Objectif :
|
||
stocker “Références / Médias / Commentaires” par page et par paragraphe (`p-...`).
|
||
|
||
### 2.3 Scripts (tooling / build)
|
||
|
||
- `scripts/inject-anchor-aliases.mjs` : injection aliases dans `dist`
|
||
- `scripts/dedupe-ids-dist.mjs` : retrait IDs dupliqués
|
||
- `scripts/build-para-index.mjs` : index paragraphes
|
||
- `scripts/build-annotations-index.mjs` : index annotations
|
||
- `scripts/check-anchors.mjs` : contrat stabilité d’ancres
|
||
- `scripts/check-annotations*.mjs` : sanity YAML + médias
|
||
|
||
> Important : ces scripts ne sont pas accessoires.
|
||
> Ils font partie du contrat de stabilité éditoriale.
|
||
|
||
---
|
||
|
||
## 3) Les trois espaces à ne jamais confondre
|
||
|
||
### 3.1 Repo canonique de développement
|
||
|
||
```text
|
||
/Volumes/FunIA/dev/archicratie-edition/site
|
||
```
|
||
|
||
Usage :
|
||
|
||
- développement normal
|
||
- branches de travail
|
||
- nouvelles fonctionnalités
|
||
- corrections manuelles
|
||
- commits
|
||
- pushes
|
||
- PR
|
||
|
||
### 3.2 Worktree localhost miroir de `main`
|
||
|
||
```text
|
||
/Users/s-funia/ops-local/archicratie/localhost-worktree
|
||
```
|
||
|
||
Branche attendue :
|
||
|
||
```text
|
||
localhost-sync
|
||
```
|
||
|
||
Usage :
|
||
|
||
- exécuter le localhost automatique
|
||
- refléter `origin/main`
|
||
- ne jamais servir d’espace de développement
|
||
|
||
### 3.3 Ops local hors repo
|
||
|
||
```text
|
||
/Users/s-funia/ops-local/archicratie
|
||
```
|
||
|
||
Usage :
|
||
|
||
- scripts d’exploitation
|
||
- état
|
||
- logs
|
||
- automatisation `launchd`
|
||
|
||
---
|
||
|
||
## 4) Pourquoi cette séparation existe
|
||
|
||
Il ne faut pas utiliser le repo canonique de développement comme serveur localhost permanent.
|
||
|
||
Sinon on mélange :
|
||
|
||
- travail en cours
|
||
- commits non poussés
|
||
- essais temporaires
|
||
- état réellement publié sur `main`
|
||
|
||
Le résultat devient ambigu.
|
||
|
||
La séparation retenue est donc :
|
||
|
||
- **repo canonique** = espace de développement
|
||
- **worktree localhost** = miroir exécutable de `origin/main`
|
||
- **ops local** = scripts et automatisation
|
||
|
||
C’est cette séparation qui rend le système lisible, robuste et opérable.
|
||
|
||
---
|
||
|
||
## 5) Workflow Git “pro” (main protégée)
|
||
|
||
### 5.1 Cycle standard (toute modif)
|
||
|
||
```bash
|
||
git checkout main
|
||
git pull --ff-only
|
||
|
||
BR="chore/xxx-$(date +%Y%m%d)"
|
||
git checkout -b "$BR"
|
||
|
||
# dev…
|
||
npm i
|
||
npm run build
|
||
npm run test:anchors
|
||
|
||
git add -A
|
||
git commit -m "xxx: description claire"
|
||
git push -u origin "$BR"
|
||
```
|
||
|
||
### 5.2 PR vers `main`
|
||
|
||
- ouvrir une PR dans Gitea
|
||
- attendre une CI verte
|
||
- merger
|
||
- laisser les workflows faire le reste
|
||
|
||
### 5.3 Cas spécial : hotfix prod (NAS)
|
||
|
||
On peut faire un hotfix d’urgence côté NAS si nécessaire.
|
||
|
||
Mais l’état final doit toujours revenir dans Gitea :
|
||
|
||
- branche
|
||
- PR
|
||
- CI
|
||
- merge
|
||
|
||
---
|
||
|
||
## 6) Déploiement (NAS) — principe
|
||
|
||
### 6.1 Release pack
|
||
|
||
On génère un pack reproductible, puis on déploie.
|
||
|
||
### 6.2 Blue/Green
|
||
|
||
- `web_blue` = staging (`8081`)
|
||
- `web_green` = live (`8082`)
|
||
|
||
Le reverse-proxy choisit l’upstream selon le host demandé.
|
||
|
||
---
|
||
|
||
## 7) Happy path complet
|
||
|
||
### 7.1 DEV (Mac)
|
||
|
||
```bash
|
||
git checkout main && git pull --ff-only
|
||
git checkout -b chore/my-change-$(date +%Y%m%d)
|
||
|
||
npm i
|
||
rm -rf .astro node_modules/.vite dist
|
||
npm run build
|
||
npm run test:anchors
|
||
npm run dev
|
||
```
|
||
|
||
### 7.2 Push + PR
|
||
|
||
```bash
|
||
git add -A
|
||
git commit -m "chore: my change"
|
||
git push -u origin chore/my-change-YYYYMMDD
|
||
```
|
||
|
||
Puis ouvrir la PR dans Gitea.
|
||
|
||
### 7.3 Déploiement NAS
|
||
|
||
Voir :
|
||
|
||
```text
|
||
docs/runbooks/DEPLOY-BLUE-GREEN.md
|
||
```
|
||
|
||
---
|
||
|
||
## 8) Localhost auto-sync — ce qu’il faut retenir
|
||
|
||
Le localhost automatique sert à voir **la vérité de `main`**, pas à développer du neuf.
|
||
|
||
### 8.1 Scripts principaux
|
||
|
||
#### Script de sync
|
||
|
||
```text
|
||
~/ops-local/archicratie/auto-sync-localhost.sh
|
||
```
|
||
|
||
Rôle :
|
||
|
||
- fetch `origin/main`
|
||
- réaligner le worktree localhost
|
||
- lancer `npm ci` si besoin
|
||
- redéclencher l’agent Astro si nécessaire
|
||
|
||
#### Script Astro
|
||
|
||
```text
|
||
~/ops-local/archicratie/run-astro-localhost.sh
|
||
```
|
||
|
||
Rôle :
|
||
|
||
- lancer `astro dev`
|
||
- depuis le bon worktree
|
||
- avec le bon runtime Node
|
||
- sur `127.0.0.1:4321`
|
||
|
||
> Oui : ce script est nécessaire.
|
||
> Il isole proprement le lancement du serveur Astro dans un contexte `launchd` stable.
|
||
|
||
### 8.2 LaunchAgents
|
||
|
||
#### Agent sync
|
||
|
||
```text
|
||
~/Library/LaunchAgents/me.archicratie.localhost-sync.plist
|
||
```
|
||
|
||
#### Agent Astro
|
||
|
||
```text
|
||
~/Library/LaunchAgents/me.archicratie.localhost-astro.plist
|
||
```
|
||
|
||
### 8.3 Document de référence
|
||
|
||
Pour tout le détail d’exploitation du localhost automatique, lire :
|
||
|
||
```text
|
||
docs/OPS-LOCALHOST-AUTO-SYNC.md
|
||
```
|
||
|
||
---
|
||
|
||
## 9) Règle d’or : il y a deux usages locaux distincts
|
||
|
||
### 9.1 Voir ce qui est réellement sur `main`
|
||
|
||
Utiliser :
|
||
|
||
```text
|
||
http://127.0.0.1:4321
|
||
```
|
||
|
||
Ce localhost doit être considéré comme :
|
||
|
||
**un miroir local exécutable de `origin/main`**
|
||
|
||
### 9.2 Développer / tester une nouvelle fonctionnalité
|
||
|
||
Utiliser le repo canonique :
|
||
|
||
```bash
|
||
cd /Volumes/FunIA/dev/archicratie-edition/site
|
||
npm run dev
|
||
```
|
||
|
||
Donc :
|
||
|
||
- **localhost auto-sync** = vérité de `main`
|
||
- **localhost de dev manuel** = expérimentation en cours
|
||
|
||
Il ne faut pas les confondre.
|
||
|
||
---
|
||
|
||
## 10) Ce qu’il ne faut pas faire
|
||
|
||
### 10.1 Ne pas développer dans le worktree localhost
|
||
|
||
Le worktree localhost est piloté automatiquement.
|
||
|
||
Il peut être :
|
||
|
||
- réaligné
|
||
- nettoyé
|
||
- redémarré
|
||
|
||
Donc :
|
||
|
||
- pas de commits dedans
|
||
- pas de dev feature dedans
|
||
- pas d’expérimentation de fond dedans
|
||
|
||
### 10.2 Ne pas utiliser le repo canonique comme miroir auto-sync
|
||
|
||
Sinon on mélange :
|
||
|
||
- espace de dev
|
||
- état publié
|
||
- serveur local permanent
|
||
|
||
### 10.3 Ne pas remettre les scripts ops sur un volume externe
|
||
|
||
Les scripts d’ops doivent rester sous `HOME`.
|
||
|
||
Le fait de les mettre sous `/Volumes/...` a déjà provoqué des erreurs du type :
|
||
|
||
```text
|
||
Operation not permitted
|
||
```
|
||
|
||
### 10.4 Ne pas supprimer `run-astro-localhost.sh`
|
||
|
||
Ce script fait partie de l’architecture actuelle.
|
||
Le supprimer reviendrait à réintroduire le flou entre sync Git et exécution d’Astro.
|
||
|
||
---
|
||
|
||
## 11) Commandes de contrôle essentielles
|
||
|
||
### 11.1 État global
|
||
|
||
```bash
|
||
~/ops-local/archicratie/doctor-localhost.sh
|
||
```
|
||
|
||
### 11.2 État Git
|
||
|
||
```bash
|
||
git -C ~/ops-local/archicratie/localhost-worktree rev-parse HEAD
|
||
git -C /Volumes/FunIA/dev/archicratie-edition/site ls-remote origin refs/heads/main
|
||
git -C ~/ops-local/archicratie/localhost-worktree branch --show-current
|
||
```
|
||
|
||
### 11.3 État LaunchAgents
|
||
|
||
```bash
|
||
launchctl print "gui/$(id -u)/me.archicratie.localhost-sync" | sed -n '1,160p'
|
||
launchctl print "gui/$(id -u)/me.archicratie.localhost-astro" | sed -n '1,160p'
|
||
```
|
||
|
||
### 11.4 État logs
|
||
|
||
```bash
|
||
tail -n 120 ~/ops-local/archicratie/logs/auto-sync-localhost.log
|
||
tail -n 120 ~/ops-local/archicratie/logs/astro-localhost.log
|
||
tail -n 80 ~/Library/Logs/archicratie-localhost-sync.err.log
|
||
tail -n 80 ~/Library/Logs/archicratie-localhost-astro.err.log
|
||
```
|
||
|
||
### 11.5 État serveur
|
||
|
||
```bash
|
||
lsof -nP -iTCP:4321 -sTCP:LISTEN
|
||
PID="$(lsof -tiTCP:4321 -sTCP:LISTEN | head -n 1)"
|
||
ps -p "$PID" -o pid=,command=
|
||
lsof -a -p "$PID" -d cwd
|
||
```
|
||
|
||
### 11.6 Vérification contenu
|
||
|
||
```bash
|
||
curl -s http://127.0.0.1:4321/archicrat-ia/prologue/ | grep -n "taxe Zucman"
|
||
```
|
||
|
||
---
|
||
|
||
## 12) Problèmes classiques + diagnostic
|
||
|
||
### 12.1 “Le staging ne ressemble pas au local”
|
||
|
||
Comparer les upstream directs :
|
||
|
||
```bash
|
||
curl -sS http://127.0.0.1:8081/ | head -n 2
|
||
curl -sS http://127.0.0.1:8082/ | head -n 2
|
||
```
|
||
|
||
Vérifier le routeur edge :
|
||
|
||
```bash
|
||
curl -sSI -H 'Host: staging.archicratie.trans-hands.synology.me' http://127.0.0.1:18080/ \
|
||
| grep -iE 'HTTP/|location:|x-archi-router'
|
||
```
|
||
|
||
Voir :
|
||
|
||
```text
|
||
docs/runbooks/EDGE-TRAEFIK.md
|
||
```
|
||
|
||
### 12.2 Canonical incorrect
|
||
|
||
Cause probable : `PUBLIC_SITE` mal injecté au build.
|
||
|
||
Test :
|
||
|
||
```bash
|
||
curl -sS http://127.0.0.1:8082/ | grep -oE 'rel="canonical" href="[^"]+"' | head -1
|
||
```
|
||
|
||
Voir :
|
||
|
||
```text
|
||
docs/runbooks/ENV-PUBLIC_SITE.md
|
||
```
|
||
|
||
### 12.3 Contrat anchors en échec après migration d’URL
|
||
|
||
Procédure safe :
|
||
|
||
```bash
|
||
cp -a tests/anchors-baseline.json /tmp/anchors-baseline.json.bak.$(date +%F-%H%M%S)
|
||
|
||
node - <<'NODE'
|
||
import fs from 'fs';
|
||
const p='tests/anchors-baseline.json';
|
||
const j=JSON.parse(fs.readFileSync(p,'utf8'));
|
||
const out={};
|
||
for (const [k,v] of Object.entries(j)) {
|
||
const nk = k.replace(/^archicratie\/archicrat-ia\//, 'archicrat-ia/');
|
||
out[nk]=v;
|
||
}
|
||
fs.writeFileSync(p, JSON.stringify(out,null,2)+'\n');
|
||
console.log('updated keys:', Object.keys(j).length, '->', Object.keys(out).length);
|
||
NODE
|
||
|
||
npm run test:anchors
|
||
```
|
||
|
||
### 12.4 “Le localhost auto-sync ne montre pas les dernières modifs”
|
||
|
||
Commande réflexe :
|
||
|
||
```bash
|
||
~/ops-local/archicratie/doctor-localhost.sh
|
||
```
|
||
|
||
Puis :
|
||
|
||
```bash
|
||
git -C ~/ops-local/archicratie/localhost-worktree rev-parse HEAD
|
||
git -C /Volumes/FunIA/dev/archicratie-edition/site ls-remote origin refs/heads/main
|
||
```
|
||
|
||
Si les SHA diffèrent :
|
||
- le sync n’a pas tourné
|
||
- ou l’agent sync a un problème
|
||
|
||
### 12.5 “Le SHA est bon mais le contenu web est faux”
|
||
|
||
Vérifier quel Astro écoute réellement :
|
||
|
||
```bash
|
||
lsof -nP -iTCP:4321 -sTCP:LISTEN
|
||
PID="$(lsof -tiTCP:4321 -sTCP:LISTEN | head -n 1)"
|
||
ps -p "$PID" -o pid=,command=
|
||
lsof -a -p "$PID" -d cwd
|
||
```
|
||
|
||
Attendu :
|
||
- commande contenant `astro dev`
|
||
- cwd = `~/ops-local/archicratie/localhost-worktree`
|
||
|
||
### 12.6 Erreur `EBADENGINE`
|
||
|
||
Cause probable :
|
||
- Node 23 utilisé au lieu de Node 22
|
||
|
||
Résolution :
|
||
- forcer `node@22` dans les scripts et les LaunchAgents
|
||
|
||
### 12.7 Erreur `Operation not permitted`
|
||
|
||
Cause probable :
|
||
- scripts d’ops placés sous `/Volumes/...`
|
||
|
||
Résolution :
|
||
- garder les scripts sous :
|
||
|
||
```text
|
||
~/ops-local/archicratie
|
||
```
|
||
|
||
### 12.8 Erreur `EPERM` sur `astro.mjs`
|
||
|
||
Cause probable :
|
||
- ancien worktree sur volume externe
|
||
- ancien chemin résiduel
|
||
- Astro lancé depuis un mauvais emplacement
|
||
|
||
Résolution :
|
||
- worktree localhost sous :
|
||
|
||
```text
|
||
~/ops-local/archicratie/localhost-worktree
|
||
```
|
||
|
||
- scripts cohérents avec ce chemin
|
||
- réinstallation propre via :
|
||
|
||
```bash
|
||
~/ops-local/archicratie/install-localhost-sync.sh
|
||
```
|
||
|
||
---
|
||
|
||
## 13) Redémarrage machine
|
||
|
||
Après reboot, le comportement attendu est :
|
||
|
||
1. le LaunchAgent sync se recharge
|
||
2. le LaunchAgent Astro se recharge
|
||
3. le worktree localhost est réaligné
|
||
4. Astro redémarre sur `127.0.0.1:4321`
|
||
|
||
### Vérification rapide après reboot
|
||
|
||
```bash
|
||
~/ops-local/archicratie/doctor-localhost.sh
|
||
```
|
||
|
||
Si nécessaire :
|
||
|
||
```bash
|
||
~/ops-local/archicratie/install-localhost-sync.sh
|
||
```
|
||
|
||
---
|
||
|
||
## 14) Procédure de secours manuelle
|
||
|
||
### Forcer un sync
|
||
|
||
```bash
|
||
~/ops-local/archicratie/auto-sync-localhost.sh
|
||
```
|
||
|
||
### Réinstaller proprement le dispositif local
|
||
|
||
```bash
|
||
~/ops-local/archicratie/install-localhost-sync.sh
|
||
```
|
||
|
||
### Diagnostic complet
|
||
|
||
```bash
|
||
~/ops-local/archicratie/doctor-localhost.sh
|
||
```
|
||
|
||
---
|
||
|
||
## 15) Décision d’exploitation finale
|
||
|
||
La politique retenue est la suivante :
|
||
|
||
- **repo canonique** = espace de développement
|
||
- **worktree localhost** = miroir automatique de `main`
|
||
- **ops sous HOME** = scripts, logs, automation
|
||
- **LaunchAgent sync** = réalignement Git
|
||
- **LaunchAgent Astro** = exécution stable du serveur local
|
||
- **Astro local** = lancé uniquement depuis le worktree localhost
|
||
|
||
Cette séparation rend le dispositif plus :
|
||
|
||
- lisible
|
||
- robuste
|
||
- opérable
|
||
- antifragile
|
||
|
||
---
|
||
|
||
## 16) Résumé opératoire
|
||
|
||
### Pour voir la vérité de `main`
|
||
|
||
Ouvrir :
|
||
|
||
```text
|
||
http://127.0.0.1:4321
|
||
```
|
||
|
||
Le serveur doit provenir de :
|
||
|
||
```text
|
||
/Users/s-funia/ops-local/archicratie/localhost-worktree
|
||
```
|
||
|
||
### Pour développer
|
||
|
||
Travailler dans :
|
||
|
||
```text
|
||
/Volumes/FunIA/dev/archicratie-edition/site
|
||
```
|
||
|
||
avec les commandes habituelles.
|
||
|
||
### Pour réparer vite
|
||
|
||
```bash
|
||
~/ops-local/archicratie/doctor-localhost.sh
|
||
~/ops-local/archicratie/auto-sync-localhost.sh
|
||
```
|
||
|
||
---
|
||
|
||
## 17) Mémoire courte
|
||
|
||
Si un jour plus rien n’est clair, repartir de ces commandes :
|
||
|
||
```bash
|
||
~/ops-local/archicratie/doctor-localhost.sh
|
||
git -C ~/ops-local/archicratie/localhost-worktree rev-parse HEAD
|
||
git -C /Volumes/FunIA/dev/archicratie-edition/site ls-remote origin refs/heads/main
|
||
lsof -nP -iTCP:4321 -sTCP:LISTEN
|
||
```
|
||
|
||
Puis lire :
|
||
|
||
```bash
|
||
tail -n 120 ~/ops-local/archicratie/logs/auto-sync-localhost.log
|
||
tail -n 120 ~/ops-local/archicratie/logs/astro-localhost.log
|
||
```
|
||
|
||
---
|
||
|
||
## 18) Statut actuel visé
|
||
|
||
Quand tout fonctionne correctement :
|
||
|
||
- le worktree localhost pointe sur le même SHA que `origin/main`
|
||
- `astro dev` écoute sur `127.0.0.1:4321`
|
||
- son cwd est `~/ops-local/archicratie/localhost-worktree`
|
||
- le contenu servi correspond au contenu mergé sur `main`
|
||
|
||
C’est l’état de référence à préserver. |