#!/bin/bash # # Publie une version de MaBibli de bout en bout, en une commande. # # Enchaîne ce qui était jusqu'ici tapé à la main, toujours dans le même ordre : # # 1. produire l'archive et mettre à jour manifest.toml (publier-release.sh) # 2. committer et pousser mabibli_ynh (le serveur lit Gitea, pas le local) # 3. taguer et pousser mabibli (le tag porte le code de la release) # # La version se choisit ici, à partir de celle déjà publiée : rien à aller chercher. # La seule chose qui reste manuelle est le dépôt de l'archive dans la release Gitea — # l'URL est rappelée en fin de sortie. # set -euo pipefail racine_paquet="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" manifeste="$racine_paquet/manifest.toml" source_dir="${MABIBLI_SOURCE_DIR:-$(cd "$racine_paquet/../mabibli" 2>/dev/null && pwd || true)}" base_url="${MABIBLI_BASE_URL:-https://git.akbar.nohost.me/mathieu/mabibli/releases/download}" url_releases="${MABIBLI_URL_RELEASES:-https://git.akbar.nohost.me/mathieu/mabibli/releases}" version="" increment="" sans_confirmation=0 usage() { cat <<'FIN' Usage : publier.sh [options] --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) --minor Incrémenter le chiffre du milieu (0.3.0 -> 0.4.0) --major Incrémenter le premier chiffre (0.3.0 -> 1.0.0) --oui Ne rien demander (pour une CI) -h, --help Cette aide FIN } while [ $# -gt 0 ]; do case "$1" in --version) version="$2"; shift 2 ;; --patch|--minor|--major) increment="${1#--}"; shift ;; --oui|-y) sans_confirmation=1; shift ;; -h|--help) usage; exit 0 ;; *) echo "Option inconnue : $1" >&2; usage >&2; exit 2 ;; esac done echoerr() { echo "$@" >&2; } if [ -z "$source_dir" ] || [ ! -d "$source_dir/.git" ]; then echoerr "Dépôt du code introuvable : '${source_dir:-}' (MABIBLI_SOURCE_DIR)." exit 1 fi #================================================= # LA VERSION PRÉCÉDENTE, DEUX SOURCES QUI DOIVENT S'ACCORDER #================================================= # Le tag fait foi : c'est lui qui désigne le code publié. Le manifeste ne porte que la # dernière version *empaquetée*, qui peut être en retard si une publication a échoué en # cours de route. On prend le plus élevé des deux pour ne jamais proposer un numéro déjà pris. version_tag="$(git -C "$source_dir" tag --list 'v[0-9]*' --sort=-v:refname | head -1 | sed 's/^v//')" version_manifeste="$(sed -n 's/^version *= *"\([^"~]*\).*"/\1/p' "$manifeste" | head -1)" precedente="$(printf '%s\n%s\n' "$version_tag" "$version_manifeste" \ | grep -E '^[0-9]+(\.[0-9]+)*$' | sort -V | tail -1)" if [ -z "$precedente" ]; then echoerr "Aucune version précédente trouvée (ni tag, ni manifest.toml) ; utilisez --version." exit 1 fi echo "Dernière version publiée : $precedente" [ "$version_tag" != "$version_manifeste" ] && echo " ⚠ tag v${version_tag:-—} et manifest.toml ${version_manifeste:-—} divergent" suivante() { # suivante IFS=. read -r maj min cor <<<"$1" case "$2" in major) echo "$((maj + 1)).0.0" ;; minor) echo "$maj.$((min + 1)).0" ;; patch) echo "$maj.$min.$((cor + 1))" ;; esac } if [ -z "$version" ] && [ -n "$increment" ]; then version="$(suivante "$precedente" "$increment")" fi if [ -z "$version" ]; then if [ "$sans_confirmation" -eq 1 ] || [ ! -t 0 ]; then echoerr "Pas de terminal pour demander la version ; utilisez --version ou --patch/--minor/--major." exit 1 fi echo echo " 1) $(suivante "$precedente" patch) (correction)" echo " 2) $(suivante "$precedente" minor) (nouveautés)" echo " 3) $(suivante "$precedente" major) (rupture)" echo " 4) autre — à saisir" echo read -rp "Version à publier [1] ? " choix case "${choix:-1}" in 1) version="$(suivante "$precedente" patch)" ;; 2) version="$(suivante "$precedente" minor)" ;; 3) version="$(suivante "$precedente" major)" ;; 4) read -rp "Numéro de version : " version ;; *) version="$choix" ;; # un numéro tapé directement passe aussi esac fi if ! [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echoerr "Version invalide : '$version' (attendu X.Y.Z)." exit 1 fi if git -C "$source_dir" rev-parse "v$version" >/dev/null 2>&1; then echoerr "Le tag v$version existe déjà dans $source_dir." exit 1 fi #================================================= # CE QUI DOIT ÊTRE VRAI AVANT DE COMPILER #================================================= # 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. if [ -n "$(git -C "$source_dir" status --porcelain)" ]; then echoerr "Le dépôt du code a des modifications non committées :" git -C "$source_dir" status --short >&2 exit 1 fi branche="$(git -C "$source_dir" rev-parse --abbrev-ref HEAD)" echo echo "=== À publier ===" echo " version : $precedente -> $version" echo " code : $source_dir ($branche, $(git -C "$source_dir" rev-parse --short HEAD))" echo " paquet : $racine_paquet" if [ "$sans_confirmation" -ne 1 ]; then read -rp "Continuer ? [O/n] " reponse case "${reponse:-o}" in [oO]*) ;; *) echo "Abandon."; exit 1 ;; esac fi #================================================= # 1. ARCHIVE + MANIFESTE #================================================= "$racine_paquet/build/publier-release.sh" --version "$version" --source-dir "$source_dir" --base-url "$base_url" archive_nom="mabibli-$version-linux-x64.tar.gz" archive="${MABIBLI_OUTPUT_DIR:-$racine_paquet/build/dist}/$archive_nom" #================================================= # 2. LE PAQUET (le serveur lit Gitea, jamais la copie locale) #================================================= echo echo "=== Paquet : commit et push ===" git -C "$racine_paquet" add -A if git -C "$racine_paquet" diff --cached --quiet; then echo " rien à committer (manifeste déjà à jour)" else git -C "$racine_paquet" commit -m "Publier la version $version" fi git -C "$racine_paquet" push #================================================= # 3. LE CODE : tag et push #================================================= echo echo "=== Code : tag v$version et push ===" git -C "$source_dir" tag "v$version" git -C "$source_dir" push origin "$branche" --tags # Un push qui échoue à demi ne se voit pas dans la sortie de git : on redemande au distant. verifier_pousse() { # verifier_pousse if git -C "$1" ls-remote --exit-code origin "$2" >/dev/null 2>&1; then echo " ✓ $2 présent sur origin" else echoerr " ✗ $2 ABSENT sur origin — le push n'a pas abouti." exit 1 fi } echo echo "=== Vérification côté distant ===" verifier_pousse "$source_dir" "refs/tags/v$version" verifier_pousse "$racine_paquet" "refs/heads/$(git -C "$racine_paquet" rev-parse --abbrev-ref HEAD)" #================================================= # CE QUI RESTE À FAIRE À LA MAIN #================================================= url_archive="$base_url/v$version/$archive_nom" cat <