Files
claude-skills/scripts/release.sh
T

94 lines
3.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Baut das ZIP eines Skills und legt damit ein Gitea-Release an.
# Kein Actions-Runner. Der Tag <name>/v<version> muss lokal und auf dem Server liegen.
# Token: Umgebungsvariable GITEA_TOKEN (persönliches Zugangs-Token, nicht ins Repo).
# Aufruf: scripts/release.sh <skill-name>
set -euo pipefail
source "$(dirname "$0")/lib.sh"
name="${1:-}"
if [[ -z "$name" ]]; then
echo "Aufruf: scripts/release.sh <skill-name>" >&2
exit 1
fi
if [[ -z "${GITEA_TOKEN:-}" ]]; then
echo "GITEA_TOKEN fehlt. Persönliches Zugangs-Token mit Schreibrecht (write:repository), nur in der Umgebung." >&2
exit 1
fi
if ! command -v python3 >/dev/null 2>&1 || ! command -v curl >/dev/null 2>&1; then
echo "release.sh braucht curl und python3. Unter Windows: scripts\\release.ps1" >&2
exit 1
fi
dir="$SKILLS_DIR/$name"
version="$(skill_version "$dir")"
if [[ -z "$version" ]]; then
echo "CHANGELOG von $name hat keine Version '## x.y.z (YYYY-MM-DD)'." >&2
exit 1
fi
tag="$name/v$version"
if ! git -C "$ROOT" rev-parse --verify --quiet "refs/tags/$tag" >/dev/null; then
echo "Tag $tag fehlt lokal. Setzen, nicht verschieben: git tag $tag" >&2
exit 1
fi
bash "$(dirname "$0")/package.sh" "$name"
zip_name="$name-v$version.zip"
zip_path="$DIST_DIR/$zip_name"
[[ -f "$zip_path" ]] || { echo "ZIP fehlt: dist/$zip_name" >&2; exit 1; }
notes="$(mktemp)"
payload="$(mktemp)"
trap 'rm -f "$notes" "$payload"' EXIT
awk -v v="$version" '
index($0, "## " v " ") == 1 { on = 1; next }
/^## / && on { exit }
on { print }' "$dir/CHANGELOG.md" > "$notes"
TAG="$tag" TITLE="$name $version" NOTES="$notes" python3 -c '
import json, os
print(json.dumps({
"tag_name": os.environ["TAG"],
"name": os.environ["TITLE"],
"body": open(os.environ["NOTES"], encoding="utf-8").read().strip(),
}))' > "$payload"
api="https://git.gundel.dev/api/v1/repos/dg/claude-skills"
resp="$(mktemp)"
code="$(curl -sS -o "$resp" -w '%{http_code}' -X POST "$api/releases" \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
--data-binary @"$payload")"
if [[ "$code" != "201" ]]; then
echo "API $code" >&2
cat "$resp" >&2
echo "Tag auf dem Server? git push origin $tag" >&2
rm -f "$resp"
exit 1
fi
created="$(cat "$resp")"
rm -f "$resp"
rel_id="$(CREATED="$created" python3 -c 'import json,os; print(json.loads(os.environ["CREATED"])["id"])')"
html="$(CREATED="$created" python3 -c 'import json,os; print(json.loads(os.environ["CREATED"]).get("html_url",""))')"
asset_resp="$(mktemp)"
code="$(curl -sS -o "$asset_resp" -w '%{http_code}' -X POST "$api/releases/$rel_id/assets?name=$zip_name" \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/octet-stream" \
--data-binary @"$zip_path")"
if [[ "$code" != "201" ]]; then
echo "API $code" >&2
cat "$asset_resp" >&2
rm -f "$asset_resp"
exit 1
fi
asset="$(cat "$asset_resp")"
rm -f "$asset_resp"
download="$(ASSET="$asset" python3 -c 'import json,os; print(json.loads(os.environ["ASSET"]).get("browser_download_url",""))')"
[[ -n "$html" ]] && echo "$html"
[[ -n "$download" ]] && echo "$download"
echo "Release $tag angelegt."