iOSプロジェクトのGitLab-CI環境を構築してみた

## はじめに

iOSアプリを開発してみようと思って先日から[Start Developing iOS Apps](https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/index.html#//apple_ref/doc/uid/TP40011343-CH2-SW1) を見ながらお勉強してました。
やっと一通り終えてチュートリアルアプリが完成したので、その流れでGitLab-CI環境も構築してみた次第です。

## できるようになったこと
* ソースをリポジトリにpushするたびに自動ビルド・テストを実行する

まだ開発者アカウントを取得していないのでここまで。。。

## 前提とか
* [Start Developing iOS Apps](https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/index.html#//apple_ref/doc/uid/TP40011343-CH2-SW1) で作ったチュートリアルアプリを例にあげて書きます
	* すなわち最低限のUnit Testはすでにできている
* 基本的に[GitLabの公式ドキュメント](https://gitlab.com/help/ci/quick_start/README)に書いてあるとおりにやっただけです
* 上にも書いたとおり開発者アカウントを取得していないので自動ビルドとテストまで

### 環境
* GitLab Enterprise Edition 10.2.4-ee (gitlab.com)
* Xcode 9.2
* macOS High Sierra (10.13.2)

## .gitlab-ci.ymlの作成
GitLab上からテンプレートを使って.gitlab-ci.ymlとCI環境を構築するブランチとを作成します。

1. GitLabのプロジェクトトップページ -> `Set up CI`

	![setupci.png](https://qiita-image-store.s3.amazonaws.com/0/222294/f9fecd78-cac4-ad1e-9c3c-e96033d10b89.png)

2. `Apply a GitLab CI Yaml template` -> `Swift`
	* テンプレートが作成されます
3. `Target Branch`を任意のブランチ名に書き換える
	* ここでは`ci-pipeline`
4. `Start a new merge request with these changes`のチェックを外す
5. `Commit changes`
![addyaml.png](https://qiita-image-store.s3.amazonaws.com/0/222294/ed104a11-2dd2-4134-0546-6c3abd6e366b.png)

## GitLab Runnerの構築
[公式ドキュメント](https://docs.gitlab.com/runner/install/osx.html)に書いてあるとおりに実行していきます。

1. バイナリのダウンロード 

	```
	$ sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64
	```
2. 実行権限の付与

	```
	$ sudo chmod +x /usr/local/bin/gitlab-runner
	```
3. Runnerの登録

	ここも[公式ドキュメント](https://docs.gitlab.com/runner/register/index.html#macos)を参考に進めます。
	1. 以下のコマンドを実行

		```
		$ gitlab-runner register
		```
	2. GitLabインスタンスのURLを入力
	
		```
		Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
		https://gitlab.com
		```
	3. トークンを入力

		```
		Please enter the gitlab-ci token for this runner
		xxx
		```
	`xxx`には実際のトークンを入力します。GitLabの`Setting` -> `CI/CD`から確認できます。(画像の黒塗り部分)

		![token.png](https://qiita-image-store.s3.amazonaws.com/0/222294/f4af9c20-b4b9-41ed-0fff-4027b8def8e0.png)

	4. Runnerのホスト名を入力

		```
		Please enter the gitlab-ci description for this runner
		[hostame] my-runner
		```
		ここでは`my-runner`と入力します。
	5. Runnerに関連付けるタグを入力

		```
		Please enter the gitlab-ci tags for this runner (comma separated):
		ios_11-2, xcode_9-2, macos_10-13-2
		```
		ここでは`ios_11-2, xcode_9-2, macos_10-13-2`と入力します。任意のタグでいいのですが、(後述する).gitlab-ci.ymlの内容と一致させる必要があるので注意。
	6. タグのないジョブを実行するか選択

		```
		Whether to run untagged jobs [true/false]:
		[false]: true
		```
		あとで変えられるのでとりあえず`true`
	7. Runnerを現在のプロジェクトにロックするか選択

		```
		Whether to lock Runner to current project [true/false]:
		[true]: true
		```
		ここもあとで変えられるのでとりあえず`true`
		
	8. Runner executorの入力

		```
		Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
		shell
		```
		`shell`を選択します。
		
4. Runnerをインストールして実行

	```
	$ cd ~
	$ gitlab-runner install
	$ gitlab-runner start
	```
	ここで一応Runnerが動いていることを確認してみましょう。
	
	```
	$ gitlab-runner status
	gitlab-runner: Service is running!
	```
	問題なければ`gitlab-runner: Service is running!`と出力されるはずです。
5. Runnerのアップデート

	1. サービスの一旦停止

		```
		$ gitlab-runner stop
		```
		
	2. バイナリのダウンロード

		```
		$ curl -o /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64
		```
		
	3. 実行権限の付与

		```
		$ chmod +x /usr/local/bin/gitlab-runner
		```
		
	4. サービスの再開

		```
		$ gitlab-runner start
		```

## Xcodeプロジェクトの設定
[公式ドキュメント](https://about.gitlab.com/2016/03/10/setting-up-gitlab-ci-for-ios-projects/)を参考にプロジェクトをsharedに設定します。

> By sharing your scheme, GitLab CI gets context it needs to build and test your project.
> To share a scheme in Xcode, choose Product > Scheme > Manage Schemes.

![shared.png](https://qiita-image-store.s3.amazonaws.com/0/222294/e7301238-28d6-2eff-3d7a-a87d0ce75437.png)


## xcpretty のインストール
xcprettyというモジュールが必要なためインストールします。

```
$ gem install xcpretty
```

## .gitlab-ci.ymlの編集
テンプレートのままでは通らないので編集します。

### 変更点

* `stages: `から`- archive`を削除
* `ProjectName`を`FoodTracker`に
* `SchemeName`を`FoodTracker`に
* `name=iPhone 6s,OS=9.2`を`name=iPhone 7,OS=11.2`に
* `tags:`を[GitLab Runnerの構築](#gitlab-runnerの構築)で設定したとおりに変更
* `archive_project: `以下をごっそり削除

### 編集後のファイル
```
# This file is a template, and might need editing before it works on your project.
# Lifted from: https://about.gitlab.com/2016/03/10/setting-up-gitlab-ci-for-ios-projects/
# This file assumes an own GitLab CI runner, setup on an OS X system.
stages:
  - build

build_project:
  stage: build
  script:
    - xcodebuild clean -project FoodTracker.xcodeproj -scheme FoodTracker | xcpretty
    - xcodebuild test -project FoodTracker.xcodeproj -scheme FoodTracker -destination 'platform=iOS Simulator,name=iPhone 7,OS=11.2' | xcpretty -s
  tags:
    - ios_11-2
    - xcode_9-2
    - macos_10-13-2
```

## .gitlab-ci.ymlのpush
.gitlab-ci.ymlをpushして自動ビルド・テストが走るか確認します。

その前に、手元で以下を実行してみます。当然うまくできなければ自動化してもこけるので。。。

```
$ xcodebuild clean -project FoodTracker.xcodeproj -scheme FoodTracker | xcpretty
$ xcodebuild test -project FoodTracker.xcodeproj -scheme FoodTracker -destination 'platform=iOS Simulator,name=iPhone 7,OS=11.2' | xcpretty -s
```

問題なければpushしちゃいましょう。

```
$ git add .gitlab-ci.yml
$ git commit -m "update .gitlab-ci.yml"
$ git push origin ci-pipeline
```

## 事後確認

プロジェクトの`CI/CD` -> `Pipelines`からステータスが`passed`になっていることが確認できればおわりです。

あとはソースをpushするたびに自動ビルド・テストが走ってくれるはずです。

![after.png](https://qiita-image-store.s3.amazonaws.com/0/222294/c197983c-b9ab-c58f-c96d-5e212c9a5db0.png)


## おわりに

イマドキな開発をやってみたくてCI構築してみました。

近いうちに開発者アカウントを取得して配布用パッケージの作成とかまでやってみようかと思います。