大晦日〜正月にiOSでCircleCIを試したので振り返ってみた

##はじめに
皆様、新年あけましておめでとうございます
今年も不定期に思いつきで記事をあげていくのでよろしくお願いいたしますm(_ _)m

昨今TravisCIに代表されるCIサービスが流行ってますね。
Rettyでは内製JenkinsでCIを頑張っているのですが、[CircleCIでiOSのBetaできるよって公式ドキュメント](https://circleci.com/docs/ios)を見つけたので、大晦日〜正月にかけてトライしてみました。

だいぶ記事が長いので「結論から知りたい」という方は[こちらのまとめ](http://qiita.com/saku/items/9c093535967e4452a8d0#%E3%81%BE%E3%81%A8%E3%82%81)から御覧くださいませ。

##CircleCI事始め
###アカウントの作成
まずはアカウントを作ります。
アカウントはGithub認証を利用したものになるため、Githubアカウントがないと登録できません。
CircleCIのアカウント作成は[こちら](https://circleci.com/)からどうぞ。

###対象リポジトリの選択
登録したらまずはCI対象にするリポジトリを選びます。
アカウントにOrganizationのリポジトリの権限があればそれらも自動でリストアップされます。

![スクリーンショット 2015-01-01 18.58.07.png](https://qiita-image-store.s3.amazonaws.com/0/34824/357ad6bc-9c56-704f-9a60-a0f278b6c7e2.png)

対象のアカウント（個人 or Organization）を選びリポジトリを選択すると、Githubの認証画面がはさまりCircleCIからGithubのリポジトリにアクセスする権限を与えてよいか確認が入ります。
許可するとビルド画面に遷移して、自動でインスタンスが立ち上がり（中身はなんかDockerっぽい？）Githubからコードを取得して実行しようとします。
しかし、最初の実行はテストの設定をしていないため No Tests と表示されて終了します。

![スクリーンショット 2015-01-01 18.42.47.png](https://qiita-image-store.s3.amazonaws.com/0/34824/f34056e6-021b-d3c3-18af-b8e33c48f4b3.png)

とはいえ、まだドキュメントにあったiOSビルドのための設定をしてなかったのでここで実行されてもどうしようも無いというか（^^;

###iOSビルドの有効化、そして挫折へ
まずはドキュメントに従い `Project Setting -> Experimental Settings` を見ると確かに `Build iOS project` という項目があります。

![スクリーンショット 2015-01-01 18.38.30.png](https://qiita-image-store.s3.amazonaws.com/0/34824/c28c0be0-3242-366c-eae2-ccbe1aa0ecf4.png)

これをOnにすればめくるめくiOS CI環境の世界が・・・と思ってた時期が私にもありました(´・ω・｀)
何故かビルドがスタートしません。

よくよく見ると以下のようなWarningが出ていました。

![スクリーンショット 2015-01-01 18.46.18.png](https://qiita-image-store.s3.amazonaws.com/0/34824/31f1cf41-4de7-f2c8-2da8-e8ddbc24a3fb.png)

要約すると、「ゴメンね、キミのところのチームはまだiOSビルドを許可されてないんだ(・ω<) あっでも気軽にサポートに連絡してYO」という感じ。
なんのための設定画面だったのかと思いつつも、サポートページを探しました。

###神対応のサポート
画面右下にあるヘルプっぽいボタンを押すと右からシュッと問い合わせ用の画面が出てきます。
大晦日だしもう今日は進められないなーと思いつつ、サポートに質問を投げてみるとなんと３時間で返信がありました！
曰く、「キミのチームのiOSビルドを有効にしたから、さっそくトライしてみてよ」

![スクリーンショット 2015-01-01 12.54.45.png](https://qiita-image-store.s3.amazonaws.com/0/34824/3fbfcd4e-f428-dc9d-1055-a0e550abd594.png)


時差があるとはいえ、アメリカも新年のはずなのに・・・((；ﾟДﾟ))ｶﾞｸﾌﾞﾙ
さっそくお礼を言ってやってみるとうまくいきました！ありがとうRobさん、マジで神対応でした！！

しかし全画面にサポートとのやりとりのための動線があるのはいいですね。困ってもすぐに質問ができるし、チャット風のUIなのもわかりやすくて便利でした。これはなにかのライブラリなのかな？

###再チャレンジと挫折その２
ビルドもうまく実行されたので、さっそくもう一回テストのために再ビルドしてみました。
すると、「machine」の「Restore cache」というフェーズで固まってしまい先に進んでくれません。。。

![スクリーンショット 2015-01-01 21.00.00.png](https://qiita-image-store.s3.amazonaws.com/0/34824/eb9b7b4c-19c0-90e1-4155-bd03a0d763d9.png)

最初のうまくいったビルドが5分くらいで終わるのに、「machine」の「Restore cache」で10分以上かかっても先に進んでくれません。

色々試してみると「cache clear & build」するとうまくいくということがわかりました。
このあたり謎が多く、circle.yml（CircleCIの設定ファイル） でmachineフェーズのtimeoutを設定してみたりしましたが、そんな設定はできないと怒られたりまた行き詰まってしまいました。
そんなわけで正月からまたサポートにお助けメッセージを送って初詣に行ってきました。

###神対応ふたたび
初詣から帰って再び開いてみると返信が！
（画像は時間がたってからスクショしたので表示が変です）
どうやら向こう側のバグのようで、さっそく修正対応したのでもう一度試してみてくれ、とのこと。
なんなんだ、この対応の速さは・・・？！((((；ﾟДﾟ))))ｶﾞｸｶﾞｸﾌﾞﾙﾌﾞﾙ

![スクリーンショット 2015-01-01 20.58.30.png](https://qiita-image-store.s3.amazonaws.com/0/34824/92bdb0dc-e321-aeb7-9118-3c3a74b9ddc6.png)

実際にcache clearせずにrebuildしてみたところスムーズに実行され、テストもうまくいきました。

##CircleCI設定編
だいたいうまくいったので、今度は設定のほうを進めます。
（実際には上記手順の中でもXCODE_SCHEMEという環境変数を設定していましたが、分散して書くとややこしいのでこちらに記載）
今回はテストのために以下の３つの設定を行いました。

 * XCODE_SCHEMEの設定
 * pod install の実行
 * xcodebuild test の実行

設定項目は基本的には管理画面（UI）でも設定ファイル（circle.yml）でもどちらでも大丈夫ですが、今回は circle.yml のみ説明します。
実際にやるときは、管理画面で設定を試しつつ、それでうまくいくとわかったタイミングで circle.yml に書き換えていくのがオススメです。

###最終的なcircle.yml
こんな感じになりました。それぞれ解説していきます。

```yml
machine:
  environment:
    XCODE_SCHEME: Retty
dependencies:
  override:
    - pod install:
        timeout: 300
test:
  override:
    - xcodebuild test -scheme Retty -workspace Retty.xcworkspace -destination 'name=iPhone 6'
```

 * machine フェーズで環境変数 XCODE_SCHEME に Retty を指定
	 * [CircleCIのドキュメント](https://circleci.com/docs/ios)にもありましたが、複数のスキーマがある場合はこれを指定しないとどのスキーマが指定されるかわからない状態になります
 * dependencies フェーズで pod install を実行
 * test フェーズで xcode build を実行
	 * 今はテキトーに destination 付けてましたが、これはまぁ sdk でもいいです

##追記(2015.01.06)
###ChatOpsとの連携
RettyではSlackを使い始めてHerokuにHubotを置くようになったので、これを使って最近流行りのChatOpsも書いてみました。
目的としては２つ。Nightly buildと任意のタイミングで簡単にテスト実行をすることです。

というわけで作成したcoffeeスクリプトとpackage.json（その他のライブラリもだいぶ入ってますｗ）を書いておきます。
npmのcircleciモジュールはまだビルド環境変数の指定はできないようですので、それをしたい場合には個別にREST APIを叩く必要がありそうです。
circleci.coffee の `new cron` の部分でcronの定義を（この場合は日本時間の23:00にテスト開始）、bot に対して `ios test` とmentionを送ると #dev というチャンネルに `OK. ios test start` とbotが応答してテストが開始されるようになりました。
API Key と username, projectname 部分はご自身の環境に合わせて変えてみてください。

package.json

```json
{
  "name": "slackbot",
  "version": "0.0.0",
  "private": true,
  "author": "hogehoge@example.com",
  "description": "retty",
  "dependencies": {
    "hubot-maps": "0.0.0",
    "hubot-google-images": "~0.1.1",
    "hubot-help": "~0.1.1",
    "hubot-diagnostics": "0.0.1",
    "hubot-pugme": "~0.1.0",
    "hubot-youtube": "~0.1.2",
    "hubot-rules": "~0.1.0",
    "hubot-google-translate": "~0.1.0",
    "hubot-heroku-keepalive": "0.0.4",
    "hubot-shipit": "~0.1.1",
    "hubot-slack": "~2.2.0",
    "hubot-redis-brain": "0.0.2",
    "hubot-scripts": "~2.5.16",
    "hubot": "~2.9.3",
    "hubot-weather-ja": "0.0.1",
    "time": "~0.11.0",
    "cron": "~1.0.5",
    "circleci": "0.2.0",
    "aws-sdk": "~2.0.31"
  },
  "engines": {
    "node": "0.10.x"
  }
}
```

circleci.coffee

```coffeescript
cron = require('cron').CronJob
CircleCI = require('circleci')
ci = new CircleCI({
  auth: "Your API Key"
})

module.exports = (robot) ->
  robot.enter ->
  new cron
    cronTime: "00 00 14 * * *"
    start: true
    timeZone: "UTC"
    onTick: ->
      robot.send {room: "#dev", link_names: 1}, "start nightly build!"
      testExec()
  robot.respond /ios test/i, (msg) ->
    msg.reply "OK. ios test start"
    testExec()

testExec = () ->
  ci.startBuild({
    username: "Your username or Organization name",
    project: "Your Project Name",
    branch: "master"
  })
```

###気になるお値段
けっこう気に入ったので今後も使おうと思ってお値段を調べた所、1Containers 1Parallelism は Free と書いてあって「んなわけねーだろ」的な感じでまた問い合わせしてみました。
冗談かと思ったら本当みたいです。しかもPrivate Repositoryでも大丈夫とのこと。サイコーです！(´；ω；｀)ﾌﾞﾜｯ
（2015.01.06 現在　注・将来的にどうなるかはわからないです）

まだ試用期間が残ってるので、これが過ぎた後も本当に使えるかはこれから検証してみます。

![スクリーンショット 2015-01-06 1.07.55.png](https://qiita-image-store.s3.amazonaws.com/0/34824/d7452dd4-f786-7db4-703a-b78a1273906a.png)


##今後やりたいこと
Nightly buildしたりChatOpsしたりはできたので、次はTestFlight連携とかもしたいですね。(｀・ω・´)
あと[きしかわさんの記事](http://kishikawakatsumi.hatenablog.com/entry/20141022/1413963656)にあるような自動化も本当はしたかったのですが、残念ながらタイムアップです(´・ω・｀)

##まとめ
新年でテンション高まってうだうだ書いてしまったので、まとめ。
シンプルに書くとこの程度だったのか orz

 1. Githubアカウントを作る
 2. CircleCIのページからGithub連携でCircleCIのアカウントを作る
 3. `Project Setting -> Experimental Settings` をひらいて `Build iOS project` を on にする
 4. サポートに連絡して、iOSのCIを試したい旨お願いする
 5. しばし待つ
 6. 返信がきたら、再度ビルドを試してみる
 7. 管理画面（UI）or [circle.yml](http://qiita.com/saku/items/9c093535967e4452a8d0#%E6%9C%80%E7%B5%82%E7%9A%84%E3%81%AAcircleyml) で必要なフェーズで必要なコマンドを実行するように記載
 8. PRやマージのタイミングで自動的にテストが始まるのを確認する
 9. ﾆｯｺﾘ

追記もあるので、そちらもよかったら見てね。

##おわりに
今年もいろいろ隙を見計らって面白そうな技術に手を出していきたいと思います。
それともくもくiOS勉強会というのも隔週で定期的にやっていますので、もし詳しい話聞きたい！実際に動いてる所みたい！ということがあれば是非遊びにきてくださいませー。

もくもくiOS勉強会@Retty
http://connpass.com/series/748/