a81a450e7e
Merged into tinqs/studio: - cmd/tinqs-cli/ — tinqs-cli (Go binary, from bot/cli) - cmd/tea/ — Gitea CLI tool (from tinqs/cli-tea) - services/bot/ — Bot service (from tinqs-ltd/bot on git.arikigame.com) - services/admin/ — Admin panel (from tinqs/admin) - services/team-tool/ — Team Tool (from tinqs/team-tool) - services/proxy/ — tinqs-proxy (from bot/proxy) - web/landing/ — tinqs.com website (from tinqs/website) - web/docs/ — Platform docs (from tinqs/docs) - web/blog/ — Blog (placeholder) - runner/ — Ephemeral CI runner (from tinqs/runner) All source repos will be deleted after verification.
107 lines
3.6 KiB
Bash
Executable File
107 lines
3.6 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# generate-appcast.sh — Produce appcast.xml for Sparkle 2.x auto-update.
|
|
#
|
|
# Usage:
|
|
# ./scripts/generate-appcast.sh <signed-app.zip> <version> <edsa-private-key-path> [output-path]
|
|
#
|
|
# Arguments:
|
|
# signed-app.zip Path to the codesigned, zipped .app bundle
|
|
# version Semantic version string (e.g. 1.2.0)
|
|
# edsa-private-key-path Path to EdDSA private key file (from sparkle/bin/generate_keys)
|
|
# output-path Optional output file (default: stdout)
|
|
#
|
|
# Requirements:
|
|
# - Sparkle's sign_update tool on PATH or at ./sparkle/bin/sign_update
|
|
#
|
|
# Outputs an appcast.xml with one <item> containing EdDSA signature, download URL,
|
|
# and file size — ready to upload to S3.
|
|
|
|
readonly S3_BASE="https://tinqs-cli-releases.s3.eu-west-1.amazonaws.com/releases/darwin"
|
|
|
|
ZIP_PATH="${1:?Usage: $0 <signed-app.zip> <version> <edsa-private-key-path> [output-path]}"
|
|
VERSION="${2:?Usage: $0 <signed-app.zip> <version> <edsa-private-key-path> [output-path]}"
|
|
PRIVATE_KEY_PATH="${3:?Usage: $0 <signed-app.zip> <version> <edsa-private-key-path> [output-path]}"
|
|
OUTPUT_PATH="${4:-}"
|
|
|
|
# Validate inputs
|
|
if [ ! -f "$ZIP_PATH" ]; then
|
|
echo "Error: ZIP file not found: $ZIP_PATH" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f "$PRIVATE_KEY_PATH" ]; then
|
|
echo "Error: EdDSA private key not found: $PRIVATE_KEY_PATH" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Locate sign_update tool
|
|
SIGN_UPDATE=""
|
|
if command -v sign_update >/dev/null 2>&1; then
|
|
SIGN_UPDATE="sign_update"
|
|
elif [ -x "./sparkle/bin/sign_update" ]; then
|
|
SIGN_UPDATE="./sparkle/bin/sign_update"
|
|
elif [ -x "/usr/local/bin/sign_update" ]; then
|
|
SIGN_UPDATE="/usr/local/bin/sign_update"
|
|
else
|
|
echo "Error: Sparkle sign_update tool not found on PATH or at ./sparkle/bin/sign_update" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Generate EdDSA signature for the zip
|
|
SIGNATURE=$("$SIGN_UPDATE" "$ZIP_PATH" --ed-key-file "$PRIVATE_KEY_PATH" 2>/dev/null)
|
|
if [ -z "$SIGNATURE" ]; then
|
|
echo "Error: sign_update produced empty signature" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Extract the edSignature value (sign_update outputs: sparkle:edSignature="..." length="...")
|
|
ED_SIGNATURE=$(echo "$SIGNATURE" | sed -n 's/.*sparkle:edSignature="\([^"]*\)".*/\1/p')
|
|
if [ -z "$ED_SIGNATURE" ]; then
|
|
# Some versions output just the signature string
|
|
ED_SIGNATURE="$SIGNATURE"
|
|
fi
|
|
|
|
# File size in bytes
|
|
FILE_SIZE=$(stat -f%z "$ZIP_PATH" 2>/dev/null || stat -c%s "$ZIP_PATH" 2>/dev/null)
|
|
|
|
# Publication date in RFC 2822 format
|
|
PUB_DATE=$(date -R 2>/dev/null || date "+%a, %d %b %Y %H:%M:%S %z")
|
|
|
|
# Download URL
|
|
DOWNLOAD_URL="${S3_BASE}/TinqsTeamTool-${VERSION}.zip"
|
|
|
|
# Generate appcast XML
|
|
APPCAST=$(cat <<XMLEOF
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
|
<channel>
|
|
<title>Tinqs Team Tool Updates</title>
|
|
<link>${S3_BASE}/appcast.xml</link>
|
|
<description>Updates for Tinqs Team Tool macOS</description>
|
|
<language>en</language>
|
|
<item>
|
|
<title>Version ${VERSION}</title>
|
|
<pubDate>${PUB_DATE}</pubDate>
|
|
<sparkle:version>${VERSION}</sparkle:version>
|
|
<sparkle:shortVersionString>${VERSION}</sparkle:shortVersionString>
|
|
<sparkle:minimumSystemVersion>14.0</sparkle:minimumSystemVersion>
|
|
<enclosure
|
|
url="${DOWNLOAD_URL}"
|
|
sparkle:edSignature="${ED_SIGNATURE}"
|
|
length="${FILE_SIZE}"
|
|
type="application/octet-stream" />
|
|
</item>
|
|
</channel>
|
|
</rss>
|
|
XMLEOF
|
|
)
|
|
|
|
if [ -n "$OUTPUT_PATH" ]; then
|
|
echo "$APPCAST" > "$OUTPUT_PATH"
|
|
echo "Appcast written to: $OUTPUT_PATH" >&2
|
|
else
|
|
echo "$APPCAST"
|
|
fi
|