🦔

FlutterアプリをGitHub ActionsでDeployGateのデプロイを自動化!

2022/04/17に公開

概要

こんな感じの説明をする。

私はいわゆるITゼネコンのSEなので、仕事ではなかなか新しい技術を習得することが難しい。そこで、仕事とは別にSingularitySociety(社会を技術で良くしていこうNPO)でMaaSプロジェクトに参加している。
SingularitySocietyでは小規模のFlutterアプリの配布にDeployGateを使用しており、GitHub ActionsでのCI/CDを実施している。Societyからの勧めもあるが、どなたかの参考になればと思い公開する。
Flutterの開発スピードが尋常ではないので、少し古いバージョン(8.1.1)になる。最新のバージョンでの確認はしていない。

GitHub Actions の登録

ワークフローを新規作成する。
GitHubの "Actions" タブをクリックし、"set up a workflow yourself" をクリックする。

workflow の名称 "main.yaml"(デフォルト) を設定し、
"Edit new file" にGitHub Actions のスクリプト を入力する。
"Start commit" ボタンをクリックする。

GitHub Actions に登録するスクリプト。

name: iOS CI/CD

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: macos-latest

    steps:
      - uses: actions/checkout@v2

      - name: Select Xcode version 13.1
        run: sudo xcode-select -s '/Applications/Xcode_13.1.app/Contents/Developer'

      - name: Show Xcode version
        run: xcodebuild -version

      - name: setup cache      
        uses: actions/cache@v1
        with: 
          path: /Users/runner/hostedtoolcache/flutter
          key: ${{runner.OS}}-flutter-install-cache

      - name: install flutter      
        uses: subosito/flutter-action@v1
        with:
          flutter-version: '2.8.1'
          channel: 'stable'

      - name: flutter dependencies install
        run: flutter pub get

      - name: Import Provisioning Profile
        run: |
          mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
          touch ~/Library/MobileDevice/Provisioning\ Profiles/decoded.mobileprovision
          echo -n '${{ secrets.PROVISIONING_PROFILE }}' | base64 -d -o ~/Library/MobileDevice/Provisioning\ Profiles/decoded.mobileprovision
      - name: Import Code-Signing Certificates
        uses: Apple-Actions/import-codesign-certs@v1
        with:
          p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
          p12-password: ${{ secrets.CERTIFICATE_PASSWORD }}

      - name: Import Export Options
        run: echo -n '${{ secrets.EXPORT_OPTIONS }}' >> ExportOptions.plist

      - run: flutter build ipa --export-options-plist=ExportOptions.plist

      - name: Distribute iOS app
        run: |
          curl \
            -H "Authorization: token ${{secrets.DEPLOYGATE_API_KEY}}" \
            -F "file=@/Users/runner/work/kochi_bus_photo_app/kochi_bus_photo_app/build/ios/ipa/xxxxxxxxxx_app.ipa" \
            -F "message=git:$GIT_HASH" \
            -F "distribution_name=$GIT_BRANCH" \
            -F "release_note=new ios build" \
            -F "distribution_key=${{secrets.IOS_DISTRIBUTION_HASH}}" \
            "https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps"

スクリプト内で{secrets.XXXXXX} となっている箇所は暗号化されたシークレットを入力する必要がある。

Secretsに設定する内容

シークレット 内容
PROVISIONING_PROFILE プロビジョニングファイルの内容
EXPORT_OPTIONS ExportOptions.plistファイルの内容
DEPLOYGATE_API_KEY アカウントのAPIキー
DEPLOYGATE_USER DeployGateアカウントのユーザー名
IOS_DISTRIBUTION_HASH アプリの配布ページのリンクの末尾部分(/distributions/の後ろの値)

Secretsに設定する内容は、Apple Developer で発行する証明書(プロビジョニングファイル)や、DeployGata 関連の情報が必要となるため、以下に順を追って説明していく。

Secrets の登録について

GitHub の"Settings"でsecretsを登録する。
ただし、情報漏れ対策のため参照は出来ない。

また、VSCodeのGitHub Actions機能拡張によりSecretsの設定ができる。
こちらも、Webと同様、設定は可能であるが参照はできない。

GitHub Actions機能拡張について

以下はVSCodeの機能拡張をインストールする手順である。
https://marketplace.visualstudio.com/items?itemName=cschleiden.vscode-GitHub-actions

VSCodeのGitHub Actions機能拡張をインストールする。GitHubの接続サイトにログインする。
「このページでVisual Studio Code"を開くことを許可しますか?」と問われるので、「許可」をクリックする

VSCodeのGitHub Actions機能拡張をインストールすると、GitHubの接続サイトに誘導される。
「このページでVisual Studio Code"を開くことを許可しますか?」と問われるので、「許可」をクリックする

※認証画面が出ない場合はVSCodeの左下のアカウントボタンでGitHubサイトにログインする。

設定は、鉛筆ボタンをクリックして 表示される上部の入力欄に設定値を入力し、RETURNキーを押下する

Apple Developer が発行する証明書の種類

Flutterで作成したiOSアプリを実機にインストールするためには、Apple Developerによる証明書を発行し、XCodeに登録する必要がある。

XCodeで証明書を登録する際に自動管理と手動管理がある。自動ではApple Developerの証明書を登録でき、手動ではApple Distributionの証明書を登録することができる。リリースにはiOS Distributionの証明書を登録する。


XCode証明書を登録する際に、"Automatically managed signing"のチェックで切り替える。
Automaticallyを指定したいところであるが、Automaticallyだと"Development"を含むプロファイルしか指定できない。Deverlopmentの証明書を指定すると、デプロイ時に、プロファイルにdistributionの証明書がないというエラーになってしまう。
このため、本手順ではAutomaticallyを指定していない。

今回使用する認証は以下の2つになる。

ソフトウェアの認証

  • Apple Distribution(配布者)
  • iOS Distribution(配布者)

サービスの認証

  • なし

    Apple Developerが発行する証明書について簡単に説明しておく。

Software

  • Apple Development
    iOS、macOS、tvOS、watchOSアプリの開発バージョンに署名する。Xcode 11 以降で使用する。

  • Apple Distribution
    App Storeへの提出やアドホックな配布のために署名する。Xcode 11 またはそれ以降で使用する。

  • iOS App Development
    iOSアプリの開発バージョンに署名する。

  • iOS Distribution (App Store and Ad Hoc)
    iOSアプリをApp Storeに提出するため、またはアドホック配布のために署名する。

  • Mac Development
    Macアプリの開発バージョンに署名する。

  • Mac App Distribution
    この証明書は、アプリにコード署名を行い、Mac App Storeに提出するためのDistribution Provisioning Profileを設定するために使用する。

  • Mac Installer Distribution
    この証明書は、Mac App Storeに提出するアプリケーションのインストーラーパッケージに署名するために使用される。

  • Developer ID Application
    この証明書は、Mac App Store以外で配布するアプリにコード署名を行うために使用される。

Services

  • Apple Push Notification service SSL (Sandbox)
    通知サーバーとApple Push Notificationサービスのサンドボックス環境との接続を確立し、アプリにリモート通知を配信する。
    開発するアプリごとに個別の証明書が必要。

  • Apple Push Notification service SSL (Sandbox & Production)
    通知サーバー、Apple Push Notificationサービスのサンドボックス、本番環境間の接続を確立し、アプリにリモート通知を配信する。
    HTTP/2を利用する場合、同じ証明書を使用して、アプリ通知の配信、ClockKit複雑化データの更新、バックグラウンドVoIPアプリの着信アラートを行うことができる。
    配布するアプリごとに個別の証明書が必要。

  • Pass Type ID Certificate
    Wallet内のパスに署名し、更新を送信する。

  • Website Push ID Certificate
    Webサイトのアップデートに署名して送信する。

  • Swift Package Collection Certificate
    Swiftパッケージコレクションに署名して配布する。

  • WatchKit Services Certificate
    通知サーバー、Apple Push Notificationサービスのサンドボックス、本番環境間の接続を確立し、ClockKitのコンプリケーションデータを更新する。
    HTTP/2を利用する場合、同じ証明書を使用して、アプリ通知の配信、ClockKitコンプリケーションデータの更新、バックグラウンドVoIPアプリへの着信の警告を行うことができる。配布するアプリごとに個別の証明書が必要。

  • VoIP Services Certificate
    通知サーバー、Apple Push Notificationサービスのサンドボックス、および本番環境間の接続を確立し、バックグラウンドのVoIPアプリに着信を通知する。
    配布するアプリごとに個別の証明書が必要。

  • Apple Pay Payment Processing Certificate
    Appleから販売店/開発者に送信されるアプリの取引データを復号化する。

  • Apple Pay Merchant Identity Certificate
    Apple Pay決済処理サーバーとの認証に使用されるクライアントTLS証明書
    チームのアカウントホルダーは、契約書「Apple Pay Platform Web Merchant Terms and Conditions」に同意する必要がある。

Apple Developerで証明書を発行しダウンロードする

Apple Developerのサイトから証明書を発行するには、まず、証明書を発行するための要求ファイルを作成する。

キーチェーンアクセスを起動し、”キーチェーンアクセス" メニューの"証明書アシスト" "認証局に証明書を要求..." を選択する。

証明書アシスタントでメールアドレス、通称を入力し、"ディスクに保存"を選択して"続ける"をクリックする。

鍵ペア情報の鍵のサイズに"2048ビット"、アルゴリズムに"RSA"を設定し、"続ける"をクリックする。

保存先を示すダイアログが表示されるので、認証局に証明書を要求する為のファイル "CertificateSigningRequest.certSigningRequest"を保存する。

apple developperのサイト
https://developer.apple.com/jp/
を表示し、
"アカウント" をクリックする。ログインしていなければログインする。

”Certificates, IDs & Profiles”をクリックする。

左側の"Certivicates"をクリックし、"+" ボタンをクリックする。

"Apple Distribution"を選択し、 "Continue"をクリックする。"Apple Distribution"の証明書を発行した後、"iOs Distribution (App Store and Ad Hoc)"を選択し、同様に進める。

”Choose File”をクリックする。
認証局に証明書を要求する為のcertSigningRequestファイルを指定する。

ダウンロードしたcerファイルをダブルクリックしてキーチェーンアクセスに登録する

証明書をp12形式で書き出す

証明書(iPhone Distribution)を右クリックしてp12ファイルを書き出す

ファイル名を指定する。

任意のパスワードを入力する。

Secretsの設定(証明書関連)

  • CERTIFICATES_P12
    以下のコマンドを実行してコピーされた値を中央上の入力欄に張り付ける。
base64 build/ios/cert.p12 | tr -d  "\n" | pbcopy
  • CERTIFICATE_PASSWORD
    p12書き出しのパスワードを設定する。

アプリケーションのIDを登録する

すでにXCodeにアプリケーションIDを設定しているものとする。FlutterのiOSディレクトリ内にある Runner.xcworkspace を開き、左側ツリーの Runner を選択し、更に TARGETS の Runner を選択する。
"Automatically manage signing" のチェックを外す。
General タブのSigning and Capabirities の Bundle Identifer が 登録するアプリケーションIDとなる。
これから説明するアプリケーションID、デバイスの登録をして、出力する プロビジョニングプロファイルをProvisProvisioning Profile に設定する。

apple developperのサイト https://developer.apple.com/jp/ に戻り、左側の"Identifiers"をクリックし、"+" ボタンをクリックする。

"App IDs"を選択し、"Continue" ボタンをクリックする。

"Sekect a type"の"App"を選択し、"Continue" ボタンをクリックする。

"Description" にアプリケーションの概要を記載し、"App"を選択し、"Bundle ID"に先ほど確認した、XCodeの"Bundle Identifire" を指定し "Continue" ボタンをクリックする。

デバイスの登録

ファインダーでMacに繋いだデバイスを選ぶ
情報が表示されている部分をクリックすると、クリックするごとに表記が3パターンに変わる
シリアル番号・UDID・機種が表示されているところで右クリックする
[UDIDをコピー]でUDIDがクリップボードにコピーされる

apple developperのサイト https://developer.apple.com/jp/ に戻り、左側の"Devices"をクリックし、"+" ボタンをクリックする。

Platform を選択し、Device Name、および、先ほど確認したUDIDを設定する。
"Continue" ボタンをクリックする。

プロビジョニングファイルを作成しダウンロードする

左側の"Profile"をクリックし、"+" ボタンをクリックする。

App Store のプロビジョニングファイル

  • "App Store" を選択し、"Continue" ボタンをクリックする。

  • Select App ID で先ほど登録したアプリケーションIDを選択する。
    "Continue" ボタンをクリックする。

  • Probisioning Profile Nameを指定して、"Continue" ボタンをクリックする。

  • "Download" ボタンをクリックしてプロビジョニングファイルをダウンロードする。
    ■■■■■■■■■■■■Appdev.mobileprovision

Ad Hoc のプロビジョニングファイル

App Store と同様に、"Ad Hoc" を選択し、"Continue" ボタンをクリックする。

  • 登録したApp IDを選択する。
    "Continue" ボタンをクリックする。

  • iOS Distoribution を選択する。
    "Continue" ボタンをクリックする。

  • Select Device で登録したデバイスを選択する。
    "Continue" ボタンをクリックする。

  • Probisioning Profile Nameを指定して、"Continue" ボタンをクリックする。
    ■■■■■■■■■■■■AppAhc

  • "Download" ボタンをクリックしてプロビジョニングファイルをダウンロードする。
    ■■■■■■■■■■■■AppAhc.mobileprovision

Secretsの設定(プロビジョニング関連)

VSCodeのGitHub Actions機能拡張かGitHubのWebを使用してプロビジョニングに必要なSecretsを設定する。

PROVISIONING_PROFILE

以下のコマンドを実行してコピーされた値を貼り付ける。

base64 ~/Downloads/■■■■■■■■■■■■Appdev.mobileprovision | tr -d  "\n" | pbcopy 

EXPORT_OPTIONS

ExportOptions.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>compileBitcode</key>
<false/>
<key>destination</key>
<string>export</string>
<key>method</key>
<string>ad-hoc</string>
<key>provisioningProfiles</key>
<dict>
<key>com.example.■■■■■■■■■■■■App.dev</key>
<string>■■■■■■■■■■■■AppAhc</string>
</dict>
<key>signingStyle</key>
<string>manual</string>
<key>stripSwiftSymbols</key>
<false/>
<key>teamID</key>
<string>■■■■■</string>
<key>thinning</key>
<string>&lt;none&gt;</string>
</dict>
</plist>

Secretsの設定(DeployGate関連)

続いてDeployGateへのデプロイに必要なSecretsを設定する。

DEPLOYGATE_API_KEY

  • アカウントのAPIキーを入力する。
    ※アプリのAPIキーではないことに注意
    DeployGateのサイトのプロフィールのユーザ名とアイコンの横にあるアカウントのAPIキーを設定する。

DEPLOYGATE_USER

  • DeployGateアカウントのユーザー名を設定する。

IOS_DISTRIBUTION_HASH

  • アプリの配布ページのリンクの末尾部分(/distributions/の後ろの値)を設定する。

ユーザ名とアイコン に DEPLOYGATE_USER を設定する。
API Key に IOS_DISTRIBUTION_HASH を設定する。

アプリの配布ページのリンクをクリックする。

ビルドイメージ

あとは main ブランチに push されると自動でビルドが走り、デプロイされる。

GitHub Actions の Summary画面

シンギュラリティ・ソサエティ

Discussion