ci(forgejo): build JSON bodies in pure bash, no python3

L'image runner pazof/yavsc-build-env n'a pas python3 (ni jq, ni
node). Le step de publication Forgejo utilisait python3 pour générer
les bodies JSON (POST /releases, PATCH /releases/{id}) et pour
extraire le 'id' de la réponse.

Fix : deux fonctions bash :
- json_escape : escaping JSON des chaînes (\\, \", \n, \r, \t)
- json_field : extraction d'un champ scalaire d'un fichier JSON via sed

Suffisant pour les bodies qu'on envoie (tag_name, name, body,
prerelease) et les champs qu'on lit (id).
This commit is contained in:
Paul Schneider 2026-08-17 02:16:46 +01:00
commit 2df364aa1e
Signed by: notazof
GPG key ID: 1DD5D838E5343B06

View file

@ -222,6 +222,28 @@ jobs:
API_BASE="${GITHUB_API_URL%/}" API_BASE="${GITHUB_API_URL%/}"
API_BASE="${API_BASE%/api/v1}" API_BASE="${API_BASE%/api/v1}"
# Pas de python3, pas de jq dans l'image runner. On génère
# le JSON à la main : escaping minimal des caractères
# spéciaux JSON dans les chaînes (\\, \", \n, \r, \t).
# Suffisant pour un CHANGELOG.md bien formé.
json_escape() {
local s="$1"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//$'\n'/\\n}"
s="${s//$'\r'/\\r}"
s="${s//$'\t'/\\t}"
printf '%s' "$s"
}
# Extraction d'un champ JSON scalaire (string ou number) depuis
# un fichier. Utilise sed basique, suffisant pour les champs
# id / tag_name que l'API renvoie en clair.
json_field() {
local file="$1" field="$2"
sed -n "s/.*\"$field\"[[:space:]]*:[[:space:]]*\"\?\([^\",}]*\)\"\?.*/\1/p" "$file" | head -1
}
# 1. Vérifier si la release existe déjà pour ce tag. # 1. Vérifier si la release existe déjà pour ce tag.
echo "::group::Check existing release for tag $TAG" echo "::group::Check existing release for tag $TAG"
HTTP=$(curl -sS -o /tmp/existing.json -w '%{http_code}' \ HTTP=$(curl -sS -o /tmp/existing.json -w '%{http_code}' \
@ -231,17 +253,16 @@ jobs:
echo "GET releases/tags/$TAG -> HTTP $HTTP" echo "GET releases/tags/$TAG -> HTTP $HTTP"
EXISTING_ID="" EXISTING_ID=""
if [[ "$HTTP" == "200" ]]; then if [[ "$HTTP" == "200" ]]; then
EXISTING_ID=$(python3 -c "import json,sys; print(json.load(open('/tmp/existing.json')).get('id',''))" 2>/dev/null || true) EXISTING_ID=$(json_field /tmp/existing.json id)
echo "Existing release id: ${EXISTING_ID:-none}" echo "Existing release id: ${EXISTING_ID:-none}"
fi fi
echo "::endgroup::" echo "::endgroup::"
# 2. Créer ou mettre à jour la release. # 2. Créer ou mettre à jour la release.
# On utilise python3 pour générer le body JSON proprement
# (jq n'est pas garanti dans l'image runner).
if [[ -n "$EXISTING_ID" ]]; then if [[ -n "$EXISTING_ID" ]]; then
echo "::group::Update release id=$EXISTING_ID" echo "::group::Update release id=$EXISTING_ID"
BODY=$(IS_PRERELEASE="$IS_PRERELEASE" RELEASE_BODY="$RELEASE_BODY" python3 -c 'import json,os; print(json.dumps({"body":os.environ["RELEASE_BODY"],"prerelease":os.environ["IS_PRERELEASE"].lower()=="true"}))') BODY=$(printf '{"body":"%s","prerelease":%s}' \
"$(json_escape "$RELEASE_BODY")" "$IS_PRERELEASE")
HTTP=$(curl -sS -o /tmp/release.json -w '%{http_code}' \ HTTP=$(curl -sS -o /tmp/release.json -w '%{http_code}' \
-X PATCH \ -X PATCH \
-H "Authorization: token $GITHUB_TOKEN" \ -H "Authorization: token $GITHUB_TOKEN" \
@ -253,7 +274,11 @@ jobs:
echo "::endgroup::" echo "::endgroup::"
else else
echo "::group::Create release" echo "::group::Create release"
BODY=$(IS_PRERELEASE="$IS_PRERELEASE" RELEASE_BODY="$RELEASE_BODY" TAG="$TAG" python3 -c 'import json,os; print(json.dumps({"tag_name":os.environ["TAG"],"name":os.environ["TAG"],"body":os.environ["RELEASE_BODY"],"prerelease":os.environ["IS_PRERELEASE"].lower()=="true"}))') BODY=$(printf '{"tag_name":"%s","name":"%s","body":"%s","prerelease":%s}' \
"$(json_escape "$TAG")" \
"$(json_escape "$TAG")" \
"$(json_escape "$RELEASE_BODY")" \
"$IS_PRERELEASE")
HTTP=$(curl -sS -o /tmp/release.json -w '%{http_code}' \ HTTP=$(curl -sS -o /tmp/release.json -w '%{http_code}' \
-X POST \ -X POST \
-H "Authorization: token $GITHUB_TOKEN" \ -H "Authorization: token $GITHUB_TOKEN" \
@ -271,7 +296,7 @@ jobs:
exit 1 exit 1
fi fi
RELEASE_ID=$(python3 -c "import json; print(json.load(open('/tmp/release.json'))['id'])") RELEASE_ID=$(json_field /tmp/release.json id)
echo "Release id=$RELEASE_ID" echo "Release id=$RELEASE_ID"
# 3. Upload l'APK en asset. # 3. Upload l'APK en asset.