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]>
This commit is contained in:
1 parent
16bae4410d
commit
f772f4e4c4
4 files changed
+141
-4
No files matched your search
Executable
+89
@@ -0,0 +1,89 @@
|
||||
#!/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
|
||||
Reference in new issue
Block a user