feat : versionnage semver, migrations contenu, bandeau mise à jour admin
- CHANGELOG.md : structure semver (1.0.0 / 1.1.0 / 1.2.0) remplace le journal non versionné - public/version.txt : généré à chaque push depuis la première entrée CHANGELOG - scripts/push.sh : extrait la version CHANGELOG avant git add - src/UpdateChecker.php : compare version déployée vs version Gitea (raw file), cache 1 h - templates/layout.php : bandeau alerte admin (nouvelle version / migrations en attente) - templates/admin.php : dashboard moteur Folio (version déployée / disponible) - scripts/migrate_content.php + migration_001 : ajout # titre dans les articles existants - templates/maintenance.php : page HTTP 503 pendant une migration - src/helpers.php : extractMarkdownTitle(), normalisation \r\n dans lineDiff() - templates/wizard/step1.php : suppression champ titre, plan TOC dynamique - public/assets/js/wizard.js : scope titleEl, scrollToCursor, buildToc, handlers externalisés Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
// Runner de migrations de contenu (fichiers articles).
|
||||
// Analogie avec database/migrate.php, mais pour les fichiers data/.
|
||||
//
|
||||
// Usage : php scripts/migrate_content.php [/chemin/vers/data]
|
||||
//
|
||||
// - Lit data/.content_migrations.json pour savoir ce qui a déjà tourné.
|
||||
// - Active data/.maintenance pendant l'exécution (→ page 503 aux visiteurs).
|
||||
// - Applique les scripts scripts/content/migration_*.php non encore appliqués.
|
||||
|
||||
$baseDir = dirname(__DIR__);
|
||||
$dataDir = $argv[1] ?? ($baseDir . '/data');
|
||||
|
||||
if (!is_dir($dataDir)) {
|
||||
fwrite(STDERR, "Répertoire data introuvable : $dataDir\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$trackFile = $dataDir . '/.content_migrations.json';
|
||||
$maintenanceFlag = $dataDir . '/.maintenance';
|
||||
|
||||
$applied = [];
|
||||
if (file_exists($trackFile)) {
|
||||
$applied = json_decode((string) file_get_contents($trackFile), true) ?? [];
|
||||
}
|
||||
|
||||
$files = glob(__DIR__ . '/content/migration_*.php') ?: [];
|
||||
sort($files);
|
||||
|
||||
$pending = array_values(array_filter($files, fn ($f) => !isset($applied[basename($f)])));
|
||||
|
||||
if (empty($pending)) {
|
||||
echo " (aucune migration de contenu en attente)\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
file_put_contents($maintenanceFlag, date('Y-m-d H:i:s'));
|
||||
echo "→ Mode maintenance activé\n";
|
||||
|
||||
$count = 0;
|
||||
$errors = 0;
|
||||
|
||||
foreach ($pending as $file) {
|
||||
$name = basename($file);
|
||||
echo " → $name ... ";
|
||||
try {
|
||||
require $file;
|
||||
$applied[$name] = date('Y-m-d H:i:s');
|
||||
file_put_contents(
|
||||
$trackFile,
|
||||
json_encode($applied, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "\n"
|
||||
);
|
||||
echo "✓\n";
|
||||
$count++;
|
||||
} catch (Throwable $e) {
|
||||
echo "✗ " . $e->getMessage() . "\n";
|
||||
$errors++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (file_exists($maintenanceFlag)) {
|
||||
unlink($maintenanceFlag);
|
||||
}
|
||||
echo "→ Mode maintenance désactivé\n";
|
||||
echo "→ $count migration(s) appliquée(s)" . ($errors ? ", $errors erreur(s)" : '') . ".\n";
|
||||
|
||||
exit($errors > 0 ? 1 : 0);
|
||||
Reference in New Issue
Block a user