Compare commits
1
Commits
241f61f433
..
v1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1373532345 |
@@ -1,6 +1,6 @@
|
|||||||
# Paquet YunoHost pour MaBibli
|
# Paquet YunoHost pour MaBibli
|
||||||
|
|
||||||
Paquet d'installation de [MaBibli](https://git.akbar.nohost.me/mathieu/mabibli), application de
|
Paquet d'installation de [MaBibli](https://forge.example.org/mabibli), application de
|
||||||
gestion de bibliothèque personnelle (catalogue, prêts, scan ISBN).
|
gestion de bibliothèque personnelle (catalogue, prêts, scan ISBN).
|
||||||
|
|
||||||
Ce dépôt **ne contient aucun code C#**. Il porte uniquement de quoi installer sur YunoHost une
|
Ce dépôt **ne contient aucun code C#**. Il porte uniquement de quoi installer sur YunoHost une
|
||||||
@@ -9,7 +9,7 @@ d'installation, et les scripts de publication.
|
|||||||
|
|
||||||
## 📖 Toute la documentation est dans le dépôt du code
|
## 📖 Toute la documentation est dans le dépôt du code
|
||||||
|
|
||||||
Elle a été regroupée dans **[le README de `mabibli`](https://git.akbar.nohost.me/mathieu/mabibli#readme)**,
|
Elle a été regroupée dans **[le README de `mabibli`](https://forge.example.org/mabibli#readme)**,
|
||||||
qui est le point d'entrée unique du projet : contenu et points de conception du paquet,
|
qui est le point d'entrée unique du projet : contenu et points de conception du paquet,
|
||||||
publication d'une version, mise en production pas à pas, montée de version, retour arrière,
|
publication d'une version, mise en production pas à pas, montée de version, retour arrière,
|
||||||
désinstallation, et contraintes permanentes.
|
désinstallation, et contraintes permanentes.
|
||||||
|
|||||||
+118
-68
@@ -3,29 +3,17 @@
|
|||||||
# Publie une version de MaBibli de bout en bout, en une commande.
|
# Publie une version de MaBibli de bout en bout, en une commande.
|
||||||
#
|
#
|
||||||
# 1. choisir la version, à partir de celle déjà publiée
|
# 1. choisir la version, à partir de celle déjà publiée
|
||||||
# 2. compiler self-contained, vérifier le publish, produire l'archive
|
# 2. compiler self-contained POUR CHAQUE ARCHITECTURE, vérifier chaque publish,
|
||||||
# 3. réécrire manifest.toml (version, url, sha256)
|
# produire une archive par architecture
|
||||||
|
# 3. réécrire manifest.toml (version, url et sha256 de chaque architecture)
|
||||||
# 4. committer et pousser mabibli_ynh (le serveur lit Gitea, jamais le local)
|
# 4. committer et pousser mabibli_ynh (le serveur lit Gitea, jamais le local)
|
||||||
# 5. taguer et pousser mabibli (le tag porte le code de la release)
|
# 5. taguer et pousser mabibli (le tag porte le code de la release)
|
||||||
#
|
#
|
||||||
# La seule chose qui reste manuelle est le dépôt de l'archive dans la release Gitea :
|
# La seule chose qui reste manuelle est le dépôt des archives dans la release Gitea :
|
||||||
# l'URL est rappelée en fin de sortie.
|
# elles sont rappelées en fin de sortie, une par architecture.
|
||||||
#
|
#
|
||||||
# ⚠️ POURQUOI UN SEUL SCRIPT, ET PAS DEUX
|
# Le mode `--archive-seule` compile et archive sans toucher ni
|
||||||
#
|
# au manifeste ni à git
|
||||||
# Ce fichier était jusqu'au 2026-08-21 un orchestrateur appelant `publier-release.sh`,
|
|
||||||
# qui compilait et réécrivait le manifeste. Deux scripts, dont le mauvais portait le nom
|
|
||||||
# le plus convaincant : lancé seul, `publier-release.sh` réécrivait le manifeste sans le
|
|
||||||
# committer, et acceptait de recompiler une version dont le tag existait déjà.
|
|
||||||
#
|
|
||||||
# Les deux moitiés de la panne du 2026-08-21 en sont sorties : une release `v0.4.0`
|
|
||||||
# contenant en réalité six commits de plus que son tag, et un `manifest.toml` corrigé
|
|
||||||
# mais jamais poussé — donc un `yunohost app upgrade` qui échoue sur le sha256, et dont
|
|
||||||
# le retour arrière échoue pour la même raison.
|
|
||||||
#
|
|
||||||
# D'où la fusion. Le mode `--archive-seule` conserve la brique réutilisable en CI
|
|
||||||
# (compiler et archiver, sans toucher ni au manifeste ni à git), mais sous CE nom : il
|
|
||||||
# n'y a plus deux commandes voisines entre lesquelles se tromper.
|
|
||||||
#
|
#
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -37,11 +25,6 @@ racine_paquet="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|||||||
manifeste="$racine_paquet/manifest.toml"
|
manifeste="$racine_paquet/manifest.toml"
|
||||||
|
|
||||||
# ⚠️ Chaque réglage a UNE seule façon de se donner : son option en ligne de commande.
|
# ⚠️ Chaque réglage a UNE seule façon de se donner : son option en ligne de commande.
|
||||||
# Cinq variables d'environnement jumelles (MABIBLI_SOURCE_DIR, MABIBLI_BASE_URL…) ont
|
|
||||||
# existé jusqu'au 2026-08-22, chacune doublant une option qu'elle ne faisait que
|
|
||||||
# répéter : l'aide en listait dix pour cinq réglages, et rien ne disait laquelle
|
|
||||||
# l'emportait sur l'autre. Ne pas les réintroduire pour une CI hypothétique — une CI
|
|
||||||
# passe des options aussi bien que des variables.
|
|
||||||
# ⚠️ LA SEULE LIGNE À CHANGER pour héberger ce projet ailleurs.
|
# ⚠️ LA SEULE LIGNE À CHANGER pour héberger ce projet ailleurs.
|
||||||
# Tout ce qui suit en dérive : URL de release, URL d'archive, message de fin.
|
# Tout ce qui suit en dérive : URL de release, URL d'archive, message de fin.
|
||||||
#
|
#
|
||||||
@@ -61,17 +44,35 @@ version=""
|
|||||||
increment=""
|
increment=""
|
||||||
sans_confirmation=0
|
sans_confirmation=0
|
||||||
archive_seule=0
|
archive_seule=0
|
||||||
runtime="linux-x64"
|
|
||||||
projet="MaBibli.Api"
|
projet="MaBibli.Api"
|
||||||
|
|
||||||
|
# ⚠️ Les DEUX architectures se compilent à chaque publication, et il n'y a pas d'option
|
||||||
|
# pour n'en faire qu'une. Le manifeste déclare `architectures = ["amd64", "arm64"]` : un
|
||||||
|
# serveur arm64 ira chercher `arm64.url`. Publier une seule archive laisserait le
|
||||||
|
# manifeste promettre une URL que personne n'a téléversée — et l'échec surviendrait chez
|
||||||
|
# celui qui installe, dans `ynh_setup_source`, sans rapport apparent avec la cause.
|
||||||
|
#
|
||||||
|
# ⚠️ Le RID désigne le SERVEUR, jamais la machine qui compile : le SDK télécharge le
|
||||||
|
# runtime pack de la cible, et un hôte arm64 produit un binaire x86-64 sans rien de plus.
|
||||||
|
runtimes=("linux-x64" "linux-arm64")
|
||||||
|
|
||||||
|
# Nom YunoHost de chaque RID .NET — c'est la clé du manifeste (`amd64.url`, `arm64.url`).
|
||||||
|
arch_ynh() {
|
||||||
|
case "$1" in
|
||||||
|
linux-x64) echo "amd64" ;;
|
||||||
|
linux-arm64) echo "arm64" ;;
|
||||||
|
*) echoerr "RID sans architecture YunoHost connue : $1"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<'FIN'
|
cat <<'FIN'
|
||||||
Usage : publier.sh [options]
|
Usage : publier.sh [options]
|
||||||
|
|
||||||
--version X.Y.Z Version à publier (sinon : demandée, à partir de la précédente)
|
--version X.Y.Z Version à publier (sinon : demandée, à partir de la précédente)
|
||||||
--patch Incrémenter le dernier chiffre (0.3.0 -> 0.3.1)
|
--patch Incrémenter le dernier chiffre (1.0.0 -> 1.0.1)
|
||||||
--minor Incrémenter le chiffre du milieu (0.3.0 -> 0.4.0)
|
--minor Incrémenter le chiffre du milieu (1.0.0 -> 1.1.0)
|
||||||
--major Incrémenter le premier chiffre (0.3.0 -> 1.0.0)
|
--major Incrémenter le premier chiffre (1.0.0 -> 2.0.0)
|
||||||
--oui, -y Ne rien demander (pour une CI)
|
--oui, -y Ne rien demander (pour une CI)
|
||||||
--archive-seule Compiler et archiver SEULEMENT : ni manifeste, ni commit, ni tag.
|
--archive-seule Compiler et archiver SEULEMENT : ni manifeste, ni commit, ni tag.
|
||||||
Pour REPRENDRE une publication à la main après un échec en cours
|
Pour REPRENDRE une publication à la main après un échec en cours
|
||||||
@@ -190,12 +191,10 @@ suivante() { # suivante <version> <patch|minor|major>
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
# ⚠️ Le calcul de la version est le MÊME dans les deux modes, et c'est délibéré.
|
# ⚠️ Le calcul de la version est le MÊME dans les deux modes, et c'est délibéré : une
|
||||||
# `--archive-seule` retombait auparavant sur la version du manifeste, c'est-à-dire sur
|
# reprise après échec veut la version qu'on était en train de publier, c'est-à-dire ce
|
||||||
# celle **déjà publiée** : reprendre une publication à la main reproduisait donc le
|
# que l'incrément propose. Faire retomber `--archive-seule` sur la version du manifeste
|
||||||
# numéro précédent tant qu'on ne passait pas `--version`. Le README devait avertir de ce
|
# reproduirait le numéro DÉJÀ publié tant qu'on ne passerait pas `--version`.
|
||||||
# piège ; il n'existe plus. Une reprise après échec veut la version qu'on était en train
|
|
||||||
# de publier, et c'est exactement ce que l'incrément propose.
|
|
||||||
if [ -z "$precedente" ]; then
|
if [ -z "$precedente" ]; then
|
||||||
echoerr "Aucune version précédente trouvée (ni tag, ni manifest.toml) ; utilisez --version."
|
echoerr "Aucune version précédente trouvée (ni tag, ni manifest.toml) ; utilisez --version."
|
||||||
exit 1
|
exit 1
|
||||||
@@ -239,7 +238,7 @@ fi
|
|||||||
# CE QUI DOIT ÊTRE VRAI AVANT DE COMPILER
|
# CE QUI DOIT ÊTRE VRAI AVANT DE COMPILER
|
||||||
#=================================================
|
#=================================================
|
||||||
|
|
||||||
# ⚠️ Le garde-fou qui manquait le 2026-08-21. Recompiler une version dont le tag existe
|
# ⚠️ Recompiler une version dont le tag existe
|
||||||
# déjà produit une archive qui ne correspond PAS au code que ce tag désigne : la release
|
# déjà produit une archive qui ne correspond PAS au code que ce tag désigne : la release
|
||||||
# se met alors à mentir, et l'écran « À propos » avec elle, sans que rien ne le signale.
|
# se met alors à mentir, et l'écran « À propos » avec elle, sans que rien ne le signale.
|
||||||
if git -C "$source_dir" rev-parse "v$version" >/dev/null 2>&1; then
|
if git -C "$source_dir" rev-parse "v$version" >/dev/null 2>&1; then
|
||||||
@@ -257,11 +256,6 @@ fi
|
|||||||
|
|
||||||
# Le tag va désigner le HEAD du dépôt du code : un travail non committé ne serait donc
|
# Le tag va désigner le HEAD du dépôt du code : un travail non committé ne serait donc
|
||||||
# pas dans la release, alors même que l'archive, elle, le contiendrait.
|
# pas dans la release, alors même que l'archive, elle, le contiendrait.
|
||||||
#
|
|
||||||
# ⚠️ Ce contrôle était auparavant SAUTÉ en `--archive-seule`, qui produisait donc en
|
|
||||||
# silence une archive contenant du travail non committé. Il s'exécute désormais toujours,
|
|
||||||
# et se contente d'avertir quand rien n'est publié : c'est précisément l'écart qu'on veut
|
|
||||||
# voir quand on reprend une publication à la main.
|
|
||||||
if [ -n "$(git -C "$source_dir" status --porcelain)" ]; then
|
if [ -n "$(git -C "$source_dir" status --porcelain)" ]; then
|
||||||
git -C "$source_dir" status --short >&2
|
git -C "$source_dir" status --short >&2
|
||||||
refuser "" \
|
refuser "" \
|
||||||
@@ -311,10 +305,20 @@ travail="$(mktemp -d)"
|
|||||||
# shellcheck disable=SC2064
|
# shellcheck disable=SC2064
|
||||||
trap "rm -rf '$travail'" EXIT
|
trap "rm -rf '$travail'" EXIT
|
||||||
|
|
||||||
publish="$travail/publish"
|
# Une passe complète par architecture : compilation, contrôles, archive. Les trois
|
||||||
|
# blocs sont RIGOUREUSEMENT les mêmes d'une architecture à l'autre — c'est ce qui
|
||||||
|
# garantit qu'une archive arm64 est vérifiée aussi durement qu'une amd64.
|
||||||
|
declare -A sommes=()
|
||||||
|
declare -A urls=()
|
||||||
|
declare -A archives=()
|
||||||
|
|
||||||
|
for runtime in "${runtimes[@]}"; do
|
||||||
|
|
||||||
|
arch="$(arch_ynh "$runtime")"
|
||||||
|
publish="$travail/publish-$runtime"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "=== Compilation self-contained $runtime ==="
|
echo "=== Compilation self-contained $runtime ($arch) ==="
|
||||||
echo " source : $source_dir"
|
echo " source : $source_dir"
|
||||||
echo " version: $version"
|
echo " version: $version"
|
||||||
echo " build : $date_build"
|
echo " build : $date_build"
|
||||||
@@ -325,6 +329,12 @@ echo " build : $date_build"
|
|||||||
# `MaBibli.Api` référence `MaBibli.Client` : le client Blazor WebAssembly est compilé
|
# `MaBibli.Api` référence `MaBibli.Client` : le client Blazor WebAssembly est compilé
|
||||||
# au passage et atterrit dans `wwwroot/`. Un seul publish suffit donc pour les trois
|
# au passage et atterrit dans `wwwroot/`. Un seul publish suffit donc pour les trois
|
||||||
# projets.
|
# projets.
|
||||||
|
#
|
||||||
|
# ⚠️ Le client compilé est le MÊME quelle que soit l'architecture — c'est du WebAssembly,
|
||||||
|
# zbar compris. Seul l'hôte .NET change. On le recompile quand même par architecture
|
||||||
|
# plutôt que de recopier un `wwwroot/` d'une passe à l'autre : le publish est le seul
|
||||||
|
# geste dont on sait qu'il produit un ensemble cohérent, et les contrôles ci-dessous
|
||||||
|
# portent sur ce qu'on archive vraiment, pas sur ce qu'on croit y avoir mis.
|
||||||
dotnet publish "$source_dir/$projet" \
|
dotnet publish "$source_dir/$projet" \
|
||||||
--configuration Release \
|
--configuration Release \
|
||||||
--runtime "$runtime" \
|
--runtime "$runtime" \
|
||||||
@@ -338,10 +348,10 @@ dotnet publish "$source_dir/$projet" \
|
|||||||
#=================================================
|
#=================================================
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "=== Vérification du publish ==="
|
echo "=== Vérification du publish ($arch) ==="
|
||||||
|
|
||||||
if [ ! -x "$publish/$projet" ]; then
|
if [ ! -x "$publish/$projet" ]; then
|
||||||
echoerr "Binaire '$projet' absent ou non exécutable dans le publish."
|
echoerr "Binaire '$projet' absent ou non exécutable dans le publish $runtime."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -349,7 +359,7 @@ fi
|
|||||||
# C'est le défaut qui est passé inaperçu pendant trois phases du projet, faute de
|
# C'est le défaut qui est passé inaperçu pendant trois phases du projet, faute de
|
||||||
# regarder ailleurs que la racine. On le vérifie donc ici, à la source.
|
# regarder ailleurs que la racine. On le vérifie donc ici, à la source.
|
||||||
if [ ! -f "$publish/wwwroot/index.html" ]; then
|
if [ ! -f "$publish/wwwroot/index.html" ]; then
|
||||||
echoerr "wwwroot/index.html absent : le client Blazor n'a pas été embarqué."
|
echoerr "wwwroot/index.html absent : le client Blazor n'a pas été embarqué ($runtime)."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -357,8 +367,8 @@ fi
|
|||||||
# substitué (`blazor.webassembly#[.{fingerprint}].js`) donnerait une page blanche
|
# substitué (`blazor.webassembly#[.{fingerprint}].js`) donnerait une page blanche
|
||||||
# alors que `/` répondrait 200.
|
# alors que `/` répondrait 200.
|
||||||
if grep -q '#\[\.{fingerprint}\]' "$publish/wwwroot/index.html"; then
|
if grep -q '#\[\.{fingerprint}\]' "$publish/wwwroot/index.html"; then
|
||||||
echoerr "index.html contient des placeholders d'empreinte non substitués."
|
echoerr "index.html contient des placeholders d'empreinte non substitués ($runtime)."
|
||||||
echoerr "Voir CLAUDE.md, « Empreintes WASM désactivées »."
|
echoerr "Voir CLAUDE.md, « Les invariants à ne jamais casser »."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -366,12 +376,23 @@ for ressource in $(grep -oE '(src|href)="[^"]+"' "$publish/wwwroot/index.html" \
|
|||||||
| sed -E 's/^(src|href)="//; s/"$//' \
|
| sed -E 's/^(src|href)="//; s/"$//' \
|
||||||
| grep -vE '^(https?:|data:|#|/$|\.$)'); do
|
| grep -vE '^(https?:|data:|#|/$|\.$)'); do
|
||||||
if [ ! -f "$publish/wwwroot/$ressource" ]; then
|
if [ ! -f "$publish/wwwroot/$ressource" ]; then
|
||||||
echoerr "index.html référence '$ressource', absent du publish."
|
echoerr "index.html référence '$ressource', absent du publish ($runtime)."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
echo " binaire, wwwroot et ressources d'index.html : OK"
|
# ⚠️ Le contrôle qui n'existait pas tant qu'il n'y avait qu'une architecture : rien
|
||||||
|
# n'empêche un publish de rendre un binaire de l'architecture de la MACHINE plutôt que
|
||||||
|
# de la cible. Le symptôme serait un service qui refuse de démarrer sur le serveur, avec
|
||||||
|
# un « Exec format error » qui ne désigne pas la publication.
|
||||||
|
attendu_elf="$(case "$runtime" in linux-x64) echo "x86-64" ;; linux-arm64) echo "aarch64" ;; esac)"
|
||||||
|
if ! file -b "$publish/$projet" | grep -q "$attendu_elf"; then
|
||||||
|
echoerr "Le binaire produit n'est pas du $attendu_elf :"
|
||||||
|
echoerr " $(file -b "$publish/$projet")"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " binaire ($attendu_elf), wwwroot et ressources d'index.html : OK"
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# ARCHIVE
|
# ARCHIVE
|
||||||
@@ -382,7 +403,7 @@ mkdir -p "$output_dir"
|
|||||||
archive="$output_dir/$archive_nom"
|
archive="$output_dir/$archive_nom"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "=== Archive ==="
|
echo "=== Archive ($arch) ==="
|
||||||
|
|
||||||
# Fichiers à la racine de l'archive, sans dossier intermédiaire : cohérent avec
|
# Fichiers à la racine de l'archive, sans dossier intermédiaire : cohérent avec
|
||||||
# `in_subdir = false` dans manifest.toml.
|
# `in_subdir = false` dans manifest.toml.
|
||||||
@@ -406,16 +427,27 @@ echo " fichier : $archive"
|
|||||||
echo " taille : $taille ($taille_octets octets)"
|
echo " taille : $taille ($taille_octets octets)"
|
||||||
echo " sha256 : $somme"
|
echo " sha256 : $somme"
|
||||||
|
|
||||||
url_archive="$base_url/v$version/$archive_nom"
|
sommes[$arch]="$somme"
|
||||||
|
archives[$arch]="$archive"
|
||||||
|
urls[$arch]="$base_url/v$version/$archive_nom"
|
||||||
|
|
||||||
|
# Le publish pèse ~150 Mo : le garder pendant la passe suivante doublerait l'occupation
|
||||||
|
# du disque pour rien, l'archive étant déjà produite.
|
||||||
|
rm -rf "$publish"
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
if [ "$archive_seule" -eq 1 ]; then
|
if [ "$archive_seule" -eq 1 ]; then
|
||||||
|
echo
|
||||||
|
echo "=== Terminé (--archive-seule) ==="
|
||||||
|
echo
|
||||||
|
for runtime in "${runtimes[@]}"; do
|
||||||
|
arch="$(arch_ynh "$runtime")"
|
||||||
|
echo " $arch : ${archives[$arch]}"
|
||||||
|
echo " sha256 ${sommes[$arch]}"
|
||||||
|
done
|
||||||
cat <<FIN
|
cat <<FIN
|
||||||
|
|
||||||
=== Terminé (--archive-seule) ===
|
|
||||||
|
|
||||||
Archive prête : $archive
|
|
||||||
sha256 : $somme
|
|
||||||
|
|
||||||
Rien n'a été publié : manifest.toml est inchangé, aucun commit, aucun tag.
|
Rien n'a été publié : manifest.toml est inchangé, aucun commit, aucun tag.
|
||||||
Pour publier réellement cette version, relancez sans --archive-seule.
|
Pour publier réellement cette version, relancez sans --archive-seule.
|
||||||
|
|
||||||
@@ -441,17 +473,31 @@ else
|
|||||||
echo " version : $version_actuelle -> $version_paquet"
|
echo " version : $version_actuelle -> $version_paquet"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
python3 - "$manifeste" "$version_paquet" "$url_archive" "$somme" <<'PY'
|
# Les architectures sont passées à plat : arch, url, sha256, arch, url, sha256…
|
||||||
|
arguments=()
|
||||||
|
for runtime in "${runtimes[@]}"; do
|
||||||
|
arch="$(arch_ynh "$runtime")"
|
||||||
|
arguments+=("$arch" "${urls[$arch]}" "${sommes[$arch]}")
|
||||||
|
done
|
||||||
|
|
||||||
|
python3 - "$manifeste" "$version_paquet" "${arguments[@]}" <<'PY'
|
||||||
import re, sys
|
import re, sys
|
||||||
|
|
||||||
chemin, version, url, somme = sys.argv[1:5]
|
chemin, version = sys.argv[1:3]
|
||||||
|
reste = sys.argv[3:]
|
||||||
with open(chemin, encoding="utf-8") as f:
|
with open(chemin, encoding="utf-8") as f:
|
||||||
texte = f.read()
|
texte = f.read()
|
||||||
|
|
||||||
remplacements = [
|
remplacements = [(r'^version = ".*"$', f'version = "{version}"')]
|
||||||
(r'^version = ".*"$', f'version = "{version}"'),
|
|
||||||
(r'^ amd64\.url = ".*"$', f' amd64.url = "{url}"'),
|
# ⚠️ Chaque motif DOIT correspondre exactement une fois. Une architecture déclarée au
|
||||||
(r'^ amd64\.sha256 = ".*"$', f' amd64.sha256 = "{somme}"'),
|
# manifeste mais absente d'ici laisserait une URL périmée pointer sur la version
|
||||||
|
# précédente : le serveur téléchargerait une archive réelle, dont le sha256 ne
|
||||||
|
# correspondrait pas — ou pire, correspondrait, et installerait l'ancienne version.
|
||||||
|
for arch, url, somme in zip(reste[0::3], reste[1::3], reste[2::3]):
|
||||||
|
remplacements += [
|
||||||
|
(rf'^ {arch}\.url = ".*"$', f' {arch}.url = "{url}"'),
|
||||||
|
(rf'^ {arch}\.sha256 = ".*"$', f' {arch}.sha256 = "{somme}"'),
|
||||||
]
|
]
|
||||||
|
|
||||||
for motif, valeur in remplacements:
|
for motif, valeur in remplacements:
|
||||||
@@ -463,8 +509,11 @@ with open(chemin, "w", encoding="utf-8") as f:
|
|||||||
f.write(texte)
|
f.write(texte)
|
||||||
PY
|
PY
|
||||||
|
|
||||||
echo " url : $url_archive"
|
for runtime in "${runtimes[@]}"; do
|
||||||
echo " sha256 : $somme"
|
arch="$(arch_ynh "$runtime")"
|
||||||
|
echo " $arch : ${urls[$arch]}"
|
||||||
|
echo " sha256 ${sommes[$arch]}"
|
||||||
|
done
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# LE PAQUET (le serveur lit Gitea, jamais la copie locale)
|
# LE PAQUET (le serveur lit Gitea, jamais la copie locale)
|
||||||
@@ -513,15 +562,16 @@ cat <<FIN
|
|||||||
=== Publié : $version ===
|
=== Publié : $version ===
|
||||||
|
|
||||||
Il ne reste qu'une chose, dans Gitea : créer la release v$version et y téléverser
|
Il ne reste qu'une chose, dans Gitea : créer la release v$version et y téléverser
|
||||||
l'archive.
|
LES DEUX archives. Une seule des deux téléversée, et le manifeste promet à l'autre
|
||||||
|
architecture une URL qui répondra 404 à l'installation.
|
||||||
|
|
||||||
Releases : $url_releases
|
Releases : $url_releases
|
||||||
Archive : $archive
|
$(for r in "${runtimes[@]}"; do a="$(arch_ynh "$r")"; echo " $a : ${archives[$a]}"; done)
|
||||||
|
|
||||||
Ensuite, vérifier que le manifeste pointe sur un fichier réellement téléchargeable
|
Ensuite, vérifier que le manifeste pointe sur des fichiers réellement téléchargeables
|
||||||
(sans être authentifié) :
|
(sans être authentifié) :
|
||||||
|
|
||||||
curl -fsSLI "$url_archive" | head -1
|
$(for r in "${runtimes[@]}"; do a="$(arch_ynh "$r")"; echo " curl -fsSLI \"${urls[$a]}\" | head -1"; done)
|
||||||
|
|
||||||
Puis, sur le serveur :
|
Puis, sur le serveur :
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=MaBibli — gestion de bibliothèque personnelle
|
Description=MaBibli — gestion de bibliothèque personnelle
|
||||||
Documentation=https://git.akbar.nohost.me/mathieu/mabibli
|
Documentation=https://forge.example.org/mabibli
|
||||||
After=network.target
|
After=network.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
|
|||||||
+1
-1
@@ -65,4 +65,4 @@ sqlite3 /home/yunohost.app/mabibli/mabibli.db ".backup '/quelque/part/mabibli.db
|
|||||||
---
|
---
|
||||||
|
|
||||||
Le détail — conception du paquet, publication, mise à jour pas à pas, retour arrière —
|
Le détail — conception du paquet, publication, mise à jour pas à pas, retour arrière —
|
||||||
est dans le [README du dépôt du code](https://git.akbar.nohost.me/mathieu/mabibli#readme).
|
est dans le [README du dépôt du code](https://forge.example.org/mabibli#readme).
|
||||||
|
|||||||
+18
-11
@@ -7,7 +7,7 @@ name = "MaBibli"
|
|||||||
description.fr = "Gestion de bibliothèque personnelle : catalogue, prêts et scan ISBN"
|
description.fr = "Gestion de bibliothèque personnelle : catalogue, prêts et scan ISBN"
|
||||||
description.en = "Personal library manager: catalogue, loans and ISBN scanning"
|
description.en = "Personal library manager: catalogue, loans and ISBN scanning"
|
||||||
|
|
||||||
version = "1.1.0~ynh1"
|
version = "1.0.0~ynh1"
|
||||||
|
|
||||||
maintainers = ["mathieu"]
|
maintainers = ["mathieu"]
|
||||||
|
|
||||||
@@ -19,10 +19,13 @@ code = "https://git.akbar.nohost.me/mathieu/mabibli"
|
|||||||
yunohost = ">= 12.1.38"
|
yunohost = ">= 12.1.38"
|
||||||
helpers_version = "2.1"
|
helpers_version = "2.1"
|
||||||
|
|
||||||
# x86_64 uniquement : CLAUDE.md acte un serveur PC/VPS, et la chaîne de publication
|
# ⚠️ Une architecture déclarée ici DOIT avoir son archive dans la release : YunoHost
|
||||||
# ne produit qu'un binaire `linux-x64`. Déclarer d'autres architectures promettrait
|
# choisit `<arch>.url` d'après la machine, et une URL manquante échoue chez celui qui
|
||||||
# des archives qui n'existent pas.
|
# installe, dans `ynh_setup_source`. `build/publier.sh` compile les deux à chaque
|
||||||
architectures = ["amd64"]
|
# publication, précisément pour qu'aucune des deux ne puisse être oubliée.
|
||||||
|
#
|
||||||
|
# armhf (32 bits) n'est PAS déclarée : .NET ne la prend plus en charge.
|
||||||
|
architectures = ["amd64", "arm64"]
|
||||||
|
|
||||||
# Une seule instance : la bibliothèque est commune au foyer (CLAUDE.md, « Portée des
|
# 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
|
# données »). Deux instances voudraient dire deux collections étanches, ce qui est
|
||||||
@@ -99,14 +102,18 @@ ram.runtime = "256M"
|
|||||||
[resources]
|
[resources]
|
||||||
|
|
||||||
[resources.sources.main]
|
[resources.sources.main]
|
||||||
# Archive **déjà compilée** (publish self-contained linux-x64), produite par
|
# Archives **déjà compilées** (publish self-contained), produites par
|
||||||
# `build/publier.sh` et déposée en release sur le Gitea de l'utilisateur.
|
# `build/publier.sh` et déposées 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
|
# 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 »).
|
# self-contained (CLAUDE.md, « Décisions techniques actées »).
|
||||||
#
|
#
|
||||||
# Ces deux valeurs sont réécrites par `build/publier.sh`.
|
# YunoHost retient la ligne correspondant à l'architecture de la machine.
|
||||||
amd64.url = "https://git.akbar.nohost.me/mathieu/mabibli/releases/download/v1.1.0/mabibli-1.1.0-linux-x64.tar.gz"
|
#
|
||||||
amd64.sha256 = "cb151491b408176ff67ed5dccda47737aaa13227ea6d84dac4340f9a60e5b83a"
|
# ⚠️ Ces quatre valeurs sont réécrites par `build/publier.sh`, jamais à la main.
|
||||||
|
amd64.url = "https://git.akbar.nohost.me/mathieu/mabibli/releases/download/v1.0.0/mabibli-1.0.0-linux-x64.tar.gz"
|
||||||
|
amd64.sha256 = "2a405d58fad19faf2860857de7305a37918f903f528fc190d71f6b150f5da332"
|
||||||
|
arm64.url = "https://git.akbar.nohost.me/mathieu/mabibli/releases/download/v1.0.0/mabibli-1.0.0-linux-arm64.tar.gz"
|
||||||
|
arm64.sha256 = "51de1819543389a431861ed25099738937092d5947e7ce54afc0f348968b9dfd"
|
||||||
|
|
||||||
# L'archive dépose ses fichiers à la racine, sans dossier intermédiaire.
|
# L'archive dépose ses fichiers à la racine, sans dossier intermédiaire.
|
||||||
in_subdir = false
|
in_subdir = false
|
||||||
|
|||||||
Reference in New Issue
Block a user