🛫

【Flutter】CodemagicでTestFlightへPublishする

2023/10/15に公開

概要

Codemagiccodemagic.yaml を使って、FlutterアプリをTestFlightにPublishできるまでを書き留めたメモになります。

App Store Connect publishing using codemagic.yaml

↑こちらの公式のドキュメントを元に進めていきたいと思います。

事前準備

App Store Connect API keyの作成

  1. App Store Connect にログインし、「ユーザーとアクセス」 > 「キー」に移動
    image1.png

  2. 初回は「アクセス権をリクエスト」が表示されているので、クリック
    image2.png

  3. ダイアログを確認し、「提出」をクリック
    image3.png

  4. 承認後は「APIキーを生成」が表示されているのでクリック
    image4.png

  5. 権限は「App Manager」が必要なので、名前を今回は「Publisher」、権限を「App Manager」にしてキーを作成
    image5.png

  6. 秘密鍵のダウンロードは一度しかできないので、準備が出来次第ダウンロード、管理しておく
    image6.png

アカウントの Apple Developer Portal 統合を接続

Codemagicのダッシュボードから「Teams」>「Personal Account(※ チームの場合はチーム名)」>「Integrations」から「Developer Portal」の「Connect」をクリックします。

image7.png

ユーザとアクセスと「キー」の画面を参考にしながら必要な項目を入力します。

image8.png

image9.png

最後にダウンロードしたキーをアップロードして「Save」をクリックします。

正しく接続されていれば↓の様な表示に変わるかと思います。

image10.png

codemagic.yaml の作成

準備が出来たのでTestFlightへアップロードする codemagic.yaml を作成していきたいと思います。今回は main ブランチにpushされたらTestFlightへアップロードし最後に dSYM をFirebase Crashlyticsにアップロードする流れの処理を作成しています。

以下が最終的な codemagic.yaml になります。ポイント毎に説明していきたいと思います。
※ 各verや細かい設定などは適宜修正してください。

workflows:
  test-flight-ios-workflow:
    name: TestFlight iOS Workflow
    integrations:
      app_store_connect: Publisher
    labels:
      - iOS
    max_build_duration: 60
    instance_type: mac_mini_m1
    environment:
      ios_signing:
        distribution_type: app_store
        bundle_identifier: xxx.xxx.xxx
      vars:
        APP_ID: XXXXXXX
      flutter: v3.3.8
      xcode: latest
      cocoapods: default
    triggering:
      events:
        - push
      branch_patterns:
        - pattern: "main"
          include: true
          source: true
    scripts:
      - name: Set up code signing settings on Xcode project
        script: |
          xcode-project use-profiles
      - name: Get Flutter packages
        script: |
          flutter packages pub get
      - name: Install pods
        script: |
          find . -name "Podfile" -execdir pod install \;
      - name: Flutter build ipa and automatic versioning
        script: |
          flutter build ipa --release --dart-define=FLAVOR=production --flavor prod -t lib/main_prod.dart \
            --export-options-plist=/Users/builder/export_options.plist \
            --build-number=$(($(app-store-connect get-latest-testflight-build-number "$APP_ID") + 1))
    artifacts:
      - build/ios/ipa/*.ipa
      - /tmp/xcodebuild_logs/*.log
      - flutter_drive.log
      - $HOME/Library/Developer/Xcode/DerivedData/**/Build/**/*.dSYM
    publishing:
      # https://github.com/codemagic-ci-cd/codemagic-sample-projects/blob/bfcf910be8894ba63b875af6c942ac7e1dace526/integrations/firebase_crashlytics_demo_project/codemagic.yaml
      scripts:
        - name: Upload debug symbols to Firebase Crashlytics
          script: |
            echo "Find build artifacts"
            dsymPath=$(find $CM_BUILD_DIR/build/ios/archive/Runner.xcarchive -name "*.dSYM" | head -1)
            if [[ -z ${dsymPath} ]]
            then
              echo "No debug symbols were found, skip publishing to Firebase Crashlytics"
            else
              echo "Publishing debug symbols from $dsymPath to Firebase Crashlytics"
              ls -d -- ios/Pods/*
              $CM_BUILD_DIR/ios/Pods/FirebaseCrashlytics/upload-symbols \
                -gsp ios/Runner/GoogleService-Info.plist -p ios $dsymPath
            fi
      app_store_connect:
        auth: integration
        submit_to_testflight: true
        beta_groups:
          - Developer

integrations / app_store_connect

    integrations:
      app_store_connect: Publisher

こちらには先程Codemagicのダッシュボード上で AppStore Connect API key name に設定した名前を設定しています。これでCodemagic上で App Store Connect API を使えるようになります。

environment

    environment:
      ios_signing:
        distribution_type: app_store
        bundle_identifier: xxx.xxx.xxx
      vars:
        APP_ID: XXXXXXX
      flutter: v3.3.8
      xcode: latest
      cocoapods: default

ios_signing には今回TestFlightへのアップロードなので app_store を指定し、 bundle_identifier にはアップロードするアプリのidを設定します。

APP_ID に関しては ipa をビルド時の build_number を設定する際に、現在のTestFlightのversion numberを取得する為に使用します。

          flutter build ipa --release --dart-define=FLAVOR=production --flavor prod -t lib/main_prod.dart \
            --export-options-plist=/Users/builder/export_options.plist \
            --build-number=$(($(app-store-connect get-latest-testflight-build-number "$APP_ID") + 1))

APP_IDApp Store Connect で対象アプリを開き、「一般」>「アプリ情報」の「Apple ID」の値になります。

image11.png

※ 間違いやすい項目

publishing

dSYM のアップロードは codemagicのサンプルプロジェクトのこちらとほぼ同じ実装になっています。

最後に app_store_connect にてTestFlightにアップロードし、 submit_to_testflight を有効化する事で beta_groups に指定したグループに配布するようにしています。

まとめ

今回 get-latest-app-store-build-numberget-latest-testflight-build-number を混同していた為少しハマりましたが、
事前にIntegrations設定を行っておくことで比較的スムーズにTestFlightに配布できるまでを設定できたかと思います。

Discussion