#!/usr/bin/env bash # Attache des fichiers à une release Gitea, de façon idempotente (re-run friendly). # # Usage : attach-release-assets.sh # Env : RELEASE_TOKEN (token Gitea avec write:repository), GITHUB_SERVER_URL, GITHUB_REPOSITORY. # # Partagé par tous les jobs de release desktop (Linux, Windows, canal flottant) : la logique était # dupliquée dans chaque job, et toute correction devait être faite trois fois. set -uo pipefail tag="${1:?tag manquant}" release_name="${2:?nom de release manquant}" shift 2 # Token ABSENT : cas légitime (fork, run sans secret) → on sort proprement. # Token PRÉSENT mais refusé par l'API : anomalie, on doit ÉCHOUER. Sinon le job reste vert alors # qu'aucun asset n'est attaché et qu'aucune release n'est créée, ce qui s'est produit avec un token # expiré : trois workflows « réussis » et zéro fichier publié. if [ -z "${RELEASE_TOKEN:-}" ]; then echo "::notice::RELEASE_TOKEN absent, aucun asset attaché (les artefacts du run restent disponibles)." exit 0 fi api="${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}" auth="Authorization: token ${RELEASE_TOKEN}" release_id=$(curl -fsSL -H "$auth" "${api}/releases/tags/${tag}" \ | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).id || ''" || true) if [ -z "$release_id" ]; then release_id=$(curl -fsSL -X POST -H "$auth" -H 'Content-Type: application/json' \ -d "{\"tag_name\":\"${tag}\",\"name\":\"${release_name}\"}" \ "${api}/releases" | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).id || ''") fi if [ -z "$release_id" ]; then echo "::error::impossible de résoudre ou créer la release ${tag} avec le token fourni." echo "::error::vérifier que le secret porte les portées write:repository et write:package, et qu'il n'a pas expiré." exit 1 fi for f in "$@"; do [ -f "$f" ] || continue name=$(basename "$f") # L'API Gitea refuse un asset de même nom : on supprime l'ancien pour que le dernier build gagne. existing=$(curl -fsSL -H "$auth" "${api}/releases/${release_id}/assets" \ | node -e "const a=JSON.parse(require('fs').readFileSync(0,'utf8'));const m=Array.isArray(a)?a.find(x=>x.name===process.argv[1]):null;process.stdout.write(m?String(m.id):'')" "$name" || true) if [ -n "$existing" ]; then echo "replacing existing $name (asset $existing)" curl -fsSL -X DELETE -H "$auth" "${api}/releases/${release_id}/assets/${existing}" || true fi echo "attaching $name" if ! curl -fsSL -X POST -H "$auth" -F "attachment=@${f}" "${api}/releases/${release_id}/assets?name=${name}"; then echo "::error::échec de l'upload de ${name}" failed=1 fi done if [ "${failed:-0}" != "0" ]; then echo "::error::au moins un asset n'a pas pu être attaché à ${tag}." exit 1 fi echo "Assets attachés à la release ${tag}."