Files
mabibli_ynh/manifest.toml
T
mathieuandClaude Opus 5 5ebfd4a82b Remplace l'URL du depot par un placeholder, centralise, et refuse de publier avec
Sortie du projet : l'URL du Gitea prive disparait au profit de
https://forge.example.org/mabibli — example.org est reserve a la documentation
par la RFC 2606, donc definitivement injoignable.

Une seule ligne commande tout le reste : depot_code, en tete de publier.sh, d'ou
derivent les URL de release, d'archive et le message de fin. --depot-code fait la
meme chose sans modifier le fichier.

⚠ publier.sh REFUSE desormais de publier tant que le placeholder est en place, et
il refuse avant de compiler, comme ses autres garde-fous. Sans cela on ecrirait
dans manifest.toml une amd64.url que personne ne peut telecharger, et l'echec
surviendrait bien plus loin — a l'installation, dans ynh_setup_source, sans
rapport apparent avec la cause.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 13:03:45 +02:00

141 lines
6.3 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.5.0~ynh1"
maintainers = ["mathieu"]
[upstream]
license = "AGPL-3.0-or-later"
code = "https://forge.example.org/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` ne désigne AUCUNE compilation : rien n'est compilé sur le serveur, c'est
# tout l'intérêt du self-contained. Il couvre le téléchargement et la décompression de
# l'archive de 69 Mo. Ne pas aller chercher la valeur du côté d'un build .NET.
ram.build = "50M"
# Mesuré sur le serveur le 2026-08-22, service en marche :
# cat /sys/fs/cgroup/system.slice/mabibli.service/memory.peak -> 208 793 600 o
# soit 199,1 Mio de pic, contre 200M déclarés jusqu'ici : 0,4 % de marge, c'est-à-dire
# aucune. Porté à 256M.
#
# ⚠️ `systemctl show -p MemoryPeak` ne renvoie RIEN sur ce serveur — la commande réussit
# en silence et l'on croit lire un pic là où l'on ne lit rien. Passer par le cgroup.
#
# ⚠️ Le chiffre MAJORE le besoin : `memory.peak` compte le cache de fichiers, donc une
# part des 69 Mo de binaire mappé, récupérable sous pression — et le GC de .NET se serre
# sur une machine étroite. Mais YunoHost compare une déclaration statique à la RAM
# disponible, sans faire cette nuance. L'asymétrie tranche : un refus d'installation est
# visible et se contourne, un OOM survient plus tard, sous une opération lourde, sans que
# rien ne désigne la cause.
#
# ⚠️ Le pic n'est PAS le lookup ISBN, contrairement à l'intuition — une notice. C'est
# « Nouveautés » sur un auteur très réédité : jusqu'à dix pages de 100 notices SRU en
# parallèle, plus le catalogue entier chargé pour le rapprochement. Ce cas-là n'a pas
# encore été mesuré, et il croît avec la taille de la bibliothèque : à reprendre le jour
# où le fonds aura beaucoup grossi.
ram.runtime = "256M"
[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://forge.example.org/mabibli/releases/download/v0.5.0/mabibli-0.5.0-linux-x64.tar.gz"
amd64.sha256 = "15fb2ee67fb8f3a77a4c4734229e74d2605231713e100da38972d4dcf29e225d"
# 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"