feat(18-02): Task 2 — Release-Dateien idempotent an den Gitea-Release haengen
- upload_asset() nach dem bestehenden GET-then-PATCH/POST-Idempotenzmuster: GET .../assets -> vorhandene Datei gleichen Namens per DELETE entfernen -> frisch per POST multipart (Feld attachment) hochladen - Zweite Header-Datei HDR_AUTH (nur Authorization, kein JSON-Content-Type) fuer den multipart-Upload; Token bleibt in Header-Dateien, nie als Argument (T-18-03) - Nach Release-Anlage/-Aktualisierung wird jede Datei aus desktop-dist/manifest.json hochgeladen; fehlt das Manifest bei einem Freigabe-Tag, bricht das Skript hart ab - --dry-run listet zusaetzlich die geplanten Uploads aus dem Manifest, ohne Netzaufruf Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,9 +21,21 @@
|
||||
# sonst http://localhost:3002/api/v1 (nur lokal erreichbar).
|
||||
# GITEA_REPO owner/repo; sonst GITHUB_REPOSITORY, sonst schalli/tessera-ctl.
|
||||
# CHANGELOG_FILE Pfad zur Aenderungsliste; Vorgabe CHANGELOG.md.
|
||||
# DESKTOP_DIST Ordner mit den Desktop-Paketen und manifest.json (Phase 18,
|
||||
# 18-02); Vorgabe desktop-dist. Fehlt manifest.json bei Tags,
|
||||
# bricht das Skript ab -- der Release-Text ist dann schon
|
||||
# angelegt/aktualisiert, der Job wird sichtbar rot.
|
||||
#
|
||||
# Fehlt der Abschnitt fuer die Version, endet das Skript mit Exit 1 -- es entsteht
|
||||
# nie ein leerer Release. JSON wird ausschliesslich mit jq gebaut.
|
||||
#
|
||||
# Release-Dateien (Phase 18, 18-02): jede Datei aus manifest.json wird idempotent
|
||||
# angehaengt -- GET .../releases/{id}/assets, vorhandene Datei gleichen Namens per
|
||||
# DELETE .../releases/{id}/assets/{asset_id} entfernen, dann frisch per
|
||||
# POST .../releases/{id}/assets?name=... (multipart-Feld attachment) hochladen.
|
||||
# Der multipart-Upload braucht eine zweite Header-Datei ($HDR_AUTH) OHNE
|
||||
# Content-Type: application/json -- curl setzt den multipart-Content-Type sonst
|
||||
# nicht korrekt, wenn der JSON-Header schon gesetzt ist.
|
||||
set -eu
|
||||
|
||||
usage() {
|
||||
@@ -101,11 +113,21 @@ UPDATE_JSON=$(jq -n --arg name "$NAME" --arg body "$BODY" '{name: $name, body: $
|
||||
RELEASES_URL="$API/repos/$REPO/releases"
|
||||
TAG_URL="$API/repos/$REPO/releases/tags/$TAG"
|
||||
|
||||
DESKTOP_DIST="${DESKTOP_DIST:-desktop-dist}"
|
||||
MANIFEST="$DESKTOP_DIST/manifest.json"
|
||||
|
||||
if [ "$DRY_RUN" -eq 1 ]; then
|
||||
echo "Probelauf (kein Netzaufruf):"
|
||||
echo " POST $RELEASES_URL"
|
||||
echo " PATCH $RELEASES_URL/<id> (falls GET $TAG_URL bereits 200 liefert)"
|
||||
printf '%s\n' "$CREATE_JSON"
|
||||
if [ -f "$MANIFEST" ]; then
|
||||
for FNAME in $(jq -r '.files[].name' "$MANIFEST"); do
|
||||
echo " POST $RELEASES_URL/<id>/assets?name=$FNAME"
|
||||
done
|
||||
else
|
||||
echo " ($MANIFEST fehlt -- keine geplanten Uploads im Probelauf)"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -118,9 +140,46 @@ umask 077
|
||||
TMPDIR_REL=$(mktemp -d)
|
||||
trap 'rm -rf "$TMPDIR_REL"' EXIT INT TERM
|
||||
HDR="$TMPDIR_REL/headers"
|
||||
HDR_AUTH="$TMPDIR_REL/headers-auth"
|
||||
RESP="$TMPDIR_REL/response.json"
|
||||
ASSETS_RESP="$TMPDIR_REL/assets.json"
|
||||
JSONFILE="$TMPDIR_REL/payload.json"
|
||||
printf 'Authorization: token %s\nContent-Type: application/json\n' "$GITEA_TOKEN" > "$HDR"
|
||||
# Zweite Header-Datei ohne Content-Type: application/json -- der multipart-Upload
|
||||
# (POST .../assets) darf keinen JSON-Content-Type mitbekommen.
|
||||
printf 'Authorization: token %s\n' "$GITEA_TOKEN" > "$HDR_AUTH"
|
||||
|
||||
# upload_asset FILE NAME RELEASE_ID -- idempotent: vorhandene Datei gleichen Namens
|
||||
# wird zuerst entfernt (GET -> DELETE), dann frisch hochgeladen (POST multipart).
|
||||
upload_asset() {
|
||||
ASSET_FILE="$1"
|
||||
ASSET_NAME="$2"
|
||||
ASSET_RELEASE_ID="$3"
|
||||
|
||||
ASSETS_CODE=$(curl -sS --header @"$HDR" -o "$ASSETS_RESP" -w '%{http_code}' "$RELEASES_URL/$ASSET_RELEASE_ID/assets")
|
||||
if [ "$ASSETS_CODE" != "200" ]; then
|
||||
echo "GET $RELEASES_URL/$ASSET_RELEASE_ID/assets antwortete mit $ASSETS_CODE:" >&2
|
||||
cat "$ASSETS_RESP" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
EXISTING_ID=$(jq -r --arg n "$ASSET_NAME" '.[] | select(.name == $n) | .id' "$ASSETS_RESP")
|
||||
if [ -n "$EXISTING_ID" ]; then
|
||||
DEL_CODE=$(curl -sS --header @"$HDR" -X DELETE -o "$RESP" -w '%{http_code}' "$RELEASES_URL/$ASSET_RELEASE_ID/assets/$EXISTING_ID")
|
||||
if [ "$DEL_CODE" != "204" ]; then
|
||||
echo "DELETE $RELEASES_URL/$ASSET_RELEASE_ID/assets/$EXISTING_ID antwortete mit $DEL_CODE:" >&2
|
||||
cat "$RESP" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
UPLOAD_CODE=$(curl -sS --header @"$HDR_AUTH" -X POST -F "attachment=@${ASSET_FILE};filename=${ASSET_NAME}" -o "$RESP" -w '%{http_code}' "$RELEASES_URL/$ASSET_RELEASE_ID/assets?name=$ASSET_NAME")
|
||||
if [ "$UPLOAD_CODE" != "201" ]; then
|
||||
echo "POST $RELEASES_URL/$ASSET_RELEASE_ID/assets?name=$ASSET_NAME antwortete mit $UPLOAD_CODE:" >&2
|
||||
cat "$RESP" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
CODE=$(curl -sS --header @"$HDR" -o "$RESP" -w '%{http_code}' "$TAG_URL")
|
||||
case "$CODE" in
|
||||
@@ -140,7 +199,8 @@ case "$CODE" in
|
||||
printf '%s' "$CREATE_JSON" > "$JSONFILE"
|
||||
CODE=$(curl -sS --header @"$HDR" -X POST --data @"$JSONFILE" -o "$RESP" -w '%{http_code}' "$RELEASES_URL")
|
||||
if [ "$CODE" = "201" ]; then
|
||||
echo "Release $TAG angelegt (id $(jq -r .id "$RESP"))"
|
||||
ID=$(jq -r .id "$RESP")
|
||||
echo "Release $TAG angelegt (id $ID)"
|
||||
else
|
||||
echo "POST $RELEASES_URL antwortete mit $CODE:" >&2
|
||||
cat "$RESP" >&2
|
||||
@@ -153,3 +213,16 @@ case "$CODE" in
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Release-Dateien aus dem Manifest anhaengen (Phase 18, 18-02). Der Release-Text
|
||||
# ist an dieser Stelle bereits angelegt/aktualisiert -- fehlt das Manifest, wird
|
||||
# das trotzdem hart abgebrochen (kein Release ohne Pakete bei einem Freigabe-Tag).
|
||||
if [ ! -f "$MANIFEST" ]; then
|
||||
echo "$MANIFEST fehlt -- kein Release ohne Desktop-Pakete." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for FNAME in $(jq -r '.files[].name' "$MANIFEST"); do
|
||||
upload_asset "$DESKTOP_DIST/$FNAME" "$FNAME" "$ID"
|
||||
echo "Release-Datei $FNAME hochgeladen"
|
||||
done
|
||||
|
||||
Reference in New Issue
Block a user