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.
106 lines
3.8 KiB
106 lines
3.8 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.
|
|
|
|
echo "==> Fertig: ${BASE_URL}/${FILENAME}"
|
|
echo " Zum Prüfen: curl -s ${BASE_URL}/appcast.xml | head -20"
|