Simpl-Resultat/.claude/skills/release/scripts/verify-release.sh
le king fu 11e12ab7a3 docs(skills): add /issue-license and a release verification script
- issue-license (new): issue licenses by hand through maximus-api's admin
  endpoint (testers, gifts, refund compensation, admin account); the admin
  key and the issued keys never enter the transcript. Third-party
  beneficiaries are named by their Logto id, never by email: the
  repository is public.
- release step 0: when a release tightens edition gating, tester keys must
  be entered before the tag, since an install without a key receives that
  version and then nothing more.
- release step 9: scripts/verify-release.sh checks the 7 assets by suffix
  and the content of latest.json, instead of a script rewritten each time.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 19:51:01 -04:00

52 lines
2.6 KiB
Bash
Executable file

#!/usr/bin/env bash
# Step 9 of /release: verify the published Forgejo release for a tag —
# the 7 expected assets and the content of latest.json (drives auto-update).
set -uo pipefail
TAG="${1:?usage: verify-release.sh vX.Y.Z}"
VERSION="${TAG#v}"
TOKEN=$(cat ~/.forgejo-token)
API="https://git.lacompagniemaximus.com/api/v1/repos/maximus/simpl-resultat"
WORK="${TMPDIR:-/tmp}/verify-release-${TAG}"; mkdir -p "$WORK"
OUT="$WORK/latest.json"
echo "=== release ${TAG} ==="
timeout 20 curl -s -H "Authorization: token $TOKEN" "${API}/releases/tags/${TAG}" > "$WORK/release.json"
python3 - "$WORK/release.json" "$VERSION" <<'EOF'
import sys, json
r = json.load(open(sys.argv[1])); version = sys.argv[2]
if "id" not in r:
print("PAS DE RELEASE :", r); sys.exit(1)
print(f"name={r.get('name')!r} tag={r.get('tag_name')} draft={r.get('draft')} prerelease={r.get('prerelease')} assets={len(r.get('assets', []))}")
names = {}
for a in r.get("assets", []):
n = a["name"]; s = a["size"]; names[n] = a["browser_download_url"]
print(f" {n} {s/1_000_000:.1f} MB" if s > 100_000 else f" {n} {s} B")
# Naming conventions vary by Tauri version — report by suffix rather than failing on exact names.
kinds = {"exe": 0, "exe.sig": 0, "deb": 0, "deb.sig": 0, "rpm": 0, "rpm.sig": 0, "latest.json": 0}
for n in names:
for k in ("exe.sig", "deb.sig", "rpm.sig"):
if n.endswith("." + k): kinds[k] += 1; break
else:
for k in ("exe", "deb", "rpm"):
if n.endswith("." + k): kinds[k] += 1; break
else:
if n == "latest.json": kinds["latest.json"] += 1
missing = [k for k, v in kinds.items() if v == 0]
print("couverture:", kinds, "| MANQUANT:" if missing else "| complet", missing if missing else "")
open(sys.argv[1] + ".latest-url", "w").write(names.get("latest.json") or "")
EOF
URL=$(cat "$WORK/release.json.latest-url" 2>/dev/null)
if [ -z "$URL" ]; then echo "latest.json absent — arrêt"; exit 1; fi
echo; echo "=== latest.json ($URL) ==="
timeout 20 curl -sL "$URL" > "$OUT"
python3 - "$OUT" "$VERSION" <<'EOF'
import sys, json
j = json.load(open(sys.argv[1])); version = sys.argv[2]
v = j.get("version"); pub = j.get("pub_date"); notes = j.get("notes", "")
print(f"version={v} {'OK' if v == version else 'MAUVAISE VERSION'} | pub_date={pub}")
print(f"notes: {len(notes)} caractères — début: {notes[:120]!r}")
for plat, p in j.get("platforms", {}).items():
sig = p.get("signature", ""); url = p.get("url", "")
print(f" {plat}: url={url.rsplit('/', 1)[-1]} | signature={'OK (' + str(len(sig)) + ' car.)' if sig else 'VIDE'} | url contient version={'oui' if version in url else 'NON'}")
EOF