Ajoute les mises à jour autonomes

Les installations hors YunoHost peuvent désormais vérifier et installer une release Forgejo avec sauvegarde et retour arrière complet.
This commit is contained in:
Alexandre NOEL 2026-09-08 20:13:55 +02:00
commit 53e79a72d7
25 changed files with 1146 additions and 61 deletions

View file

@ -15,6 +15,7 @@ foreach (
'Auth',
'AuditService',
'BackupService',
'UpdateService',
'NotificationService',
'PrivacyService',
]
@ -36,6 +37,9 @@ try {
if (in_array($command, ['run', 'notifications'], true)) {
$results['notifications'] = NotificationService::send(false);
}
if (in_array($command, ['run', 'updates'], true)) {
$results['updates'] = UpdateService::refreshIfDue();
}
echo json_encode(
['ok' => true, 'at' => date(DATE_ATOM), 'results' => $results],
JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE,

View file

@ -2,15 +2,4 @@
set -euo pipefail
root_dir="$(cd "$(dirname "$0")/.." && pwd)"
snapshot="${1:-}"
if [[ -z "$snapshot" || ! -f "$snapshot" || "$(basename "$snapshot")" != code-*.tar.gz ]]; then
echo "Usage: $0 storage/releases/code-VERSION-DATE.tar.gz" >&2
exit 2
fi
case "$(realpath "$snapshot")" in "$root_dir"/storage/releases/*) ;; *) echo "Snapshot hors de storage/releases refusé." >&2; exit 2;; esac
touch "$root_dir/storage/maintenance.flag"
trap 'rm -f "$root_dir/storage/maintenance.flag"' EXIT
tar -xzf "$snapshot" -C "$root_dir"
php "$root_dir/scripts/migrate.php"
rm -f "$root_dir/storage/maintenance.flag"
echo "Code restauré. La base n’a pas été rétrogradée automatiquement."
exec php "$root_dir/scripts/update.php" --rollback

56
scripts/update.php Normal file
View file

@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
if (PHP_SAPI !== 'cli') {
http_response_code(404);
exit(1);
}
$root = dirname(__DIR__);
foreach (['DB', 'Migrations', 'I18n', 'AppSettings', 'Auth', 'AuditService', 'BackupService', 'UpdateService'] as $class) {
require_once $root . '/app/Services/' . $class . '.php';
}
Migrations::run($root . '/migrations');
I18n::setLocale(AppSettings::get('app_language'));
$arguments = array_slice($argv, 1);
$command = $arguments[0] ?? '--help';
try {
if ($command === '--check') {
echo json_encode(UpdateService::check(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), PHP_EOL;
exit(0);
}
if ($command === '--rollback') {
echo json_encode(UpdateService::rollbackLast(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), PHP_EOL;
exit(0);
}
if ($command === '--online') {
echo json_encode(UpdateService::installFromRepository(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), PHP_EOL;
exit(0);
}
if (is_file($command)) {
$hash = '';
foreach ($arguments as $argument) {
if (str_starts_with($argument, '--sha256=')) {
$hash = substr($argument, 9);
}
}
if ($hash === '') {
throw new InvalidArgumentException('L’option --sha256=<empreinte> est obligatoire.');
}
echo json_encode(UpdateService::install($command, $hash, 'cli'), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), PHP_EOL;
exit(0);
}
fwrite(STDERR, "Utilisation :\n");
fwrite(STDERR, " php scripts/update.php --check\n");
fwrite(STDERR, " php scripts/update.php --online\n");
fwrite(STDERR, " php scripts/update.php archive.tar.gz --sha256=EMPREINTE\n");
fwrite(STDERR, " php scripts/update.php --rollback\n");
exit(2);
} catch (Throwable $e) {
fwrite(STDERR, $e->getMessage() . PHP_EOL);
exit(1);
}

View file

@ -2,42 +2,4 @@
set -euo pipefail
root_dir="$(cd "$(dirname "$0")/.." && pwd)"
release_archive="${1:-}"
if [[ -z "$release_archive" || ! -f "$release_archive" ]]; then
echo "Usage: $0 /chemin/vers/globinours.tar.gz" >&2
exit 2
fi
if [[ ! -f "$root_dir/public/index.php" || ! -f "$root_dir/VERSION" ]]; then
echo "Installation Globinours invalide: $root_dir" >&2
exit 2
fi
stage_dir="$(mktemp -d /tmp/globinours-update-XXXXXX)"
trap 'rm -rf "$stage_dir"; rm -f "$root_dir/storage/maintenance.flag"' EXIT
if tar -tzf "$release_archive" | grep -Eq '(^/|(^|/)\.\.(/|$))'; then
echo "Archive refusée: chemin dangereux." >&2
exit 3
fi
tar -xzf "$release_archive" -C "$stage_dir"
source_dir="$stage_dir"
if [[ ! -f "$source_dir/public/index.php" ]]; then
first_dir="$(find "$stage_dir" -mindepth 1 -maxdepth 1 -type d | head -n 1)"
source_dir="$first_dir"
fi
if [[ ! -f "$source_dir/public/index.php" || ! -f "$source_dir/VERSION" ]]; then
echo "Archive Globinours invalide." >&2
exit 3
fi
mkdir -p "$root_dir/storage/releases"
current_version="$(tr -d '[:space:]' < "$root_dir/VERSION")"
new_version="$(tr -d '[:space:]' < "$source_dir/VERSION")"
rollback_archive="$root_dir/storage/releases/code-${current_version}-$(date +%Y%m%d-%H%M%S).tar.gz"
php "$root_dir/scripts/backup.php" pre-upgrade
tar --exclude='./data' --exclude='./storage' --exclude='./public/media' --exclude='./.env' -czf "$rollback_archive" -C "$root_dir" .
touch "$root_dir/storage/maintenance.flag"
rsync -a --delete --exclude=data --exclude=storage --exclude=public/media --exclude=.env "$source_dir/" "$root_dir/"
php "$root_dir/scripts/migrate.php"
rm -f "$root_dir/storage/maintenance.flag"
echo "Globinours $current_version -> $new_version"
echo "Retour arrière du code: $rollback_archive"
exec php "$root_dir/scripts/update.php" "$@"