Xcode からアプリを TestFlight へ自動アップロード


※ 本記事で扱っている TestFlight は 2015/2/26 でサービスを終了しました. Apple 版の TestFlight では本記事の記述は動作しません.


TestFlight は便利なんだけど、繰り返しビルドとアップロードをするのが辛くなってきたので、自動化してみた.

利用するのは Xcode の Post-actions. プロジェクトを Xcode で Archive すると TestFlight に新しいビルドが自動でアップロードされるようになります.

※ ちなみに、以下の作業で Post-actions を作成すると .xcodeproj/xcuserdata/{username}.xcuserdatad に保存されます. プロジェクトをバージョン管理して複数人で開発しているような場合は一緒にコミットしてしまわないように注意しましょう.

1. Xcode で対象となるプロジェクトを開き、スキーマ編集画面を開く

Edit Scheme

2. Archive -> Post actions を選択し、+マークから New Run Script Action を選択

Add Archive Post Action

3. アクションの内容を設定

Edit Shell Script

  1. Shell を /bin/bash
  2. Provide build settings from は自身のアプリのターゲットを選択
  3. スクリプトに以下を入力 (一部書き換える必要アリ. 詳細は後述)
UPLOAD_API_TOKEN=YOUR-UPLOAD-API-TOKEN
TEAM_TOKEN=YOUR-TEAM-TOKEN
SIGNING_IDENTITY="iPhone Developer: Your Name (XXXXXXXXXX)"
PROVISIONING_PROFILE="${HOME}/Library/MobileDevice/Provisioning Profiles/your.mobileprovision"

NOTIFIER="/path/to/terminal-notifier -title TestFlight"

DATE=$( /bin/date +"%Y-%m-%d" )
ARCHIVE=$( /bin/ls -t "${HOME}/Library/Developer/Xcode/Archives/${DATE}" | /usr/bin/grep xcarchive | /usr/bin/sed -n 1p )
DSYM="${HOME}/Library/Developer/Xcode/Archives/${DATE}/${ARCHIVE}/dSYMs/${PRODUCT_NAME}.app.dSYM"
APP="${HOME}/Library/Developer/Xcode/Archives/${DATE}/${ARCHIVE}/Products/Applications/${PRODUCT_NAME}.app"

echo "Creating .ipa for ${PRODUCT_NAME}" | ${NOTIFIER}

/bin/rm "/tmp/${PRODUCT_NAME}.ipa"
/usr/bin/xcrun -sdk iphoneos PackageApplication -v "${APP}" -o "/tmp/${PRODUCT_NAME}.ipa" --sign "${SIGNING_IDENTITY}" --embed "${PROVISIONING_PROFILE}"

echo "Created .ipa for ${PRODUCT_NAME}" | ${NOTIFIER}

echo "Zipping .dSYM for ${PRODUCT_NAME}" | ${NOTIFIER}

/bin/rm "/tmp/${PRODUCT_NAME}.dSYM.zip"
/usr/bin/zip -r "/tmp/${PRODUCT_NAME}.dSYM.zip" "${DSYM}"

echo "Created .dSYM for ${PRODUCT_NAME}" | ${NOTIFIER}

echo "Uploading to TestFlight" | ${NOTIFIER}

/usr/bin/curl "http://testflightapp.com/api/builds.json" \
-F file=@"/tmp/${PRODUCT_NAME}.ipa" \
-F dsym=@"/tmp/${PRODUCT_NAME}.dSYM.zip" \
-F api_token="${UPLOAD_API_TOKEN}" \
-F team_token="${TEAM_TOKEN}" \
-F notes="Build uploaded automatically from Xcode on ${DATE}."

echo "Uploaded to TestFlight" | ${NOTIFIER} && /usr/bin/open "https://testflightapp.com/dashboard/builds/"

アプリに応じて書き換える箇所は以下の通り.

  1. UPLOAD_API_TOKEN … TestFlight のアカウントページ で確認できる
  2. TEAM_TOKEN … TestFlight のチームページ で確認できる (※複数のチームがある場合は、対象のチームが選ばれているかどうかに注意)
  3. SIGNING_IDENTITY … プロジェクトの Build Settings の Code Signing Identity のとこに設定するやつ
  4. PROVISIONING_PROFILE … ダウンロード済みの .mobileprovision ファイルのパス
  5. NOTIFIER … /path/to/terminal-notifier を terminal-notifier のフルパスに

上のスクリプトだと進行状況の表示には terminal-notifier を使ってみました. この gem パッケージを使うと、OS X の Notification Center に任意の通知を出すことができるので、「動いてないかも…」と心配しなくて済みます. terminal-notifier を利用しないとしても、Console.app とかを使ってログファイルに書き出しておくと、うまく動かないときの調査に便利です.

以上の準備をして Xcode で Archive すると、TestFlight に ipa ファイルが自動でアップロードされるます. dSYM 作りや毎回ブラウザでアップロードすることに疲れた方は是非お試しあれ.

参考: