対象読者:
- CIについて全然分からない方
- 自動コードレビュー・デプロイツールを使いたいiOSエンジニアの方
- 何も知らない方
とりあえず、基本な概念を把握しましょう
CI/CD とは?
CI は Continuous Integration(継続的インテグレーション) の略です。
CIは共有ブランチに開発者が自分のコードを毎日マージできるような手法になります。テストを含めて結合プロセスを自動化することによってバグを素早く容易に発見できます。それと、CIを使用することで開発チームのソースコード結合するときの問題を最小限に抑え、遠足に開発ができます。
CD は Continuous Delivery(継続的デリバリー) の略です。
CDはCIを拡張した手動で、テスト環境またはステージング環境に変更されたソースコードをアプリとして自動的にリリースできます。本番環境にリリースする前に、開発者が単体テスト・ソフトウェアを検証する事に加えて、UIテスト・負荷テスト・結合テスト・APIテストといったテストの自動化ができます。
CIの仕組み
開発者がコードをリポジトリ(GitHubなど)にコミットでCIの自動プロセスが開始します。一つの変更にしてもCIがトリガーされます。CIプロセスは一般的に下記のシナリオになります。
- まず、リポジトリにコードをコミットする
- CIサーバーとの連携で自動的にリポジトリの変更を検証する(1分一回ぐらい)
- 変更がリポジトリにマージされると、CIサーバーが最新のコードを取得してから、ビルド、単体テスト、結合テストが実行されます。
- CIサーバーがプロジェクトの開発者にフィードバックを送信します
- CIが続けてリポジトリの変更待ち状態に戻ります。
タスクを実装したごとに開発者はプライベートビルド(ローカルに実行する事)を実行して検証します。OKしたらリポジトリにコミットします。変更はリポジトリにマージされていない場合はインテグレーションビルドが事項されません。(プルリクしたのにまだマージされていない状態など)。
CIの方針は “Build Software at Every Change”(変更があれば必ずビルドすること)。そういうのは「僕のローカルに通常に動作できますのに。。」という問題を抜けることになります。
開発チームには複数のメンバーで当然各機能に対して、同時に開発を進め、ブランチにマージしますので、自分が使用しているコードは最新のコードではないことを避けるようにします。開発チームのソースコードの結合する時間を最小限にするために、開発者が常にリポジトリにコードをコミットすれば良いと思われます。
CIの利点
- バグを素早く簡単にに発見し、修正できますのでリスクを減少します。そして、テスト・検証が自動化できるので品質も向上できる
- 繰り返される手動プロセスを最小限に抑え、ビルド・テストを自動化する
- どこでもいつでもデプロイできるソフトウェアを作れます。
この記事では、CIに注目します。 CDについては、別の記事で説明します。
なぜ Travis CIか?
CIツールはたくさんありますが、今回紹介したいのはTravis CIです。
iOSはMac OSであるOSで実行されていますが、MacOSに対応するCIは少なく、対応しても有料および限りになりますのでiOSプロジェクトに対応しているTravis CIを選びました。その上、Travis CIの構成が上記で説明した仕組みと違いが少ないなので、Travis CIが把握できたら他のCIも簡単に設定できます。
Travis-CIのサービスは2つがあります
- 無料 (公開なリポジトリしか使用できない) : https://travis-ci.org/
- 有料 (プライベート・公開の両方に使用できる) : https://travis-ci.com/
無料のURLにアクセスしてから自分のGitHubアカウントでログインし、GitHubでソースを格納しています。
ログインしてから自分のリポジトリが見えます。使用したいリポジトリを選択してからオンにします。
iOSプロジェクトの構成
1. YAMLファイル
- ymlの拡張子があるファイルである
- これはリポジトリ用のCI設定を定義するファイルになります
- CIサービスがリポジトリから自動でソースをクローンします。リポジトリにはファイルがある場合は、ファイルを自動に読んでからyamlファイルに定義しているコンテンツの通りに設定されます
- Travis CIの場合はファイル名が.travis.ymlになります
例:
language: objective-c
osx_image: xcode10.1
xcode_workspace: TheLastProject.xcworkspace
xcode_scheme: TheLastProject_Development
xcode_destination: platform=iOS Simulator,OS=12.1,name=iPhone X
before_install:
- bundle install
- bundle exec pod install --repo-update
2. YAMLを
ブランチを新規作成し、上記例のような設定する値で .travis.ymlの名称で新ファイルを作成します。
作成したら、リポジトリにプッシュしてプルリクエストを作ります。
Travis BOT の黄色が表示されます。CIの動きおよびログを参照できます。デフォルトとして新しいプルリクエストがあるとき、もしくは Master.にコミット・マージがあるときにTravis CIは自動的に検証します。
3. ビルドのトリガー
- ビルドトリガーはデフォルトでTracis CIがマスターへの プルリクエストをトラッキングします
- そのため、 正しいブランチ を作成してから プルリクエスト を作ります。そこから、その ブランチ にコミットし、プッシュしたらCIが動き始めます。
- 今回の説明しているのは無料版になりますので、今度、有料版の複雑なトリガーを説明します。
Travis CIを開くと、GitHubから自動的に設定を取得し、プロジェクトのビルドを行うことが見れます。
実行しているログを参照できます。
このプロセスはYAMLの設定により時間がかかります。それと、初回実行する時や複数のリポジトリで実行する時も遅くなります。なぜなら、無料アカウントで1つの job しかないというからです。
4. YAMLファイルのストラクチャー
- language
- TravisObjective-C と Swiftを対応しています
- ただ、設定するときにobjective-cにします。
- osx_image
- これはプロジェクトのビルドする仮想マシンである
- 仮想マシンのOSはたくさんあって、プロジェクトに対応しないものを使用する場合はビルドできないため、プロジェクトに適切な仮想マシンを選んでください。
- Travis CIが対応している仮想マシンはにこちらなります
- xcode_workspace
- ワークスペースには多くのプロジェクトがあります(Pod、現行プロジェクト、プロジェクトから直接にビルドする場合のライブラリー)
- そのため、正しく選択してください。
- フォルダーがあればパスを指定します。例えば:
./Example/TravisCIBlog.xcworkspace
- xcode_scheme
- どのスキームでビルドするかを設定する。スキームが違ったらアプリが全然違いますので気をつけて選んでください。
- それと、CIがビルドできるようにスキームのシェアすることも必要になります。(Scheme -> Management —>選択)
- xcode_destination
- iPhone simulatorを使用する時のオプション
- ビルド用の仮想マシンを選ぶ
- 対応している仮想マシンは こちら
- before_install
- 実施する前に実行されるコマンド
- 仮想マシンはローカルのパソコンと違って、podなどのコマンドを手動で実行することができないので事前にコマンドの追加が必要です。
before_install:
- bundle install
- bundle exec pod install --repo-update
そうすると。。。初回は絶対正常に動けないので大丈夫ですよね〜笑
何回も失敗することがありますので、気にしないで、落ち着いて続けましょう。エラーログを確認して修正しましょう。次にして修正のヒントを紹介します
iOSプロジェクトを構成
- yaml file を設定したらCIが正常に実行できるわけではないです。下記でよくあるエラーを紹介します。
The command "set -o pipefail && xcodebuild -workspace TheLastProject.xcworkspace -scheme TheLastProject_Development build test | xcpretty" exited with 66
- このエラーに対して、プロジェクトにはテストの対象があるかを確認すべきです。ない場合は
- テストの対象を追加 (単体 & UI)
- テストのビルドを設定
- 各スキームを確認
- 次のよくあるエラーは
error: No profiles for 'com.fx.TheLastProject' were found: Xcode couldn't find any iOS App Development provisioning profiles matching 'com.fx.TheLastProject'. Automatic signing is disabled and unable to generate a profile. To enable automatic signing, pass -allowProvisioningUpdates to xcodebuild. (in target 'TheLastProject')
- dev, certificate, provisioning profile … のプロフィールが漏れてしまいました。簡単に言うとビルド用の dev signing の部分がないからです。修正方法は:
- auto signingをオフにする
- オフにしてもできない場合は team developerを削除する
- 他には、 xcode_destinationを確認し、 simulator が実行できるように設定を変えましょう。
- 成功した場合は
- 他のビルドを確認
- GitHubのはこのような画面になります
- 単体テスト・UIテストもCIに実施されています。
YAMLファイルを綺麗にします
- cache : bundler と pod の実行時間が結構長いですので、こちらに再度キャッシュします。キャッシュフォルダーのパスを指定します
cache:
- bundler
- cocoapods
- script: 複雑のコマンドを実行するためです
- install: 他の設定・ツールを追加します
こちらは自分のサンプル yaml file です
language: objective-c
osx_image: xcode10.1
cache:
- bundler
- cocoapods
xcode_workspace: TheLastProject.xcworkspace
xcode_scheme: TheLastProject_Development
xcode_destination: platform=iOS Simulator,OS=12.1,name=iPhone X
before_install:
- bundle install
- bundle exec pod install --repo-update
install:
- set -o pipefail
- sudo systemsetup -settimezone Asia/Ho_Chi_Minh
- bundle install --path=vendor/bundle --jobs 4 --retry 3
まとめ
CIは:
- 仮想マシンである
- CIでiOSプロジェクトが実行できるために、仮想マシンのOSはMAC OS にしてXcodeをインストールする
- iOSプロジェクトがビルドできるにはプロジェクトの設定と仮想マシンのXcodeとSimulator設定が合ってるかを確認する
- Simulator実行できるため、cocoapodにあるライブラリーをインストールする
- スクリプト とYAML Fileを確認する
- CIの動作を早くするためにYAMLファイルを最適化する
以上でありがとうございます!