[iOS] GitHub Actionsでfastlaneのmatchを使わずにAdHoc書き出しをしてからFirebase App Distributionにアップロードする
こんにちは!きんくまです。
今回は「GitHub Actionsでfastlaneのmatchを使わずにAdHoc書き出しをしてからFirebase App Distributionにアップロードする」です!(長いっ)
作ったGitHub Acitonsのワークフロー
- GitHubでプルリクを作ってから、マージされたイベントをトリガーにする
- macOSを立ち上げる
- fastlaneを使う
- テストする。失敗したらSlackに通知
- AdHocビルドする。 その際、証明書とプロビジョニングファイルはGitHubのsecretsに登録したものを使用する 登録するファイルはbase64化したもの
- Firebase App Distributionにアップロードする
- Slackに通知
参考にした神情報のみなさま
先に申し上げますと、さきほど「作った」と書いてしまったのですが、先人のみなさまの情報を元に組み合わせて作成しました。 ありがとうございます!
- GitHub Actionsを使ってFirebase App Distributionへ配布する - Lento con forza
- GitHub Actions と App Store Connect API を活用して ipa を自動アップロード - Qiita
- Github Actions で Xcode プロジェクトをビルドしてみる - Qiita
- 署名なしでiOSアプリのビルド&単体テスト〜GitHub Actions編〜 - Qiita
ファイル構成
2020/05/05追記 いまのプロジェクト見たらCocoaPodsが追加されていたけど、この記事書いたときはないのでPodfile, Podfile.lock, プロジェクト名.xcworkspaceは抜いてあります。
- .github/ | - workflows/ | - adhoc.yml - Cartfile - Cartfile.resolved - fastlane/ | - Fastfile | - その他にAppfile, Pluginfile, README.md, report.xmlが入ってる - Gemfile - Gemfile.lock - プロジェクト名/ - プロジェクト名.xcodeproj - プロジェクト名Tests/ - README.md
Gemfile
fastlaneだけ書いてます。
# frozen_string_literal: true source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gem "fastlane", "2.139.0" plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') eval_gemfile(plugins_path) if File.exist?(plugins_path)
2020/05/05追記
もしCocoaPods使っているときはこれも入れてください
gem "fastlane", "2.139.0" // fastlaneの後ろに追加 gem "cocoapods", "1.9.1"
fastalneにFirebase App Distributionのプラグイン追加
fastlane add_plugin firebase_app_distribution
このコマンドを打つと fastlane/Pluginfile
が追加されます。これもGitにコミットしてください。
ワークフローファイル
2020/02/11修正 Carthageのif文追加しました。
adhoc.yml
name: AdHoc Distribution on: pull_request: branches: - master types: - closed jobs: build: runs-on: macos-latest steps: - uses: actions/checkout@v2 # Firebaseのため - uses: actions/setup-node@v1 with: node-version: '10.x' - name: Bundle Install run: bundle install # Xcode 11.2.1 を使う - name: Select Xcode version run: sudo xcode-select -s '/Applications/Xcode_11.2.1.app' - name: Show Xcode version run: xcodebuild -version - name: Keychain.p12 run: | echo "${{ secrets.P12_BASE64 }}" > ios_distribution.p12.txt base64 --decode ios_distribution.p12.txt > ios_distribution.p12 - name: ProvisioningProfile run: | echo "${{ secrets.PROVISIONING_BASE64 }}" > adhoc.mobileprovision.txt base64 --decode adhoc.mobileprovision.txt > adhoc.mobileprovision - name: list files run: ls -l - name: Cache Carthage uses: actions/[email protected] id: cache-carthage with: path: Carthage key: ${{ runner.os }}-carthage-${{ hashFiles('**/Cartfile.resolved') }} restore-keys: | ${{ runner.os }}-carthage- - name: Carthage if: steps.cache-carthage.outputs.cache-hit != 'true' run: carthage bootstrap --platform iOS --no-use-binaries --cache-builds - name: Tests env: SLACK_URL: ${{ secrets.SLACK_URL }} run: | bundle exec fastlane tests - name: Upload Tests Result uses: actions/upload-artifact@v1 with: name: test-results path: fastlane/test_output/report.html - name: Adhoc env: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} SLACK_URL: ${{ secrets.SLACK_URL }} CERT_PASSWORD: ${{ secrets.CERT_PASSWORD }} FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} run: | npm install -g firebase-tools bundle exec fastlane adhoc
2020/05/05追記
もしCocoaPods使っているときは Carthageの前か後ろにこれを追加してください
- name: CocoaPods run: bundle exec pod install
あと、Carthage使ってない人はファイルの存在確認するプラグインがあるとのことなので、それを使ってうまいことやってください。
あと、欲を言いますと、Carthageを使ってない人はエラーになるので「 andstor/file-existence-action@v1」使うといいと思います。
— shinriyo (@shinriyo) May 5, 2020
Cacheについて
2020/02/11追記
Carthageのキャッシュ設定を上のyamlでは入れているのですが、この設定だと残念ながらできません。
[warning]No scopes with read permission were found on the request.
というメッセージが実行時に出力されます。
調べてみると、Cacheが使えるのはpushとpull_requestのみです。 ただしpull_requestにtypesを指定すると使えなくなりました、、、。 上のyamlでは、typesにclosedを指定しています。これはプルリクをマージしたときのイベントです。 pull_requestのデフォルトのtypeは opened, synchronize, reopenedとなっていて、何も指定しないとこのイベントでワークフローが走ります。ですが、今現在はこれ以外を指定するとダメだというだと思います。
なので、types設定を削除すれば、上のyamlでもCacheが使えるようになります! そのうちclosedでも使えるようになれるといいなー
Fastfile
Fastfile
default_platform(:ios) platform :ios do desc "Unit Tests" lane :tests do scan( scheme: "スキーム名", device: "iPhone 11", clean: true, slack_message: "テストが完了しました!", slack_url: ENV["SLACK_URL"], slack_only_on_failure: true ) end desc "Import Certificates and Provisioning Profile" private_lane :import_certificates_and_provisioning_profile do create_keychain( name: "mykeychain", password: ENV["KEYCHAIN_PASSWORD"], timeout: 1800 ) import_certificate( certificate_path: "ios_distribution.p12", certificate_password: ENV["CERT_PASSWORD"], keychain_name: "mykeychain", keychain_password: ENV["KEYCHAIN_PASSWORD"] ) install_provisioning_profile(path: "adhoc.mobileprovision") end desc "Archive AdHoc and send to Firebase" lane :adhoc do import_certificates_and_provisioning_profile build_app(project: "プロジェクト名.xcodeproj", scheme: "スキーム名", configuration: "Configuration名", clean: true, export_options: { method: "ad-hoc" }) firebase_app_distribution( app: "Firebaseプロジェクトから取得したApp ID (AppleのBundle IDではない)", groups: "developer", release_notes: "ベータ版配信", firebase_cli_path: `which firebase`.strip() ) slack( message: "ベータ版が配信されました\nhttps://appdistribution.firebase.dev/app_distro/projects", slack_url: ENV["SLACK_URL"] ) end end
2020/05/05追記
もしCocoaPods使っているときは こんな感じに変えてください
//これを //build_app(project: "プロジェクト名.xcodeproj", //こうする build_app(workspace: "プロジェクト名.xcworkspace",
firebase_app_distributionのappのところだけ補足
設定ページのここです。
GitHubのSecretsに登録するもの
Secretsは、GitHubの画面上のSettingsタブ > 画面左のSecretsメニュー から見れます。 ただし、権限がないと見れないかも
キー | 何するもの? |
---|---|
P12_BASE64 | base64化されたAcHoc用のp12証明書 |
PROVISIONING_BASE64 | base64化されたプロビジョニングプロファイル |
SLACK_URL | 投稿したいチャンネル情報のWebhook URL |
KEYCHAIN_PASSWORD | 適当なキーチェーン用パスワード(一時的なものなのでわからなそうなやつであればなんでも) |
CERT_PASSWORD | キーチェーンから証明書を書き出した際に使用したパスワード |
FIREBASE_TOKEN | firebaseをCIから利用するときのトークン |
ファイルをbase64化する
キーチェーンからp12ファイル形式で書き出したAdHoc用証明書と、プロビジョニングファイルはbase64化します。
コマンド例
openssl base64 -in cert.p12 -out cert_base64.txt
base64化すれば、バイナリファイルがテキストファイルに変換できるのでsecrets内に登録することができます。 それをワークフロー内でbase64デコードしてバイナリファイルに戻してあげて使用します。
FIREBASE_TOKEN
firebase login:ci
を実行すると、こんな感じになります。
Waiting for authentication... ✔ Success! Use this token to login on a CI server: ここにトークンが書いてあります
2020/05/05追記
たまにトークンが期限切れになってビルドがエラーになります。上のlogin:ciコマンドをもう一度叩いて新しいトークンを発行してから、secretsに再登録してください。
fastalneから書き出されたテスト結果ファイル
ここにあります。 <- 変わりました
2020/05/05追記
いまはこういう感じになってました
まとめ
ここではfastlaneを使いました。ですが、yaml内のrunにコマンドを書けば、xcodebuildコマンドでもいけるみたいです。 あと、acitions/checkoutは@v2が出ていたので、そちらにしました。
あと、チームのみんなと料金表見ていたのですが、macランナーはLinuxランナーに対して10倍のポイント分(と呼べばよいのか?)を消費するみたいなので、少し気をつけた方が良いかもしれないです。
ただ、普段使っているGitHubでCI/CDが使えるというのはとても便利だと思いました! ではでは。