【TravisCI】travis.ymlに書くあれこれ

# TravisCIのビルドの流れを知ろう！
* 1. Githubから(.travis.ymlが配置されている)リポジトリをgit cloneする
 * git cloneの際に、オプション--depth=50が付いています 
* 2. cloneしたリポジトリに移動する
* 3. git checkoutしてコミットしたコードを取得する
 * .travis.ymlに書いた環境変数はここで適用される
* 4. キャッシュを使う場合、キャッシュを取得する
* 5. 使用するRubyのバージョンを指定する 
* 6. before_installで定義したものが実行される
 * キャッシュを使う場合、ここで追加される
* 7. installで定義したものが実行される
* 8. before_scriptで定義したものが実行される
* 9. scriptで定義したものが実行される
 * exitコードが0ならば成功、それ以外は失敗と判定される
* 10. after_successまたはafter_failureで定義したものが実行される
* 11. after_scriptで定義したものが実行される

# やりたいこと別に書き方をずらっと
* 「こんなことやりたいんだけど、どう書くのだっけ？」を解決する一枚になればと思い書き綴っていきます
* 言語はRubyとして書いていきます

## 言語を指定

```rb:.travis.yml
language: ruby
```

## 使用するRubyのバージョンを指定する

```rb:.travis.yml
rvm: 1.9.3
```

## 環境変数を定義する
* 暗号化したいものはtravis encriptコマンドを使用してsecure文字列を発行してやればよい
 * [Travis CIでsecret valueを扱う](http://qiita.com/arukoh@github/items/0315e6b2c1ac046ab34f) ( By @arukoh@github さん)の記事に詳しく書いてあります
 * travis encryptコマンドを実行する際に、-aオプションを付けると.travis.ymlのインデントがずれたりや付けているコメントが除去されるので注意！！

```rb:.travis.yml
env:
  global:
    - RAILS_ENV=development # Travisの場合デフォルトでtest
    - secure: "Vl4wZ31VKVsF+w2Vowv1l/hC6p1a7BR8......."
```

## ジョブを並行実行させて実行時間を短縮する
* 料金プランによって並行実行可能数は変わってきますが最低でも２つは可能なので並行実行させる価値があるケースは多いのかなと思います
* 利用すると良いケースの一例としては、Seleinumを使った受け入れテストがあるときに対象ブラウザとしてFirefoxとChromeの２つでそれぞれテストを実行しているなど
* ```$ bundle exec rake acceptance BROWSER=Firefox```でFirefoxを対象としたテストが実行できると仮定して、記述例を以下に示します

```rb:.travis.yml
env:
  matrix:
    - TEST_BROWSER='Firefox'
    - TEST_BROWSER='Chrome'
    
script: bundle exec rake acceptance BROWSER=$TEST_BROWSER
```

## ブランチを絞って実行するかどうかを決める
* 例えば、developブランチに.travis.ymlを置いていた場合
* featureブランチを切ってきたら、featureブランチのpushの度に実行されますよね
* これをやりたくないときは、TravisCIを実行する対象のブランチを絞り込めばいいのです
* 絞り込み方は「only(このブランチだけ)」と「except(このブランチ以外は)」の２つ
 * 正規表現で書くこともできます

```rb:travis.yml
# featureとtryブランチ以外のブランチは実行対象に入れる
branches:
  except: /^(feature|try).*$/

# masterとdevelopブランチのみ実行対象に入れる
branches:
  only: 
    - master
    - develop
```

## bundle installを毎回走らせないようにキャッシュする
* 詳細は[【TravisCI高速化】bundle installを毎回走らせないようにキャッシュする](http://qiita.com/oh_rusty_nail/items/374c30ecc5aa9997d1f3)に書いています
* 以下の書き方はどちらでも構いません

```rb:.travis.yml
# 書き方その１
language: ruby
install: bundle install --deployment
cache:
  directories: vendor/bundle

# 書き方その２
language: ruby
bundler_args: --deployment
cache: bundler
```

## SSHの設定をする
* Gemfileのソースにプライベートリポジトリを指定しているとき、設定しなければgit cloneに失敗するのです
* before_installで以下のように書いてやればよい
* .travis.ymlに書くこと以外に１つだけやっておかなければならないことがある
* 鍵の生成と鍵の暗号化
* 鍵は```$ ssh-keygen -f travis_key```で生成
* 鍵の暗号化については[TravisCIでファイルを(簡単に)暗号化して使用する](http://qiita.com/kmats@github/items/d22fd856883e6c16d7ea) ( By @kmats@github さん )に詳しく書いてあります
 * .travis.ymlに書くopensslコマンドもここで生成されますのでコピペするだけ
* あとは、RAILS_ROOTに.travisディレクトリを作成し、その中にtravis_key.encという名前で暗号化済の鍵を配置しておくだけ


```rb:.travis.yml
before_install:
  - eval `ssh-agent -s`
  - chmod 600 ~/.ssh/config
  - openssl aes-256-cbc -K $encrypted_XXXXXXXXX_key -iv $encrypted_XXXXXXXXX_iv -in .travis/travis_key.enc -out travis_key -d
  - cp travis_key ~/.ssh/
  - chmod 600 ~/.ssh/travis_key
  - ssh-add ~/.ssh/travis_key
```

## 成功/失敗後の処理を行う
* これはIRC通知なりメール送信なり何をやらせるかはその人次第なので書き方だけ

```rb:.travis.yml
# 成功時と失敗時にそれぞれスクリプトを実行させる例
after_success: .travis/after_success.sh
after_failure: .travis/after_failure.sh
```

# ～ただの宣伝～
* [全国のSeleniumer必読](http://qiita.com/oh_rusty_nail/items/b8ba525d31ea7c522856)
* Selenium, SauceLabs, Travis, Jenkinsに関するノウハウ書いているのでよかったら参考にしてみてください