Files
gibandClaude Opus 5.5 f772f4e4c4 Watch: TestFlight archive, iOS stub container, testflight.sh
The App Store only accepts a watch-only app inside an empty iOS stub
(watchapp2-container), the pair Xcode's Watch-only App template makes.
The stub takes org.gbrown.wristcode; the watch app, and so the APNs topic,
becomes org.gbrown.wristcode.watchkitapp.

Adds ITSAppUsesNonExemptEncryption = NO and scripts/testflight.sh, which
archives with API key automatic signing and a timestamp build number,
then exports and uploads (or exports only with --no-upload).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-01 10:08:55 -05:00

90 lines
2.6 KiB
Bash
Executable File

#!/bin/bash
# Archive WristCode and upload it to App Store Connect for TestFlight.
#
# scripts/testflight.sh archive, then export and upload
# scripts/testflight.sh --no-upload archive, then export an .ipa to build/export without uploading
#
# BUILD_NUMBER defaults to a timestamp so every upload is unique. The App Store Connect API key comes
# from ASC_KEY_PATH, ASC_KEY_ID and ASC_ISSUER_ID.
set -euo pipefail
upload=1
for arg in "$@"; do
case "$arg" in
--no-upload) upload=0 ;;
*) echo "usage: $0 [--no-upload]" >&2; exit 2 ;;
esac
done
cd "$(dirname "$0")/.."
TEAM_ID="${TEAM_ID:-GQJNM5YK2M}"
ASC_KEY_ID="${ASC_KEY_ID:-864GCL5SDC}"
ASC_ISSUER_ID="${ASC_ISSUER_ID:-af37ae36-1f23-4245-b220-a7dc56d1a724}"
ASC_KEY_PATH="${ASC_KEY_PATH:-$HOME/.appstoreconnect/private_keys/AuthKey_${ASC_KEY_ID}.p8}"
BUILD_NUMBER="${BUILD_NUMBER:-$(date +%Y%m%d%H%M)}"
build_dir="build"
archive_path="$build_dir/WristCode-$BUILD_NUMBER.xcarchive"
export_path="$build_dir/export-$BUILD_NUMBER"
export_options="$build_dir/ExportOptions.plist"
auth=(
-allowProvisioningUpdates
-authenticationKeyPath "$ASC_KEY_PATH"
-authenticationKeyID "$ASC_KEY_ID"
-authenticationKeyIssuerID "$ASC_ISSUER_ID"
)
if [[ ! -f "$ASC_KEY_PATH" ]]; then
echo "App Store Connect API key not found at $ASC_KEY_PATH" >&2
exit 1
fi
xcodegen generate
mkdir -p "$build_dir"
echo "Archiving build $BUILD_NUMBER to $archive_path"
xcodebuild archive \
-project WristCode.xcodeproj \
-scheme WristCode \
-destination 'generic/platform=watchOS' \
-archivePath "$archive_path" \
"${auth[@]}" \
CURRENT_PROJECT_VERSION="$BUILD_NUMBER"
if (( upload )); then destination=upload; else destination=export; fi
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-connect</string>
<key>destination</key>
<string>$destination</string>
<key>teamID</key>
<string>$TEAM_ID</string>
<key>signingStyle</key>
<string>automatic</string>
<key>uploadSymbols</key>
<true/>
<key>manageAppVersionAndBuildNumber</key>
<false/>
</dict>
</plist>
PLIST
echo "Exporting ($destination) to $export_path"
xcodebuild -exportArchive \
-archivePath "$archive_path" \
-exportPath "$export_path" \
-exportOptionsPlist "$export_options" \
"${auth[@]}"
if (( upload )); then
echo "Uploaded build $BUILD_NUMBER. It appears in TestFlight once App Store Connect finishes processing."
else
echo "Exported build $BUILD_NUMBER to $export_path"
fi