126 lines
4.0 KiB
Bash
Executable File
126 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Builds the skill ZIP (and .mcpb if extension/) and creates a remote release with those assets.
|
|
# Auth: git credential helper, or env RELEASE_TOKEN if set.
|
|
# The tag <name>/v<version> must exist locally and on the remote. Does not push tags.
|
|
# Usage: 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 ! 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
|
|
|
|
REPO_HOST=git.gundel.dev
|
|
api="https://$REPO_HOST/api/v1/repos/dg/claude-skills"
|
|
|
|
auth_header=""
|
|
if [[ -n "${RELEASE_TOKEN:-}" ]]; then
|
|
auth_header="Authorization: token $RELEASE_TOKEN"
|
|
else
|
|
cred="$(printf 'protocol=https\nhost=%s\n\n' "$REPO_HOST" | git credential fill 2>/dev/null || true)"
|
|
user="$(printf '%s\n' "$cred" | sed -n 's/^username=//p' | head -n1)"
|
|
pass="$(printf '%s\n' "$cred" | sed -n 's/^password=//p' | head -n1)"
|
|
if [[ -n "$user" && -n "$pass" ]]; then
|
|
basic="$(printf '%s:%s' "$user" "$pass" | base64 | tr -d '\n')"
|
|
auth_header="Authorization: Basic $basic"
|
|
fi
|
|
fi
|
|
if [[ -z "$auth_header" ]]; then
|
|
echo "Keine Auth fuer das Release (git credential oder RELEASE_TOKEN)." >&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"
|
|
|
|
resp="$(mktemp)"
|
|
code="$(curl -sS -o "$resp" -w '%{http_code}' -X POST "$api/releases" \
|
|
-H "$auth_header" \
|
|
-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",""))')"
|
|
|
|
upload_asset() {
|
|
local file_path="$1" file_name="$2"
|
|
local asset_resp code asset download
|
|
asset_resp="$(mktemp)"
|
|
code="$(curl -sS -o "$asset_resp" -w '%{http_code}' -X POST "$api/releases/$rel_id/assets?name=$file_name" \
|
|
-H "$auth_header" \
|
|
-H "Content-Type: application/octet-stream" \
|
|
--data-binary @"$file_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 "$download" ]] && echo "$download"
|
|
}
|
|
|
|
upload_asset "$zip_path" "$zip_name"
|
|
|
|
mcpb_name="$name-v$version.mcpb"
|
|
mcpb_path="$DIST_DIR/$mcpb_name"
|
|
if [[ -f "$dir/extension/manifest.json" ]]; then
|
|
if [[ ! -f "$mcpb_path" ]]; then
|
|
bash "$(dirname "$0")/package-mcpb.sh" "$name"
|
|
fi
|
|
if [[ -f "$mcpb_path" ]]; then
|
|
upload_asset "$mcpb_path" "$mcpb_name"
|
|
fi
|
|
fi
|
|
|
|
[[ -n "$html" ]] && echo "$html"
|
|
echo "Release $tag angelegt."
|