stremio/apps/ios/scripts/upload-testflight.sh
Jos Vooges | STH d1b627752c Fix iOS ClearKey live-list DASH proxy immediate stop (0.5.2).
Preserve BaseURL/Location, warm up MPD, clear sinf for VLC, and retry early stops so custom live DRM plays instead of Gestopt.
2026-09-19 06:53:13 +02:00

209 lines
7.2 KiB
Bash

#!/bin/bash
# TestFlight upload via App Store Connect API key (headless, no GUI).
# Expects: ~/AuthKey.p8 (or AUTH_KEY_PATH)
# Requires: KEY_ID, ISSUER_ID (env or --key-id / --issuer-id)
# Optional: KEYCHAIN_PASS to unlock login keychain
set -euo pipefail
IOS_DIR="${IOS_DIR:-$HOME/Code/mediacluster/apps/ios}"
AUTH_KEY_PATH="${AUTH_KEY_PATH:-$HOME/AuthKey.p8}"
EXPORT_OPTIONS="${EXPORT_OPTIONS:-$IOS_DIR/ExportOptions.plist}"
ARCHIVE_PATH="${ARCHIVE_PATH:-$IOS_DIR/build/VMC.xcarchive}"
EXPORT_PATH="${EXPORT_PATH:-$IOS_DIR/build/export}"
SCHEME="${SCHEME:-VMC}"
CONFIGURATION="${CONFIGURATION:-Release}"
TEAM_ID="${TEAM_ID:-X25NYX3K49}"
BUNDLE_ID="${BUNDLE_ID:-nl.vonas.mediacluster.ios}"
SKIP_ARCHIVE=0
SKIP_EXPORT=0
IPA_PATH=""
usage() {
cat <<'EOF'
Usage: upload-testflight.sh [options]
--key-id ID App Store Connect API Key ID (or env KEY_ID)
--issuer-id UUID App Store Connect Issuer ID (or env ISSUER_ID)
--auth-key PATH Path to .p8 (default: ~/AuthKey.p8)
--ipa PATH Skip archive/export; upload existing IPA
--skip-archive Reuse existing xcarchive
--skip-export Reuse existing IPA in export path
-h, --help Show help
Env:
KEY_ID, ISSUER_ID, AUTH_KEY_PATH, KEYCHAIN_PASS, IOS_DIR
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--key-id) KEY_ID="${2:-}"; shift 2 ;;
--issuer-id) ISSUER_ID="${2:-}"; shift 2 ;;
--auth-key) AUTH_KEY_PATH="${2:-}"; shift 2 ;;
--ipa) IPA_PATH="${2:-}"; SKIP_ARCHIVE=1; SKIP_EXPORT=1; shift 2 ;;
--skip-archive) SKIP_ARCHIVE=1; shift ;;
--skip-export) SKIP_EXPORT=1; shift ;;
-h|--help) usage; exit 0 ;;
*) echo "Unknown arg: $1" >&2; usage; exit 2 ;;
esac
done
KEY_ID="${KEY_ID:-}"
ISSUER_ID="${ISSUER_ID:-}"
# Derive Key ID from AuthKey_XXXXX.p8 filename if missing
if [[ -z "$KEY_ID" && -f "$AUTH_KEY_PATH" ]]; then
base="$(basename "$AUTH_KEY_PATH")"
if [[ "$base" =~ ^AuthKey_([A-Z0-9]+)\.p8$ ]]; then
KEY_ID="${BASH_REMATCH[1]}"
echo "KEY_ID derived from filename: $KEY_ID"
fi
fi
# Also accept ~/AuthKey_XXXXX.p8 if ~/AuthKey.p8 missing
if [[ ! -f "$AUTH_KEY_PATH" ]]; then
for cand in "$HOME"/AuthKey_*.p8; do
if [[ -f "$cand" ]]; then
AUTH_KEY_PATH="$cand"
base="$(basename "$cand")"
if [[ -z "$KEY_ID" && "$base" =~ ^AuthKey_([A-Z0-9]+)\.p8$ ]]; then
KEY_ID="${BASH_REMATCH[1]}"
fi
echo "Using API key file: $AUTH_KEY_PATH"
break
fi
done
fi
die() { echo "ERROR: $*" >&2; exit 1; }
[[ -n "$KEY_ID" ]] || die "KEY_ID ontbreekt (env KEY_ID of --key-id, of AuthKey_XXXXX.p8)"
[[ -n "$ISSUER_ID" ]] || die "ISSUER_ID ontbreekt (env ISSUER_ID of --issuer-id)"
[[ -f "$AUTH_KEY_PATH" ]] || die "API key niet gevonden: $AUTH_KEY_PATH (scp AuthKey*.p8 naar ~ op de Mac)"
# Private keys for altool/transporter must live in a predictable API Keys folder
API_KEYS_DIR="$HOME/.appstoreconnect/private_keys"
mkdir -p "$API_KEYS_DIR"
API_KEY_DEST="$API_KEYS_DIR/AuthKey_${KEY_ID}.p8"
if [[ "$(cd "$(dirname "$AUTH_KEY_PATH")" && pwd)/$(basename "$AUTH_KEY_PATH")" != "$API_KEY_DEST" ]]; then
cp -f "$AUTH_KEY_PATH" "$API_KEY_DEST"
chmod 600 "$API_KEY_DEST"
fi
# Also keep canonical ~/AuthKey.p8 symlink/copy for convenience
if [[ ! -f "$HOME/AuthKey.p8" ]]; then
cp -f "$AUTH_KEY_PATH" "$HOME/AuthKey.p8"
chmod 600 "$HOME/AuthKey.p8"
fi
echo "=== VMC TestFlight upload ==="
echo "KEY_ID=$KEY_ID"
echo "ISSUER_ID=$ISSUER_ID"
echo "AUTH_KEY=$AUTH_KEY_PATH"
echo "BUNDLE_ID=$BUNDLE_ID"
echo "TEAM_ID=$TEAM_ID"
# Unlock keychain if password provided (headless codesign)
if [[ -n "${KEYCHAIN_PASS:-}" ]]; then
echo "Unlocking login keychain..."
security unlock-keychain -p "$KEYCHAIN_PASS" "$HOME/Library/Keychains/login.keychain-db" || \
security unlock-keychain -p "$KEYCHAIN_PASS" "$HOME/Library/Keychains/login.keychain" || true
security set-keychain-settings -t 3600 -u "$HOME/Library/Keychains/login.keychain-db" 2>/dev/null || true
fi
security list-keychains -s "$HOME/Library/Keychains/login.keychain-db" /Library/Keychains/System.keychain || true
cd "$IOS_DIR"
mkdir -p build "$EXPORT_PATH" store
# Ensure ExportOptions.plist for App Store
if [[ ! -f "$EXPORT_OPTIONS" ]]; then
cat > "$EXPORT_OPTIONS" <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>app-store</string>
<key>teamID</key>
<string>${TEAM_ID}</string>
<key>signingStyle</key>
<string>automatic</string>
<key>uploadSymbols</key>
<true/>
<key>destination</key>
<string>export</string>
<key>manageAppVersionAndBuildNumber</key>
<false/>
</dict>
</plist>
PLIST
echo "Created $EXPORT_OPTIONS"
fi
if [[ "$SKIP_ARCHIVE" -eq 0 ]]; then
echo "=== Archive (Release / generic iOS) ==="
rm -rf "$ARCHIVE_PATH"
xcodebuild \
-project VMC.xcodeproj \
-scheme "$SCHEME" \
-configuration "$CONFIGURATION" \
-destination 'generic/platform=iOS' \
-archivePath "$ARCHIVE_PATH" \
-allowProvisioningUpdates \
DEVELOPMENT_TEAM="$TEAM_ID" \
CODE_SIGN_STYLE=Automatic \
archive
echo "ARCHIVE_OK: $ARCHIVE_PATH"
fi
if [[ "$SKIP_EXPORT" -eq 0 ]]; then
[[ -d "$ARCHIVE_PATH" ]] || die "Archive ontbreekt: $ARCHIVE_PATH"
echo "=== Export IPA ==="
rm -rf "$EXPORT_PATH"
mkdir -p "$EXPORT_PATH"
xcodebuild -exportArchive \
-archivePath "$ARCHIVE_PATH" \
-exportPath "$EXPORT_PATH" \
-exportOptionsPlist "$EXPORT_OPTIONS" \
-allowProvisioningUpdates
IPA_PATH="$(find "$EXPORT_PATH" -name '*.ipa' -type f | head -1)"
[[ -n "$IPA_PATH" && -f "$IPA_PATH" ]] || die "Geen IPA na export in $EXPORT_PATH"
VER="$(/usr/libexec/PlistBuddy -c 'Print :ApplicationProperties:CFBundleShortVersionString' "$ARCHIVE_PATH/Info.plist" 2>/dev/null || echo '0.5.0')"
BUILD="$(/usr/libexec/PlistBuddy -c 'Print :ApplicationProperties:CFBundleVersion' "$ARCHIVE_PATH/Info.plist" 2>/dev/null || echo 'unknown')"
cp -f "$IPA_PATH" "$IOS_DIR/store/VMC-${VER}-${BUILD}.ipa"
echo "IPA_OK: $IPA_PATH (copied to store/VMC-${VER}-${BUILD}.ipa)"
fi
if [[ -z "${IPA_PATH:-}" ]]; then
IPA_PATH="$(find "$EXPORT_PATH" -name '*.ipa' -type f 2>/dev/null | head -1 || true)"
fi
[[ -n "${IPA_PATH:-}" && -f "$IPA_PATH" ]] || die "Geen IPA om te uploaden"
echo "=== Upload via altool (API key) ==="
# Prefer modern notary/upload path; altool still works for ASC API key upload
set +e
xcrun altool --upload-app \
--type ios \
--file "$IPA_PATH" \
--apiKey "$KEY_ID" \
--apiIssuer "$ISSUER_ID" \
2>&1 | tee "$IOS_DIR/build/testflight-upload.log"
UPLOAD_EC=${PIPESTATUS[0]}
set -e
if [[ "$UPLOAD_EC" -ne 0 ]]; then
echo "altool failed (exit $UPLOAD_EC); trying iTMSTransporter..."
TRANSPORTER="/Applications/Xcode.app/Contents/SharedFrameworks/ContentDeliveryServices.framework/Versions/A/itms/bin/iTMSTransporter"
if [[ -x "$TRANSPORTER" ]]; then
"$TRANSPORTER" -m upload \
-assetFile "$IPA_PATH" \
-apiKey "$KEY_ID" \
-apiIssuer "$ISSUER_ID" \
-v informational 2>&1 | tee -a "$IOS_DIR/build/testflight-upload.log"
else
die "Upload mislukt (altool exit $UPLOAD_EC) en iTMSTransporter niet gevonden"
fi
fi
echo "UPLOAD_OK $(date)"
echo "IPA=$IPA_PATH"
echo "Log: $IOS_DIR/build/testflight-upload.log"