You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
drop.two/scripts/publish-release.sh

107 lines
3.9 KiB

#!/usr/bin/env bash
#
# publish-release.sh — signiert ein fertiges DMG mit dem Sparkle-Schlüssel,
# trägt den Eintrag in den appcast ein und lädt beides auf den Update-Server.
#
# Läuft auf dem MAC, nicht auf dem Server.
# Voraussetzung: DMG ist bereits gebaut, signiert, notarisiert und gestapled.
#
# Aufruf aus dem Repo-Wurzelverzeichnis:
# ./scripts/publish-release.sh dist/drop.two-1.0.1.dmg 1.0.1 12
#
# Alle Einstellungen unten lassen sich per Umgebungsvariable überschreiben,
# z. B.: DEPLOY_HOST=deploy@anderer-host ./scripts/publish-release.sh ...
#
set -euo pipefail
DMG="${1:?Pfad zum DMG fehlt}"
SHORT_VERSION="${2:?Versionsstring fehlt, z.B. 1.0.1}"
BUILD="${3:?Buildnummer fehlt, z.B. 12}"
# --- Einstellungen ----------------------------------------------------------
HOST="${DEPLOY_HOST:-deploy@10.0.5.223}"
REMOTE_DIR="${DEPLOY_DIR:-/var/www/updates/droptwo}"
BASE_URL="${DEPLOY_BASE_URL:-https://update.zielke.studio/droptwo}"
SIGN_UPDATE="${SPARKLE_SIGN_UPDATE:-./bin/sign_update}"
# ----------------------------------------------------------------------------
[[ -f "$DMG" ]] || { echo "DMG nicht gefunden: $DMG" >&2; exit 1; }
[[ -x "$SIGN_UPDATE" ]] || {
echo "sign_update nicht gefunden unter: $SIGN_UPDATE" >&2
echo "Aus dem Sparkle-Release holen oder SPARKLE_SIGN_UPDATE setzen." >&2
exit 1
}
echo "==> Notarisierung prüfen"
if ! spctl -a -t open --context context:primary-signature "$DMG" 2>&1 | grep -q accepted; then
echo "FEHLER: DMG ist nicht notarisiert oder nicht gestapled." >&2
echo "Ein Upload jetzt würde Kollegen eine blockierte App ausliefern." >&2
exit 1
fi
echo "==> Signieren"
# sign_update liefert die fertigen Attribute inkl. length und edSignature
ATTRS="$("$SIGN_UPDATE" "$DMG")"
echo " $ATTRS"
FILENAME="$(basename "$DMG")"
PUBDATE="$(LC_ALL=C date -u '+%a, %d %b %Y %H:%M:%S +0000')"
echo "==> appcast-Eintrag bauen"
ITEM=$(cat <<XML
<item>
<title>${SHORT_VERSION}</title>
<pubDate>${PUBDATE}</pubDate>
<sparkle:version>${BUILD}</sparkle:version>
<sparkle:shortVersionString>${SHORT_VERSION}</sparkle:shortVersionString>
<sparkle:minimumSystemVersion>13.0</sparkle:minimumSystemVersion>
<enclosure url="${BASE_URL}/${FILENAME}" ${ATTRS} type="application/octet-stream"/>
</item>
XML
)
echo "==> appcast vom Server holen"
scp -q "${HOST}:${REMOTE_DIR}/appcast.xml" /tmp/appcast.xml 2>/dev/null || {
echo " kein appcast vorhanden, lege neuen an"
cat > /tmp/appcast.xml <<XML
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle">
<channel>
<title>drop.two</title>
<link>${BASE_URL}/appcast.xml</link>
<description>Updates für drop.two</description>
<language>de</language>
</channel>
</rss>
XML
}
# Neuen Eintrag direkt nach <title>drop.two</title> einfügen — neueste oben
python3 - "$ITEM" "$BUILD" <<'PY'
import sys, io, re
item, build = sys.argv[1], sys.argv[2]
p = "/tmp/appcast.xml"
s = io.open(p, encoding="utf-8").read()
if re.search(r"<sparkle:version>\s*%s\s*</sparkle:version>" % re.escape(build), s):
sys.exit("FEHLER: Buildnummer %s steht bereits im appcast. "
"Sparkle vergleicht nur diese Zahl — bitte hochzählen." % build)
anchor = "<title>drop.two</title>"
if anchor not in s:
sys.exit("Anker im appcast nicht gefunden — Datei manuell prüfen.")
s = s.replace(anchor, anchor + "\n" + item, 1)
io.open(p, "w", encoding="utf-8").write(s)
print(" Eintrag eingefügt")
PY
echo "==> Hochladen"
scp -q "$DMG" "${HOST}:${REMOTE_DIR}/${FILENAME}"
scp -q /tmp/appcast.xml "${HOST}:${REMOTE_DIR}/appcast.xml"
# Kein chown nötig: das SGID-Bit auf dem Ordner vererbt die Gruppe www-data.
ssh "$HOST" "ln -sf '${FILENAME}' '${REMOTE_DIR}/drop.two-latest.dmg'"
echo "==> Fertig: ${BASE_URL}/${FILENAME}"
echo " Zum Prüfen: curl -s ${BASE_URL}/appcast.xml | head -20"

Powered by TurnKey Linux.