From 07d004b3f0e4081d36c619d99aa42f394f362bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9drix?= Date: Fri, 15 May 2026 10:13:56 +0200 Subject: [PATCH 1/4] =?UTF-8?q?feat=20:=20bouton=20unique=20Mettre=20?= =?UTF-8?q?=C3=A0=20jour=20(git=20pull=20+=20SQL=20+=20contenu),=20branche?= =?UTF-8?q?=20dev?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- CLAUDE.md | 31 +++++++++++++++++---- public/index.php | 68 ++++++++++++++++++++++++++++++++++++++++++++- scripts/push.sh | 2 +- templates/admin.php | 48 ++++++++++++++++---------------- 4 files changed, 117 insertions(+), 32 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index c68c7ee..7c727ef 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,19 +22,38 @@ Les articles ne sont pas versionnés dans ce dépôt. Ils ont leur propre git lo ## Modifier le moteur -Pour toute correction ou fonctionnalité : **créer un ticket et une PR**. +### Branches -1. Coder ici dans `~/Projects/folio/` (branche feature) -2. **Tester sur varlog.a5l.fr** : +| Branche | Rôle | +|---------|------| +| `dev` | Branche d'intégration permanente. **Tout le développement courant se fait ici.** | +| `main` | Branche de production. **Jamais de commit direct.** | +| `feat/*` | Branches feature optionnelles pour du travail isolé, mergées dans `dev`. | + +### Workflow + +1. Toujours travailler sur `dev` (ou une branche feature mergée dans `dev`) : + ```bash + git checkout dev + ``` +2. **Tester sur varlog.a5l.fr** à chaque itération (rsync des fichiers locaux, DB persistante) : ```bash ~/Projects/varlog/scripts/sync.sh # puis tester sur http://varlog.acegrp.lan ``` -3. Une fois validé, ouvrir une PR sur Gitea. Le commit doit inclure : - - `public/version.txt` (bump semver) - - `CHANGELOG.md` (entrée `### Ajouté / Corrigé / Modifié`) +3. Quand `dev` est stable et prête pour la production : + - Bumper `public/version.txt` (semver) + - Ajouter une entrée `CHANGELOG.md` (`### Ajouté / Corrigé / Modifié`) + - Ouvrir une **PR `dev` → `main`** sur Gitea 4. Merger la PR → abonnel.fr se met à jour automatiquement. +**Règle absolue : ne jamais commiter directement sur `main`.** Le script `scripts/push.sh` bloque cette action. + +### Pourquoi `dev` et non des branches feature à la volée + +- La DB de varlog (test) accumule les migrations au fil du temps — changer de branche ne fait pas reculer les migrations. +- Travailler toujours sur `dev` évite toute désynchronisation entre le code rsyncé et la DB. + ## Données articles (`DATA_PATH`) Les articles sont stockés dans un répertoire **hors du dépôt Folio**, configurable via `DATA_PATH` dans `.env`. diff --git a/public/index.php b/public/index.php index b57a1dc..05f354e 100644 --- a/public/index.php +++ b/public/index.php @@ -45,7 +45,7 @@ $action = $_GET['action'] ?? 'list'; $uuid = $_GET['uuid'] ?? ''; $slug = $_GET['slug'] ?? ''; -$_noindexActions = ['create', 'edit', 'admin', 'categories', 'diff', 'add_files', 'import_image', 'import_image_step2', 'sources', 'profile', 'delete_file', 'delete_external_link', 'rename_category', 'delete_category', 'toggle_private_category', 'admin_save_site', 'not_found', 'add_feed', 'delete_feed', 'add_link', 'delete_link', 'reorder_links', 'react', 'comment', 'verify_comment', 'comment_moderate', 'comment_delete', 'comment_resend', 'create_tag_type', 'delete_tag_type', 'edit_tags', 'book_save', 'book_delete', 'admin_save_as_groups', 'admin_save_folio_config']; +$_noindexActions = ['create', 'edit', 'admin', 'categories', 'diff', 'add_files', 'import_image', 'import_image_step2', 'sources', 'profile', 'delete_file', 'delete_external_link', 'rename_category', 'delete_category', 'toggle_private_category', 'admin_save_site', 'not_found', 'add_feed', 'delete_feed', 'add_link', 'delete_link', 'reorder_links', 'react', 'comment', 'verify_comment', 'comment_moderate', 'comment_delete', 'comment_resend', 'create_tag_type', 'delete_tag_type', 'edit_tags', 'book_save', 'book_delete', 'admin_save_as_groups', 'admin_save_folio_config', 'run_engine_update']; $metaRobots = in_array($action, $_noindexActions, true) ? 'noindex, nofollow' : null; unset($_noindexActions); @@ -2816,6 +2816,72 @@ switch ($action) { header('Location: /admin?tab=dashboard¬ice=' . ($_cmErrors ? 'migration_error' : 'migrated')); exit; + case 'run_engine_update': + requireAuth(); + if (!isAdmin() || $_SERVER['REQUEST_METHOD'] !== 'POST') { + http_response_code(403); + exit; + } + + // 1. git pull + exec('cd ' . escapeshellarg(BASE_PATH) . ' && git pull origin main 2>&1', $_gitOut, $_gitCode); + if ($_gitCode !== 0) { + $_SESSION['_update_log'] = implode("\n", $_gitOut); + header('Location: /admin?tab=dashboard¬ice=update_git_error'); + exit; + } + + // 2. composer install (non-bloquant si absent) + exec('which composer 2>/dev/null', $_composerPath); + if (!empty($_composerPath)) { + exec('cd ' . escapeshellarg(BASE_PATH) . ' && composer install --no-dev --optimize-autoloader -q 2>&1'); + } + + // 3. Migrations SQL + $pdo->exec('CREATE TABLE IF NOT EXISTS schema_migrations (name TEXT NOT NULL PRIMARY KEY, applied_at TIMESTAMP NOT NULL DEFAULT NOW())'); + $_sqlApplied = array_flip($pdo->query('SELECT name FROM schema_migrations ORDER BY name')->fetchAll(PDO::FETCH_COLUMN)); + $_sqlFiles = glob(BASE_PATH . '/database/migration_*.sql') ?: []; + sort($_sqlFiles); + foreach ($_sqlFiles as $_sqlFile) { + $_sqlName = basename($_sqlFile); + if (isset($_sqlApplied[$_sqlName])) { + continue; + } + $pdo->exec((string) file_get_contents($_sqlFile)); + $pdo->prepare('INSERT INTO schema_migrations (name) VALUES (:n)')->execute([':n' => $_sqlName]); + } + + // 4. Migrations de contenu + $_cmDataDir = DATA_PATH; + $_cmTrack = $_cmDataDir . '/.content_migrations.json'; + $_cmFlag = $_cmDataDir . '/.maintenance'; + $_cmApplied = file_exists($_cmTrack) ? (json_decode((string) file_get_contents($_cmTrack), true) ?? []) : []; + $_cmFiles = glob(BASE_PATH . '/scripts/content/migration_*.php') ?: []; + sort($_cmFiles); + $_cmPending = array_values(array_filter($_cmFiles, fn ($f) => !isset($_cmApplied[basename($f)]))); + $_cmErrors = 0; + if (!empty($_cmPending)) { + file_put_contents($_cmFlag, date('Y-m-d H:i:s')); + $dataDir = $_cmDataDir; + foreach ($_cmPending as $_cmFile) { + try { + require $_cmFile; + $_cmApplied[basename($_cmFile)] = date('Y-m-d H:i:s'); + file_put_contents($_cmTrack, json_encode($_cmApplied, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "\n"); + } catch (Throwable $_cmEx) { + $_cmErrors++; + break; + } + } + if (file_exists($_cmFlag)) { + unlink($_cmFlag); + } + } + + $_updateChecker->clearCache(); + header('Location: /admin?tab=dashboard¬ice=' . ($_cmErrors ? 'update_content_error' : 'engine_updated')); + exit; + case 'force_update_check': requireAuth(); if (!isAdmin() || $_SERVER['REQUEST_METHOD'] !== 'POST') { diff --git a/scripts/push.sh b/scripts/push.sh index 3bc618f..096e428 100755 --- a/scripts/push.sh +++ b/scripts/push.sh @@ -24,7 +24,7 @@ fi BRANCH=$(git rev-parse --abbrev-ref HEAD) if [[ "$BRANCH" == "main" ]]; then echo "✗ Refus de pousser directement sur main." - echo " Créer une branche feature : git checkout -b feat/nom" + echo " Travailler sur 'dev' ou une branche feature : git checkout dev" exit 1 fi diff --git a/templates/admin.php b/templates/admin.php index 41e3488..3d02e0e 100644 --- a/templates/admin.php +++ b/templates/admin.php @@ -126,13 +126,17 @@ function adminStatusBadge(array $a, int $now): string Dernière version disponible - Mise à jour disponible' : '' ?> - -
- -
+ + +
+ +
+ +
+ +
- (FOLIO_REPO_URL non configuré) + (FOLIO_REPO_URL non configuré) @@ -140,24 +144,20 @@ function adminStatusBadge(array $a, int $now): string Branche suivie · vérifié le ' . date('d/m/Y à H:i', $_lastChecked) . '' : '' ?> - - - Actions requises - - - -
- -
- - - - - - -
Migrations appliquées avec succès.
- -
Une erreur est survenue pendant la migration.
+ +
Moteur mis à jour avec succès (code, base de données, contenu).
+ + +
+ Erreur git pull — vérifiez les droits d'accès au dépôt. + +
+ + +
+ + +
Code et base de données mis à jour, mais une migration de contenu a échoué.
-- 2.52.0 From eddde2165ad5960e2470da02c31fdecb0876a514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9drix?= Date: Fri, 15 May 2026 10:23:03 +0200 Subject: [PATCH 2/4] =?UTF-8?q?fix=20:=20run=5Fengine=5Fupdate=20v=C3=A9ri?= =?UTF-8?q?fie=20origin=20=3D=3D=20folio=5Frepo=5Furl=20avant=20git=20pull?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- public/index.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/public/index.php b/public/index.php index 05f354e..13220e8 100644 --- a/public/index.php +++ b/public/index.php @@ -2823,7 +2823,18 @@ switch ($action) { exit; } - // 1. git pull + // 1. git pull — vérifier que origin pointe vers le dépôt folio configuré + $_folioRepo = rtrim(folioRepoUrl(), '/'); + exec('git -C ' . escapeshellarg(BASE_PATH) . ' remote get-url origin 2>&1', $_originOut, $_originCode); + $_originUrl = rtrim(trim(implode('', $_originOut)), '/'); + // Normaliser : supprimer les credentials éventuels de l'URL (token@host → host) + $_originNorm = preg_replace('#https?://[^@]+@#', 'https://', $_originUrl); + $_repoNorm = preg_replace('#https?://[^@]+@#', 'https://', $_folioRepo); + if ($_originCode !== 0 || $_originNorm !== $_repoNorm) { + $_SESSION['_update_log'] = "Le remote git 'origin' (" . $_originUrl . ") ne correspond pas à FOLIO_REPO_URL (" . $_folioRepo . "). git pull annulé."; + header('Location: /admin?tab=dashboard¬ice=update_git_error'); + exit; + } exec('cd ' . escapeshellarg(BASE_PATH) . ' && git pull origin main 2>&1', $_gitOut, $_gitCode); if ($_gitCode !== 0) { $_SESSION['_update_log'] = implode("\n", $_gitOut); -- 2.52.0 From 0280ef3ca1c0e5430df31553fd5cc60570ce2933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9drix?= Date: Fri, 15 May 2026 10:51:28 +0200 Subject: [PATCH 3/4] docs : architecture articles git (varlog.git + abonnel-www.git), sync bidirectionnelle Co-Authored-By: Claude Sonnet 4.6 --- CLAUDE.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 7c727ef..609a908 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -56,14 +56,17 @@ Les articles ne sont pas versionnés dans ce dépôt. Ils ont leur propre git lo ## Données articles (`DATA_PATH`) -Les articles sont stockés dans un répertoire **hors du dépôt Folio**, configurable via `DATA_PATH` dans `.env`. +Les articles sont stockés dans un répertoire **hors du dépôt Folio**, configurable via `DATA_PATH` dans `.env` (défaut production : `/srv/data/folio`). -| Environnement | Chemin local | Chemin serveur | -|--------------|-------------|----------------| -| varlog | `~/Projects/varlog-data/` | `/srv/data/folio` | -| abonnel.fr | `~/Projects/fr.abonnel.www-data/` | `/srv/data/folio` | +| Environnement | Dépôt local articles | Dépôt Gitea | Serveur | +|--------------|---------------------|------------|---------| +| varlog | `~/Projects/varlog-data/` | `cedricAbonnel/varlog` | `varlog:/srv/data/folio` | +| abonnel.fr | `~/Projects/fr.abonnel.www-data/` | `cedricAbonnel/abonnel-www` | `abonnel-wiki:/srv/data/folio` | -Les scripts de sync (`pull-data.sh`, `push-data.sh`, `sync.sh`) utilisent `DATA_DIR` (overridable via env) pointant vers ces chemins locaux. +Sync bidirectionnelle via **git** (pas rsync). Scripts dans `~/Projects/varlog/scripts/` et `~/Projects/fr.abonnel.www/scripts/` : +- `pull-data.sh` : commit auto serveur + git pull local +- `push-data.sh` : git commit local + git push + git pull serveur +- `sync.sh` : moteur (rsync) + articles (git bidirectionnel) ## Asymétrie de déploiement moteur -- 2.52.0 From 331e9c9ecd73fd8f8e43a903f7f07455d48b370e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9drix?= Date: Fri, 15 May 2026 11:13:56 +0200 Subject: [PATCH 4/4] =?UTF-8?q?chore=20:=20version=201.6.0=20=E2=80=94=20b?= =?UTF-8?q?outon=20Mettre=20=C3=A0=20jour,=20branche=20dev,=20guard=20git?= =?UTF-8?q?=20pull?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- CHANGELOG.md | 11 +++++++++++ public/version.txt | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21927fd..c6efe3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,17 @@ Format : [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/) — versionnag --- +## [1.6.0] - 2026-05-15 + +### Ajouté +- Admin → Dashboard : bouton unique **Mettre à jour** (git pull + migrations SQL + migrations contenu) remplace les boutons séparés +- Branche `dev` : branche d'intégration permanente pour le développement quotidien + +### Corrigé +- `run_engine_update` : vérifie que le remote git `origin` correspond à `FOLIO_REPO_URL` avant tout `git pull` (évite le pull sur le mauvais dépôt) + +--- + ## [1.5.0] - 2026-05-15 ### Ajouté diff --git a/public/version.txt b/public/version.txt index bc80560..dc1e644 100644 --- a/public/version.txt +++ b/public/version.txt @@ -1 +1 @@ -1.5.0 +1.6.0 -- 2.52.0