Flutterで作ったアプリをiOS向けにクローズド配信する時に、せっかくなので自動化したいと思い、Github Actionsを使用してCI/CD環境を構築する方法をまとめました。
masterブランチにpushされた時に、自動でDeployGateにアップロードされるようになっています。
また、今回の方法はこちらの記事を参考にしました。
完成版
name: iOS CI/CD
on:
push:
branches: [ master ]
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- 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: '3.3.8'
channel: 'stable'
- name: flutter dependencies install
run: flutter pub get
- name: Import Provisioning Profile
env:
PROVISIONING_PROFILE: ${{ secrets.PROVISIONING_PROFILE }}
run: |
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
touch ~/Library/MobileDevice/Provisioning\ Profiles/decoded.mobileprovision
echo -n $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
env:
EXPORT_OPTIONS: ${{ secrets.EXPORT_OPTIONS }}
run: echo -n $EXPORT_OPTIONS >> ExportOptions.plist
- run: flutter build ipa --export-options-plist=ExportOptions.plist
- name: Distribute iOS app
env:
DEPLOYGATE_API_KEY: ${{ secrets.DEPLOYGATE_API_KEY }}
IOS_DISTRIBUTION_HASH: ${{ secrets.IOS_DISTRIBUTION_HASH }}
DEPLOYGATE_USER: ${{ secrets.DEPLOYGATE_USER }}
run: |
curl \
-H "Authorization: token $DEPLOYGATE_API_KEY" \
-F "file=@/Users/runner/work/<アプリ名>/<アプリ名>/build/ios/ipa/<アプリ名>.ipa" \
-F "message=git:$GIT_HASH" \
-F "distribution_name=$GIT_BRANCH" \
-F "release_note=new ios build" \
-F "distribution_key=$IOS_DISTRIBUTION_HASH" \
"https://deploygate.com/api/users/$DEPLOYGATE_USER/apps"
Github Secretsの概要
名前 | 内容 |
---|---|
PROVISIONING_PROFILE | mobileprovisionファイルをbase64でエンコードしたもの |
CERTIFICATES_P12 | p12ファイルをbase64でエンコードしたもの |
CERTIFICATE_PASSWORD | p12ファイルに設定したパスワード |
EXPORT_OPTIONS | ipaと一緒に出力されたExportOptions.plistファイル |
DEPLOYGATE_API_KEY | DeployGateの アカウント設定 > APIKey に記載されているAPIキー |
IOS_DISTRIBUTION_HASH | DeployGateのアプリ配布ページURLに記載されているハッシュ値 |
DEPLOYGATE_USER | DeployGateのアカウントに登録したユーザ名 |
Certificates と p12ファイル
Apple DeveloperのCertificatesタブから、Apple Distributionを選択し作成する方法と、Xcodeから作成する方法があります。
Apple Developerサイトから作成する場合、キーチェーンアクセスを使用して手動で登録する必要があるため、Xcodeを利用したほうが楽です。
やり方としては、XcodeのPreferenceから Manage Certificates... を選択しApple Distributionを作成するだけです。
その後、MacのキーチェーンアクセスからApple Distributionを選択しp12形式で書き出すことで完了です。
base64でエンコードしたp12ファイルと、書き出し時に使用したパスワードを、それぞれSecretsに登録してください。
キーチェーンアクセスからの出力に関してはこちらの記事が参考になります。
Provisioning Profile
Apple DeveloperのProfilesタブから、Ad Hocを選択して新しいプロファイルを作成します。
右上のDownloadからダウンロードしたmobileprovisionファイルをbase64でエンコードすると完了です。
Export Options
Flutter 1.24.0-6.0 以降のバージョンから flutter build ipa
でipaファイルが出力できるようになりました。
ExportOptions.plist を指定しないとアーカイブのみ出力されますので、こちらも用意します。
予めローカル環境にて flutter build ipa
を行った後、Xcodeで Runner.xcarchive ファイルを開き、Ad hoc形式で出力するとipaファイルと同じフォルダ内に ExportOptions.plist も出力されています。
今回はそのままSecretsにそのまま貼り付けましたが、余力があれば必要な部分のみ隠すよう main.yml を変更すると尚良いです。
また、下記のようなエラーが発生する場合
No profiles for <bundle id> were found: Xcode couldn't find any iOS App Development provisioning profiles matching <bundle id>. Automatic signing is disabled and unable to generate a profile.
出力する前に、ReleaseタブのAutomatically manage signingのチェックを外しておき、先程作成したProfileを指定すると解決します。
DeployGate
詳しい説明については省きます。
-
DEPLOYGATE_API_KEY
⇒ アカウント設定 > APIKey に記載されているAPIキー -
IOS_DISTRIBUTION_HASH
⇒ アプリ配布ページURLに記載されているハッシュ値 -
DEPLOYGATE_USER
⇒ アカウントに登録したユーザ名
その他
App Extension (共有等) を使用する場合、追加でプロファイルを作成し、指定する必要があります。
基本的には、先程行った手順と同じです。
最後に main.yml の Import Provisioning Profile
にApp Extensionのbase64形式のプロファイルをデコードする処理をこのように追記します。
touch ~/Library/MobileDevice/Provisioning\ Profiles/decoded-share-extension.mobileprovision
echo -n '${{ secrets.SHARE_EXTENSION_PROVISIONING_PROFILE }}' | base64 -d -o ~/Library/MobileDevice/Provisioning\ Profiles/decoded-share-extension.mobileprovision
iOS Build Actionを使用してipaを出力する場合、こちらの指定が上手くいっていなかったため、一応ここに記載しておきます。
参考