From 56f7ea4444dc4477b4669927b3f1a2f73d9a3ad5 Mon Sep 17 00:00:00 2001 From: Keysat Date: Wed, 17 Jun 2026 21:23:21 -0500 Subject: [PATCH] fix: gitea-release.sh tolerate 404 on tag lookup; report HTTP errors; mark v0.22.0 published --- AGENTS.md | 2 +- scripts/gitea-release.sh | 44 +++++++++++++++++++++++++++++----------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e1be247..fea5d5b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -63,4 +63,4 @@ Subsystem guidance lives in `docs/guides/` and loads when matching files are tou - **Known limits:** `/health` blips while the GPU is busy (mitigated client-side); dual-channel can miss a quiet local word under loud remote bleed; connectivity log misses sub-5s outages between 5s polls; diarizer caps at 4 speakers; matrix-bridge badge won't visibly flip on a fast `docker restart` (status re-checked only after the command returns). - **Infra gotcha (safety):** passwordless sudo is NOT configured on spark2 — design unprivileged probes for any Spark feature (the badge uses `ip`, not `sudo wg show`). spark2 sits on the `starttunnel` WireGuard subnet (`10.59.211.6/24`, survives reboot). Owner declined SSH-key rotation after the 2026-06-12 history scrub (only the key *name* leaked) — don't re-flag. - **Hosting:** self-hosted Gitea — remote `gitea`, branch `master`, over SSH; push after committing. (Wart: commit `8d839e3` is mislabeled `v0.13.0:4` but contains through v0.18.0:0.) -- **Next — committed 2026-06-17: OpenClaw/Johnny-5 coexistence epic (full plan + design stance in `ROADMAP.md` → "Cluster coordination").** Stance: Spark Control = control plane / GPU arbiter, **not** a job runner; business cron jobs live in separate services that *call* its swap API (swaps are already API-driven via `POST /api/swap`). Sequence: (1) **configurable `VLLM_PORT`** — SHIPPED **v0.22.0:0** (Configure-Sparks field, blank ⇒ 8888; + `_env_int` hardening in `config.py` so a blank/bad port no longer crashes startup, killing a P3 tech-debt item). Committed `136a471`, pushed, tagged `v0.22.0`, rebuilt clean, installed to `immense-voyage.local` 2026-06-17. **Gitea release publish pending** — distribution is now Gitea Releases + a read-only token for the adopter (decided 2026-06-17); `scripts/gitea-release.sh` + `make release` are ready, need `GITEA_URL` + a write token to run. (2) local-path/fine-tuned models (in ROADMAP under Dashboard). (3) configurable topology (service→Spark→port map + container names). (4) coordination layer (swap lock + swap webhook + schedule visibility) — only when our own automation lands. Still-open older threads: audio concurrency sweep (only if the Signal Engine dev wants the knee; needs a quiet window); optional matrix-bridge Docker `HEALTHCHECK` if the bot dev asks; Parakeet long-audio guard deferred (rationale in ROADMAP). +- **Next — committed 2026-06-17: OpenClaw/Johnny-5 coexistence epic (full plan + design stance in `ROADMAP.md` → "Cluster coordination").** Stance: Spark Control = control plane / GPU arbiter, **not** a job runner; business cron jobs live in separate services that *call* its swap API (swaps are already API-driven via `POST /api/swap`). Sequence: (1) **configurable `VLLM_PORT`** — SHIPPED **v0.22.0:0** (Configure-Sparks field, blank ⇒ 8888; + `_env_int` hardening in `config.py` so a blank/bad port no longer crashes startup, killing a P3 tech-debt item). Committed `136a471`, pushed, tagged `v0.22.0`, rebuilt clean, installed, and **published to the self-hosted Gitea Releases** 2026-06-17 (`make release` → `scripts/gitea-release.sh`, takes `GITEA_URL` + a write token). **Distribution model (decided 2026-06-17):** Gitea Releases + a read-only token the adopter's agent uses to pull the latest s9pk (`GET /api/v1/repos/grant/spark-control/releases/latest` → download the `.s9pk` asset → sideload). Note: Gitea returns `browser_download_url` on its `.local` ROOT_URL, which won't resolve off-LAN — a remote adopter pulls via whatever address reaches the Gitea (the WireGuard IP). (2) local-path/fine-tuned models (in ROADMAP under Dashboard). (3) configurable topology (service→Spark→port map + container names). (4) coordination layer (swap lock + swap webhook + schedule visibility) — only when our own automation lands. Still-open older threads: audio concurrency sweep (only if the Signal Engine dev wants the knee; needs a quiet window); optional matrix-bridge Docker `HEALTHCHECK` if the bot dev asks; Parakeet long-audio guard deferred (rationale in ROADMAP). diff --git a/scripts/gitea-release.sh b/scripts/gitea-release.sh index 95939ea..39b478a 100755 --- a/scripts/gitea-release.sh +++ b/scripts/gitea-release.sh @@ -8,38 +8,58 @@ # The git tag (vX.Y.Z, derived from the version) must already exist and be pushed # (`git tag v0.22.0 && git push gitea v0.22.0`). Re-running is idempotent: it # reuses an existing release for the tag and replaces a same-named asset. +# Set GITEA_INSECURE=1 to skip TLS verification (self-signed cert on a LAN box). set -euo pipefail VERSION="${1:-}"; S9PK="${2:-}" [ -n "$VERSION" ] && [ -n "$S9PK" ] || { echo "usage: GITEA_URL=.. GITEA_TOKEN=.. $0 " >&2; exit 2; } : "${GITEA_URL:?set GITEA_URL to your Gitea base URL, e.g. https://gitea.lan:3000}" -: "${GITEA_TOKEN:?set GITEA_TOKEN to a token with repository write access}" +: "${GITEA_TOKEN:?set GITEA_TOKEN to a token with repository read+write access}" [ -f "$S9PK" ] || { echo "s9pk not found: $S9PK" >&2; exit 1; } TAG="v${VERSION%%:*}" # 0.22.0:0 -> v0.22.0 ASSET="$(basename "$S9PK")" SLUG="$(git remote get-url gitea | sed -E 's#.*[:/]([^/:]+/[^/]+)\.git$#\1#')" # grant/spark-control API="${GITEA_URL%/}/api/v1/repos/${SLUG}" -AUTH=(-H "Authorization: token ${GITEA_TOKEN}") +CURL=(curl -sS) # no -f: we inspect HTTP codes ourselves +[ "${GITEA_INSECURE:-}" = "1" ] && CURL+=(-k) echo "repo ${SLUG} | tag ${TAG} | asset ${ASSET} | ${GITEA_URL}" +# api METHOD URL [extra curl args...] -> sets globals HTTP_CODE and BODY +api() { + local method="$1" url="$2"; shift 2 + local out + out="$("${CURL[@]}" -X "$method" -H "Authorization: token ${GITEA_TOKEN}" "$@" \ + -w $'\n%{http_code}' "$url")" + HTTP_CODE="${out##*$'\n'}" + BODY="${out%$'\n'*}" +} + # Reuse an existing release for this tag, otherwise create one. -id="$(curl -fsS "${AUTH[@]}" "$API/releases/tags/$TAG" 2>/dev/null | jq -r '.id // empty')" -if [ -z "$id" ]; then - id="$(curl -fsS -X POST "${AUTH[@]}" -H 'Content-Type: application/json' \ +api GET "$API/releases/tags/$TAG" +if [ "$HTTP_CODE" = 200 ]; then + id="$(printf '%s' "$BODY" | jq -r '.id')" +elif [ "$HTTP_CODE" = 404 ]; then + api POST "$API/releases" -H 'Content-Type: application/json' \ --data "$(jq -n --arg t "$TAG" --arg n "$VERSION" \ - '{tag_name:$t, name:$n, body:("Spark Control "+$n+". See AGENTS.md / release notes.")}')" \ - "$API/releases" | jq -r '.id')" + '{tag_name:$t, name:$n, body:("Spark Control "+$n+". See AGENTS.md / release notes.")}')" + [ "$HTTP_CODE" = 201 ] || { echo "create release failed (HTTP $HTTP_CODE): $BODY" >&2; exit 1; } + id="$(printf '%s' "$BODY" | jq -r '.id')" +else + echo "release lookup failed (HTTP $HTTP_CODE) — check GITEA_URL and the token's scope: $BODY" >&2 + exit 1 fi -[ -n "$id" ] && [ "$id" != null ] || { echo "could not obtain release id (check URL/token/tag)" >&2; exit 1; } +[ -n "$id" ] && [ "$id" != null ] || { echo "could not parse release id: $BODY" >&2; exit 1; } # Replace a same-named asset so re-runs don't 409. -old="$(curl -fsS "${AUTH[@]}" "$API/releases/$id/assets" | jq -r --arg n "$ASSET" '.[] | select(.name==$n) | .id')" -[ -n "$old" ] && curl -fsS -X DELETE "${AUTH[@]}" "$API/releases/$id/assets/$old" >/dev/null || true +api GET "$API/releases/$id/assets" +old="$(printf '%s' "$BODY" | jq -r --arg n "$ASSET" '.[]? | select(.name==$n) | .id')" +[ -n "$old" ] && { api DELETE "$API/releases/$id/assets/$old"; } -curl -fsS -X POST "${AUTH[@]}" -F "attachment=@${S9PK};type=application/octet-stream" \ - "$API/releases/$id/assets?name=$ASSET" >/dev/null +api POST "$API/releases/$id/assets?name=$ASSET" \ + -F "attachment=@${S9PK};type=application/octet-stream" +[ "$HTTP_CODE" = 201 ] || { echo "asset upload failed (HTTP $HTTP_CODE): $BODY" >&2; exit 1; } echo "published: ${GITEA_URL%/}/${SLUG}/releases/tag/${TAG}"