thunderbird2docuware/scripts/release.sh
sylyx 1b15973c9e release.sh: web-ext 7.x für ATN-API v4 pinnen + --xpi-Modus
- web-ext fest auf 7.x via npx (ab 8.x spricht es nur AMO-v5 → ATN gibt 404)
- korrekter Flag --api-url-prefix für ATN-API v4
- neuer --xpi-Modus: bereits signiertes XPI veröffentlichen (Gitea-Release +
  updates.json + push), ohne erneut zu signieren. Nötig, weil ATN das signierte
  XPI nicht über die API zurückgibt – Download aus dem ATN-Entwicklerbereich.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 15:50:06 +02:00

169 lines
7.7 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
#
# release.sh signiert die Extension bei addons.thunderbird.net (Kanal "unlisted",
# also signiert ABER nicht öffentlich gelistet), lädt das signierte XPI als
# Gitea-Release hoch und trägt es in updates.json fürs Auto-Update ein.
#
# Benötigt: bash, node, npx, curl, git. web-ext wird genutzt, wenn global
# installiert; sonst automatisch via "npx web-ext" (kein globales Install nötig).
#
# Secrets kommen aus der Umgebung bzw. aus scripts/.env (gitignored, NIE committen):
# ATN_API_KEY API-Schlüssel von addons.thunderbird.net (Entwicklerbereich)
# ATN_API_SECRET zugehöriges Secret
# GITEA_TOKEN Gitea Personal Access Token (Scope: write:repository)
# Optionale Overrides (sonst aus dem git-Remote "origin" abgeleitet):
# GITEA_BASE, GITEA_OWNER, GITEA_REPO, REPO_DIR
#
# Aufruf:
# scripts/release.sh # signiert via ATN, nutzt Version aus manifest.json
# scripts/release.sh 0.9.0 # setzt zuerst diese Version, dann signieren
# scripts/release.sh --xpi <datei.xpi> # bereits signiertes XPI veröffentlichen
# scripts/release.sh --xpi <datei.xpi> 0.9.0
#
# Hinweis ATN: addons.thunderbird.net gibt das signierte XPI nicht zuverlässig über
# die API zurück. In der Praxis: einmal mit dem Skript hochladen (legt die Version an),
# das signierte XPI aus dem ATN-Entwicklerbereich herunterladen, dann mit --xpi
# veröffentlichen. Der --xpi-Modus überspringt das Signieren komplett.
#
set -euo pipefail
# --- Argumente: optional vorsigniertes XPI (--xpi) --------------------------
PRESIGNED=""
if [ "${1:-}" = "--xpi" ]; then
PRESIGNED="${2:-}"; shift 2
[ -n "$PRESIGNED" ] && [ -f "$PRESIGNED" ] || { echo "FEHLER: --xpi braucht eine existierende Datei." >&2; exit 1; }
fi
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# .env (falls vorhanden) laden liefert die Secrets, ohne sie ins Repo zu schreiben.
if [ -f "$SCRIPT_DIR/.env" ]; then
set -a; . "$SCRIPT_DIR/.env"; set +a
fi
# Projektwurzel: Standard = ein Ordner über diesem Skript. Bei abweichendem Ort
# REPO_DIR setzen. Es muss eine manifest.json enthalten.
REPO_DIR="${REPO_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}"
MANIFEST="$REPO_DIR/manifest.json"
UPDATES="$REPO_DIR/updates.json"
ARTIFACTS="$REPO_DIR/web-ext-artifacts"
die() { echo "FEHLER: $*" >&2; exit 1; }
need() { command -v "$1" >/dev/null 2>&1 || die "'$1' nicht gefunden. Bitte installieren."; }
# --- Vorbedingungen -----------------------------------------------------------
need node; need curl; need git
[ -f "$MANIFEST" ] || die "manifest.json nicht gefunden ($MANIFEST). Ggf. REPO_DIR setzen."
[ -f "$UPDATES" ] || die "updates.json nicht gefunden ($UPDATES)."
: "${GITEA_TOKEN:?GITEA_TOKEN fehlt (scripts/.env oder Umgebung)}"
if [ -z "$PRESIGNED" ]; then
# web-ext: ATN nutzt die Signing-API v4. Das geht nur mit web-ext 7.x ab 8.x
# spricht web-ext ausschließlich die AMO-v5-API und ATN antwortet mit 404.
# Daher fest auf 7.x via npx (kein globales Install nötig); per WEBEXT_CMD überschreibbar.
need npx
WEBEXT="${WEBEXT_CMD:-npx --yes web-ext@^7}"
: "${ATN_API_KEY:?ATN_API_KEY fehlt (scripts/.env oder Umgebung)}"
: "${ATN_API_SECRET:?ATN_API_SECRET fehlt}"
fi
# --- Version setzen / lesen ---------------------------------------------------
if [ "${1:-}" ]; then
node -e 'const fs=require("fs"),p=process.argv[1],v=process.argv[2];
const m=JSON.parse(fs.readFileSync(p,"utf8"));m.version=v;
fs.writeFileSync(p,JSON.stringify(m,null,2)+"\n");' "$MANIFEST" "$1"
echo "manifest.json → Version $1"
fi
VERSION="$(node -p "require('$MANIFEST').version")"
ADDON_ID="$(node -p "require('$MANIFEST').applications.gecko.id")"
[ -n "$VERSION" ] && [ -n "$ADDON_ID" ] || die "Version/Add-on-ID konnten nicht gelesen werden."
TAG="v${VERSION}"
XPI_NAME="docuware-ablage-${VERSION}.xpi"
# --- Gitea-Koordinaten aus dem Remote ableiten (oder per Env überschreiben) ---
REMOTE_URL="$(git -C "$REPO_DIR" remote get-url origin)"
case "$REMOTE_URL" in
git@*) host="${REMOTE_URL#git@}"; host="${host%%:*}"; path="${REMOTE_URL#*:}";;
ssh://*) rest="${REMOTE_URL#ssh://}"; rest="${rest#*@}"; host="${rest%%/*}"; path="${rest#*/}";;
http://*|https://*) rest="${REMOTE_URL#*://}"; host="${rest%%/*}"; path="${rest#*/}";;
*) die "Remote-URL-Form nicht erkannt: $REMOTE_URL";;
esac
path="${path%.git}"
GITEA_BASE="${GITEA_BASE:-https://$host}"
GITEA_OWNER="${GITEA_OWNER:-${path%%/*}}"
GITEA_REPO="${GITEA_REPO:-${path#*/}}"
API="$GITEA_BASE/api/v1/repos/$GITEA_OWNER/$GITEA_REPO"
BRANCH="$(git -C "$REPO_DIR" rev-parse --abbrev-ref HEAD)"
UPDATE_LINK="$GITEA_BASE/$GITEA_OWNER/$GITEA_REPO/releases/download/$TAG/$XPI_NAME"
echo "Release $VERSION (Add-on $ADDON_ID)"
echo " Gitea : $GITEA_BASE/$GITEA_OWNER/$GITEA_REPO (Branch $BRANCH)"
echo " Asset : $UPDATE_LINK"
# --- 1) XPI besorgen: entweder bereits signiert (--xpi) oder via ATN signieren --
mkdir -p "$ARTIFACTS"
if [ -n "$PRESIGNED" ]; then
echo "→ Nutze vorsigniertes XPI: $PRESIGNED"
cp -f "$PRESIGNED" "$ARTIFACTS/$XPI_NAME"
else
echo "→ Signiere bei addons.thunderbird.net (unlisted) …"
rm -f "$ARTIFACTS"/*.xpi 2>/dev/null || true
$WEBEXT sign \
--channel=unlisted \
--api-url-prefix="https://addons.thunderbird.net/api/v4" \
--api-key="$ATN_API_KEY" \
--api-secret="$ATN_API_SECRET" \
--source-dir="$REPO_DIR" \
--artifacts-dir="$ARTIFACTS" \
--ignore-files "web-ext-artifacts/**" "scripts/**" "docs/**" "*.md" "*.xpi" \
".git/**" ".gitignore" "*.env" ".env"
SIGNED="$(ls -t "$ARTIFACTS"/*.xpi 2>/dev/null | head -1)"
[ -n "${SIGNED:-}" ] && [ -f "$SIGNED" ] || die "Kein signiertes XPI in $ARTIFACTS gefunden."
cp -f "$SIGNED" "$ARTIFACTS/$XPI_NAME"
fi
echo "✓ XPI bereit: $ARTIFACTS/$XPI_NAME"
# --- 2) updates.json patchen --------------------------------------------------
node -e 'const fs=require("fs");
const [p,id,ver,link]=process.argv.slice(1);
const j=JSON.parse(fs.readFileSync(p,"utf8"));
j.addons=j.addons||{}; j.addons[id]=j.addons[id]||{updates:[]};
const u=j.addons[id].updates=j.addons[id].updates||[];
const e={version:ver,update_link:link}, i=u.findIndex(x=>x.version===ver);
if(i>=0)u[i]=e; else u.push(e);
fs.writeFileSync(p, JSON.stringify(j,null,2)+"\n");' \
"$UPDATES" "$ADDON_ID" "$VERSION" "$UPDATE_LINK"
echo "✓ updates.json aktualisiert"
# --- 3) Version + updates.json committen und pushen ---------------------------
git -C "$REPO_DIR" add manifest.json updates.json
if ! git -C "$REPO_DIR" diff --cached --quiet; then
git -C "$REPO_DIR" commit -m "Release $VERSION"
fi
git -C "$REPO_DIR" push origin "$BRANCH"
echo "✓ committed & gepusht"
# --- 4) Gitea-Release anlegen (oder vorhandenes nehmen) + XPI hochladen -------
echo "→ Lege Gitea-Release $TAG an …"
gitea() { curl -fsS -H "Authorization: token $GITEA_TOKEN" "$@"; }
REL_JSON="$(gitea -X POST "$API/releases" -H "Content-Type: application/json" \
-d "{\"tag_name\":\"$TAG\",\"target_commitish\":\"$BRANCH\",\"name\":\"$TAG\",\"body\":\"DocuWare Ablage $VERSION\"}" \
2>/dev/null || true)"
if [ -z "$REL_JSON" ]; then
echo " (Release/Tag existiert evtl. schon hole vorhandenes)"
REL_JSON="$(gitea "$API/releases/tags/$TAG")"
fi
RELEASE_ID="$(printf '%s' "$REL_JSON" | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).id")"
[ -n "$RELEASE_ID" ] || die "Konnte Release-ID nicht ermitteln."
echo "→ Lade $XPI_NAME hoch …"
gitea -X POST "$API/releases/$RELEASE_ID/assets?name=$XPI_NAME" \
-F "attachment=@$ARTIFACTS/$XPI_NAME;type=application/x-xpinstall" >/dev/null \
|| die "Asset-Upload fehlgeschlagen (existiert der Asset-Name schon? Dann altes Asset löschen)."
echo
echo "✓ Release $VERSION fertig."
echo " Download : $UPDATE_LINK"
echo " Auto-Update zieht beim nächsten Thunderbird-Check."