[iOS] CircleCI, fastlane, Fabric を用いたCI環境と自動ベータ配布環境の構築「前編」

Date
March 18, 2016

こんにちは。CTOの kamoc です。

本連載では iOS アプリの開発におけるCircleCIを用いたCI環境構築と、Fabric/Crashlyticsへの自動ベータ版配布を実現する手順を紹介します。構成図は以下の通りです。

左から順に説明を記載します。

image
  1. XcodeでiOSアプリを開発
  2. GitHubにPush
  3. CircleCIがHookしてビルド/テストを実行
  4. Fastlaneでベータ配布版をビルド(.ipaファイルを作成)
  5. 4.で作成した.ipaファイルを Fabric/Crashlytics へアップロード
  6. Slackに通知

といったことを実現して行きます。 本記事では、5のFabric/Crashlyticsを除いた内容を紹介し、Fabric/Crashlyticsについては

で紹介します。

解決したい課題

最も解決したいのは、Provisioning Profile や証明書の問題にハマって時間を浪費することと、ハマることで開発者のヘイトが溜まることです。

iOS開発をしているとビルド周りの問題って結構頻繁に発生します。

  • AdHoc配布用のビルドがうまくいきません!
  • 最新版のProvisionig Profileでビルドしたはずなのに、○○さんの端末でインストールできません!
  • 昨日までビルドできていたのに、今朝になったらできなくなりました!

というような声を耳にして、その度に有識者が対応に当たっていました。

流石に毎度トラブルが起こる度に対応というのはよろしくないので、自動ビルド/テストからベータ配布を行うまでを自動化することにしました。

CircleCIの導入

プランについて

記事執筆時点(2016/03/16)では CircleCI でiOSアプリをビルドするためには、有料プランの加入が必須となります。 SEED, STARTUP, GROWTH, MOBILE FOCUSED の4つのプランがあり、GROWTHは2週間無料で試すことができます。

image

プラン間での違いは以下の通りです。

  • 同時にビルドを実行できる数
  • 月間での稼働時間上限
  • サポートの有無(恐らく英語)

なお、以下の項目はあくまで推奨値であり、制限がかかるわけではないようです。

  • 1日のビルド数
  • チームメンバー数

無料トライアル時にクレジットカード情報の入力や、自動での本会員移行は無いようなので、まずはGROWTHでトライアルに申し込み、期間終了後SEEDプランで課金する方針で行きます。

申し込んだら、ブラウザのCircleCIページからプロジェクトのリポジトリを追加します。

スキーム設定ファイル(.xcscheme )の作成

ここからは細かい手順の話になります。 今回は“SikmiBlog”というプロジェクトを例に使用します。 まずは以下の手順でスキーム設定ファイルを作成してリポジトリに追加します。

  1. Xcode メニュー > Product > Scheme > Manage schemes… を選択
  2. 対象のスキームの“Shared”にチェックを入れる(画像参照)
  3. image
  4. .xcschemeファイルができていることを確認
$ find . -name "*.xcscheme"
./SikmiBlog.xcodeproj/xcshareddata/xcschemes/SikmiBlog.xcscheme

circle.yml の作成

circle.yml をリポジトリルートに作成します。 今回作成した circle.yml ファイルは以下の通りです。

machine:
xcode:
version: 7.2
environment:
XCODE_SCHEME: SikmiBlog #=> スキーム名
XCODE_PROJECT: ./SikmiBlog/SikmiBlog.xcodeproj #=> .xcodeproj ファイルへの相対パス
GYM_CODE_SIGNING_IDENTITY: "iPhone Distribution: Sikmi Inc. (WPSV9RT9QG)" #=> コード署名に使うIDを設定(後述)

# 後述する fastlane を利用するために bundle install を行う

dependencies:
override:
- cd SikmiBlog && bundle install

# develop ブランチにコードがPushされた時に fastlane(後述) の beta レーンを実行

deployment:
develop:
branch: develop
commands:
- cd SikmiBlog && bundle exec fastlane beta

CocoaPods を利用している場合は、 XCODE_PROJECT の代わりにXCODE_WORKSPACE に . xcworkspace への相対パスを入力します。

CircleCIに証明書ファイル(.p12)を登録

CircleCI の Project Setting ページを開き、 Permissions > OS X Code Signing を選択して、.p12 ファイルをアップロードします。 この時、.p12ファイルのファイル名に全角文字が含まれるとエラーになるので注意して下さい。

image

GYM_CODE_SIGNING_IDENTITY の調べ方

前の手順でアップロードした証明書ファイルをローカル環境のキーチェインにも登録し、以下のコマンドを実行します。

security find-identity -p codesigning

すると、ローカル環境にインストールされた証明書一覧が表示されるので、該当するIDの名前をコピーしてcircle.ymlファイルに貼り付けます。

Provisioning Profile をリポジトリに設置

前の手順でアップロードした .p12 に対応したProvisioning Profileをリポジトリに追加します。

fastlane の導入

次にfastlaneを導入していきます。 筆者も fastlane のついてまだ探り探りですが、ざっくり言うと「iOS開発周辺の面倒事をラクにしてくれる素敵なツール群」といった感じです。今回は fastlane に AdHoc の ipa 作成と、Fabric / Crashlytics へのベータ配布を担当してもらいます。 それでは、早速インストールしていきましょう。(bundler は既にinstallされていることを前提としています)

$ bundle init
$ vim Gemfile
source "https://rubygems.org"

gem "fastlane" #=> この行を追加する
$ bundle install
$ bundle exec fastlane init

最後のコマンドを実行すると対話式でいろいろと聞かれるので回答すると、 プロジェクトのルートディレクトリに“fastlane”ディレクトリが作成されます。 その中の “Fastfile” に fastlane のツール群を使った振る舞いを定義していきます。

以下の Fastfile ではテストを実行する test レーンと、ビルドしてipaファイルを生成して Fabric / Crashlytics にベータ版を配布する beta レーンを定義しています。 また、終了時にビルド結果がSlackに通知されるようになっています。

fastlane_version "1.66.0"

default_platform :ios

platform :ios do
before_all do
ENV["SLACK_URL"] = "https://hooks.slack.com/services/・・・・・"
end

desc "テストを実行"
lane :test do
scan
end

desc "ベータ版をFabric/Crashlyticsにデプロイ"
lane :beta do
gym(scheme: "SikmiBlog", use_legacy_build_api: true)

# Fabric / Crashlytics へのデプロイについては次の記事にて紹介します。
end

after_all do |lane|
slack(
message: "Successfully deployed new App Update."
)
end

error do |lane, exception|
slack(
message: exception.message,
success: false
)
end
end

ここまでの手順を実行してGitHubにコードをPushすると、自動的にビルドが行われ、結果がSlackに飛んで来ます。 今回の記事で紹介する導入手順は以上です。

付録 ハマりどころとその対応

最後に、環境構築をする上でハマったことと、その対処法を書いておきます。

Code Sign error でビルドに失敗する

「またお前か!」と言いたくなるくらい見慣れたやつです。

Code Sign error: No code signing identities found: No valid signing identities (i.e. certificate and private key pair) were found.

このエラーが発生した場合は、以下の手順を行ったか確認してください。 1. CircleCIに証明書ファイル(.p12)を登録していない #=> 行っていない場合は 「CircleCIに証明書ファイル(.p12)を登録」の手順を実施 2. circle.yml でGYM_CODE_SIGNING_IDENTITY を正しく設定していない #=> 行っていない場合は「circle.yml の作成」の内容を再度読み返して下さい。

CircleCIのビルドが “NO TESTS” となって失敗する

テストが存在するはずなのに、 以下の警告が表示され、“NO TESTS” でビルドに失敗しました。

Warning: CircleCI has located an Xcode project or workspace in this repository. CircleCI is currently offering limited release to our iOS build system. Please contact support if you would like access.

これは、プロジェクト設定の Build OS X project が何故かデフォルトで Off になっており、OS X 環境でビルドされていないことが原因だったようです。 少しわかりにくいので設定箇所のスクショを載せておきます。

image

fastlaneのgymによるパッケージングに失敗する

以下のエラーメッセージが表示されました。

[23:27:30]: Exit status: 70
[23:27:30]: 2016-03-17 14:27:29 +0000 [MT] Running step: IDEDistributionSigningAssetsStep with ', distributionTask(resolved)='2', distributionMethod(resolved)='', teamID(resolved)='(null)'>
Chain (2, self inclusive):
', teamID='(null)'>
', distributionMethod='(null)', teamID='(null)'>
</IDEDistributionContext: 0x7fee0df00bb0>
・・・(中略)・・・
[23:27:30]: There was an error exporting your application
[23:27:30]: Unfortunately the new Xcode export API is unstable and causes problems on some project
[23:27:30]: You can temporary use the :use_legacy_build_api option to get the build to work again

この問題ですが、メッセージの指示通り、use_legacy_build_api オプションを指定してやることによって解決しました。 具体的には、Fastlaneファイルの以下の箇所を修正してオプションを設定します。

gym(scheme: "SikmiBlog", use_legacy_build_api: true)

まとめ

本記事では CrcleCI, fastlane を用いたCI環境構築手順を紹介しました。 次回は作成した .ipa ファイルを自動的に Fabric/Crashlytics でベータ配布する手順を紹介していきます。

しくみ製作所では一緒に働く仲間を募集しています。 この記事に興味を持った、ラクすることが好きな面倒くさがり(褒め言葉)な方をお待ちしています。

Twitter @kamomc か、 kamo(at)sikmi.com までお気軽にご連絡下さい!

ルンバかわいいよ。 ルンバ。