thunderbird2docuware/scripts/release.sh
sylyx 0ca212dd4c Release-Skript: ATN-Signierung (unlisted) + Gitea-Release + Auto-Update
scripts/release.sh signiert die Extension via web-ext gegen
addons.thunderbird.net (Kanal unlisted, also signiert aber nicht öffentlich
gelistet), lädt das XPI als Gitea-Release hoch und trägt es in updates.json
ein. web-ext wird global genutzt oder per npx (kein globales Install nötig).
Secrets kommen aus scripts/.env (gitignored); .env.example als Vorlage.

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

150 lines
6.6 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 # nutzt die Version aus manifest.json
# scripts/release.sh 0.9.0 # setzt zuerst diese Version in manifest.json
#
set -euo pipefail
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
# web-ext: global installiert bevorzugen, sonst per npx (kein globales Install nötig).
if command -v web-ext >/dev/null 2>&1; then
WEBEXT="web-ext"
else
need npx
WEBEXT="npx --yes web-ext"
fi
[ -f "$MANIFEST" ] || die "manifest.json nicht gefunden ($MANIFEST). Ggf. REPO_DIR setzen."
[ -f "$UPDATES" ] || die "updates.json nicht gefunden ($UPDATES)."
: "${ATN_API_KEY:?ATN_API_KEY fehlt (scripts/.env oder Umgebung)}"
: "${ATN_API_SECRET:?ATN_API_SECRET fehlt}"
: "${GITEA_TOKEN:?GITEA_TOKEN fehlt}"
# --- 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) Signieren (zuerst schlägt hier fehl, bevor irgendwas gepusht wird) ---
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"
echo "✓ Signiert: $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."