もふもふ技術部

IT技術系mofmofメディア

FlutterでiOSアプリのビルドとデプロイを自動化した話

こんにちは。豊泉です。

少し前に良い個人開発のアイデアが浮かんだので開発していたのですが、アプリのビルドやアップロードなどは少しややこしく以前から面倒に感じていたので、せっかくならビルドとアップロードを自動化しようと思いGithub Actionsを使ってやってみました。

必要なもの

自動化する前に、アプリをビルド&アップロードするにあたって下記が必要です。

準備

上記が準備できたらGithub Actionsのワークフローを書いていきます。

環境変数にはビルドとアップロードに必要な下記項目を入れておきます。

今回は下記を設定しました。

  • APPLE_ID
    • 上記のApple IDです
  • APPLE_APP_PASS
    • 上記のApp-specific passwordです
  • CERTIFICATES_P12
    • 上記のCertificateをexportした際のp12ファイルをbase64でエンコードしたものです
  • CERTIFICATE_PASSWORD
    • 上記のCertificate passwordです
  • PROVISIONING_PROFILE
    • 上記のProfileをbase64でエンコードしたものです
  • ENVIRON_JSON
    • アプリで使用する環境変数です

ソース

出来上がったソースです。

下記を参考にしました。

https://docs.github.com/en/actions/deployment/deploying-xcode-applications/installing-an-apple-certificate-on-macos-runners-for-xcode-development

name: CD_iOS

on:
  workflow_dispatch:
    inputs:
      build_number:
        description: 'Build Number'
        required: true
        type: number

jobs:
  build_iOS:
    name: Build for iOS
    runs-on: macos-13
    timeout-minutes: 20

    steps:
      - name: Check out
        uses: actions/checkout@v4

      - name: Install the Apple certificate and provisioning profile
        env:
          BUILD_CERTIFICATE_BASE64: ${{ secrets.CERTIFICATES_P12 }}
          P12_PASSWORD: ${{ secrets.CERTIFICATE_PASSWORD }}
          BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.PROVISIONING_PROFILE }}
          KEYCHAIN_PASSWORD: ${{ secrets.APPLE_APP_PASS }}
        run: |
          # create variables
          CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
          PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
          KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db

          # import certificate and provisioning profile from secrets
          echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
          echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH

          # create temporary keychain
          security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
          security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH

          # import certificate to keychain
          security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
          security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          security list-keychain -d user -s $KEYCHAIN_PATH

          # apply provisioning profile
          mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
          cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles

      - name: Install Flutter
        uses: subosito/flutter-action@v2
        with:
          flutter-version: '3.19.3'
          channel: 'stable'
          cache: true

      - name: Install Flutter dependencies
        run: flutter pub get

      - name: Run build_runner build
        run: dart run build_runner build --delete-conflicting-outputs

      - name: Create environ.json
        env:
          ENVIRON_JSON: ${{ secrets.ENVIRON_JSON }}
        run: echo "$ENVIRON_JSON" > ./environ.json

      - name: Building IPA
        run: |
          flutter build ipa --release \
          --dart-define-from-file=environ.json \
          --export-options-plist=ios/Runner/ExportOptions.plist \
          --build-number ${{ github.event.inputs.build_number }}

      - name: Upload to AppStoreConnect
        env:
          APPLE_ID: ${{ secrets.APPLE_ID }}
          APPLE_APP_PASS: ${{ secrets.APPLE_APP_PASS }}
        run: xcrun altool --upload-app -f "./build/ios/ipa/xxxx.ipa" -t ios -u "$APPLE_ID" -p "$APPLE_APP_PASS"

最後に

個人開発でありプライベートリポジトリなので、一旦は手動でCDを実行するようにしていますが、それでも自動化したことで煩わしかったアップロードの手間が少なくなりとても快適になりました。