LoginSignup
42
39

More than 5 years have passed since last update.

ShippableでCI 完全マスター

Last updated at Posted at 2014-10-16

概要

これはCIサービスであるShippableの紹介と、Herokuを使用したCIのための具体的な設定について説明する記事である。

経緯

自前でホスティングしているJenkinsのメンテとかさむAWS EC2の費用が嫌になった俺達は、クラウド型CIサービスを探す旅に出たのだった。
Travis CIは試用してみたもののそもそもの値段で却下(でも100回分お試しは堪能しました)。CircleCIは最近流行ってきていて候補の筆頭に上がったものの、以前と課金体験が変わりテスト時間短縮のために並列に走らせると値段が高くなってしまうことを知ったのでテンションが下って却下。
どうせだったら先駆者になろう(ただポッと出のサービスですぐに終了してあとで大変になるのはNG)と、Leanstakにあるサービスを漁って見つけた「安い!速い!上手い!」を兼ね備えたのがこのShippableである(※なお日本語の記事もぐぐればある程度見つかりました)。ちなみに昨年末$2Mの調達をしている。

注意

意欲的なサービスで抜本的に変わったりしたことがあったり、機能追加や不具合修正などが日々なされているサービスなのでその点は注意。(サポートの窓口であるGithubIssuesを見るとよく分かります)

安い!速い!旨い!

安い!

  • Privateリポジトリであろうが完全無料で無制限にビルド可能
    • ただ制限として同時に走らせられるテストは1つのみ
    • しかしその制約さえ守れば、リポジトリ数に制限は無い
  • 5個並列にテストを走らせられるStartupプランは $12/YEAR !
    • YEARだよYEAH!
    • でも正直いつまでこれが続くのか不安だけどね!!

速い!

  • テストに使用したコンテナはキャッシュすることが可能
    • つまりどういうことかというと、テストはDcokerで取り扱えるコンテナが作成されそこで行われるのだが、テスト終了時にコンテナごと保存し次のテスト時に使いまわすことが可能
      • GemやDBに格納されているスキーマさえまるごと保存される
      • bundle installやrake db:migrateに取られる時間が減る!
    • この機能は現V2になった時一度無くなったのだが、数日前に復活した
      • ちなみにこの機能、V1ではデフォルトで有効(オプトアウトで無効)だった
      • (ただ機能が不安定な気がするんだけど気のせいかな……)
  • 安いにもある通り安価に、そして簡単に並列テストが出来る
    • (でも全てのテストが通った時のみafter_successを実行するparallelized_testフラグが効いていない気がするんだけど気のせいかな……)

旨い!

  • もちろんHerokuへのデプロイも意識している(公式にHeroku toolbeltを使ったデプロイサンプルもあるよ!)
  • 並列デプロイ時には複数のデプロイをデプロイグループとしてまとめて個別に表示
  • テストやカバレッジレポートを吐き出させればそれをウェブUI上で表示させることも可能
  • 一応、.travis.yml互換(Travis CIで使用しているリポジトリがそのまま動く……はず)
    • 余り入り組んだことはしていない私の過去のリポジトリはそのまま動いた

上記を網羅した設定例

  • Ruby on Railsを想定
  • PostgreSQLを想定 (Herokuなので)
    • ユーザとデータベースががまだ無い場合は作成
  • キャッシュ有効
  • 3並列テスト
  • テストとカバレッジレポートを出力
  • テスト成功後Herokuへデプロイ
shippable.yml
language: ruby
rvm:
  - 2.1.3
cache: true
parallelized_test: true
services:
  - mongodb
script:
  - RAILS_ENV=test bundle exec rake db:migrate
  - bundle exec parallel_test spec -n $PARA_NUM_GROUPS --only-group $PARA_GROUPS --group-by filesize --type rspec
env:
  matrix:
    - "PARA_NUM_GROUPS=3 PARA_GROUPS=1"
    - "PARA_NUM_GROUPS=3 PARA_GROUPS=2"
    - "PARA_NUM_GROUPS=3 PARA_GROUPS=3"
  global:
    - COVERAGE_REPORTS=shippable/codecoverage
    - SPEC_OPTS="--format RspecJunitFormatter --out shippable/testresults/results.xml"
    - APP_NAME=heroku_application_name
    - secure: # HEROKU_API_KEY=<your key here> を ENCRYPT ENV VARIABLE 機能で暗号化してここへ
before_install:
  - which heroku || wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh
after_success:
  - test -f ~/.ssh/id_rsa.heroku || ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.heroku && heroku keys:add ~/.ssh/id_rsa.heroku
  - git remote -v | grep ^heroku || heroku git:remote --app $APP_NAME
  - git push heroku master
  - heroku run rake db:migrate
before_script:
  - psql -c "CREATE EXTENSION IF NOT EXISTS dblink" -U postgres
  - |
    c="DO
    \$body\$
    BEGIN
       IF NOT EXISTS (
          SELECT 1
          FROM   pg_catalog.pg_user
          WHERE  usename = 'alice') THEN
          CREATE ROLE alice LOGIN PASSWORD 'password';
       END IF;
    END
    \$body\$
    "
  - psql -c "$c" -U postgres
  - |
    c="DO
    \$body\$
    BEGIN
       IF NOT EXISTS (
          SELECT 1
          FROM   pg_database
          WHERE  datname = 'web_application_test') THEN
          PERFORM dblink_exec('dbname=' || current_database(),
                              'CREATE DATABASE web_application_test OWNER alice;');
       END IF;
    END
    \$body\$
    "
  - psql -c "$c" -U postgres

Gemfile
gem "parallel_tests", group: :development

group :test do
  gem 'simplecov'
  gem 'simplecov-csv'
  gem 'rspec_junit_formatter'
spec/spec_helper.rb
require 'simplecov'
if ENV["COVERAGE_REPORTS"]
  require 'simplecov-csv'
  SimpleCov.formatter = SimpleCov::Formatter::CSVFormatter
  SimpleCov.coverage_dir(ENV["COVERAGE_REPORTS"])
end
SimpleCov.start 'rails'

おわりに

PostgreSQLでMySQLの"CREATE DATABASE IF NOT EXISTS db_name"相当のことするの面倒なんですね……(はっけん)

42
39
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
39