フューチャー技術ブログ

iOSアプリのCI入門

はじめに

はじめまして!2021年10月新卒入社、HealthCare Inovation Group(HIG)所属の清水です。

春の入門ブログ連載の22日目は、入門ブログ連載のテーマとして、今までやってこなかったCIをやってみた記事です。

CIについてあまり知らない自分が、プロジェクトにCIを導入したいと思い、実際に調べてみた・試したことをまとめます。

内容

  • CIとは
  • 何はともあれ試してみる
  • iOSアプリでのCI

CIとは

以下は、SaaS型のCI/CDサービスを提供しているCircleCIさんのページからの引用です。

継続的インテグレーション(CI)とは、Continuous Integrationの略であり、デプロイするコードの品質を確保しながら、開発スピードを向上させるDevOpsソフトウェア開発手法です。開発者は継続的にコードを少しずつ(少なくとも1日1回、可能なら1日に数回)コミットし、そのコードが共有リポジトリにマージされる前にビルドとテストが自動的に実行されます。

https://circleci.com/ja/continuous-integration/

私が所属するプロジェクトでは、元々1~3人でアプリ開発を進めていました。

ただ最近は、機能が増えて、プロジェクトに参画する人が増えて、開発者も増えて、改修箇所も増えて、テストも増えて…という状況になっています。アプリの品質を確保しながら、チームでの開発をより安心して前に進めるために、CIを導入したいと思い試し始めました。

ちなみに…

セットになっていることが多いCDは、Continuous Delivery & Deployment(継続的デリバリー及び継続的デプロイ)の略です。
Continuous Deliveryは、いつでもデプロイできる状態にすることを指し、デプロイ自体の操作は手動であり、Continuous Deploymentは、ビルド〜デプロイまでを自動で行うことを指すようです。

何はともあれ試してみる

ここでは実際にSwiftで実装したiOSアプリのリポジトリをCIツールによって自動でビルド&テストするところまで試してみます。

前提

  • macOS: Ventura 13.4
  • Xcode: Version 14.3 (14E222b)
  • CIツール: GitLab CI/CD

普段、業務ではGitLabを利用してバージョン&issueを管理しているため、GitLabのCI/CDツールを利用します。
今回試していく内容の大きな手順は以下です。

  1. iOSアプリのリポジトリを用意
  2. MacにGitLab Runnerをセットアップ
  3. リポジトリにRunnerを登録
  4. リポジトリにCI用のconfigファイルを追加

やっていきます。

iOSアプリのリポジトリを用意

検証用のリポジトリを用意します。今回は、GitLabのtemplateから作成したリポジトリを利用します。

食事の画像とレビューを記録するアプリのようです(初めて使いました)。

アプリのソースコードだけではなく、UnitテストとUIテストのコードも最初から用意されているようです。

GitLab上から見るとこのような状態です。CI/CDのセットアップは未完了です。

MacにGitLab Runnerをセットアップ

ここでは基本的にGitLab公式の記事に従って手元のMacにビルド&テストを実行するためのツールをセットアップします。
Homebrewを利用してインストールすることもできますが、GitLabがメンテナンスしていないようなので、Manual(curl)でインストールしました。

リポジトリにRunnerを登録

次に、GitLabのリポジトリにセットアップしたRunnerを登録します。

GitLabの日本語ブログを参考に進めました。

GitLabのリポジトリ > CI/CD Settings > Runners から登録するためのURL①とトークン②を確認することができます。

ターミナルを立ち上げて、以下のように進めていきます。(一部省略・隠蔽しています。)

gitlab-runner register
Runtime platform arch=amd64 os=darwin pid=12166 revision=dcfb4b66 version=15.10.1

Enter the GitLab instance URL (for example, https://gitlab.com/):
// ①をコピペします。
Enter the registration token:
// ②をコピペします。
Enter a description for the runner:
[XXXXX.local]: ForBlogMyMac // ③Runnerの説明を加えます。
Enter tags for the runner (comma-separated):
blog, // ④タグの設定。技術ブログ用なので、"blog"タグを設定します。
Enter optional maintenance note for the runner:
// 説明とは異なるメモ。今回は空にしている。
Registering runner... succeeded runner=XXXXXX
Enter an executor: virtualbox, docker-ssh+machine, kubernetes, docker-ssh, parallels, shell, ssh, custom, docker, docker+machine, instance:
shell // 実行環境。"xcodebuild"を利用するため、shellを選択しています。
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

Configuration (with the authentication token) was saved in "/Users/XXXXX/.gitlab-runner/config.toml"

GitLab側からRunnerが登録されていることを確認できます。

リポジトリにCI用のconfigファイルを追加

いよいよリポジトリにCI用のファイルを追加します。

GitLabでは、.gitlab-ci.ymlというYAMLファイルでCI/CDパイプラインの構成や順序を定義してきます。

https://gitlab-docs.creationline.com/ee/ci/yaml/

Webから追加できます。

GitLabにtemplateが用意されているため、そちらを使います。

https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/lib/gitlab/ci/templates/Swift.gitlab-ci.yml

上述のtemplateでは、アプリのビルド&テスト→アーカイブの作成→デプロイまで実行しようとしています。

stages:
- build
- test
- archive
- deploy

build_project:
stage: build
script:
- xcodebuild clean -project ProjectName.xcodeproj -scheme SchemeName | xcpretty
- xcodebuild test -project ProjectName.xcodeproj -scheme SchemeName -destination 'platform=iOS Simulator,name=iPhone 8,OS=11.3' | xcpretty -s
tags:
- ios_11-3
- xcode_9-3
- macos_10-13

archive_project:
stage: archive
script:
- xcodebuild clean archive -archivePath build/ProjectName -scheme SchemeName
- xcodebuild -exportArchive -exportFormat ipa -archivePath "build/ProjectName.xcarchive" -exportPath "build/ProjectName.ipa" -exportProvisioningProfile "ProvisioningProfileName"
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
artifacts:
paths:
- build/ProjectName.ipa
tags:
- ios_11-3
- xcode_9-3
- macos_10-13

deploy:
stage: deploy
script: echo "Define your deployment script!"
environment: production

今回は、最低限のビルド&テストのみ実行したいので、以下のように記述しました。

stages:
- build
- test

build_project:
stage: build
script:
- xcodebuild clean -project iOSTemplate.xcodeproj -scheme iOSTemplate
- xcodebuild test -project iOSTemplate.xcodeproj -scheme iOSTemplate -destination 'platform=iOS Simulator,name=iPhone 14 Pro,OS=16.4'
tags:
- blog

templateから大きく違う点は、以下4点です。

  • アーカイブとデプロイを削除
  • xcprettyコマンドを削除(※xcprettyはログを見やすくするライブラリらしいです。)
  • テストを実行するシミュレータを最新のもの(”iPhone 14 Pro,OS=16.4”)に変更
  • tagを登録したblogに設定
    • 事前に登録したtagに含まれるものでないと実行されないため注意

.gitlab-ci.ymlを追加完了すると、処理が実行開始します。(手元のMacBookのファンが元気になり、物理的にも実行しているのが感じられました。)

最小限の構成で、2分ちょっとで完了しました。

ちなみに

誤ったテストを追加してmasterにpushしたところ、ちゃんと失敗になってくれました。

iOSアプリでのCI/CD

本記事では、個人のリポジトリに対して、個人PCをRunnerとして登録してCIを実行しました。

しかし、本記事で設定したリポジトリでチーム開発を進めた場合、リポジトリに変更があるたび登録したPCがCIを実行し続けます。その際にはCI用の実行環境を、自前で用意する(オンプレミス)か、サービスとして提供されているものを利用する必要があります。

ただし、Swiftで実装したiOSアプリをビルドするためには、Xcodeが必要であり、そのためにはmacOSの実行環境が必要となります。

今回は、ツールの選定と検証まで辿り着かなかったですが、今後、業務にCIを導入した際は、CI/CDツール選定とその経緯を記事にしたいと思っています。

終わりに

本記事では、CIについて知らない状態からCI実行までを入門してみました。

今後は、他のツールについての調査と検証を行って業務に導入し、アプリの品質向上に活用していきたいです。

次は齊藤さんのAmazon OpenSearch Serverless を触ってみたです。