Cas d'usage rapporté : « je peux avoir une version 1.5.3 pour les
pompiers et une version 1.5.3 pour la police ». Le check anti-doublon
sur le numéro de version bloquait la création — c'était un faux check
puisque la duplication SUR DES CHANNELS DIFFÉRENTS est légitime.
Changements :
1. ID stable interne : chaque entry de version reçoit un `id` immutable
généré à la création (`v` + 8 hex aléatoires). Ce id devient l'identifiant
primaire dans les forms et URLs admin. Le numéro de version reste un
libellé human-readable, possiblement dupliqué.
2. Migration douce : loadManifest() ajoute un id aux entrées qui n'en
ont pas, et auto-save pour persister. Stable aux reloads suivants.
Les manifests legacy fonctionnent sans aucune action manuelle.
3. Check anti-doublon déplacé sur le NOM DE ZIP au lieu du numéro de
version. Deux entries v1.5.3 sont autorisées si elles pointent vers
des ZIPs différents (proserve-1.5.3-police.zip + proserve-1.5.3-pompier.zip).
Une vraie ambiguïté sur disque (deux entries → même ZIP) est rejetée.
4. Toutes les actions row-level (edit_meta, edit_notes, set_beta,
set_channels, toggle_available, delete, set_skip_hash, sync_one)
identifient l'entry par `id` au lieu de `version`. Forms HTML mis
à jour en conséquence.
5. Release notes : addressables par id stable. Stockées en
releasenotes/{id}.md. Compat ascendante : si un fichier {id}.md
n'existe pas, l'admin lit le legacy {version}.md (pour les notes
créées avant v0.27.1). L'endpoint API releasenotes/{key} accepte
les deux formats.
6. Suppression d'une entry : nettoie le fichier {id}.md correspondant.
7. SignManifest::run filtre toujours par version string : si plusieurs
entries partagent un numéro de version, toutes sont re-hashées via
« 🔁 Hash » sur une row. Comportement correct (chaque entry a sa
propre URL/ZIP, donc son hash spécifique), juste moins efficient.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
36 lines
1.1 KiB
PHP
36 lines
1.1 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace PSLauncher\Routes;
|
|
|
|
use PSLauncher\Response;
|
|
|
|
/**
|
|
* Release notes endpoint. Accepte deux formats d'identifiant :
|
|
* - id stable d'entrée : 'v' + 8 hex chars (format depuis v0.27.1, supporte
|
|
* plusieurs entries de même version)
|
|
* - numéro de version legacy : X.Y.Z (compat ascendante avec les notes
|
|
* créées avant v0.27.1)
|
|
*/
|
|
final class Releasenotes
|
|
{
|
|
public static function handle(string $key): void
|
|
{
|
|
$isEntryId = (bool)preg_match('/^v[0-9a-f]{8}$/', $key);
|
|
$isVersion = (bool)preg_match('/^[0-9]+\.[0-9]+\.[0-9]+$/', $key);
|
|
|
|
if (!$isEntryId && !$isVersion) {
|
|
Response::error('invalid_id', 'Bad release-notes identifier', 400);
|
|
}
|
|
|
|
$file = dirname(__DIR__, 2) . "/releasenotes/{$key}.md";
|
|
if (!is_file($file)) {
|
|
Response::error('not_found', "Release notes for {$key} not found", 404);
|
|
}
|
|
header('Cache-Control: public, max-age=3600, must-revalidate');
|
|
header('Content-Type: text/markdown; charset=utf-8');
|
|
header('Content-Length: ' . filesize($file));
|
|
readfile($file);
|
|
}
|
|
}
|