iOSのビルド・テスト・iTunesConnectへのサブミット作業をCircleCI+fastlaneで自動化

このエントリーは、エキサイト Advent Calendar 2016 の 12/07 の記事です。
エキサイトとしては初のAdvent Calendar参戦です。

こんにちは、Eレシピを担当しています小林です。よろしくお願いします。
今回はiOSのビルド自動化にfastlaneとCircleCIを導入した話になります。
弊社のiOSアプリのサブミット作業自動化は、Jenkins+shellスクリプトで行っておりましたが、今年になってからCircleCI+fastlaneに移行しました。
この記事はそれの導入手順になります。


準備

Xcode8でビルドできるようにしておく
Xcodeコマンドラインツールを最新にしておく
xcode-select --install

ローカルにbundlerをインストールしておく
sudo gem install bundler

CIから使用する以下の共通アカウントを作成しておく。
  • Apple Developer
  • iTunes Connect
  • Github

fastlane

iOSのビルド・テスト・iTunesConnectへのサブミット作業をCircleCI+fastlaneで自動化_f0364156_20561295.png
https://fastlane.tools/
まずfastlaneを追加します。
Gemfileでの管理が推薦されているのでファイルをプロジェクトトップに追加します。

Gemfile

source "https://rubygems.org"

gem "cocoapods"
gem "fastlane"

インストール
bundle

fastlaneの初期設定をします。プロジェクトトップで、
bundle exec fastlane init
# Apple ID: {作成した共通アカウント}

これでfastlane関連のファイルが作成されます。

match

iOSのビルド・テスト・iTunesConnectへのサブミット作業をCircleCI+fastlaneで自動化_f0364156_20573473.png

matchはfastlaneのツールで、証明書をgithub管理してチームでシェアできるようになります。
まずgithubのプライベートリポジトリを、リポジトリ名を certificates などとして作成しておきます。

matchの初期設定をします。プロジェクトトップで、
bundle exec match init
# リポジトリURL: {作成したリポジトリURL}

これで、fastlane/Matchfile が作成されます。

Provisioning Profile作成

Developmentのプロビジョニングを作成します。プロジェクトトップで、
bundle exec match development
# Passphrase for Git Repo: {パスワード}

ここで入力したパスワードは、チーム内で共有して忘れないようにしておきます。
新しくDevのProvisioningが生成され、Developer Centerに登録、Githubにpush、ローカルのkechainに登録まで全てツールがやってくれます。

Distributionも作成します。
bundle exec match appstore

これでDevelop Center https://developer.apple.com/account/ios/profile/
match AppStore {bundle id} iOS Distribution
match Development {bundle id} iOS Development

が作成されています。
enterprise版もある場合は、ブランチ、AppIdentifier、ユーザー名を以下のように指定して実行します。
bundle exec match appstore --git_branch enterprise --app_identifier {bundle id} -u {エンタープライズのAppleID}


Xcodeの設定変更

Signing設定の部分の Automatically manage signing のチェックを外して、それぞれのProvisioning Profileをmatchで生成したものに変更します。

certificatesレーンをfastlane/Fastfileに追加します。
lane :certificates do
match(type: "development", readonly: true)
end

今後開発者が増えた時は、プロジェクトトップで、
bundle exec fastlane certificates

と打ってもらうだけで、開発証明書を共有できます。

deliver

iOSのビルド・テスト・iTunesConnectへのサブミット作業をCircleCI+fastlaneで自動化_f0364156_21010714.png
deliverもfastlaneのツールの一つで、iTC上でのスクリーンショットのアップロードやストア情報やキーワードの変更を自動化することができます。
bundle exec  deliver init

で、iTC上のスクリーンショットやメタデータを取り込んでバージョン管理するようにします。

ファイル変更

fastlane/Fastfile に、test, beta, tflight, releaseなどの名前でレーンを追加します。
Fastfileはプロジェクトごとにカスタマイズすると良いです。
before_all do
# ビルド番号更新
set_info_plist_value(
path: 'Info.plist',
key: 'CFBundleVersion',
value: ENV['CIRCLE_BUILD_NUM']
)
end

lane :test do
cocoapods
scan(scheme: "{スキーム名}")
end

lane :beta do
# 証明書取得
match(
type: "appstore",
app_identifier: "{Bundle id}",
git_branch: "enterprise",
username: "{Apple ID}"
)
# ビルド
gym(
scheme: "{スキーム名}",
configuration: "InHouse",
output_name: "inhouse.ipa"
)
# Betaに送信
crashlytics(
crashlytics_path: "./Pods/Crashlytics/",
ipa_path: "./inhouse.ipa"
)
end

lane :tflight do
match(
type: "appstore",
app_identifier: "{Bundle id}",
username: "{Apple ID}"
)
gym(
scheme: "{Scheme名}",
configuration: "Release",
output_name: "release.ipa"
)
# TestFlightに送信
pilot(
ipa: "./release.ipa"
)
end

lane :release do
match(
type: "appstore",
app_identifier: "{Bundle id}",
username: "{Apple ID}"
)
gym(
scheme: "{スキーム名}",
configuration: "Release",
output_name: "release.ipa"
)
# iTCに送信
deliver(force: true)
end

.gitignoreに追加します。
# fastlane
fastlane/report.xml
fastlane/test_output
Preview.html

バイナリアップロードの部分でエラーにならないように、Info.plistに以下を追加します。
<key>ITSAppUsesNonExemptEncryption</key>
<false/>

ローカルでそれぞれのレーンが成功すればOKです。
bundle exec fastlane test
bundle exec fastlane beta
bundle exec fastlane tflight
bundle exec fastlane release

circle.ymlをプロジェクトトップに追加します。
machine:
timezone: Asia/Tokyo
xcode:
version: "8.1"
dependencies:
pre:
- sudo gem update --system
- sudo gem install bundler
test:
override:
- bundle exec fastlane test
deployment:
beta:
branch: develop
commands:
- bundle exec fastlane beta
- bundle exec fastlane tflight
release:
branch: master
commands:
- bundle exec fastlane release

CircleCIはgithubへのpushがトリガーとなって、CircleCI上でビルドが走ります。push先ブランチが指定ブランチの場合は、testが実行された後にdeploymentが実行されます。
これでファイル追加は終わりなので、コミットしてプルリクを出しておきます。

Circle CI

iOSのビルド・テスト・iTunesConnectへのサブミット作業をCircleCI+fastlaneで自動化_f0364156_21054230.png

プロジェクト設定

Circle CIにGithubアカウントでログインします。
https://circleci.com/
左メニューの ADD PROJECTS -> OS X -> プロジェクト名をクリックしてプロジェクト画面を開きます。
右上の設定リンクをクリックします。

環境定数設定

BUILD SETTINGS -> Environment Variablesから環境定数を設定します。
iOSのビルド・テスト・iTunesConnectへのサブミット作業をCircleCI+fastlaneで自動化_f0364156_21094394.png

FASTLANE_USER: {Apple Developer ID}
FASTLANE_PASSWORD: {Apple Developer Password}
MATCH_PASSWORD: {作成したmatch用パスワード}
CRASHLYTICS_API_TOKEN: {token}
CRASHLYTICS_BUILD_SECRET: {secret}
CRASHLYTICS_GROUPS: {グループ名}
SLACK_URL: {SLACKのWebhook URL}


SSH key設定

PERMISSIONS -> Checkout SSH keysを選択します。
証明書用リポジトリなど、複数のリポジトリ間で共通のSSH keyを使う必要があるため、
作成したGithubの共通アカウントでCircleCIにログインし、Authorize with Githubボタンを押して、共通アカウントのSSH keyを登録します。他にPodfileなどでプライベートリポジトリを使用している場合も、同様の方法で共通アカウントのSSH keyを登録します。

ビルドを実行して、すべてのレーンが成功すれば設定完了です!



感想

iOSアプリの一連のサブミット作業の自動化は、一度設定してしまえばそれ以降はその作業をCIに任せられるので、他の作業に集中できます。またJenkinsからCircleCIに移行したことのメリットも大きく、今までは社内に設置されているJenkinsが急に体調不良になりジョブやジョブ履歴が消えたりして、丸一日それの対応に時間が取られることもありましたが、CircleCIではその心配がなくなりました。またmatchやdeliverの機能が想像以上に便利で、matchでは証明書の管理を自動化してくれたり、deliverでは今まではバージョン管理していなかったストア上のメタデータやスクリーンショットなどをバージョン管理するようになったり、何よりもアップロードが完了したらあとはビルドを選択して審査に提出ボタンを押すだけの手軽さに感動しました!まだ試されてない方は是非使ってみてください。

明日は2年目エンジニアの壷井くんの、Nginxのリバースプロキシについてのお話です!どうぞお楽しみに!

エンジニア募集

エキサイトではエンジニアとして一緒に働いてくださる方を
新卒採用中途採用で募集しています。
詳しくは、こちらの採用情報ページをご覧ください。


by ex-engineer | 2016-12-07 12:00