この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは!きんくまです。
今回は「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/cache@v1.1.2
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が使えるというのはとても便利だと思いました! ではでは。