Ir para o conteúdo
Bondry

Empacotamento e formato de versão

O pacote de update assinado, o que o instalador recusa, e como uma versão é construída.

Existem dois artefatos por versão: o pacote de update que o updater aplica, e o pacote completo que um comprador instala do zero. Esta página é sobre o primeiro, porque é o que tem um formato.

O pacote#

Um zip com exatamente três coisas:

Código
bondry-package.json      o manifesto
bondry-package.sig       a assinatura
files/<relative path>    os arquivos, relativos à raiz da instalação

O manifesto#

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 O slug do produto: o core ou o seu módulo
version A versão que este pacote instala
min_from A versão mais baixa sobre a qual este pacote pode ser aplicado
php A restrição de PHP
files Todo arquivo do pacote com o seu sha256
delete Arquivos removidos por esta versão

A assinatura#

bondry-package.sig é uma assinatura RSA-SHA256, codificada em base64, sobre a forma canônica do manifesto: json_encode de {product, version, min_from, php, files (ordenado por chave), delete} com JSON_UNESCAPED_SLASHES.

A chave privada nunca sai do servidor de release, e assinar só acontece como parte da publicação de uma versão. Um pacote não é algo que você assina num notebook, e esse é o ponto.

O que o instalador recusa#

Nesta ordem, e qualquer um deles rejeita o pacote inteiro:

  1. a assinatura não verifica;
  2. o sha256 de algum arquivo não bate com o manifesto;
  3. algum caminho é absoluto, contém .., ou cai fora das raízes permitidas.

Raízes permitidas: app/, bootstrap/, config/, database/, lang/, modules/, public/, resources/, routes/, vendor/, mais composer.*, artisan e o manifesto de integridade.

Nunca escritos por um update: .env, storage/, public/uploads/ e bootstrap/cache/. A configuração, os uploads e os dados de um comprador não são seus para sobrescrever.

Construindo uma versão#

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

Ele percorre a árvore, calcula os hashes, compara com a versão anterior do mesmo produto para preencher delete, escreve o manifesto e assina.

Pacotes de módulo e de tema#

Um módulo ou tema instalado a partir do painel é um zip simples do diretório, com o manifesto na raiz. Não é assinado a menos que official esteja definido, e official só é aceito para pacotes que nós assinamos.

A extração é reforçada da mesma forma: um diretório temporário isolado, validação de schema, nenhum caminho absoluto, nenhum .., nenhum symlink, e um limite no tamanho descomprimido para que uma zip bomb não vá a lugar nenhum.

Exportações do Designer#

Um documento do Designer é exportado como .bondry-design.json, ou .bondry-design.zip quando mídia viaja junto. A importação valida o schema, remapeia a mídia, avisa sobre módulos ausentes e sobre tokens sem correspondência.

Nada numa importação executa código: é JSON puro. O zip tem um limite de 500 entradas e 64 MB descomprimidos, entradas com .. ou caminhos absolutos são recusadas, a mídia precisa ter uma extensão permitida e um sha256 correspondente, e qualquer divergência rejeita o pacote inteiro.

Checklist antes de lançar#

  • Assets compilados e incluídos; nenhum passo de build para o comprador.
  • tested_up_to definido com a versão do core que você realmente testou.
  • Migrações tocam só no seu próprio prefixo.
  • onUninstall remove suas tabelas e deixa o core intacto.
  • Toda string nos seus próprios arquivos de idioma, em inglês.
  • Nenhum script inline em lugar nenhum.
  • Uma instalação limpa e um upgrade a partir da versão anterior, ambos testados.