Aller au contenu
Bondry

Empaquetage et format de version

Le paquet de mise à jour signé, ce que l'installateur refuse, et comment une version est construite.

Deux artefacts existent par version : le paquet update que l'updater applique, et le paquet full qu'un acheteur installe à partir de zéro. Cette page parle du premier, car c'est celui qui a un format.

Le paquet#

Un zip avec exactement trois choses :

Code
bondry-package.json      le manifeste
bondry-package.sig       la signature
files/<relative path>    les fichiers, relatifs à la racine d'installation

Le manifeste#

JSON
{
  "product": "bondry-core",
  "version": "1.2.0",
  "min_from": "1.0.0",
  "php": ">=8.2",
  "files": { "app/Kernel/Foo.php": "<sha256>", "...": "..." },
  "delete": ["app/Kernel/Removed.php"]
}
Champ Signification
product Le product slug : le core ou votre module
version La version que ce paquet installe
min_from La version la plus basse sur laquelle ce paquet peut être appliqué
php La contrainte PHP
files Chaque fichier du paquet avec son sha256
delete Les fichiers supprimés par cette version

La signature#

bondry-package.sig est une signature RSA-SHA256, encodée en base64, sur la forme canonique du manifeste : le json_encode de {product, version, min_from, php, files (sorted by key), delete} avec JSON_UNESCAPED_SLASHES.

La clé privée ne quitte jamais le serveur de version, et la signature n'a lieu que dans le cadre de la publication d'une version. Un paquet n'est pas quelque chose que vous pouvez signer sur un portable, et c'est bien le but.

Ce que l'installateur refuse#

Dans cet ordre, et chacun d'eux rejette la totalité du paquet :

  1. la signature ne se vérifie pas ;
  2. le sha256 d'un fichier ne correspond pas au manifeste ;
  3. un chemin est absolu, contient .., ou tombe hors des racines autorisées.

Racines autorisées : app/, bootstrap/, config/, database/, lang/, modules/, public/, resources/, routes/, vendor/, plus composer.*, artisan et le manifeste d'intégrité.

Jamais écrit par un update : .env, storage/, public/uploads/ et bootstrap/cache/. La configuration, les uploads et les données de l'acheteur ne sont pas à vous pour les écraser.

Construire une version#

Shell
php artisan release:build <product> <version> <folder>

Elle parcourt l'arborescence, calcule les hashes, compare avec la version précédente du même produit pour remplir delete, écrit le manifeste et le signe.

Paquets de module et de thème#

Un module ou un thème installé depuis le panneau est un simple zip du répertoire, avec le manifeste à sa racine. Il n'est pas signé sauf si official est défini, et official n'est accepté que pour les paquets que nous signons.

L'extraction est durcie de la même façon : un répertoire temporaire isolé, une validation du schéma, aucun chemin absolu, aucun .., aucun symlink, et un plafond sur la taille décompressée pour qu'un zip bomb n'aille nulle part.

Exports Designer#

Un document Designer s'exporte en .bondry-design.json, ou en .bondry-design.zip quand des médias voyagent avec lui. L'import valide le schéma, remappe les médias, avertit des modules manquants et des tokens sans correspondance.

Rien dans un import n'exécute de code : c'est du JSON pur. Le zip est plafonné à 500 entrées et 64 Mo décompressés, les entrées avec .. ou des chemins absolus sont refusées, les médias doivent avoir une extension autorisée et un sha256 correspondant, et toute divergence rejette la totalité du paquet.

Liste de vérification avant de livrer#

  • Assets compilés et inclus ; aucune étape de build pour l'acheteur.
  • tested_up_to réglé sur la version du core que vous avez réellement testée.
  • Les migrations ne touchent que votre propre préfixe.
  • onUninstall supprime vos tables et laisse le core tranquille.
  • Chaque chaîne dans vos propres fichiers de langue, en anglais.
  • Aucun script inline nulle part.
  • Une installation propre et une mise à niveau depuis la version précédente, toutes deux testées.