Il y en avait deux, et le mauvais portait le nom le plus convaincant : `publier-release.sh` compilait, archivait et réécrivait le manifeste, à charge pour l'appelant de committer. Lancé seul, il a produit les deux moitiés de la panne du 2026-08-21 — un manifeste corrigé mais non poussé, et une release v0.4.0 contenant six commits de plus que son tag. `publier.sh` absorbe l'étape et refuse désormais de publier, avant de compiler, si le tag de la version existe déjà (en nommant le commit du tag et celui de HEAD) ou si le dépôt du code n'est pas propre. `--archive-seule` garde la brique réutilisable en CI, sous le même nom : ni manifeste, ni commit, ni tag, donc rien à moitié publié. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
116 lines
4.8 KiB
TOML
116 lines
4.8 KiB
TOML
#:schema https://raw.githubusercontent.com/YunoHost/apps/master/schemas/manifest.v2.schema.json
|
|
|
|
packaging_format = 2
|
|
|
|
id = "mabibli"
|
|
name = "MaBibli"
|
|
description.fr = "Gestion de bibliothèque personnelle : catalogue, prêts et scan ISBN"
|
|
description.en = "Personal library manager: catalogue, loans and ISBN scanning"
|
|
|
|
version = "0.4.1~ynh1"
|
|
|
|
maintainers = ["mathieu"]
|
|
|
|
[upstream]
|
|
license = "AGPL-3.0-or-later"
|
|
code = "https://git.akbar.nohost.me/mathieu/mabibli"
|
|
|
|
[integration]
|
|
yunohost = ">= 12.1.38"
|
|
helpers_version = "2.1"
|
|
|
|
# x86_64 uniquement : CLAUDE.md acte un serveur PC/VPS, et la chaîne de publication
|
|
# ne produit qu'un binaire `linux-x64`. Déclarer d'autres architectures promettrait
|
|
# des archives qui n'existent pas.
|
|
architectures = ["amd64"]
|
|
|
|
# Une seule instance : la bibliothèque est commune au foyer (CLAUDE.md, « Portée des
|
|
# données »). Deux instances voudraient dire deux collections étanches, ce qui est
|
|
# exactement ce que le projet a écarté.
|
|
multi_instance = false
|
|
|
|
# L'application ne parle pas à LDAP : elle lit l'identité dans les en-têtes que
|
|
# SSOwat injecte. C'est bien une intégration SSO, mais pas une intégration LDAP.
|
|
ldap = false
|
|
sso = true
|
|
|
|
# ~170 Mo de publish self-contained (runtime .NET embarqué), plus la base et la marge
|
|
# de décompression de l'archive.
|
|
disk = "500M"
|
|
ram.build = "50M"
|
|
ram.runtime = "200M"
|
|
|
|
[install]
|
|
|
|
[install.domain]
|
|
type = "domain"
|
|
|
|
# Pas de question `path` : MaBibli s'installe sur un domaine entier.
|
|
#
|
|
# Ce n'est pas un oubli. Le client Blazor WebAssembly fige son `<base href="/">`
|
|
# et les empreintes de `service-worker-assets.js` **à la compilation**. Servir
|
|
# l'application sous un sous-chemin demanderait de réécrire `index.html` sur le
|
|
# serveur, ce qui invaliderait les empreintes d'intégrité du service worker et
|
|
# casserait le mode hors-ligne. Comme le paquet ne compile rien sur le serveur,
|
|
# la seule option honnête est le domaine entier.
|
|
#
|
|
# Conséquence côté YunoHost : `resources.permissions.main.url` étant une chaîne,
|
|
# le cœur classe l'app en « full_domain » et refusera un changement d'URL vers
|
|
# un sous-chemin.
|
|
|
|
[install.init_main_permission]
|
|
type = "group"
|
|
default = "all_users"
|
|
help.fr = "Qui peut accéder à la bibliothèque. MaBibli n'a pas de connexion propre : l'identité vient du portail YunoHost, et la collection est commune à toutes les personnes autorisées."
|
|
help.en = "Who may access the library. MaBibli has no login of its own: identity comes from the YunoHost portal, and the collection is shared between all allowed users."
|
|
|
|
[resources]
|
|
|
|
[resources.sources.main]
|
|
# Archive **déjà compilée** (publish self-contained linux-x64), produite par
|
|
# `build/publier.sh` et déposée en release sur le Gitea de l'utilisateur.
|
|
# Le SDK .NET n'est jamais installé sur le serveur : c'est tout l'intérêt du
|
|
# self-contained (CLAUDE.md, « Ne jamais compiler sur le serveur »).
|
|
#
|
|
# Ces deux valeurs sont réécrites par `build/publier.sh`.
|
|
amd64.url = "https://git.akbar.nohost.me/mathieu/mabibli/releases/download/v0.4.1/mabibli-0.4.1-linux-x64.tar.gz"
|
|
amd64.sha256 = "21f6a437dcd118ed863d24ce1137f711ca19e004b5e89b6d482dcfd07ab7a884"
|
|
|
|
# L'archive dépose ses fichiers à la racine, sans dossier intermédiaire.
|
|
in_subdir = false
|
|
|
|
# Pas d'`autoupdate` : les releases sont déposées à la main sur un Gitea privé,
|
|
# aucune stratégie amont connue de YunoHost ne s'y applique.
|
|
|
|
[resources.system_user]
|
|
|
|
[resources.install_dir]
|
|
# Le service tourne sous `mabibli` mais ne doit **pas** pouvoir réécrire ses
|
|
# propres binaires : propriétaire root, application en lecture seule. Cela va de
|
|
# pair avec `ProtectSystem=strict` dans l'unité systemd.
|
|
owner = "root:rwx"
|
|
group = "__APP__:rx"
|
|
|
|
[resources.data_dir]
|
|
# La base SQLite vit ici, et **pas** à côté du binaire : c'est ce qui permet à une
|
|
# mise à jour de remplacer intégralement `install_dir` sans toucher aux données.
|
|
owner = "__APP__:rwx"
|
|
group = "__APP__:rx"
|
|
|
|
[resources.permissions]
|
|
# Toute l'application derrière le SSO, `/api` compris : la bibliothèque est
|
|
# familiale, rien n'a vocation à être public. `auth_header` vaut `true` par
|
|
# défaut, c'est lui qui autorise SSOwat à injecter `YNH_USER` — sans quoi
|
|
# l'application ne saurait jamais qui la consulte.
|
|
main.url = "/"
|
|
main.auth_header = true
|
|
|
|
[resources.ports]
|
|
# Port interne uniquement. `exposed` vaut `false` par défaut : le pare-feu reste
|
|
# fermé, et l'unité systemd n'écoute que sur 127.0.0.1.
|
|
|
|
[resources.apt]
|
|
# `sqlite3` sert aux sauvegardes : la base est en mode WAL (vérifié), un simple
|
|
# `cp` du fichier `.db` ne suffit pas. Voir `scripts/backup`.
|
|
packages = "sqlite3"
|