#!/usr/bin/env bash # iOS 아카이브 → TestFlight 업로드. # # **계정이 열린 날 이 스크립트 하나로 끝나게 하는 것이 목적**이다. 별첨 2 가 # 3주차부터 매주 TestFlight 제출을 요구했고 그것을 지키지 못했으므로(미이행 F-2), # 계정이 열리면 지체 없이 재개되어야 한다. # # 사전 조건 # 1. ios/Runner/GoogleService-Info.plist 배치 · tools/ios/inject_url_scheme.py 실행 # 2. Xcode 정식판을 `xcode-select` 로 지정 (베타 SDK 빌드는 업로드가 거부된다) # 3. App Store Connect API 키 (환경변수 3종) # # 실행: # export ASC_KEY_ID=... ASC_ISSUER_ID=... ASC_KEY_PATH=~/private_keys/AuthKey_XXX.p8 # bash tools/ios/upload_testflight.sh set -euo pipefail ROOT="$(cd "$(dirname "$0")/../.." && pwd)" APP="$ROOT" ARCHIVE="$APP/build/ios/Runner.xcarchive" EXPORT_DIR="$APP/build/ios/ipa" OPTIONS="$APP/ios/ExportOptions.plist" if grep -q REPLACE_WITH_TEAM_ID "$OPTIONS"; then echo "ExportOptions.plist 의 teamID 를 먼저 채우십시오." >&2 exit 1 fi for var in ASC_KEY_ID ASC_ISSUER_ID ASC_KEY_PATH; do if [ -z "${!var:-}" ]; then echo "환경변수 $var 이 없습니다." >&2 exit 1 fi done echo "▸ 아카이브" cd "$APP" flutter build ipa --release --export-options-plist="$OPTIONS" # flutter build ipa 가 아카이브와 내보내기를 함께 한다. 실패했을 때만 손으로 나눈다. IPA="$(find "$EXPORT_DIR" -name '*.ipa' -maxdepth 1 | head -1)" if [ -z "$IPA" ]; then echo "IPA 를 찾지 못했습니다. 아카이브만 따로 시도합니다." >&2 xcodebuild -workspace ios/Runner.xcworkspace -scheme Runner \ -configuration Release -archivePath "$ARCHIVE" archive xcodebuild -exportArchive -archivePath "$ARCHIVE" \ -exportOptionsPlist "$OPTIONS" -exportPath "$EXPORT_DIR" IPA="$(find "$EXPORT_DIR" -name '*.ipa' -maxdepth 1 | head -1)" fi echo "▸ 검증" xcrun altool --validate-app -f "$IPA" -t ios \ --apiKey "$ASC_KEY_ID" --apiIssuer "$ASC_ISSUER_ID" echo "▸ 업로드" xcrun altool --upload-app -f "$IPA" -t ios \ --apiKey "$ASC_KEY_ID" --apiIssuer "$ASC_ISSUER_ID" cat <<'DONE' 업로드했습니다. 남은 것 둘. 1. App Store Connect 에서 처리가 끝나면(보통 10~30분) TestFlight 탭에 뜹니다. 2. 발주사 담당자 이메일을 외부 테스터로 초대하십시오. 수출 규정 응답은 Info.plist 의 ITSAppUsesNonExemptEncryption 이 대신합니다. DONE