premier essaie
This commit is contained in:
BIN
Binary file not shown.
Executable
+272
@@ -0,0 +1,272 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Produit l'archive de release de MaBibli et met à jour manifest.toml.
|
||||
#
|
||||
# Pourquoi ce script vit dans `mabibli_ynh` et non dans `mabibli` :
|
||||
# sa sortie utile n'est pas l'archive, c'est le couple (url, sha256) que le
|
||||
# manifeste doit porter. Le garder ici permet de compiler, d'archiver et de mettre à
|
||||
# jour le manifeste en une commande, puis de committer le tout d'un bloc — le
|
||||
# manifeste ne peut pas se désynchroniser de l'archive qu'il décrit.
|
||||
#
|
||||
# Réutilisable en CI (Gitea Actions) sans modification : aucune interaction, aucune
|
||||
# variable propre à un environnement d'intégration, tout passe par des options ou des
|
||||
# variables d'environnement, et le script échoue au premier problème.
|
||||
#
|
||||
# Exemple d'usage en CI :
|
||||
# ./build/publier-release.sh \
|
||||
# --source-dir "$GITHUB_WORKSPACE/mabibli" \
|
||||
# --version 0.2.0 \
|
||||
# --base-url "https://gitea.exemple.org/mathieu/mabibli/releases/download"
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
#=================================================
|
||||
# VALEURS PAR DÉFAUT
|
||||
#=================================================
|
||||
|
||||
racine_paquet="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
|
||||
source_dir="${MABIBLI_SOURCE_DIR:-$(cd "$racine_paquet/../mabibli" 2>/dev/null && pwd || true)}"
|
||||
version="${MABIBLI_VERSION:-}"
|
||||
base_url="${MABIBLI_BASE_URL:-https://gitea.example.org/mathieu/mabibli/releases/download}"
|
||||
output_dir="${MABIBLI_OUTPUT_DIR:-$racine_paquet/build/dist}"
|
||||
maj_manifeste=1
|
||||
runtime="linux-x64"
|
||||
projet="MaBibli.Api"
|
||||
|
||||
#=================================================
|
||||
# OPTIONS
|
||||
#=================================================
|
||||
|
||||
usage() {
|
||||
cat <<'FIN'
|
||||
Usage : publier-release.sh [options]
|
||||
|
||||
--source-dir CHEMIN Dépôt du code C# (défaut : ../mabibli)
|
||||
--version X.Y.Z Version de la release (défaut : déduite de manifest.toml)
|
||||
--base-url URL Racine des URL de release, sans le tag ni le fichier
|
||||
--output-dir CHEMIN Où déposer l'archive (défaut : build/dist)
|
||||
--no-manifest-update Ne pas réécrire manifest.toml
|
||||
-h, --help Cette aide
|
||||
|
||||
Variables d'environnement équivalentes : MABIBLI_SOURCE_DIR, MABIBLI_VERSION,
|
||||
MABIBLI_BASE_URL, MABIBLI_OUTPUT_DIR.
|
||||
FIN
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--source-dir) source_dir="$2"; shift 2 ;;
|
||||
--version) version="$2"; shift 2 ;;
|
||||
--base-url) base_url="$2"; shift 2 ;;
|
||||
--output-dir) output_dir="$2"; shift 2 ;;
|
||||
--no-manifest-update) maj_manifeste=0; shift ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "Option inconnue : $1" >&2; usage >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
manifeste="$racine_paquet/manifest.toml"
|
||||
|
||||
#=================================================
|
||||
# CONTRÔLES PRÉALABLES
|
||||
#=================================================
|
||||
|
||||
echoerr() { echo "$@" >&2; }
|
||||
|
||||
if [ -z "$source_dir" ] || [ ! -d "$source_dir" ]; then
|
||||
echoerr "Dépôt du code introuvable : '${source_dir:-<vide>}'"
|
||||
echoerr "Précisez-le avec --source-dir."
|
||||
exit 1
|
||||
fi
|
||||
source_dir="$(cd "$source_dir" && pwd)"
|
||||
|
||||
if [ ! -d "$source_dir/$projet" ]; then
|
||||
echoerr "'$source_dir' ne contient pas de projet $projet."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v dotnet >/dev/null; then
|
||||
echoerr "Le SDK .NET est introuvable. Il n'est nécessaire QUE sur cette machine :"
|
||||
echoerr "le serveur YunoHost reçoit un publish self-contained et n'a pas de SDK."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# La version par défaut se lit dans le manifeste, en retirant le suffixe ~ynhN :
|
||||
# le tag et le nom de fichier portent la version applicative, pas celle du paquet.
|
||||
if [ -z "$version" ]; then
|
||||
version="$(sed -n 's/^version *= *"\([^"~]*\).*"/\1/p' "$manifeste" | head -1)"
|
||||
if [ -z "$version" ]; then
|
||||
echoerr "Impossible de déduire la version depuis $manifeste ; utilisez --version."
|
||||
exit 1
|
||||
fi
|
||||
echo "Version déduite de manifest.toml : $version"
|
||||
fi
|
||||
|
||||
#=================================================
|
||||
# COMPILATION
|
||||
#=================================================
|
||||
|
||||
travail="$(mktemp -d)"
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '$travail'" EXIT
|
||||
|
||||
publish="$travail/publish"
|
||||
|
||||
echo
|
||||
echo "=== Compilation self-contained $runtime ==="
|
||||
echo " source : $source_dir"
|
||||
echo " version: $version"
|
||||
|
||||
# `--self-contained` embarque le runtime .NET dans le dossier publié : c'est ce qui
|
||||
# permet au paquet YunoHost de ne dépendre d'aucun `dotnet-runtime` côté serveur.
|
||||
#
|
||||
# `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
|
||||
# projets.
|
||||
dotnet publish "$source_dir/$projet" \
|
||||
--configuration Release \
|
||||
--runtime "$runtime" \
|
||||
--self-contained \
|
||||
--output "$publish" \
|
||||
-p:Version="$version"
|
||||
|
||||
#=================================================
|
||||
# CONTRÔLES SUR LE RÉSULTAT
|
||||
#=================================================
|
||||
|
||||
echo
|
||||
echo "=== Vérification du publish ==="
|
||||
|
||||
if [ ! -x "$publish/$projet" ]; then
|
||||
echoerr "Binaire '$projet' absent ou non exécutable dans le publish."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Sans `wwwroot`, le service démarrerait et répondrait — en ne servant aucune page.
|
||||
# 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.
|
||||
if [ ! -f "$publish/wwwroot/index.html" ]; then
|
||||
echoerr "wwwroot/index.html absent : le client Blazor n'a pas été embarqué."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# `index.html` doit référencer un script réellement présent. Un placeholder non
|
||||
# substitué (`blazor.webassembly#[.{fingerprint}].js`) donnerait une page blanche
|
||||
# alors que `/` répondrait 200.
|
||||
if grep -q '#\[\.{fingerprint}\]' "$publish/wwwroot/index.html"; then
|
||||
echoerr "index.html contient des placeholders d'empreinte non substitués."
|
||||
echoerr "Voir CLAUDE.md, « Empreintes WASM désactivées »."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for ressource in $(grep -oE '(src|href)="[^"]+"' "$publish/wwwroot/index.html" \
|
||||
| sed -E 's/^(src|href)="//; s/"$//' \
|
||||
| grep -vE '^(https?:|data:|#|/$|\.$)'); do
|
||||
if [ ! -f "$publish/wwwroot/$ressource" ]; then
|
||||
echoerr "index.html référence '$ressource', absent du publish."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo " binaire, wwwroot et ressources d'index.html : OK"
|
||||
|
||||
#=================================================
|
||||
# ARCHIVE
|
||||
#=================================================
|
||||
|
||||
archive_nom="mabibli-$version-$runtime.tar.gz"
|
||||
mkdir -p "$output_dir"
|
||||
archive="$output_dir/$archive_nom"
|
||||
|
||||
echo
|
||||
echo "=== Archive ==="
|
||||
|
||||
# Fichiers à la racine de l'archive, sans dossier intermédiaire : cohérent avec
|
||||
# `in_subdir = false` dans manifest.toml.
|
||||
#
|
||||
# Options de reproductibilité : sans elles, deux compilations identiques donneraient
|
||||
# deux sha256 différents (dates, ordre de parcours, uid/gid). En CI comme en local,
|
||||
# on veut pouvoir vérifier qu'une archive correspond bien à un commit.
|
||||
tar --create --gzip \
|
||||
--file="$archive" \
|
||||
--directory="$publish" \
|
||||
--owner=0 --group=0 --numeric-owner \
|
||||
--mtime="@${SOURCE_DATE_EPOCH:-0}" \
|
||||
--sort=name \
|
||||
.
|
||||
|
||||
somme="$(sha256sum "$archive" | cut -d' ' -f1)"
|
||||
taille="$(du -h "$archive" | cut -f1)"
|
||||
taille_octets="$(stat -c%s "$archive")"
|
||||
|
||||
echo " fichier : $archive"
|
||||
echo " taille : $taille ($taille_octets octets)"
|
||||
echo " sha256 : $somme"
|
||||
|
||||
#=================================================
|
||||
# MISE À JOUR DU MANIFESTE
|
||||
#=================================================
|
||||
|
||||
url="$base_url/v$version/$archive_nom"
|
||||
|
||||
if [ "$maj_manifeste" -eq 1 ]; then
|
||||
echo
|
||||
echo "=== Mise à jour de manifest.toml ==="
|
||||
|
||||
# Le suffixe ~ynhN est conservé s'il existe déjà pour cette version, sinon
|
||||
# remis à ~ynh1 : un changement de version applicative repart toujours de 1.
|
||||
version_actuelle="$(sed -n 's/^version *= *"\([^"]*\)".*/\1/p' "$manifeste" | head -1)"
|
||||
if [[ "$version_actuelle" == "$version~ynh"* ]]; then
|
||||
version_paquet="$version_actuelle"
|
||||
echo " version : $version_paquet (inchangée)"
|
||||
else
|
||||
version_paquet="$version~ynh1"
|
||||
echo " version : $version_actuelle -> $version_paquet"
|
||||
fi
|
||||
|
||||
python3 - "$manifeste" "$version_paquet" "$url" "$somme" <<'PY'
|
||||
import re, sys
|
||||
|
||||
chemin, version, url, somme = sys.argv[1:5]
|
||||
with open(chemin, encoding="utf-8") as f:
|
||||
texte = f.read()
|
||||
|
||||
remplacements = [
|
||||
(r'^version = ".*"$', f'version = "{version}"'),
|
||||
(r'^ amd64\.url = ".*"$', f' amd64.url = "{url}"'),
|
||||
(r'^ amd64\.sha256 = ".*"$', f' amd64.sha256 = "{somme}"'),
|
||||
]
|
||||
|
||||
for motif, valeur in remplacements:
|
||||
texte, n = re.subn(motif, valeur, texte, count=1, flags=re.MULTILINE)
|
||||
if n != 1:
|
||||
sys.exit(f"Motif introuvable dans le manifeste : {motif}")
|
||||
|
||||
with open(chemin, "w", encoding="utf-8") as f:
|
||||
f.write(texte)
|
||||
PY
|
||||
|
||||
echo " url : $url"
|
||||
echo " sha256 : $somme"
|
||||
fi
|
||||
|
||||
#=================================================
|
||||
# SUITE À DONNER
|
||||
#=================================================
|
||||
|
||||
cat <<FIN
|
||||
|
||||
=== Terminé ===
|
||||
|
||||
Archive prête : $archive
|
||||
|
||||
Il reste à faire, à la main (le dépôt Gitea et la release ne sont pas automatisés) :
|
||||
|
||||
1. Créer le tag v$version sur le dépôt du code, puis la release correspondante.
|
||||
2. Y téléverser $archive_nom.
|
||||
3. Vérifier que l'URL du manifeste répond :
|
||||
curl -fsSLI "$url"
|
||||
4. Committer manifest.toml dans mabibli_ynh.
|
||||
|
||||
FIN
|
||||
Reference in New Issue
Block a user