iOS開発でGitLab CIしてみた

突如はじまった Origami Advent Calender を埋めるべく、
五日目の記事としてGitLab CI、とくにiOS向けについて書かせていただきます。

※ この記事は、2016/11/29 potatotips開催での発表内容の詳細版かつ、
より感情的なバージョンです。
（[GitLab CI の布教 for iOS - 2016/11/29](http://www.slideshare.net/IkadaKaori/potatotips-35)）

# Abstract
GitLab CIは、いままでiOS開発におけるCI選びでJenkins一択しかなかった人に特にオススメです。

その他、GitLab使ってる人は気軽にCIはじめるのにいかがでしょうか。
.travis.yml みたいなノリなので iOS については [fastlane](https://github.com/fastlane/fastlane) をゴリゴリ使うと良いと思います。

Android については iOS ほど縛りがないため詳しく書きませんが、
gradle などでビルド設定をちゃんとしてると、すぐ移行できると思います。

また、GitLab CI Multi Runner は golang 製だったので、
弊社としては勝手に親近感わきました。

※　GitLab CI　Build中の様子
![](https://cacoo.com/diagrams/PsQgTgAM30w3pZfv-E8693.png)


# たぶん、この話の対象者

- GitLab 使ってる人
- Jenkins など自分でコードや設定保管できるCI環境でいたい人
- コマンドで動かしときたい、ビルド設定をGUIなものに依存されたくない人
- iOS のため Mac 環境縛りがあるけど、全リポジトリのCIを統一したいチーム

# 環境
- GitLab 8.14.0
- gitlab-ci-multi-runner 1.7
- MacOS Sierra
- Xcode8.1

# CI/CD Configuration
　1. **Trigger** : git push や retry, pipeline を作成など trigger となるアクションをします
　2. **Pipeline** : GitLab のところで pipeline が作成されます
　3. **Building** : 新しいBuildが検知できたら登録されたRunnerで該当ジョブを走らせます
　4. **Destribution** : deploygate がやっていますが、アーカイブできたら deploygate にデプロイします
　
![](https://cacoo.com/diagrams/PsQgTgAM30w3pZfv-368CF.png)

 ※ GitLab CI Multi Runner が走っているマシンが何秒か毎にGitLabに新しいbuildが立ってないか確認しています

 ※ GitLab CI Multi Runner が走るマシンについては社内のすみっこに置いてある iMac を利用しているんですが、あまり頻繁に物理的に触らないため非エンジニアに軽視されているのが悩みのタネです。

# How to Start
Runner登録まではかなり簡単です。
　1. Gitlab で CI を有効化
　2. Macマシンに MultiRunner をインストール
　3. Runnerの登録

### 公式Links
- [Enable or disable GitLab CI](http://docs.gitlab.com/ee/ci/enable_or_disable_ci.html)
- [Install on MacOS](https://docs.gitlab.com/runner/install/osx.html)
- [Setting up GitLab CI for iOS projects](https://about.gitlab.com/2016/03/10/setting-up-gitlab-ci-for-ios-projects/)


# ジョブの作成 `.gitlab-ci.yml`
リポジトリ直下に.gitlab-ci.ymlを置く

```xml:.gitlab-ci.yml
before_script:
  - echo "Start gitlab ci runner"
  - # DeploygateのAPIKeyなどはマシン上に設定
  - . ~/.bashrc_runner 
  - bundle install

ios-master:
  stage: archive
  script:
    - # ビルド実行コマンド
    - bundle exec fastlane dg  
  only:
    - # ブランチを指定
    - master
  tags:
    - # タグ指定で走らせるRunnerを選べる
    - # マシン名つけとく運用にしてみた
    - jenkins.local
```

 ※ iOSの場合、runnerが実行される環境としてshellを選択しますが、とくに指定しなければbashで動くようです。またrunner実行時に `~/.bashrc` などは読み込んでいないようなので runner用に設定ファイルを用意すると良さげです。

# Build 失敗例
実際つらかったフェーズ
#### **git clone が失敗する、時間がかかる場合**
  - 予め job の該当箇所に ローカルコピーしておく
  - `pre_build_script` で git 環境変数設定

#### **想定していた runner とは別の runner が動いていた**
  - Shared な runner が実行されていた → Disable に
  - 個人のマシンで試しに追加した runner が走ってしまう → Tagを利用する

#### **Sierra で動かなかった**
  - 待った。milestoneの期限通りに対応バージョンが出た。定期的にアップデートされてる様子

#### **正しく設定されていても Code Signing でビルド失敗する**
  - AdHocビルド以外のBuildConfigもエラーが出てない状態にしておく


# おまけ： Runnerが走るマシンの設定 `config.toml`
軽量プロジェクトであればあまりいじらなくて大丈夫そうです。

- 場所はだいたいここ→ ~/.gitlab-runner/config.toml
- マシンに登録されたrunnerの設定も入ってる

```go:config.toml
concurrent = 1
check_interval = 30 　  // 30秒ごとにGitLabに新しいpipelineがないかCheck（単位:秒）

[[runners]]
<略>

output_limit = 8192   // 吐くログの量が制限されている。デフォルトで4096(4MB)
pre_build_script = "path/file"   // gitリポジトリからクローンされる前に実行させたいスクリプトを指定できる

<略>

```

その他設定: [advanced-configuration](https://docs.gitlab.com/runner/configuration/advanced-configuration.html)


# 導入後の感想
## :grinning:
- チームを Jenkins 縛りから解放できたことで、他プロジェクト（Webフロントエンドなど）がJenkinsしなくてよくなりました。勘違いでなければほんの一部から感謝もされたと思います。

## :hushed:
- せっかく設定したSwiftLintの結果を表示するのを再考しなければならなくなった。

# 今後やっていきたいこと
- LaunchDaemon で実行させときたい
- こういうかっこいいのやりたい 
 ![](https://cacoo.com/diagrams/PsQgTgAM30w3pZfv-BBCC1.png)

# Thank you

こちらの記事がなければたぶん始めようと思いませんでした。感謝:pray:

- [GitLab CIでXcodeプロジェクトをCIする手順](http://qiita.com/enmtknt/items/83935c1137203e1c2c0f)
- [GitLab CIでiOSアプリをビルドし、ipaを配布する](http://qiita.com/enmtknt/items/966144d6bc40ec093ac3)

# We are hiring

多分採用されると思うから応募しようぜ

- https://www.wantedly.com/companies/origami/projects