Ir al contenido
Bondry

Empaquetado y formato de versión

El paquete de update firmado, lo que el instalador rechaza, y cómo se construye una versión.

Existen dos artefactos por versión: el paquete de update que aplica el updater, y el paquete full que instala un comprador desde cero. Esta página trata sobre el primero, porque es el que tiene un formato.

El paquete#

Un zip con exactamente tres cosas:

Código
bondry-package.json      el manifiesto
bondry-package.sig       la firma
files/<relative path>    los archivos, relativos a la raíz de instalación

El manifiesto#

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"]
}
Campo Significado
product El product slug: el core o tu módulo
version La versión que instala este paquete
min_from La versión más baja sobre la que se puede aplicar este paquete
php La restricción de PHP
files Cada archivo del paquete con su sha256
delete Archivos eliminados por esta versión

La firma#

bondry-package.sig es una firma RSA-SHA256, codificada en base64, sobre la forma canónica del manifiesto: el json_encode de {product, version, min_from, php, files (ordenados por clave), delete} con JSON_UNESCAPED_SLASHES.

La clave privada nunca sale del release server, y firmar solo ocurre como parte de publicar una versión. Un paquete no es algo que puedas firmar en una laptop, y ese es justamente el punto.

Lo que rechaza el instalador#

En este orden, y cualquiera de ellos rechaza el paquete completo:

  1. la firma no verifica;
  2. el sha256 de algún archivo no coincide con el manifiesto;
  3. alguna ruta es absoluta, contiene .., o cae fuera de las raíces permitidas.

Raíces permitidas: app/, bootstrap/, config/, database/, lang/, modules/, public/, resources/, routes/, vendor/, más composer.*, artisan y el manifiesto de integridad.

Nunca escrito por un update: .env, storage/, public/uploads/ y bootstrap/cache/. La configuración, los uploads y los datos de un comprador no son tuyos para sobrescribir.

Construir una versión#

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

Recorre el árbol, calcula los hashes, compara contra la versión anterior del mismo producto para llenar delete, escribe el manifiesto y lo firma.

Paquetes de módulo y de tema#

Un módulo o un tema instalado desde el panel es un zip plano del directorio, con el manifiesto en su raíz. No está firmado a menos que official esté activado, y official solo se acepta para paquetes que nosotros firmamos.

La extracción se protege de la misma forma: un directorio temporal aislado, validación de schema, sin rutas absolutas, sin .., sin symlinks, y un límite en el tamaño descomprimido para que una zip bomb no llegue a ningún lado.

Exportaciones del Designer#

Un documento del Designer se exporta como .bondry-design.json, o .bondry-design.zip cuando viaja con medios. La importación valida el schema, remapea los medios, avisa sobre módulos faltantes y sobre tokens sin coincidencia.

Nada en una importación ejecuta código: es JSON plano. El zip está limitado a 500 entradas y 64 MB descomprimido, se rechazan las entradas con .. o rutas absolutas, los medios deben tener una extensión permitida y un sha256 coincidente, y cualquier divergencia rechaza el paquete completo.

Checklist antes de publicar#

  • Assets compilados e incluidos; sin paso de build para el comprador.
  • tested_up_to fijado a la versión del core que realmente probaste.
  • Las migraciones solo tocan tu propio prefijo.
  • onUninstall elimina tus tablas y deja el core intacto.
  • Cada string en tus propios archivos de idioma, escrito en inglés.
  • Nada de script en línea en ningún lado.
  • Una instalación limpia y un upgrade desde la versión anterior, ambos probados.